Created
May 5, 2018 08:31
-
-
Save Kenshin/e842965019057899be8227206d7bff7c to your computer and use it in GitHub Desktop.
Firebug
This file has been truncated, but you can view the full file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function() { | |
/************************************************************** | |
* | |
* Firebug Lite 1.4.0 | |
* | |
* Copyright (c) 2007, Parakey Inc. | |
* Released under BSD license. | |
* More information: http://getfirebug.com/firebuglite | |
* | |
**************************************************************/ | |
/* | |
* CSS selectors powered by: | |
* | |
* 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 FBL = {}; (function() { | |
var productionDir = "http://getfirebug.com/releases/lite/"; | |
var bookmarkletVersion = 4; | |
var reNotWhitespace = /[^\s]/; | |
var reSplitFile = /:\/{1,3}(.*?)\/([^\/]*?)\/?($|\?.*)/; | |
this.reJavascript = /\s*javascript:\s*(.*)/; | |
this.reChrome = /chrome:\/\/([^\/]*)\//; | |
this.reFile = /file:\/\/([^\/]*)\//; | |
var userAgent = navigator.userAgent.toLowerCase(); | |
this.isFirefox = /firefox/.test(userAgent); | |
this.isOpera = /opera/.test(userAgent); | |
this.isSafari = /webkit/.test(userAgent); | |
this.isIE = /msie/.test(userAgent) && !/opera/.test(userAgent); | |
this.isIE6 = /msie 6/i.test(navigator.appVersion); | |
this.browserVersion = (userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [0, "0"])[1]; | |
this.isIElt8 = this.isIE && (this.browserVersion - 0 < 8); | |
this.NS = null; | |
this.pixelsPerInch = null; | |
var namespaces = []; | |
this.ns = function(fn) { | |
var ns = {}; | |
namespaces.push(fn, ns); | |
return ns | |
}; | |
var FBTrace = null; | |
this.initialize = function() { | |
if (window.firebug && firebug.firebuglite || window.console && console.firebuglite) { | |
return | |
} | |
if (FBL.FBTrace) { | |
FBTrace = FBL.FBTrace | |
} else { | |
FBTrace = FBL.FBTrace = {} | |
} | |
var isChromeContext = window.Firebug && typeof window.Firebug.SharedEnv == "object"; | |
if (isChromeContext) { | |
sharedEnv = window.Firebug.SharedEnv; | |
delete window.Firebug.SharedEnv; | |
FBL.Env = sharedEnv; | |
FBL.Env.isChromeContext = true; | |
FBTrace.messageQueue = FBL.Env.traceMessageQueue | |
} else { | |
FBL.NS = document.documentElement.namespaceURI; | |
FBL.Env.browser = window; | |
FBL.Env.destroy = destroyEnvironment; | |
if (document.documentElement.getAttribute("debug") == "true") { | |
FBL.Env.Options.startOpened = true | |
} | |
findLocation(); | |
var prefs = FBL.Store.get("FirebugLite") || {}; | |
FBL.Env.DefaultOptions = FBL.Env.Options; | |
FBL.Env.Options = FBL.extend(FBL.Env.Options, prefs.options || {}); | |
if (FBL.isFirefox && typeof FBL.Env.browser.console == "object" && FBL.Env.browser.console.firebug && FBL.Env.Options.disableWhenFirebugActive) { | |
return | |
} | |
} | |
if (FBL.Env.isDebugMode) { | |
FBL.Env.browser.FBL = FBL | |
} | |
this.isQuiksMode = FBL.Env.browser.document.compatMode == "BackCompat"; | |
this.isIEQuiksMode = this.isIE && this.isQuiksMode; | |
this.isIEStantandMode = this.isIE && !this.isQuiksMode; | |
this.noFixedPosition = this.isIE6 || this.isIEQuiksMode; | |
if (FBL.Env.Options.enableTrace) { | |
FBTrace.initialize() | |
} | |
if (FBTrace.DBG_INITIALIZE && isChromeContext) { | |
FBTrace.sysout("FBL.initialize - persistent application", "initialize chrome context") | |
} | |
if (FBTrace.DBG_INITIALIZE) { | |
FBTrace.sysout("FBL.initialize", namespaces.length / 2 + " namespaces BEGIN") | |
} | |
for (var i = 0; i < namespaces.length; i += 2) { | |
var fn = namespaces[i]; | |
var ns = namespaces[i + 1]; | |
fn.apply(ns) | |
} | |
if (FBTrace.DBG_INITIALIZE) { | |
FBTrace.sysout("FBL.initialize", namespaces.length / 2 + " namespaces END"); | |
FBTrace.sysout("FBL waitForDocument", "waiting document load") | |
} | |
FBL.Ajax.initialize(); | |
FBL.Firebug.loadPrefs(); | |
if (FBL.Env.Options.enablePersistent) { | |
if (isChromeContext) { | |
FBL.FirebugChrome.clone(FBL.Env.FirebugChrome) | |
} else { | |
FBL.Env.FirebugChrome = FBL.FirebugChrome; | |
FBL.Env.traceMessageQueue = FBTrace.messageQueue | |
} | |
} | |
waitForDocument() | |
}; | |
var waitForDocument = function waitForDocument() { | |
var doc = FBL.Env.browser.document; | |
var body = doc.getElementsByTagName("body")[0]; | |
if (body) { | |
calculatePixelsPerInch(doc, body); | |
onDocumentLoad() | |
} else { | |
setTimeout(waitForDocument, 50) | |
} | |
}; | |
var onDocumentLoad = function onDocumentLoad() { | |
if (FBTrace.DBG_INITIALIZE) { | |
FBTrace.sysout("FBL onDocumentLoad", "document loaded") | |
} | |
if (FBL.isIE6) { | |
fixIE6BackgroundImageCache() | |
} | |
if (FBL.Env.Options.enablePersistent && FBL.Env.isChromeContext) { | |
FBL.Firebug.initialize(); | |
if (!FBL.Env.isDevelopmentMode) { | |
sharedEnv.destroy(); | |
sharedEnv = null | |
} | |
} else { | |
FBL.FirebugChrome.create() | |
} | |
}; | |
var sharedEnv; | |
this.Env = { | |
Options: { | |
saveCookies: true, | |
saveWindowPosition: false, | |
saveCommandLineHistory: false, | |
startOpened: false, | |
startInNewWindow: false, | |
showIconWhenHidden: true, | |
overrideConsole: true, | |
ignoreFirebugElements: true, | |
disableWhenFirebugActive: true, | |
disableXHRListener: false, | |
disableResourceFetching: false, | |
enableTrace: false, | |
enablePersistent: false | |
}, | |
Location: { | |
sourceDir: null, | |
baseDir: null, | |
skinDir: null, | |
skin: null, | |
app: null | |
}, | |
skin: "xp", | |
useLocalSkin: false, | |
isDevelopmentMode: false, | |
isDebugMode: false, | |
isChromeContext: false, | |
browser: null, | |
chrome: null | |
}; | |
var destroyEnvironment = function destroyEnvironment() { | |
setTimeout(function() { | |
FBL = null | |
}, | |
100) | |
}; | |
var findLocation = function findLocation() { | |
var reFirebugFile = /(firebug-lite(?:-\w+)?(?:\.js|\.jgz))(?:#(.+))?$/; | |
var reGetFirebugSite = /(?:http|https):\/\/getfirebug.com\//; | |
var isGetFirebugSite; | |
var rePath = /^(.*\/)/; | |
var reProtocol = /^\w+:\/\//; | |
var path = null; | |
var doc = document; | |
var script = doc.getElementById("FirebugLite"); | |
var scriptSrc; | |
var hasSrcAttribute = true; | |
if (script) { | |
scriptSrc = script.src; | |
file = reFirebugFile.exec(scriptSrc); | |
var version = script.getAttribute("FirebugLite"); | |
var number = version ? parseInt(version) : 0; | |
if (!version || !number || number < bookmarkletVersion) { | |
FBL.Env.bookmarkletOutdated = true | |
} | |
} else { | |
for (var i = 0, | |
s = doc.getElementsByTagName("script"), si; si = s[i]; i++) { | |
var file = null; | |
if (si.nodeName.toLowerCase() == "script") { | |
if (file = reFirebugFile.exec(si.getAttribute("firebugSrc"))) { | |
scriptSrc = si.getAttribute("firebugSrc"); | |
hasSrcAttribute = false | |
} else { | |
if (file = reFirebugFile.exec(si.src)) { | |
scriptSrc = si.src | |
} else { | |
continue | |
} | |
} | |
script = si; | |
break | |
} | |
} | |
} | |
if (script) { | |
script.firebugIgnore = true | |
} | |
if (file) { | |
var fileName = file[1]; | |
var fileOptions = file[2]; | |
if (reProtocol.test(scriptSrc)) { | |
path = rePath.exec(scriptSrc)[1] | |
} else { | |
var r = rePath.exec(scriptSrc); | |
var src = r ? r[1] : scriptSrc; | |
var backDir = /^((?:\.\.\/)+)(.*)/.exec(src); | |
var reLastDir = /^(.*\/)[^\/]+\/$/; | |
path = rePath.exec(location.href)[1]; | |
if (backDir) { | |
var j = backDir[1].length / 3; | |
var p; | |
while (j-->0) { | |
path = reLastDir.exec(path)[1] | |
} | |
path += backDir[2] | |
} else { | |
if (src.indexOf("/") != -1) { | |
if (/^\.\/./.test(src)) { | |
path += src.substring(2) | |
} else { | |
if (/^\/./.test(src)) { | |
var domain = /^(\w+:\/\/[^\/]+)/.exec(path); | |
path = domain[1] + src | |
} else { | |
path += src | |
} | |
} | |
} | |
} | |
} | |
} | |
FBL.Env.isChromeExtension = script && script.getAttribute("extension") == "Chrome"; | |
if (FBL.Env.isChromeExtension) { | |
path = productionDir; | |
FBL.Env.bookmarkletOutdated = false; | |
script = { | |
innerHTML: "{showIconWhenHidden:false}" | |
} | |
} | |
isGetFirebugSite = reGetFirebugSite.test(path); | |
if (isGetFirebugSite && path.indexOf("/releases/lite/") == -1) { | |
path += "releases/lite/" + (fileName == "firebug-lite-beta.js" ? "beta/": "latest/") | |
} | |
var m = path && path.match(/([^\/]+)\/$/) || null; | |
if (path && m) { | |
var Env = FBL.Env; | |
Env.useLocalSkin = path.indexOf(location.protocol + "//" + location.host + "/") == 0 && !isGetFirebugSite; | |
if (fileName == "firebug-lite-dev.js") { | |
Env.isDevelopmentMode = true; | |
Env.isDebugMode = true | |
} else { | |
if (fileName == "firebug-lite-debug.js") { | |
Env.isDebugMode = true | |
} | |
} | |
if (Env.browser.document.documentElement.getAttribute("debug") == "true") { | |
Env.Options.startOpened = true | |
} | |
if (fileOptions) { | |
var options = fileOptions.split(","); | |
for (var i = 0, | |
length = options.length; i < length; i++) { | |
var option = options[i]; | |
var name, value; | |
if (option.indexOf("=") != -1) { | |
var parts = option.split("="); | |
name = parts[0]; | |
value = eval(unescape(parts[1])) | |
} else { | |
name = option; | |
value = true | |
} | |
if (name == "debug") { | |
Env.isDebugMode = !!value | |
} else { | |
if (name in Env.Options) { | |
Env.Options[name] = value | |
} else { | |
Env[name] = value | |
} | |
} | |
} | |
} | |
if (hasSrcAttribute) { | |
var innerOptions = FBL.trim(script.innerHTML); | |
if (innerOptions) { | |
var innerOptionsObject = eval("(" + innerOptions + ")"); | |
for (var name in innerOptionsObject) { | |
var value = innerOptionsObject[name]; | |
if (name == "debug") { | |
Env.isDebugMode = !!value | |
} else { | |
if (name in Env.Options) { | |
Env.Options[name] = value | |
} else { | |
Env[name] = value | |
} | |
} | |
} | |
} | |
} | |
if (!Env.Options.saveCookies) { | |
FBL.Store.remove("FirebugLite") | |
} | |
if (Env.isDebugMode) { | |
Env.Options.startOpened = true; | |
Env.Options.enableTrace = true; | |
Env.Options.disableWhenFirebugActive = false | |
} | |
var loc = Env.Location; | |
var isProductionRelease = path.indexOf(productionDir) != -1; | |
loc.sourceDir = path; | |
loc.baseDir = path.substr(0, path.length - m[1].length - 1); | |
loc.skinDir = (isProductionRelease ? path: loc.baseDir) + "skin/" + Env.skin + "/"; | |
loc.skin = loc.skinDir + "firebug.html"; | |
loc.app = path + fileName | |
} else { | |
throw new Error("Firebug Error: Library path not found") | |
} | |
}; | |
this.bind = function() { | |
var args = cloneArray(arguments), | |
fn = args.shift(), | |
object = args.shift(); | |
return function() { | |
return fn.apply(object, arrayInsert(cloneArray(args), 0, arguments)) | |
} | |
}; | |
this.bindFixed = function() { | |
var args = cloneArray(arguments), | |
fn = args.shift(), | |
object = args.shift(); | |
return function() { | |
return fn.apply(object, args) | |
} | |
}; | |
this.extend = function(l, r) { | |
var newOb = {}; | |
for (var n in l) { | |
newOb[n] = l[n] | |
} | |
for (var n in r) { | |
newOb[n] = r[n] | |
} | |
return newOb | |
}; | |
this.descend = function(prototypeParent, childProperties) { | |
function protoSetter() {} | |
protoSetter.prototype = prototypeParent; | |
var newOb = new protoSetter(); | |
for (var n in childProperties) { | |
newOb[n] = childProperties[n] | |
} | |
return newOb | |
}; | |
this.append = function(l, r) { | |
for (var n in r) { | |
l[n] = r[n] | |
} | |
return l | |
}; | |
this.keys = function(map) { | |
var keys = []; | |
try { | |
for (var name in map) { | |
keys.push(name) | |
} | |
} catch(exc) {} | |
return keys | |
}; | |
this.values = function(map) { | |
var values = []; | |
try { | |
for (var name in map) { | |
try { | |
values.push(map[name]) | |
} catch(exc) { | |
if (FBTrace.DBG_ERRORS) { | |
FBTrace.sysout("lib.values FAILED ", exc) | |
} | |
} | |
} | |
} catch(exc) { | |
if (FBTrace.DBG_ERRORS) { | |
FBTrace.sysout("lib.values FAILED ", exc) | |
} | |
} | |
return values | |
}; | |
this.remove = function(list, item) { | |
for (var i = 0; i < list.length; ++i) { | |
if (list[i] == item) { | |
list.splice(i, 1); | |
break | |
} | |
} | |
}; | |
this.sliceArray = function(array, index) { | |
var slice = []; | |
for (var i = index; i < array.length; ++i) { | |
slice.push(array[i]) | |
} | |
return slice | |
}; | |
function cloneArray(array, fn) { | |
var newArray = []; | |
if (fn) { | |
for (var i = 0; i < array.length; ++i) { | |
newArray.push(fn(array[i])) | |
} | |
} else { | |
for (var i = 0; i < array.length; ++i) { | |
newArray.push(array[i]) | |
} | |
} | |
return newArray | |
} | |
function extendArray(array, array2) { | |
var newArray = []; | |
newArray.push.apply(newArray, array); | |
newArray.push.apply(newArray, array2); | |
return newArray | |
} | |
this.extendArray = extendArray; | |
this.cloneArray = cloneArray; | |
function arrayInsert(array, index, other) { | |
for (var i = 0; i < other.length; ++i) { | |
array.splice(i + index, 0, other[i]) | |
} | |
return array | |
} | |
this.createStyleSheet = function(doc, url) { | |
var style = this.createElement("link"); | |
style.setAttribute("charset", "utf-8"); | |
style.firebugIgnore = true; | |
style.setAttribute("rel", "stylesheet"); | |
style.setAttribute("type", "text/css"); | |
style.setAttribute("href", url); | |
return style | |
}; | |
this.addStyleSheet = function(doc, style) { | |
var heads = doc.getElementsByTagName("head"); | |
if (heads.length) { | |
heads[0].appendChild(style) | |
} else { | |
doc.documentElement.appendChild(style) | |
} | |
}; | |
this.appendStylesheet = function(doc, uri) { | |
if (this.$(uri, doc)) { | |
return | |
} | |
var styleSheet = this.createStyleSheet(doc, uri); | |
styleSheet.setAttribute("id", uri); | |
this.addStyleSheet(doc, styleSheet) | |
}; | |
this.addScript = function(doc, id, src) { | |
var element = doc.createElementNS("http://www.w3.org/1999/xhtml", "html:script"); | |
element.setAttribute("type", "text/javascript"); | |
element.setAttribute("id", id); | |
if (!FBTrace.DBG_CONSOLE) { | |
FBL.unwrapObject(element).firebugIgnore = true | |
} | |
element.innerHTML = src; | |
if (doc.documentElement) { | |
doc.documentElement.appendChild(element) | |
} else { | |
if (FBTrace.DBG_ERRORS) { | |
FBTrace.sysout("lib.addScript doc has no documentElement:", doc) | |
} | |
} | |
return element | |
}; | |
this.getStyle = this.isIE ? | |
function(el, name) { | |
return el.currentStyle[name] || el.style[name] || undefined | |
}: function(el, name) { | |
return el.ownerDocument.defaultView.getComputedStyle(el, null)[name] || el.style[name] || undefined | |
}; | |
var entityConversionLists = this.entityConversionLists = { | |
normal: { | |
whitespace: { | |
"\t": "\u200c\u2192", | |
"\n": "\u200c\u00b6", | |
"\r": "\u200c\u00ac", | |
" ": "\u200c\u00b7" | |
} | |
}, | |
reverse: { | |
whitespace: { | |
"	": "\t", | |
"
": "\n", | |
"\u200c\u2192": "\t", | |
"\u200c\u00b6": "\n", | |
"\u200c\u00ac": "\r", | |
"\u200c\u00b7": " " | |
} | |
} | |
}; | |
var normal = entityConversionLists.normal, | |
reverse = entityConversionLists.reverse; | |
function addEntityMapToList(ccode, entity) { | |
var lists = Array.prototype.slice.call(arguments, 2), | |
len = lists.length, | |
ch = String.fromCharCode(ccode); | |
for (var i = 0; i < len; i++) { | |
var list = lists[i]; | |
normal[list] = normal[list] || {}; | |
normal[list][ch] = "&" + entity + ";"; | |
reverse[list] = reverse[list] || {}; | |
reverse[list]["&" + entity + ";"] = ch | |
} | |
} | |
var e = addEntityMapToList, | |
white = "whitespace", | |
text = "text", | |
attr = "attributes", | |
css = "css", | |
editor = "editor"; | |
e(34, "quot", attr, css); | |
e(38, "amp", attr, text, css); | |
e(39, "apos", css); | |
e(60, "lt", attr, text, css); | |
e(62, "gt", attr, text, css); | |
e(169, "copy", text, editor); | |
e(174, "reg", text, editor); | |
e(8482, "trade", text, editor); | |
e(8210, "#8210", attr, text, editor); | |
e(8211, "ndash", attr, text, editor); | |
e(8212, "mdash", attr, text, editor); | |
e(8213, "#8213", attr, text, editor); | |
e(160, "nbsp", attr, text, white, editor); | |
e(8194, "ensp", attr, text, white, editor); | |
e(8195, "emsp", attr, text, white, editor); | |
e(8201, "thinsp", attr, text, white, editor); | |
e(8204, "zwnj", attr, text, white, editor); | |
e(8205, "zwj", attr, text, white, editor); | |
e(8206, "lrm", attr, text, white, editor); | |
e(8207, "rlm", attr, text, white, editor); | |
e(8203, "#8203", attr, text, white, editor); | |
var entityConversionRegexes = { | |
normal: {}, | |
reverse: {} | |
}; | |
var escapeEntitiesRegEx = { | |
normal: function(list) { | |
var chars = []; | |
for (var ch in list) { | |
chars.push(ch) | |
} | |
return new RegExp("([" + chars.join("") + "])", "gm") | |
}, | |
reverse: function(list) { | |
var chars = []; | |
for (var ch in list) { | |
chars.push(ch) | |
} | |
return new RegExp("(" + chars.join("|") + ")", "gm") | |
} | |
}; | |
function getEscapeRegexp(direction, lists) { | |
var name = "", | |
re; | |
var groups = [].concat(lists); | |
for (i = 0; i < groups.length; i++) { | |
name += groups[i].group | |
} | |
re = entityConversionRegexes[direction][name]; | |
if (!re) { | |
var list = {}; | |
if (groups.length > 1) { | |
for (var i = 0; i < groups.length; i++) { | |
var aList = entityConversionLists[direction][groups[i].group]; | |
for (var item in aList) { | |
list[item] = aList[item] | |
} | |
} | |
} else { | |
if (groups.length == 1) { | |
list = entityConversionLists[direction][groups[0].group] | |
} else { | |
list = {} | |
} | |
} | |
re = entityConversionRegexes[direction][name] = escapeEntitiesRegEx[direction](list) | |
} | |
return re | |
} | |
function createSimpleEscape(name, direction) { | |
return function(value) { | |
var list = entityConversionLists[direction][name]; | |
return String(value).replace(getEscapeRegexp(direction, { | |
group: name, | |
list: list | |
}), | |
function(ch) { | |
return list[ch] | |
}) | |
} | |
} | |
function escapeGroupsForEntities(str, lists) { | |
lists = [].concat(lists); | |
var re = getEscapeRegexp("normal", lists), | |
split = String(str).split(re), | |
len = split.length, | |
results = [], | |
cur, | |
r, | |
i, | |
ri = 0, | |
l, | |
list, | |
last = ""; | |
if (!len) { | |
return [{ | |
str: String(str), | |
group: "", | |
name: "" | |
}] | |
} | |
for (i = 0; i < len; i++) { | |
cur = split[i]; | |
if (cur == "") { | |
continue | |
} | |
for (l = 0; l < lists.length; l++) { | |
list = lists[l]; | |
r = entityConversionLists.normal[list.group][cur]; | |
if (r) { | |
results[ri] = { | |
str: r, | |
"class": list["class"], | |
extra: list.extra[cur] ? list["class"] + list.extra[cur] : "" | |
}; | |
break | |
} | |
} | |
if (!r) { | |
results[ri] = { | |
str: cur, | |
"class": "", | |
extra: "" | |
} | |
} | |
ri++ | |
} | |
return results | |
} | |
this.escapeGroupsForEntities = escapeGroupsForEntities; | |
function unescapeEntities(str, lists) { | |
var re = getEscapeRegexp("reverse", lists), | |
split = String(str).split(re), | |
len = split.length, | |
results = [], | |
cur, | |
r, | |
i, | |
ri = 0, | |
l, | |
list; | |
if (!len) { | |
return str | |
} | |
lists = [].concat(lists); | |
for (i = 0; i < len; i++) { | |
cur = split[i]; | |
if (cur == "") { | |
continue | |
} | |
for (l = 0; l < lists.length; l++) { | |
list = lists[l]; | |
r = entityConversionLists.reverse[list.group][cur]; | |
if (r) { | |
results[ri] = r; | |
break | |
} | |
} | |
if (!r) { | |
results[ri] = cur | |
} | |
ri++ | |
} | |
return results.join("") || "" | |
} | |
var escapeForTextNode = this.escapeForTextNode = createSimpleEscape("text", "normal"); | |
var escapeForHtmlEditor = this.escapeForHtmlEditor = createSimpleEscape("editor", "normal"); | |
var escapeForElementAttribute = this.escapeForElementAttribute = createSimpleEscape("attributes", "normal"); | |
var escapeForCss = this.escapeForCss = createSimpleEscape("css", "normal"); | |
var escapeForSourceLine = this.escapeForSourceLine = createSimpleEscape("text", "normal"); | |
var unescapeWhitespace = createSimpleEscape("whitespace", "reverse"); | |
this.unescapeForTextNode = function(str) { | |
if (Firebug.showTextNodesWithWhitespace) { | |
str = unescapeWhitespace(str) | |
} | |
if (!Firebug.showTextNodesWithEntities) { | |
str = escapeForElementAttribute(str) | |
} | |
return str | |
}; | |
this.escapeNewLines = function(value) { | |
return value.replace(/\r/g, "\\r").replace(/\n/g, "\\n") | |
}; | |
this.stripNewLines = function(value) { | |
return typeof(value) == "string" ? value.replace(/[\r\n]/g, " ") : value | |
}; | |
this.escapeJS = function(value) { | |
return value.replace(/\r/g, "\\r").replace(/\n/g, "\\n").replace('"', '\\"', "g") | |
}; | |
function escapeHTMLAttribute(value) { | |
function replaceChars(ch) { | |
switch (ch) { | |
case "&": | |
return "&"; | |
case "'": | |
return apos; | |
case '"': | |
return quot | |
} | |
return "?" | |
} | |
var apos = "'", | |
quot = """, | |
around = '"'; | |
if (value.indexOf('"') == -1) { | |
quot = '"'; | |
apos = "'" | |
} else { | |
if (value.indexOf("'") == -1) { | |
quot = '"'; | |
around = "'" | |
} | |
} | |
return around + (String(value).replace(/[&'"]/g, replaceChars)) + around | |
} | |
function escapeHTML(value) { | |
function replaceChars(ch) { | |
switch (ch) { | |
case "<": | |
return "<"; | |
case ">": | |
return ">"; | |
case "&": | |
return "&"; | |
case "'": | |
return "'"; | |
case '"': | |
return """ | |
} | |
return "?" | |
} | |
return String(value).replace(/[<>&"']/g, replaceChars) | |
} | |
this.escapeHTML = escapeHTML; | |
this.cropString = function(text, limit) { | |
text = text + ""; | |
if (!limit) { | |
var halfLimit = 50 | |
} else { | |
var halfLimit = limit / 2 | |
} | |
if (text.length > limit) { | |
return this.escapeNewLines(text.substr(0, halfLimit) + "..." + text.substr(text.length - halfLimit)) | |
} else { | |
return this.escapeNewLines(text) | |
} | |
}; | |
this.isWhitespace = function(text) { | |
return ! reNotWhitespace.exec(text) | |
}; | |
this.splitLines = function(text) { | |
var reSplitLines2 = /.*(:?\r\n|\n|\r)?/mg; | |
var lines; | |
if (text.match) { | |
lines = text.match(reSplitLines2) | |
} else { | |
var str = text + ""; | |
lines = str.match(reSplitLines2) | |
} | |
lines.pop(); | |
return lines | |
}; | |
this.safeToString = function(ob) { | |
if (this.isIE) { | |
try { | |
return ob + "" | |
} catch(E) { | |
FBTrace.sysout("Lib.safeToString() failed for ", ob); | |
return "" | |
} | |
} | |
try { | |
if (ob && "toString" in ob && typeof ob.toString == "function") { | |
return ob.toString() | |
} | |
} catch(exc) { | |
return ob + "" | |
} | |
}; | |
this.hasProperties = function(ob) { | |
try { | |
for (var name in ob) { | |
return true | |
} | |
} catch(exc) {} | |
return false | |
}; | |
var reTrim = /^\s+|\s+$/g; | |
this.trim = function(s) { | |
return s.replace(reTrim, "") | |
}; | |
this.emptyFn = function() {}; | |
this.isVisible = function(elt) { | |
return this.getStyle(elt, "visibility") != "hidden" && (elt.offsetWidth > 0 || elt.offsetHeight > 0 || elt.tagName in invisibleTags || elt.namespaceURI == "http://www.w3.org/2000/svg" || elt.namespaceURI == "http://www.w3.org/1998/Math/MathML") | |
}; | |
this.collapse = function(elt, collapsed) { | |
if (this.isIElt8) { | |
if (collapsed) { | |
this.setClass(elt, "collapsed") | |
} else { | |
this.removeClass(elt, "collapsed") | |
} | |
} else { | |
elt.setAttribute("collapsed", collapsed ? "true": "false") | |
} | |
}; | |
this.obscure = function(elt, obscured) { | |
if (obscured) { | |
this.setClass(elt, "obscured") | |
} else { | |
this.removeClass(elt, "obscured") | |
} | |
}; | |
this.hide = function(elt, hidden) { | |
elt.style.visibility = hidden ? "hidden": "visible" | |
}; | |
this.clearNode = function(node) { | |
var nodeName = " " + node.nodeName.toLowerCase() + " "; | |
var ignoreTags = " table tbody thead tfoot th tr td "; | |
if (this.isIE && ignoreTags.indexOf(nodeName) != -1) { | |
this.eraseNode(node) | |
} else { | |
node.innerHTML = "" | |
} | |
}; | |
this.eraseNode = function(node) { | |
while (node.lastChild) { | |
node.removeChild(node.lastChild) | |
} | |
}; | |
this.iterateWindows = function(win, handler) { | |
if (!win || !win.document) { | |
return | |
} | |
handler(win); | |
if (win == top || !win.frames) { | |
return | |
} | |
for (var i = 0; i < win.frames.length; ++i) { | |
var subWin = win.frames[i]; | |
if (subWin != win) { | |
this.iterateWindows(subWin, handler) | |
} | |
} | |
}; | |
this.getRootWindow = function(win) { | |
for (; win; win = win.parent) { | |
if (!win.parent || win == win.parent || !this.instanceOf(win.parent, "Window")) { | |
return win | |
} | |
} | |
return null | |
}; | |
this.getClientOffset = function(elt) { | |
var addOffset = function addOffset(elt, coords, view) { | |
var p = elt.offsetParent; | |
var chrome = Firebug.chrome; | |
if (elt.offsetLeft) { | |
coords.x += elt.offsetLeft + chrome.getMeasurementInPixels(elt, "borderLeft") | |
} | |
if (elt.offsetTop) { | |
coords.y += elt.offsetTop + chrome.getMeasurementInPixels(elt, "borderTop") | |
} | |
if (p) { | |
if (p.nodeType == 1) { | |
addOffset(p, coords, view) | |
} | |
} else { | |
var otherView = isIE ? elt.ownerDocument.parentWindow: elt.ownerDocument.defaultView; | |
if (!otherView.opener && otherView.frameElement) { | |
addOffset(otherView.frameElement, coords, otherView) | |
} | |
} | |
}; | |
var isIE = this.isIE; | |
var coords = { | |
x: 0, | |
y: 0 | |
}; | |
if (elt) { | |
var view = isIE ? elt.ownerDocument.parentWindow: elt.ownerDocument.defaultView; | |
addOffset(elt, coords, view) | |
} | |
return coords | |
}; | |
this.getViewOffset = function(elt, singleFrame) { | |
function addOffset(elt, coords, view) { | |
var p = elt.offsetParent; | |
coords.x += elt.offsetLeft - (p ? p.scrollLeft: 0); | |
coords.y += elt.offsetTop - (p ? p.scrollTop: 0); | |
if (p) { | |
if (p.nodeType == 1) { | |
var parentStyle = view.getComputedStyle(p, ""); | |
if (parentStyle.position != "static") { | |
coords.x += parseInt(parentStyle.borderLeftWidth); | |
coords.y += parseInt(parentStyle.borderTopWidth); | |
if (p.localName == "TABLE") { | |
coords.x += parseInt(parentStyle.paddingLeft); | |
coords.y += parseInt(parentStyle.paddingTop) | |
} else { | |
if (p.localName == "BODY") { | |
var style = view.getComputedStyle(elt, ""); | |
coords.x += parseInt(style.marginLeft); | |
coords.y += parseInt(style.marginTop) | |
} | |
} | |
} else { | |
if (p.localName == "BODY") { | |
coords.x += parseInt(parentStyle.borderLeftWidth); | |
coords.y += parseInt(parentStyle.borderTopWidth) | |
} | |
} | |
var parent = elt.parentNode; | |
while (p != parent) { | |
coords.x -= parent.scrollLeft; | |
coords.y -= parent.scrollTop; | |
parent = parent.parentNode | |
} | |
addOffset(p, coords, view) | |
} | |
} else { | |
if (elt.localName == "BODY") { | |
var style = view.getComputedStyle(elt, ""); | |
coords.x += parseInt(style.borderLeftWidth); | |
coords.y += parseInt(style.borderTopWidth); | |
var htmlStyle = view.getComputedStyle(elt.parentNode, ""); | |
coords.x -= parseInt(htmlStyle.paddingLeft); | |
coords.y -= parseInt(htmlStyle.paddingTop) | |
} | |
if (elt.scrollLeft) { | |
coords.x += elt.scrollLeft | |
} | |
if (elt.scrollTop) { | |
coords.y += elt.scrollTop | |
} | |
var win = elt.ownerDocument.defaultView; | |
if (win && (!singleFrame && win.frameElement)) { | |
addOffset(win.frameElement, coords, win) | |
} | |
} | |
} | |
var coords = { | |
x: 0, | |
y: 0 | |
}; | |
if (elt) { | |
addOffset(elt, coords, elt.ownerDocument.defaultView) | |
} | |
return coords | |
}; | |
this.getLTRBWH = function(elt) { | |
var bcrect, dims = { | |
left: 0, | |
top: 0, | |
right: 0, | |
bottom: 0, | |
width: 0, | |
height: 0 | |
}; | |
if (elt) { | |
bcrect = elt.getBoundingClientRect(); | |
dims.left = bcrect.left; | |
dims.top = bcrect.top; | |
dims.right = bcrect.right; | |
dims.bottom = bcrect.bottom; | |
if (bcrect.width) { | |
dims.width = bcrect.width; | |
dims.height = bcrect.height | |
} else { | |
dims.width = dims.right - dims.left; | |
dims.height = dims.bottom - dims.top | |
} | |
} | |
return dims | |
}; | |
this.applyBodyOffsets = function(elt, clientRect) { | |
var od = elt.ownerDocument; | |
if (!od.body) { | |
return clientRect | |
} | |
var style = od.defaultView.getComputedStyle(od.body, null); | |
var pos = style.getPropertyValue("position"); | |
if (pos === "absolute" || pos === "relative") { | |
var borderLeft = parseInt(style.getPropertyValue("border-left-width").replace("px", ""), 10) || 0; | |
var borderTop = parseInt(style.getPropertyValue("border-top-width").replace("px", ""), 10) || 0; | |
var paddingLeft = parseInt(style.getPropertyValue("padding-left").replace("px", ""), 10) || 0; | |
var paddingTop = parseInt(style.getPropertyValue("padding-top").replace("px", ""), 10) || 0; | |
var marginLeft = parseInt(style.getPropertyValue("margin-left").replace("px", ""), 10) || 0; | |
var marginTop = parseInt(style.getPropertyValue("margin-top").replace("px", ""), 10) || 0; | |
var offsetX = borderLeft + paddingLeft + marginLeft; | |
var offsetY = borderTop + paddingTop + marginTop; | |
clientRect.left -= offsetX; | |
clientRect.top -= offsetY; | |
clientRect.right -= offsetX; | |
clientRect.bottom -= offsetY | |
} | |
return clientRect | |
}; | |
this.getOffsetSize = function(elt) { | |
return { | |
width: elt.offsetWidth, | |
height: elt.offsetHeight | |
} | |
}; | |
this.getOverflowParent = function(element) { | |
for (var scrollParent = element.parentNode; scrollParent; scrollParent = scrollParent.offsetParent) { | |
if (scrollParent.scrollHeight > scrollParent.offsetHeight) { | |
return scrollParent | |
} | |
} | |
}; | |
this.isScrolledToBottom = function(element) { | |
var onBottom = (element.scrollTop + element.offsetHeight) == element.scrollHeight; | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("isScrolledToBottom offsetHeight: " + element.offsetHeight + " onBottom:" + onBottom) | |
} | |
return onBottom | |
}; | |
this.scrollToBottom = function(element) { | |
element.scrollTop = element.scrollHeight; | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("scrollToBottom reset scrollTop " + element.scrollTop + " = " + element.scrollHeight); | |
if (element.scrollHeight == element.offsetHeight) { | |
FBTrace.sysout("scrollToBottom attempt to scroll non-scrollable element " + element, element) | |
} | |
} | |
return (element.scrollTop == element.scrollHeight) | |
}; | |
this.move = function(element, x, y) { | |
element.style.left = x + "px"; | |
element.style.top = y + "px" | |
}; | |
this.resize = function(element, w, h) { | |
element.style.width = w + "px"; | |
element.style.height = h + "px" | |
}; | |
this.linesIntoCenterView = function(element, scrollBox) { | |
if (!scrollBox) { | |
scrollBox = this.getOverflowParent(element) | |
} | |
if (!scrollBox) { | |
return | |
} | |
var offset = this.getClientOffset(element); | |
var topSpace = offset.y - scrollBox.scrollTop; | |
var bottomSpace = (scrollBox.scrollTop + scrollBox.clientHeight) - (offset.y + element.offsetHeight); | |
if (topSpace < 0 || bottomSpace < 0) { | |
var split = (scrollBox.clientHeight / 2); | |
var centerY = offset.y - split; | |
scrollBox.scrollTop = centerY; | |
topSpace = split; | |
bottomSpace = split - element.offsetHeight | |
} | |
return { | |
before: Math.round((topSpace / element.offsetHeight) + 0.5), | |
after: Math.round((bottomSpace / element.offsetHeight) + 0.5) | |
} | |
}; | |
this.scrollIntoCenterView = function(element, scrollBox, notX, notY) { | |
if (!element) { | |
return | |
} | |
if (!scrollBox) { | |
scrollBox = this.getOverflowParent(element) | |
} | |
if (!scrollBox) { | |
return | |
} | |
var offset = this.getClientOffset(element); | |
if (!notY) { | |
var topSpace = offset.y - scrollBox.scrollTop; | |
var bottomSpace = (scrollBox.scrollTop + scrollBox.clientHeight) - (offset.y + element.offsetHeight); | |
if (topSpace < 0 || bottomSpace < 0) { | |
var centerY = offset.y - (scrollBox.clientHeight / 2); | |
scrollBox.scrollTop = centerY | |
} | |
} | |
if (!notX) { | |
var leftSpace = offset.x - scrollBox.scrollLeft; | |
var rightSpace = (scrollBox.scrollLeft + scrollBox.clientWidth) - (offset.x + element.clientWidth); | |
if (leftSpace < 0 || rightSpace < 0) { | |
var centerX = offset.x - (scrollBox.clientWidth / 2); | |
scrollBox.scrollLeft = centerX | |
} | |
} | |
if (FBTrace.DBG_SOURCEFILES) { | |
FBTrace.sysout("lib.scrollIntoCenterView ", "Element:" + element.innerHTML) | |
} | |
}; | |
var cssKeywordMap = null; | |
var cssPropNames = null; | |
var cssColorNames = null; | |
var imageRules = null; | |
this.getCSSKeywordsByProperty = function(propName) { | |
if (!cssKeywordMap) { | |
cssKeywordMap = {}; | |
for (var name in this.cssInfo) { | |
var list = []; | |
var types = this.cssInfo[name]; | |
for (var i = 0; i < types.length; ++i) { | |
var keywords = this.cssKeywords[types[i]]; | |
if (keywords) { | |
list.push.apply(list, keywords) | |
} | |
} | |
cssKeywordMap[name] = list | |
} | |
} | |
return propName in cssKeywordMap ? cssKeywordMap[propName] : [] | |
}; | |
this.getCSSPropertyNames = function() { | |
if (!cssPropNames) { | |
cssPropNames = []; | |
for (var name in this.cssInfo) { | |
cssPropNames.push(name) | |
} | |
} | |
return cssPropNames | |
}; | |
this.isColorKeyword = function(keyword) { | |
if (keyword == "transparent") { | |
return false | |
} | |
if (!cssColorNames) { | |
cssColorNames = []; | |
var colors = this.cssKeywords.color; | |
for (var i = 0; i < colors.length; ++i) { | |
cssColorNames.push(colors[i].toLowerCase()) | |
} | |
var systemColors = this.cssKeywords.systemColor; | |
for (var i = 0; i < systemColors.length; ++i) { | |
cssColorNames.push(systemColors[i].toLowerCase()) | |
} | |
} | |
return cssColorNames.indexOf ? cssColorNames.indexOf(keyword.toLowerCase()) != -1 : (" " + cssColorNames.join(" ") + " ").indexOf(" " + keyword.toLowerCase() + " ") != -1 | |
}; | |
this.isImageRule = function(rule) { | |
if (!imageRules) { | |
imageRules = []; | |
for (var i in this.cssInfo) { | |
var r = i.toLowerCase(); | |
var suffix = "image"; | |
if (r.match(suffix + "$") == suffix || r == "background") { | |
imageRules.push(r) | |
} | |
} | |
} | |
return imageRules.indexOf ? imageRules.indexOf(rule.toLowerCase()) != -1 : (" " + imageRules.join(" ") + " ").indexOf(" " + rule.toLowerCase() + " ") != -1 | |
}; | |
this.copyTextStyles = function(fromNode, toNode, style) { | |
var view = this.isIE ? fromNode.ownerDocument.parentWindow: fromNode.ownerDocument.defaultView; | |
if (view) { | |
if (!style) { | |
style = this.isIE ? fromNode.currentStyle: view.getComputedStyle(fromNode, "") | |
} | |
toNode.style.fontFamily = style.fontFamily; | |
toNode.style.fontSize = style.fontSize; | |
toNode.style.fontWeight = style.fontWeight; | |
toNode.style.fontStyle = style.fontStyle; | |
return style | |
} | |
}; | |
this.copyBoxStyles = function(fromNode, toNode, style) { | |
var view = this.isIE ? fromNode.ownerDocument.parentWindow: fromNode.ownerDocument.defaultView; | |
if (view) { | |
if (!style) { | |
style = this.isIE ? fromNode.currentStyle: view.getComputedStyle(fromNode, "") | |
} | |
toNode.style.marginTop = style.marginTop; | |
toNode.style.marginRight = style.marginRight; | |
toNode.style.marginBottom = style.marginBottom; | |
toNode.style.marginLeft = style.marginLeft; | |
toNode.style.borderTopWidth = style.borderTopWidth; | |
toNode.style.borderRightWidth = style.borderRightWidth; | |
toNode.style.borderBottomWidth = style.borderBottomWidth; | |
toNode.style.borderLeftWidth = style.borderLeftWidth; | |
return style | |
} | |
}; | |
this.readBoxStyles = function(style) { | |
var styleNames = { | |
"margin-top": "marginTop", | |
"margin-right": "marginRight", | |
"margin-left": "marginLeft", | |
"margin-bottom": "marginBottom", | |
"border-top-width": "borderTop", | |
"border-right-width": "borderRight", | |
"border-left-width": "borderLeft", | |
"border-bottom-width": "borderBottom", | |
"padding-top": "paddingTop", | |
"padding-right": "paddingRight", | |
"padding-left": "paddingLeft", | |
"padding-bottom": "paddingBottom", | |
"z-index": "zIndex" | |
}; | |
var styles = {}; | |
for (var styleName in styleNames) { | |
styles[styleNames[styleName]] = parseInt(style.getPropertyCSSValue(styleName).cssText) || 0 | |
} | |
if (FBTrace.DBG_INSPECT) { | |
FBTrace.sysout("readBoxStyles ", styles) | |
} | |
return styles | |
}; | |
this.getBoxFromStyles = function(style, element) { | |
var args = this.readBoxStyles(style); | |
args.width = element.offsetWidth - (args.paddingLeft + args.paddingRight + args.borderLeft + args.borderRight); | |
args.height = element.offsetHeight - (args.paddingTop + args.paddingBottom + args.borderTop + args.borderBottom); | |
return args | |
}; | |
this.getElementCSSSelector = function(element) { | |
var label = element.localName.toLowerCase(); | |
if (element.id) { | |
label += "#" + element.id | |
} | |
if (element.hasAttribute("class")) { | |
label += "." + element.getAttribute("class").split(" ")[0] | |
} | |
return label | |
}; | |
this.getURLForStyleSheet = function(styleSheet) { | |
return (styleSheet.href ? styleSheet.href: styleSheet.ownerNode.ownerDocument.URL) | |
}; | |
this.getDocumentForStyleSheet = function(styleSheet) { | |
while (styleSheet.parentStyleSheet && !styleSheet.ownerNode) { | |
styleSheet = styleSheet.parentStyleSheet | |
} | |
if (styleSheet.ownerNode) { | |
return styleSheet.ownerNode.ownerDocument | |
} | |
}; | |
this.getInstanceForStyleSheet = function(styleSheet, ownerDocument) { | |
if (FBL.isSystemStyleSheet(styleSheet)) { | |
return 0 | |
} | |
if (FBTrace.DBG_CSS) { | |
FBTrace.sysout("getInstanceForStyleSheet: " + styleSheet.href + " " + styleSheet.media.mediaText + " " + (styleSheet.ownerNode && FBL.getElementXPath(styleSheet.ownerNode)), ownerDocument) | |
} | |
ownerDocument = ownerDocument || FBL.getDocumentForStyleSheet(styleSheet); | |
var ret = 0, | |
styleSheets = ownerDocument.styleSheets, | |
href = styleSheet.href; | |
for (var i = 0; i < styleSheets.length; i++) { | |
var curSheet = styleSheets[i]; | |
if (FBTrace.DBG_CSS) { | |
FBTrace.sysout("getInstanceForStyleSheet: compare href " + i + " " + curSheet.href + " " + curSheet.media.mediaText + " " + (curSheet.ownerNode && FBL.getElementXPath(curSheet.ownerNode))) | |
} | |
if (curSheet == styleSheet) { | |
break | |
} | |
if (curSheet.href == href) { | |
ret++ | |
} | |
} | |
return ret | |
}; | |
var getElementType = this.getElementType = function(node) { | |
if (isElementXUL(node)) { | |
return "xul" | |
} else { | |
if (isElementSVG(node)) { | |
return "svg" | |
} else { | |
if (isElementMathML(node)) { | |
return "mathml" | |
} else { | |
if (isElementXHTML(node)) { | |
return "xhtml" | |
} else { | |
if (isElementHTML(node)) { | |
return "html" | |
} | |
} | |
} | |
} | |
} | |
}; | |
var getElementSimpleType = this.getElementSimpleType = function(node) { | |
if (isElementSVG(node)) { | |
return "svg" | |
} else { | |
if (isElementMathML(node)) { | |
return "mathml" | |
} else { | |
return "html" | |
} | |
} | |
}; | |
var isElementHTML = this.isElementHTML = function(node) { | |
return node.nodeName == node.nodeName.toUpperCase() | |
}; | |
var isElementXHTML = this.isElementXHTML = function(node) { | |
return node.nodeName == node.nodeName.toLowerCase() | |
}; | |
var isElementMathML = this.isElementMathML = function(node) { | |
return node.namespaceURI == "http://www.w3.org/1998/Math/MathML" | |
}; | |
var isElementSVG = this.isElementSVG = function(node) { | |
return node.namespaceURI == "http://www.w3.org/2000/svg" | |
}; | |
var isElementXUL = this.isElementXUL = function(node) { | |
return node instanceof XULElement | |
}; | |
this.isSelfClosing = function(element) { | |
if (isElementSVG(element) || isElementMathML(element)) { | |
return true | |
} | |
var tag = element.localName.toLowerCase(); | |
return (this.selfClosingTags.hasOwnProperty(tag)) | |
}; | |
this.getElementHTML = function(element) { | |
var self = this; | |
function toHTML(elt) { | |
if (elt.nodeType == Node.ELEMENT_NODE) { | |
if (unwrapObject(elt).firebugIgnore) { | |
return | |
} | |
html.push("<", elt.nodeName.toLowerCase()); | |
for (var i = 0; i < elt.attributes.length; ++i) { | |
var attr = elt.attributes[i]; | |
if (attr.localName.indexOf("firebug-") == 0) { | |
continue | |
} | |
if (attr.localName.indexOf("-moz-math") == 0) { | |
continue | |
} | |
html.push(" ", attr.nodeName, '="', escapeForElementAttribute(attr.nodeValue), '"') | |
} | |
if (elt.firstChild) { | |
html.push(">"); | |
var pureText = true; | |
for (var child = element.firstChild; child; child = child.nextSibling) { | |
pureText = pureText && (child.nodeType == Node.TEXT_NODE) | |
} | |
if (pureText) { | |
html.push(escapeForHtmlEditor(elt.textContent)) | |
} else { | |
for (var child = elt.firstChild; child; child = child.nextSibling) { | |
toHTML(child) | |
} | |
} | |
html.push("</", elt.nodeName.toLowerCase(), ">") | |
} else { | |
if (isElementSVG(elt) || isElementMathML(elt)) { | |
html.push("/>") | |
} else { | |
if (self.isSelfClosing(elt)) { | |
html.push((isElementXHTML(elt)) ? "/>": ">") | |
} else { | |
html.push("></", elt.nodeName.toLowerCase(), ">") | |
} | |
} | |
} | |
} else { | |
if (elt.nodeType == Node.TEXT_NODE) { | |
html.push(escapeForTextNode(elt.textContent)) | |
} else { | |
if (elt.nodeType == Node.CDATA_SECTION_NODE) { | |
html.push("<![CDATA[", elt.nodeValue, "]]>") | |
} else { | |
if (elt.nodeType == Node.COMMENT_NODE) { | |
html.push("<!--", elt.nodeValue, "-->") | |
} | |
} | |
} | |
} | |
} | |
var html = []; | |
toHTML(element); | |
return html.join("") | |
}; | |
this.getElementXML = function(element) { | |
function toXML(elt) { | |
if (elt.nodeType == Node.ELEMENT_NODE) { | |
if (unwrapObject(elt).firebugIgnore) { | |
return | |
} | |
xml.push("<", elt.nodeName.toLowerCase()); | |
for (var i = 0; i < elt.attributes.length; ++i) { | |
var attr = elt.attributes[i]; | |
if (attr.localName.indexOf("firebug-") == 0) { | |
continue | |
} | |
if (attr.localName.indexOf("-moz-math") == 0) { | |
continue | |
} | |
xml.push(" ", attr.nodeName, '="', escapeForElementAttribute(attr.nodeValue), '"') | |
} | |
if (elt.firstChild) { | |
xml.push(">"); | |
for (var child = elt.firstChild; child; child = child.nextSibling) { | |
toXML(child) | |
} | |
xml.push("</", elt.nodeName.toLowerCase(), ">") | |
} else { | |
xml.push("/>") | |
} | |
} else { | |
if (elt.nodeType == Node.TEXT_NODE) { | |
xml.push(elt.nodeValue) | |
} else { | |
if (elt.nodeType == Node.CDATA_SECTION_NODE) { | |
xml.push("<![CDATA[", elt.nodeValue, "]]>") | |
} else { | |
if (elt.nodeType == Node.COMMENT_NODE) { | |
xml.push("<!--", elt.nodeValue, "-->") | |
} | |
} | |
} | |
} | |
} | |
var xml = []; | |
toXML(element); | |
return xml.join("") | |
}; | |
this.hasClass = function(node, name) { | |
if (arguments.length == 2) { | |
return (" " + node.className + " ").indexOf(" " + name + " ") != -1 | |
} | |
if (!node || node.nodeType != 1) { | |
return false | |
} else { | |
for (var i = 1; i < arguments.length; ++i) { | |
var name = arguments[i]; | |
var re = new RegExp("(^|\\s)" + name + "($|\\s)"); | |
if (!re.exec(node.className)) { | |
return false | |
} | |
} | |
return true | |
} | |
}; | |
this.old_hasClass = function(node, name) { | |
if (!node || node.nodeType != 1) { | |
return false | |
} else { | |
for (var i = 1; i < arguments.length; ++i) { | |
var name = arguments[i]; | |
var re = new RegExp("(^|\\s)" + name + "($|\\s)"); | |
if (!re.exec(node.className)) { | |
return false | |
} | |
} | |
return true | |
} | |
}; | |
this.setClass = function(node, name) { | |
if (node && (" " + node.className + " ").indexOf(" " + name + " ") == -1) { | |
node.className += " " + name | |
} | |
}; | |
this.getClassValue = function(node, name) { | |
var re = new RegExp(name + "-([^ ]+)"); | |
var m = re.exec(node.className); | |
return m ? m[1] : "" | |
}; | |
this.removeClass = function(node, name) { | |
if (node && node.className) { | |
var index = node.className.indexOf(name); | |
if (index >= 0) { | |
var size = name.length; | |
node.className = node.className.substr(0, index - 1) + node.className.substr(index + size) | |
} | |
} | |
}; | |
this.toggleClass = function(elt, name) { | |
if ((" " + elt.className + " ").indexOf(" " + name + " ") != -1) { | |
this.removeClass(elt, name) | |
} else { | |
this.setClass(elt, name) | |
} | |
}; | |
this.setClassTimed = function(elt, name, context, timeout) { | |
if (!timeout) { | |
timeout = 1300 | |
} | |
if (elt.__setClassTimeout) { | |
context.clearTimeout(elt.__setClassTimeout) | |
} else { | |
this.setClass(elt, name) | |
} | |
elt.__setClassTimeout = context.setTimeout(function() { | |
delete elt.__setClassTimeout; | |
FBL.removeClass(elt, name) | |
}, | |
timeout) | |
}; | |
this.cancelClassTimed = function(elt, name, context) { | |
if (elt.__setClassTimeout) { | |
FBL.removeClass(elt, name); | |
context.clearTimeout(elt.__setClassTimeout); | |
delete elt.__setClassTimeout | |
} | |
}; | |
this.$ = function(id, doc) { | |
if (doc) { | |
return doc.getElementById(id) | |
} else { | |
return FBL.Firebug.chrome.document.getElementById(id) | |
} | |
}; | |
this.$$ = function(selector, doc) { | |
if (doc || !FBL.Firebug.chrome) { | |
return FBL.Firebug.Selector(selector, doc) | |
} else { | |
return FBL.Firebug.Selector(selector, FBL.Firebug.chrome.document) | |
} | |
}; | |
this.getChildByClass = function(node) { | |
for (var i = 1; i < arguments.length; ++i) { | |
var className = arguments[i]; | |
var child = node.firstChild; | |
node = null; | |
for (; child; child = child.nextSibling) { | |
if (this.hasClass(child, className)) { | |
node = child; | |
break | |
} | |
} | |
} | |
return node | |
}; | |
this.getAncestorByClass = function(node, className) { | |
for (var parent = node; parent; parent = parent.parentNode) { | |
if (this.hasClass(parent, className)) { | |
return parent | |
} | |
} | |
return null | |
}; | |
this.getElementsByClass = function(node, className) { | |
var result = []; | |
for (var child = node.firstChild; child; child = child.nextSibling) { | |
if (this.hasClass(child, className)) { | |
result.push(child) | |
} | |
} | |
return result | |
}; | |
this.getElementByClass = function(node, className) { | |
var args = cloneArray(arguments); | |
args.splice(0, 1); | |
for (var child = node.firstChild; child; child = child.nextSibling) { | |
var args1 = cloneArray(args); | |
args1.unshift(child); | |
if (FBL.hasClass.apply(null, args1)) { | |
return child | |
} else { | |
var found = FBL.getElementByClass.apply(null, args1); | |
if (found) { | |
return found | |
} | |
} | |
} | |
return null | |
}; | |
this.isAncestor = function(node, potentialAncestor) { | |
for (var parent = node; parent; parent = parent.parentNode) { | |
if (parent == potentialAncestor) { | |
return true | |
} | |
} | |
return false | |
}; | |
this.getNextElement = function(node) { | |
while (node && node.nodeType != 1) { | |
node = node.nextSibling | |
} | |
return node | |
}; | |
this.getPreviousElement = function(node) { | |
while (node && node.nodeType != 1) { | |
node = node.previousSibling | |
} | |
return node | |
}; | |
this.getBody = function(doc) { | |
if (doc.body) { | |
return doc.body | |
} | |
var body = doc.getElementsByTagName("body")[0]; | |
if (body) { | |
return body | |
} | |
return doc.firstChild | |
}; | |
this.findNextDown = function(node, criteria) { | |
if (!node) { | |
return null | |
} | |
for (var child = node.firstChild; child; child = child.nextSibling) { | |
if (criteria(child)) { | |
return child | |
} | |
var next = this.findNextDown(child, criteria); | |
if (next) { | |
return next | |
} | |
} | |
}; | |
this.findPreviousUp = function(node, criteria) { | |
if (!node) { | |
return null | |
} | |
for (var child = node.lastChild; child; child = child.previousSibling) { | |
var next = this.findPreviousUp(child, criteria); | |
if (next) { | |
return next | |
} | |
if (criteria(child)) { | |
return child | |
} | |
} | |
}; | |
this.findNext = function(node, criteria, upOnly, maxRoot) { | |
if (!node) { | |
return null | |
} | |
if (!upOnly) { | |
var next = this.findNextDown(node, criteria); | |
if (next) { | |
return next | |
} | |
} | |
for (var sib = node.nextSibling; sib; sib = sib.nextSibling) { | |
if (criteria(sib)) { | |
return sib | |
} | |
var next = this.findNextDown(sib, criteria); | |
if (next) { | |
return next | |
} | |
} | |
if (node.parentNode && node.parentNode != maxRoot) { | |
return this.findNext(node.parentNode, criteria, true) | |
} | |
}; | |
this.findPrevious = function(node, criteria, downOnly, maxRoot) { | |
if (!node) { | |
return null | |
} | |
for (var sib = node.previousSibling; sib; sib = sib.previousSibling) { | |
var prev = this.findPreviousUp(sib, criteria); | |
if (prev) { | |
return prev | |
} | |
if (criteria(sib)) { | |
return sib | |
} | |
} | |
if (!downOnly) { | |
var next = this.findPreviousUp(node, criteria); | |
if (next) { | |
return next | |
} | |
} | |
if (node.parentNode && node.parentNode != maxRoot) { | |
if (criteria(node.parentNode)) { | |
return node.parentNode | |
} | |
return this.findPrevious(node.parentNode, criteria, true) | |
} | |
}; | |
this.getNextByClass = function(root, state) { | |
var iter = function iter(node) { | |
return node.nodeType == 1 && FBL.hasClass(node, state) | |
}; | |
return this.findNext(root, iter) | |
}; | |
this.getPreviousByClass = function(root, state) { | |
var iter = function iter(node) { | |
return node.nodeType == 1 && FBL.hasClass(node, state) | |
}; | |
return this.findPrevious(root, iter) | |
}; | |
this.isElement = function(o) { | |
try { | |
return o && this.instanceOf(o, "Element") | |
} catch(ex) { | |
return false | |
} | |
}; | |
var appendFragment = null; | |
this.appendInnerHTML = function(element, html, referenceElement) { | |
referenceElement = referenceElement || null; | |
var doc = element.ownerDocument; | |
if (doc.createRange) { | |
var range = doc.createRange(); | |
range.selectNodeContents(element); | |
var fragment = range.createContextualFragment(html); | |
var firstChild = fragment.firstChild; | |
element.insertBefore(fragment, referenceElement) | |
} else { | |
if (!appendFragment || appendFragment.ownerDocument != doc) { | |
appendFragment = doc.createDocumentFragment() | |
} | |
var div = doc.createElement("div"); | |
div.innerHTML = html; | |
var firstChild = div.firstChild; | |
while (div.firstChild) { | |
appendFragment.appendChild(div.firstChild) | |
} | |
element.insertBefore(appendFragment, referenceElement); | |
div = null | |
} | |
return firstChild | |
}; | |
this.createElement = function(tagName, properties) { | |
properties = properties || {}; | |
var doc = properties.document || FBL.Firebug.chrome.document; | |
var element = doc.createElement(tagName); | |
for (var name in properties) { | |
if (name != "document") { | |
element[name] = properties[name] | |
} | |
} | |
return element | |
}; | |
this.createGlobalElement = function(tagName, properties) { | |
properties = properties || {}; | |
var doc = FBL.Env.browser.document; | |
var element = this.NS && doc.createElementNS ? doc.createElementNS(FBL.NS, tagName) : doc.createElement(tagName); | |
for (var name in properties) { | |
var propname = name; | |
if (FBL.isIE && name == "class") { | |
propname = "className" | |
} | |
if (name != "document") { | |
element.setAttribute(propname, properties[name]) | |
} | |
} | |
return element | |
}; | |
this.safeGetWindowLocation = function(window) { | |
try { | |
if (window) { | |
if (window.closed) { | |
return "(window.closed)" | |
} | |
if ("location" in window) { | |
return window.location + "" | |
} else { | |
return "(no window.location)" | |
} | |
} else { | |
return "(no context.window)" | |
} | |
} catch(exc) { | |
if (FBTrace.DBG_WINDOWS || FBTrace.DBG_ERRORS) { | |
FBTrace.sysout("TabContext.getWindowLocation failed " + exc, exc) | |
} | |
FBTrace.sysout("TabContext.getWindowLocation failed window:", window); | |
return "(getWindowLocation: " + exc + ")" | |
} | |
}; | |
this.isLeftClick = function(event) { | |
return (this.isIE && event.type != "click" && event.type != "dblclick" ? event.button == 1 : event.button == 0) && this.noKeyModifiers(event) | |
}; | |
this.isMiddleClick = function(event) { | |
return (this.isIE && event.type != "click" && event.type != "dblclick" ? event.button == 4 : event.button == 1) && this.noKeyModifiers(event) | |
}; | |
this.isRightClick = function(event) { | |
return (this.isIE && event.type != "click" && event.type != "dblclick" ? event.button == 2 : event.button == 2) && this.noKeyModifiers(event) | |
}; | |
this.noKeyModifiers = function(event) { | |
return ! event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey | |
}; | |
this.isControlClick = function(event) { | |
return (this.isIE && event.type != "click" && event.type != "dblclick" ? event.button == 1 : event.button == 0) && this.isControl(event) | |
}; | |
this.isShiftClick = function(event) { | |
return (this.isIE && event.type != "click" && event.type != "dblclick" ? event.button == 1 : event.button == 0) && this.isShift(event) | |
}; | |
this.isControl = function(event) { | |
return (event.metaKey || event.ctrlKey) && !event.shiftKey && !event.altKey | |
}; | |
this.isAlt = function(event) { | |
return event.altKey && !event.ctrlKey && !event.shiftKey && !event.metaKey | |
}; | |
this.isAltClick = function(event) { | |
return (this.isIE && event.type != "click" && event.type != "dblclick" ? event.button == 1 : event.button == 0) && this.isAlt(event) | |
}; | |
this.isControlShift = function(event) { | |
return (event.metaKey || event.ctrlKey) && event.shiftKey && !event.altKey | |
}; | |
this.isShift = function(event) { | |
return event.shiftKey && !event.metaKey && !event.ctrlKey && !event.altKey | |
}; | |
this.addEvent = function(object, name, handler, useCapture) { | |
if (object.addEventListener) { | |
object.addEventListener(name, handler, useCapture) | |
} else { | |
object.attachEvent("on" + name, handler) | |
} | |
}; | |
this.removeEvent = function(object, name, handler, useCapture) { | |
try { | |
if (object.removeEventListener) { | |
object.removeEventListener(name, handler, useCapture) | |
} else { | |
object.detachEvent("on" + name, handler) | |
} | |
} catch(e) { | |
if (FBTrace.DBG_ERRORS) { | |
FBTrace.sysout("FBL.removeEvent error: ", object, name) | |
} | |
} | |
}; | |
this.cancelEvent = function(e, preventDefault) { | |
if (!e) { | |
return | |
} | |
if (preventDefault) { | |
if (e.preventDefault) { | |
e.preventDefault() | |
} else { | |
e.returnValue = false | |
} | |
} | |
if (e.stopPropagation) { | |
e.stopPropagation() | |
} else { | |
e.cancelBubble = true | |
} | |
}; | |
this.addGlobalEvent = function(name, handler) { | |
var doc = this.Firebug.browser.document; | |
var frames = this.Firebug.browser.window.frames; | |
this.addEvent(doc, name, handler); | |
if (this.Firebug.chrome.type == "popup") { | |
this.addEvent(this.Firebug.chrome.document, name, handler) | |
} | |
for (var i = 0, | |
frame; frame = frames[i]; i++) { | |
try { | |
this.addEvent(frame.document, name, handler) | |
} catch(E) {} | |
} | |
}; | |
this.removeGlobalEvent = function(name, handler) { | |
var doc = this.Firebug.browser.document; | |
var frames = this.Firebug.browser.window.frames; | |
this.removeEvent(doc, name, handler); | |
if (this.Firebug.chrome.type == "popup") { | |
this.removeEvent(this.Firebug.chrome.document, name, handler) | |
} | |
for (var i = 0, | |
frame; frame = frames[i]; i++) { | |
try { | |
this.removeEvent(frame.document, name, handler) | |
} catch(E) {} | |
} | |
}; | |
this.dispatch = function(listeners, name, args) { | |
if (!listeners) { | |
return | |
} | |
try { | |
if (typeof listeners.length != "undefined") { | |
if (FBTrace.DBG_DISPATCH) { | |
FBTrace.sysout("FBL.dispatch", name + " to " + listeners.length + " listeners") | |
} | |
for (var i = 0; i < listeners.length; ++i) { | |
var listener = listeners[i]; | |
if (listener[name]) { | |
listener[name].apply(listener, args) | |
} | |
} | |
} else { | |
if (FBTrace.DBG_DISPATCH) { | |
FBTrace.sysout("FBL.dispatch", name + " to listeners of an object") | |
} | |
for (var prop in listeners) { | |
var listener = listeners[prop]; | |
if (listener[name]) { | |
listener[name].apply(listener, args) | |
} | |
} | |
} | |
} catch(exc) { | |
if (FBTrace.DBG_ERRORS) { | |
FBTrace.sysout(" Exception in lib.dispatch " + name, exc) | |
} | |
} | |
}; | |
var disableTextSelectionHandler = function(event) { | |
FBL.cancelEvent(event, true); | |
return false | |
}; | |
this.disableTextSelection = function(e) { | |
if (typeof e.onselectstart != "undefined") { | |
this.addEvent(e, "selectstart", disableTextSelectionHandler) | |
} else { | |
e.style.cssText = "user-select: none; -khtml-user-select: none; -moz-user-select: none;"; | |
if (!this.isFirefox) { | |
this.addEvent(e, "mousedown", disableTextSelectionHandler) | |
} | |
} | |
e.style.cursor = "default" | |
}; | |
this.restoreTextSelection = function(e) { | |
if (typeof e.onselectstart != "undefined") { | |
this.removeEvent(e, "selectstart", disableTextSelectionHandler) | |
} else { | |
e.style.cssText = "cursor: default;"; | |
if (!this.isFirefox) { | |
this.removeEvent(e, "mousedown", disableTextSelectionHandler) | |
} | |
} | |
}; | |
var eventTypes = { | |
composition: ["composition", "compositionstart", "compositionend"], | |
contextmenu: ["contextmenu"], | |
drag: ["dragenter", "dragover", "dragexit", "dragdrop", "draggesture"], | |
focus: ["focus", "blur"], | |
form: ["submit", "reset", "change", "select", "input"], | |
key: ["keydown", "keyup", "keypress"], | |
load: ["load", "beforeunload", "unload", "abort", "error"], | |
mouse: ["mousedown", "mouseup", "click", "dblclick", "mouseover", "mouseout", "mousemove"], | |
mutation: ["DOMSubtreeModified", "DOMNodeInserted", "DOMNodeRemoved", "DOMNodeRemovedFromDocument", "DOMNodeInsertedIntoDocument", "DOMAttrModified", "DOMCharacterDataModified"], | |
paint: ["paint", "resize", "scroll"], | |
scroll: ["overflow", "underflow", "overflowchanged"], | |
text: ["text"], | |
ui: ["DOMActivate", "DOMFocusIn", "DOMFocusOut"], | |
xul: ["popupshowing", "popupshown", "popuphiding", "popuphidden", "close", "command", "broadcast", "commandupdate"] | |
}; | |
this.getEventFamily = function(eventType) { | |
if (!this.families) { | |
this.families = {}; | |
for (var family in eventTypes) { | |
var types = eventTypes[family]; | |
for (var i = 0; i < types.length; ++i) { | |
this.families[types[i]] = family | |
} | |
} | |
} | |
return this.families[eventType] | |
}; | |
this.getFileName = function(url) { | |
var split = this.splitURLBase(url); | |
return split.name | |
}; | |
this.splitURLBase = function(url) { | |
if (this.isDataURL(url)) { | |
return this.splitDataURL(url) | |
} | |
return this.splitURLTrue(url) | |
}; | |
this.splitDataURL = function(url) { | |
var mark = url.indexOf(":", 3); | |
if (mark != 4) { | |
return false | |
} | |
var point = url.indexOf(",", mark + 1); | |
if (point < mark) { | |
return false | |
} | |
var props = { | |
encodedContent: url.substr(point + 1) | |
}; | |
var metadataBuffer = url.substr(mark + 1, point); | |
var metadata = metadataBuffer.split(";"); | |
for (var i = 0; i < metadata.length; i++) { | |
var nv = metadata[i].split("="); | |
if (nv.length == 2) { | |
props[nv[0]] = nv[1] | |
} | |
} | |
if (props.hasOwnProperty("fileName")) { | |
var caller_URL = decodeURIComponent(props.fileName); | |
var caller_split = this.splitURLTrue(caller_URL); | |
if (props.hasOwnProperty("baseLineNumber")) { | |
props.path = caller_split.path; | |
props.line = props.baseLineNumber; | |
var hint = decodeURIComponent(props.encodedContent.substr(0, 200)).replace(/\s*$/, ""); | |
props.name = "eval->" + hint | |
} else { | |
props.name = caller_split.name; | |
props.path = caller_split.path | |
} | |
} else { | |
if (!props.hasOwnProperty("path")) { | |
props.path = "data:" | |
} | |
if (!props.hasOwnProperty("name")) { | |
props.name = decodeURIComponent(props.encodedContent.substr(0, 200)).replace(/\s*$/, "") | |
} | |
} | |
return props | |
}; | |
this.splitURLTrue = function(url) { | |
var m = reSplitFile.exec(url); | |
if (!m) { | |
return { | |
name: url, | |
path: url | |
} | |
} else { | |
if (!m[2]) { | |
return { | |
path: m[1], | |
name: m[1] | |
} | |
} else { | |
return { | |
path: m[1], | |
name: m[2] + m[3] | |
} | |
} | |
} | |
}; | |
this.getFileExtension = function(url) { | |
if (!url) { | |
return null | |
} | |
var queryString = url.indexOf("?"); | |
if (queryString != -1) { | |
url = url.substr(0, queryString) | |
} | |
var lastDot = url.lastIndexOf("."); | |
return url.substr(lastDot + 1) | |
}; | |
this.isSystemURL = function(url) { | |
if (!url) { | |
return true | |
} | |
if (url.length == 0) { | |
return true | |
} | |
if (url[0] == "h") { | |
return false | |
} | |
if (url.substr(0, 9) == "resource:") { | |
return true | |
} else { | |
if (url.substr(0, 16) == "chrome://firebug") { | |
return true | |
} else { | |
if (url == "XPCSafeJSObjectWrapper.cpp") { | |
return true | |
} else { | |
if (url.substr(0, 6) == "about:") { | |
return true | |
} else { | |
if (url.indexOf("firebug-service.js") != -1) { | |
return true | |
} else { | |
return false | |
} | |
} | |
} | |
} | |
} | |
}; | |
this.isSystemPage = function(win) { | |
try { | |
var doc = win.document; | |
if (!doc) { | |
return false | |
} | |
if ((doc.styleSheets.length && doc.styleSheets[0].href == "chrome://global/content/xml/XMLPrettyPrint.css") || (doc.styleSheets.length > 1 && doc.styleSheets[1].href == "chrome://browser/skin/feeds/subscribe.css")) { | |
return true | |
} | |
return FBL.isSystemURL(win.location.href) | |
} catch(exc) { | |
ERROR("tabWatcher.isSystemPage document not ready:" + exc); | |
return false | |
} | |
}; | |
this.isSystemStyleSheet = function(sheet) { | |
var href = sheet && sheet.href; | |
return href && FBL.isSystemURL(href) | |
}; | |
this.getURIHost = function(uri) { | |
try { | |
if (uri) { | |
return uri.host | |
} else { | |
return "" | |
} | |
} catch(exc) { | |
return "" | |
} | |
}; | |
this.isLocalURL = function(url) { | |
if (url.substr(0, 5) == "file:") { | |
return true | |
} else { | |
if (url.substr(0, 8) == "wyciwyg:") { | |
return true | |
} else { | |
return false | |
} | |
} | |
}; | |
this.isDataURL = function(url) { | |
return (url && url.substr(0, 5) == "data:") | |
}; | |
this.getLocalPath = function(url) { | |
if (this.isLocalURL(url)) { | |
var fileHandler = ioService.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler); | |
var file = fileHandler.getFileFromURLSpec(url); | |
return file.path | |
} | |
}; | |
this.getURLFromLocalFile = function(file) { | |
var fileHandler = ioService.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler); | |
var URL = fileHandler.getURLSpecFromFile(file); | |
return URL | |
}; | |
this.getDataURLForContent = function(content, url) { | |
var uri = "data:text/html;"; | |
uri += "fileName=" + encodeURIComponent(url) + ","; | |
uri += encodeURIComponent(content); | |
return uri | |
}, | |
this.getDomain = function(url) { | |
var m = /[^:]+:\/{1,3}([^\/]+)/.exec(url); | |
return m ? m[1] : "" | |
}; | |
this.getURLPath = function(url) { | |
var m = /[^:]+:\/{1,3}[^\/]+(\/.*?)$/.exec(url); | |
return m ? m[1] : "" | |
}; | |
this.getPrettyDomain = function(url) { | |
var m = /[^:]+:\/{1,3}(www\.)?([^\/]+)/.exec(url); | |
return m ? m[2] : "" | |
}; | |
this.absoluteURL = function(url, baseURL) { | |
return this.absoluteURLWithDots(url, baseURL).replace("/./", "/", "g") | |
}; | |
this.absoluteURLWithDots = function(url, baseURL) { | |
if (url[0] == "?") { | |
return baseURL + url | |
} | |
var reURL = /(([^:]+:)\/{1,2}[^\/]*)(.*?)$/; | |
var m = reURL.exec(url); | |
if (m) { | |
return url | |
} | |
var m = reURL.exec(baseURL); | |
if (!m) { | |
return "" | |
} | |
var head = m[1]; | |
var tail = m[3]; | |
if (url.substr(0, 2) == "//") { | |
return m[2] + url | |
} else { | |
if (url[0] == "/") { | |
return head + url | |
} else { | |
if (tail[tail.length - 1] == "/") { | |
return baseURL + url | |
} else { | |
var parts = tail.split("/"); | |
return head + parts.slice(0, parts.length - 1).join("/") + "/" + url | |
} | |
} | |
} | |
}; | |
this.normalizeURL = function(url) { | |
if (!url) { | |
return "" | |
} | |
if (url.length < 255) { | |
url = url.replace(/[^\/]+\/\.\.\//, "", "g"); | |
url = url.replace(/#.*/, ""); | |
url = url.replace(/file:\/([^\/])/g, "file:///$1"); | |
if (url.indexOf("chrome:") == 0) { | |
var m = reChromeCase.exec(url); | |
if (m) { | |
url = "chrome://" + m[1].toLowerCase() + "/" + m[2] | |
} | |
} | |
} | |
return url | |
}; | |
this.denormalizeURL = function(url) { | |
return url.replace(/file:\/\/\//g, "file:/") | |
}; | |
this.parseURLParams = function(url) { | |
var q = url ? url.indexOf("?") : -1; | |
if (q == -1) { | |
return [] | |
} | |
var search = url.substr(q + 1); | |
var h = search.lastIndexOf("#"); | |
if (h != -1) { | |
search = search.substr(0, h) | |
} | |
if (!search) { | |
return [] | |
} | |
return this.parseURLEncodedText(search) | |
}; | |
this.parseURLEncodedText = function(text) { | |
var maxValueLength = 25000; | |
var params = []; | |
text = text.replace(/\+/g, " "); | |
var args = text.split("&"); | |
for (var i = 0; i < args.length; ++i) { | |
try { | |
var parts = args[i].split("="); | |
if (parts.length == 2) { | |
if (parts[1].length > maxValueLength) { | |
parts[1] = this.$STR("LargeData") | |
} | |
params.push({ | |
name: decodeURIComponent(parts[0]), | |
value: decodeURIComponent(parts[1]) | |
}) | |
} else { | |
params.push({ | |
name: decodeURIComponent(parts[0]), | |
value: "" | |
}) | |
} | |
} catch(e) { | |
if (FBTrace.DBG_ERRORS) { | |
FBTrace.sysout("parseURLEncodedText EXCEPTION ", e); | |
FBTrace.sysout("parseURLEncodedText EXCEPTION URI", args[i]) | |
} | |
} | |
} | |
params.sort(function(a, b) { | |
return a.name <= b.name ? -1 : 1 | |
}); | |
return params | |
}; | |
this.parseURLParamsArray = function(url) { | |
var q = url ? url.indexOf("?") : -1; | |
if (q == -1) { | |
return [] | |
} | |
var search = url.substr(q + 1); | |
var h = search.lastIndexOf("#"); | |
if (h != -1) { | |
search = search.substr(0, h) | |
} | |
if (!search) { | |
return [] | |
} | |
return this.parseURLEncodedTextArray(search) | |
}; | |
this.parseURLEncodedTextArray = function(text) { | |
var maxValueLength = 25000; | |
var params = []; | |
text = text.replace(/\+/g, " "); | |
var args = text.split("&"); | |
for (var i = 0; i < args.length; ++i) { | |
try { | |
var parts = args[i].split("="); | |
if (parts.length == 2) { | |
if (parts[1].length > maxValueLength) { | |
parts[1] = this.$STR("LargeData") | |
} | |
params.push({ | |
name: decodeURIComponent(parts[0]), | |
value: [decodeURIComponent(parts[1])] | |
}) | |
} else { | |
params.push({ | |
name: decodeURIComponent(parts[0]), | |
value: [""] | |
}) | |
} | |
} catch(e) { | |
if (FBTrace.DBG_ERRORS) { | |
FBTrace.sysout("parseURLEncodedText EXCEPTION ", e); | |
FBTrace.sysout("parseURLEncodedText EXCEPTION URI", args[i]) | |
} | |
} | |
} | |
params.sort(function(a, b) { | |
return a.name <= b.name ? -1 : 1 | |
}); | |
return params | |
}; | |
this.reEncodeURL = function(file, text) { | |
var lines = text.split("\n"); | |
var params = this.parseURLEncodedText(lines[lines.length - 1]); | |
var args = []; | |
for (var i = 0; i < params.length; ++i) { | |
args.push(encodeURIComponent(params[i].name) + "=" + encodeURIComponent(params[i].value)) | |
} | |
var url = file.href; | |
url += (url.indexOf("?") == -1 ? "?": "&") + args.join("&"); | |
return url | |
}; | |
this.getResource = function(aURL) { | |
try { | |
var channel = ioService.newChannel(aURL, null, null); | |
var input = channel.open(); | |
return FBL.readFromStream(input) | |
} catch(e) { | |
if (FBTrace.DBG_ERRORS) { | |
FBTrace.sysout("lib.getResource FAILS for " + aURL, e) | |
} | |
} | |
}; | |
this.parseJSONString = function(jsonString, originURL) { | |
var regex = new RegExp(/^\/\*-secure-([\s\S]*)\*\/\s*$/); | |
var matches = regex.exec(jsonString); | |
if (matches) { | |
jsonString = matches[1]; | |
if (jsonString[0] == "\\" && jsonString[1] == "n") { | |
jsonString = jsonString.substr(2) | |
} | |
if (jsonString[jsonString.length - 2] == "\\" && jsonString[jsonString.length - 1] == "n") { | |
jsonString = jsonString.substr(0, jsonString.length - 2) | |
} | |
} | |
if (jsonString.indexOf("&&&START&&&")) { | |
regex = new RegExp(/&&&START&&& (.+) &&&END&&&/); | |
matches = regex.exec(jsonString); | |
if (matches) { | |
jsonString = matches[1] | |
} | |
} | |
jsonString = "(" + jsonString + ")"; | |
var jsonObject = null; | |
try { | |
jsonObject = Firebug.context.evaluate(jsonString, null, null, | |
function() { | |
return null | |
}) | |
} catch(e) { | |
if (FBTrace.DBG_ERRORS || FBTrace.DBG_JSONVIEWER) { | |
FBTrace.sysout("jsonviewer.parseJSON EXCEPTION", e) | |
} | |
return null | |
} | |
return jsonObject | |
}; | |
this.objectToString = function(object) { | |
try { | |
return object + "" | |
} catch(exc) { | |
return null | |
} | |
}; | |
this.setSelectionRange = function(input, start, length) { | |
if (input.createTextRange) { | |
var range = input.createTextRange(); | |
range.moveStart("character", start); | |
range.moveEnd("character", length - input.value.length); | |
range.select() | |
} else { | |
if (input.setSelectionRange) { | |
input.setSelectionRange(start, length); | |
input.focus() | |
} | |
} | |
}; | |
this.getInputSelectionStart = function(input) { | |
if (document.selection) { | |
var range = input.ownerDocument.selection.createRange(); | |
var text = range.text; | |
if (text) { | |
return input.value.indexOf(text) | |
} else { | |
range.moveStart("character", -input.value.length); | |
return range.text.length | |
} | |
} else { | |
if (typeof input.selectionStart != "undefined") { | |
return input.selectionStart | |
} | |
} | |
return 0 | |
}; | |
function onOperaTabBlur(e) { | |
if (this.lastKey == 9) { | |
this.focus() | |
} | |
} | |
function onOperaTabKeyDown(e) { | |
this.lastKey = e.keyCode | |
} | |
function onOperaTabFocus(e) { | |
this.lastKey = null | |
} | |
this.fixOperaTabKey = function(el) { | |
el.onfocus = onOperaTabFocus; | |
el.onblur = onOperaTabBlur; | |
el.onkeydown = onOperaTabKeyDown | |
}; | |
this.Property = function(object, name) { | |
this.object = object; | |
this.name = name; | |
this.getObject = function() { | |
return object[name] | |
} | |
}; | |
this.ErrorCopy = function(message) { | |
this.message = message | |
}; | |
function EventCopy(event) { | |
for (var name in event) { | |
try { | |
this[name] = event[name] | |
} catch(exc) {} | |
} | |
} | |
this.EventCopy = EventCopy; | |
var toString = Object.prototype.toString; | |
var reFunction = /^\s*function(\s+[\w_$][\w\d_$]*)?\s*\(/; | |
this.isArray = function(object) { | |
return toString.call(object) === "[object Array]" | |
}; | |
this.isFunction = function(object) { | |
if (!object) { | |
return false | |
} | |
try { | |
return toString.call(object) === "[object Function]" || this.isIE && typeof object != "string" && reFunction.test("" + object) | |
} catch(E) { | |
FBTrace.sysout("Lib.isFunction() failed for ", object); | |
return false | |
} | |
}; | |
this.instanceOf = function(object, className) { | |
if (!object || typeof object != "object") { | |
return false | |
} | |
if (object.ownerDocument) { | |
var win = object.ownerDocument.defaultView || object.ownerDocument.parentWindow; | |
if (className in win && object instanceof win[className]) { | |
return true | |
} | |
} else { | |
var win = Firebug.browser.window; | |
if (className in win) { | |
return object instanceof win[className] | |
} | |
} | |
var cache = instanceCheckMap[className]; | |
if (!cache) { | |
return false | |
} | |
for (var n in cache) { | |
var obj = cache[n]; | |
var type = typeof obj; | |
obj = type == "object" ? obj: [obj]; | |
for (var name in obj) { | |
if (!obj.hasOwnProperty(name)) { | |
continue | |
} | |
var value = obj[name]; | |
if (n == "property" && !(value in object) || n == "method" && !this.isFunction(object[value]) || n == "value" && ("" + object[name]).toLowerCase() != ("" + value).toLowerCase()) { | |
return false | |
} | |
} | |
} | |
return true | |
}; | |
var instanceCheckMap = { | |
Window: { | |
property: ["window", "document"], | |
method: "setTimeout" | |
}, | |
Document: { | |
property: ["body", "cookie"], | |
method: "getElementById" | |
}, | |
Node: { | |
property: "ownerDocument", | |
method: "appendChild" | |
}, | |
Element: { | |
property: "tagName", | |
value: { | |
nodeType: 1 | |
} | |
}, | |
Location: { | |
property: ["hostname", "protocol"], | |
method: "assign" | |
}, | |
HTMLImageElement: { | |
property: "useMap", | |
value: { | |
nodeType: 1, | |
tagName: "img" | |
} | |
}, | |
HTMLAnchorElement: { | |
property: "hreflang", | |
value: { | |
nodeType: 1, | |
tagName: "a" | |
} | |
}, | |
HTMLInputElement: { | |
property: "form", | |
value: { | |
nodeType: 1, | |
tagName: "input" | |
} | |
}, | |
HTMLButtonElement: {}, | |
HTMLFormElement: { | |
method: "submit", | |
value: { | |
nodeType: 1, | |
tagName: "form" | |
} | |
}, | |
HTMLBodyElement: {}, | |
HTMLHtmlElement: {}, | |
CSSStyleRule: { | |
property: ["selectorText", "style"] | |
} | |
}; | |
var domMemberMap2 = {}; | |
var domMemberMap2Sandbox = null; | |
var getDomMemberMap2 = function(name) { | |
if (!domMemberMap2Sandbox) { | |
var doc = Firebug.chrome.document; | |
var frame = doc.createElement("iframe"); | |
frame.id = "FirebugSandbox"; | |
frame.style.display = "none"; | |
frame.src = "about:blank"; | |
doc.body.appendChild(frame); | |
domMemberMap2Sandbox = frame.window || frame.contentWindow | |
} | |
var props = []; | |
var object = null; | |
if (name == "Window") { | |
object = domMemberMap2Sandbox.window | |
} else { | |
if (name == "Document") { | |
object = domMemberMap2Sandbox.document | |
} else { | |
if (name == "HTMLScriptElement") { | |
object = domMemberMap2Sandbox.document.createElement("script") | |
} else { | |
if (name == "HTMLAnchorElement") { | |
object = domMemberMap2Sandbox.document.createElement("a") | |
} else { | |
if (name.indexOf("Element") != -1) { | |
object = domMemberMap2Sandbox.document.createElement("div") | |
} | |
} | |
} | |
} | |
} | |
if (object) { | |
for (var n in object) { | |
props.push(n) | |
} | |
} | |
return props; | |
return extendArray(props, domMemberMap[name]) | |
}; | |
this.getDOMMembers = function(object) { | |
if (!domMemberCache) { | |
FBL.domMemberCache = domMemberCache = {}; | |
for (var name in domMemberMap) { | |
var builtins = getDomMemberMap2(name); | |
var cache = domMemberCache[name] = {}; | |
for (var i = 0; i < builtins.length; ++i) { | |
cache[builtins[i]] = i | |
} | |
} | |
} | |
try { | |
if (this.instanceOf(object, "Window")) { | |
return domMemberCache.Window | |
} else { | |
if (this.instanceOf(object, "Document") || this.instanceOf(object, "XMLDocument")) { | |
return domMemberCache.Document | |
} else { | |
if (this.instanceOf(object, "Location")) { | |
return domMemberCache.Location | |
} else { | |
if (this.instanceOf(object, "HTMLImageElement")) { | |
return domMemberCache.HTMLImageElement | |
} else { | |
if (this.instanceOf(object, "HTMLAnchorElement")) { | |
return domMemberCache.HTMLAnchorElement | |
} else { | |
if (this.instanceOf(object, "HTMLInputElement")) { | |
return domMemberCache.HTMLInputElement | |
} else { | |
if (this.instanceOf(object, "HTMLButtonElement")) { | |
return domMemberCache.HTMLButtonElement | |
} else { | |
if (this.instanceOf(object, "HTMLFormElement")) { | |
return domMemberCache.HTMLFormElement | |
} else { | |
if (this.instanceOf(object, "HTMLBodyElement")) { | |
return domMemberCache.HTMLBodyElement | |
} else { | |
if (this.instanceOf(object, "HTMLHtmlElement")) { | |
return domMemberCache.HTMLHtmlElement | |
} else { | |
if (this.instanceOf(object, "HTMLScriptElement")) { | |
return domMemberCache.HTMLScriptElement | |
} else { | |
if (this.instanceOf(object, "HTMLTableElement")) { | |
return domMemberCache.HTMLTableElement | |
} else { | |
if (this.instanceOf(object, "HTMLTableRowElement")) { | |
return domMemberCache.HTMLTableRowElement | |
} else { | |
if (this.instanceOf(object, "HTMLTableCellElement")) { | |
return domMemberCache.HTMLTableCellElement | |
} else { | |
if (this.instanceOf(object, "HTMLIFrameElement")) { | |
return domMemberCache.HTMLIFrameElement | |
} else { | |
if (this.instanceOf(object, "SVGSVGElement")) { | |
return domMemberCache.SVGSVGElement | |
} else { | |
if (this.instanceOf(object, "SVGElement")) { | |
return domMemberCache.SVGElement | |
} else { | |
if (this.instanceOf(object, "Element")) { | |
return domMemberCache.Element | |
} else { | |
if (this.instanceOf(object, "Text") || this.instanceOf(object, "CDATASection")) { | |
return domMemberCache.Text | |
} else { | |
if (this.instanceOf(object, "Attr")) { | |
return domMemberCache.Attr | |
} else { | |
if (this.instanceOf(object, "Node")) { | |
return domMemberCache.Node | |
} else { | |
if (this.instanceOf(object, "Event") || this.instanceOf(object, "EventCopy")) { | |
return domMemberCache.Event | |
} else { | |
return {} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} catch(E) { | |
if (FBTrace.DBG_ERRORS) { | |
FBTrace.sysout("lib.getDOMMembers FAILED ", E) | |
} | |
return {} | |
} | |
}; | |
this.isDOMMember = function(object, propName) { | |
var members = this.getDOMMembers(object); | |
return members && propName in members | |
}; | |
var domMemberCache = null; | |
var domMemberMap = {}; | |
domMemberMap.Window = ["document", "frameElement", "innerWidth", "innerHeight", "outerWidth", "outerHeight", "screenX", "screenY", "pageXOffset", "pageYOffset", "scrollX", "scrollY", "scrollMaxX", "scrollMaxY", "status", "defaultStatus", "parent", "opener", "top", "window", "content", "self", "location", "history", "frames", "navigator", "screen", "menubar", "toolbar", "locationbar", "personalbar", "statusbar", "directories", "scrollbars", "fullScreen", "netscape", "java", "console", "Components", "controllers", "closed", "crypto", "pkcs11", "name", "property", "length", "sessionStorage", "globalStorage", "setTimeout", "setInterval", "clearTimeout", "clearInterval", "addEventListener", "removeEventListener", "dispatchEvent", "getComputedStyle", "captureEvents", "releaseEvents", "routeEvent", "enableExternalCapture", "disableExternalCapture", "moveTo", "moveBy", "resizeTo", "resizeBy", "scroll", "scrollTo", "scrollBy", "scrollByLines", "scrollByPages", "sizeToContent", "setResizable", "getSelection", "open", "openDialog", "close", "alert", "confirm", "prompt", "dump", "focus", "blur", "find", "back", "forward", "home", "stop", "print", "atob", "btoa", "updateCommands", "XPCNativeWrapper", "GeckoActiveXObject", "applicationCache"]; | |
domMemberMap.Location = ["href", "protocol", "host", "hostname", "port", "pathname", "search", "hash", "assign", "reload", "replace"]; | |
domMemberMap.Node = ["id", "className", "nodeType", "tagName", "nodeName", "localName", "prefix", "namespaceURI", "nodeValue", "ownerDocument", "parentNode", "offsetParent", "nextSibling", "previousSibling", "firstChild", "lastChild", "childNodes", "attributes", "dir", "baseURI", "textContent", "innerHTML", "addEventListener", "removeEventListener", "dispatchEvent", "cloneNode", "appendChild", "insertBefore", "replaceChild", "removeChild", "compareDocumentPosition", "hasAttributes", "hasChildNodes", "lookupNamespaceURI", "lookupPrefix", "normalize", "isDefaultNamespace", "isEqualNode", "isSameNode", "isSupported", "getFeature", "getUserData", "setUserData"]; | |
domMemberMap.Document = extendArray(domMemberMap.Node, ["documentElement", "body", "title", "location", "referrer", "cookie", "contentType", "lastModified", "characterSet", "inputEncoding", "xmlEncoding", "xmlStandalone", "xmlVersion", "strictErrorChecking", "documentURI", "URL", "defaultView", "doctype", "implementation", "styleSheets", "images", "links", "forms", "anchors", "embeds", "plugins", "applets", "width", "height", "designMode", "compatMode", "async", "preferredStylesheetSet", "alinkColor", "linkColor", "vlinkColor", "bgColor", "fgColor", "domain", "addEventListener", "removeEventListener", "dispatchEvent", "captureEvents", "releaseEvents", "routeEvent", "clear", "open", "close", "execCommand", "execCommandShowHelp", "getElementsByName", "getSelection", "queryCommandEnabled", "queryCommandIndeterm", "queryCommandState", "queryCommandSupported", "queryCommandText", "queryCommandValue", "write", "writeln", "adoptNode", "appendChild", "removeChild", "renameNode", "cloneNode", "compareDocumentPosition", "createAttribute", "createAttributeNS", "createCDATASection", "createComment", "createDocumentFragment", "createElement", "createElementNS", "createEntityReference", "createEvent", "createExpression", "createNSResolver", "createNodeIterator", "createProcessingInstruction", "createRange", "createTextNode", "createTreeWalker", "domConfig", "evaluate", "evaluateFIXptr", "evaluateXPointer", "getAnonymousElementByAttribute", "getAnonymousNodes", "addBinding", "removeBinding", "getBindingParent", "getBoxObjectFor", "setBoxObjectFor", "getElementById", "getElementsByTagName", "getElementsByTagNameNS", "hasAttributes", "hasChildNodes", "importNode", "insertBefore", "isDefaultNamespace", "isEqualNode", "isSameNode", "isSupported", "load", "loadBindingDocument", "lookupNamespaceURI", "lookupPrefix", "normalize", "normalizeDocument", "getFeature", "getUserData", "setUserData"]); | |
domMemberMap.Element = extendArray(domMemberMap.Node, ["clientWidth", "clientHeight", "offsetLeft", "offsetTop", "offsetWidth", "offsetHeight", "scrollLeft", "scrollTop", "scrollWidth", "scrollHeight", "style", "tabIndex", "title", "lang", "align", "spellcheck", "addEventListener", "removeEventListener", "dispatchEvent", "focus", "blur", "cloneNode", "appendChild", "insertBefore", "replaceChild", "removeChild", "compareDocumentPosition", "getElementsByTagName", "getElementsByTagNameNS", "getAttribute", "getAttributeNS", "getAttributeNode", "getAttributeNodeNS", "setAttribute", "setAttributeNS", "setAttributeNode", "setAttributeNodeNS", "removeAttribute", "removeAttributeNS", "removeAttributeNode", "hasAttribute", "hasAttributeNS", "hasAttributes", "hasChildNodes", "lookupNamespaceURI", "lookupPrefix", "normalize", "isDefaultNamespace", "isEqualNode", "isSameNode", "isSupported", "getFeature", "getUserData", "setUserData"]); | |
domMemberMap.SVGElement = extendArray(domMemberMap.Element, ["x", "y", "width", "height", "rx", "ry", "transform", "href", "ownerSVGElement", "viewportElement", "farthestViewportElement", "nearestViewportElement", "getBBox", "getCTM", "getScreenCTM", "getTransformToElement", "getPresentationAttribute", "preserveAspectRatio"]); | |
domMemberMap.SVGSVGElement = extendArray(domMemberMap.Element, ["x", "y", "width", "height", "rx", "ry", "transform", "viewBox", "viewport", "currentView", "useCurrentView", "pixelUnitToMillimeterX", "pixelUnitToMillimeterY", "screenPixelToMillimeterX", "screenPixelToMillimeterY", "currentScale", "currentTranslate", "zoomAndPan", "ownerSVGElement", "viewportElement", "farthestViewportElement", "nearestViewportElement", "contentScriptType", "contentStyleType", "getBBox", "getCTM", "getScreenCTM", "getTransformToElement", "getEnclosureList", "getIntersectionList", "getViewboxToViewportTransform", "getPresentationAttribute", "getElementById", "checkEnclosure", "checkIntersection", "createSVGAngle", "createSVGLength", "createSVGMatrix", "createSVGNumber", "createSVGPoint", "createSVGRect", "createSVGString", "createSVGTransform", "createSVGTransformFromMatrix", "deSelectAll", "preserveAspectRatio", "forceRedraw", "suspendRedraw", "unsuspendRedraw", "unsuspendRedrawAll", "getCurrentTime", "setCurrentTime", "animationsPaused", "pauseAnimations", "unpauseAnimations"]); | |
domMemberMap.HTMLImageElement = extendArray(domMemberMap.Element, ["src", "naturalWidth", "naturalHeight", "width", "height", "x", "y", "name", "alt", "longDesc", "lowsrc", "border", "complete", "hspace", "vspace", "isMap", "useMap"]); | |
domMemberMap.HTMLAnchorElement = extendArray(domMemberMap.Element, ["name", "target", "accessKey", "href", "protocol", "host", "hostname", "port", "pathname", "search", "hash", "hreflang", "coords", "shape", "text", "type", "rel", "rev", "charset"]); | |
domMemberMap.HTMLIFrameElement = extendArray(domMemberMap.Element, ["contentDocument", "contentWindow", "frameBorder", "height", "longDesc", "marginHeight", "marginWidth", "name", "scrolling", "src", "width"]); | |
domMemberMap.HTMLTableElement = extendArray(domMemberMap.Element, ["bgColor", "border", "caption", "cellPadding", "cellSpacing", "frame", "rows", "rules", "summary", "tBodies", "tFoot", "tHead", "width", "createCaption", "createTFoot", "createTHead", "deleteCaption", "deleteRow", "deleteTFoot", "deleteTHead", "insertRow"]); | |
domMemberMap.HTMLTableRowElement = extendArray(domMemberMap.Element, ["bgColor", "cells", "ch", "chOff", "rowIndex", "sectionRowIndex", "vAlign", "deleteCell", "insertCell"]); | |
domMemberMap.HTMLTableCellElement = extendArray(domMemberMap.Element, ["abbr", "axis", "bgColor", "cellIndex", "ch", "chOff", "colSpan", "headers", "height", "noWrap", "rowSpan", "scope", "vAlign", "width"]); | |
domMemberMap.HTMLScriptElement = extendArray(domMemberMap.Element, ["src"]); | |
domMemberMap.HTMLButtonElement = extendArray(domMemberMap.Element, ["accessKey", "disabled", "form", "name", "type", "value", "click"]); | |
domMemberMap.HTMLInputElement = extendArray(domMemberMap.Element, ["type", "value", "checked", "accept", "accessKey", "alt", "controllers", "defaultChecked", "defaultValue", "disabled", "form", "maxLength", "name", "readOnly", "selectionEnd", "selectionStart", "size", "src", "textLength", "useMap", "click", "select", "setSelectionRange"]); | |
domMemberMap.HTMLFormElement = extendArray(domMemberMap.Element, ["acceptCharset", "action", "author", "elements", "encoding", "enctype", "entry_id", "length", "method", "name", "post", "target", "text", "url", "reset", "submit"]); | |
domMemberMap.HTMLBodyElement = extendArray(domMemberMap.Element, ["aLink", "background", "bgColor", "link", "text", "vLink"]); | |
domMemberMap.HTMLHtmlElement = extendArray(domMemberMap.Element, ["version"]); | |
domMemberMap.Text = extendArray(domMemberMap.Node, ["data", "length", "appendData", "deleteData", "insertData", "replaceData", "splitText", "substringData"]); | |
domMemberMap.Attr = extendArray(domMemberMap.Node, ["name", "value", "specified", "ownerElement"]); | |
domMemberMap.Event = ["type", "target", "currentTarget", "originalTarget", "explicitOriginalTarget", "relatedTarget", "rangeParent", "rangeOffset", "view", "keyCode", "charCode", "screenX", "screenY", "clientX", "clientY", "layerX", "layerY", "pageX", "pageY", "detail", "button", "which", "ctrlKey", "shiftKey", "altKey", "metaKey", "eventPhase", "timeStamp", "bubbles", "cancelable", "cancelBubble", "isTrusted", "isChar", "getPreventDefault", "initEvent", "initMouseEvent", "initKeyEvent", "initUIEvent", "preventBubble", "preventCapture", "preventDefault", "stopPropagation"]; | |
this.domConstantMap = { | |
ELEMENT_NODE: 1, | |
ATTRIBUTE_NODE: 1, | |
TEXT_NODE: 1, | |
CDATA_SECTION_NODE: 1, | |
ENTITY_REFERENCE_NODE: 1, | |
ENTITY_NODE: 1, | |
PROCESSING_INSTRUCTION_NODE: 1, | |
COMMENT_NODE: 1, | |
DOCUMENT_NODE: 1, | |
DOCUMENT_TYPE_NODE: 1, | |
DOCUMENT_FRAGMENT_NODE: 1, | |
NOTATION_NODE: 1, | |
DOCUMENT_POSITION_DISCONNECTED: 1, | |
DOCUMENT_POSITION_PRECEDING: 1, | |
DOCUMENT_POSITION_FOLLOWING: 1, | |
DOCUMENT_POSITION_CONTAINS: 1, | |
DOCUMENT_POSITION_CONTAINED_BY: 1, | |
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 1, | |
UNKNOWN_RULE: 1, | |
STYLE_RULE: 1, | |
CHARSET_RULE: 1, | |
IMPORT_RULE: 1, | |
MEDIA_RULE: 1, | |
FONT_FACE_RULE: 1, | |
PAGE_RULE: 1, | |
CAPTURING_PHASE: 1, | |
AT_TARGET: 1, | |
BUBBLING_PHASE: 1, | |
SCROLL_PAGE_UP: 1, | |
SCROLL_PAGE_DOWN: 1, | |
MOUSEUP: 1, | |
MOUSEDOWN: 1, | |
MOUSEOVER: 1, | |
MOUSEOUT: 1, | |
MOUSEMOVE: 1, | |
MOUSEDRAG: 1, | |
CLICK: 1, | |
DBLCLICK: 1, | |
KEYDOWN: 1, | |
KEYUP: 1, | |
KEYPRESS: 1, | |
DRAGDROP: 1, | |
FOCUS: 1, | |
BLUR: 1, | |
SELECT: 1, | |
CHANGE: 1, | |
RESET: 1, | |
SUBMIT: 1, | |
SCROLL: 1, | |
LOAD: 1, | |
UNLOAD: 1, | |
XFER_DONE: 1, | |
ABORT: 1, | |
ERROR: 1, | |
LOCATE: 1, | |
MOVE: 1, | |
RESIZE: 1, | |
FORWARD: 1, | |
HELP: 1, | |
BACK: 1, | |
TEXT: 1, | |
ALT_MASK: 1, | |
CONTROL_MASK: 1, | |
SHIFT_MASK: 1, | |
META_MASK: 1, | |
DOM_VK_TAB: 1, | |
DOM_VK_PAGE_UP: 1, | |
DOM_VK_PAGE_DOWN: 1, | |
DOM_VK_UP: 1, | |
DOM_VK_DOWN: 1, | |
DOM_VK_LEFT: 1, | |
DOM_VK_RIGHT: 1, | |
DOM_VK_CANCEL: 1, | |
DOM_VK_HELP: 1, | |
DOM_VK_BACK_SPACE: 1, | |
DOM_VK_CLEAR: 1, | |
DOM_VK_RETURN: 1, | |
DOM_VK_ENTER: 1, | |
DOM_VK_SHIFT: 1, | |
DOM_VK_CONTROL: 1, | |
DOM_VK_ALT: 1, | |
DOM_VK_PAUSE: 1, | |
DOM_VK_CAPS_LOCK: 1, | |
DOM_VK_ESCAPE: 1, | |
DOM_VK_SPACE: 1, | |
DOM_VK_END: 1, | |
DOM_VK_HOME: 1, | |
DOM_VK_PRINTSCREEN: 1, | |
DOM_VK_INSERT: 1, | |
DOM_VK_DELETE: 1, | |
DOM_VK_0: 1, | |
DOM_VK_1: 1, | |
DOM_VK_2: 1, | |
DOM_VK_3: 1, | |
DOM_VK_4: 1, | |
DOM_VK_5: 1, | |
DOM_VK_6: 1, | |
DOM_VK_7: 1, | |
DOM_VK_8: 1, | |
DOM_VK_9: 1, | |
DOM_VK_SEMICOLON: 1, | |
DOM_VK_EQUALS: 1, | |
DOM_VK_A: 1, | |
DOM_VK_B: 1, | |
DOM_VK_C: 1, | |
DOM_VK_D: 1, | |
DOM_VK_E: 1, | |
DOM_VK_F: 1, | |
DOM_VK_G: 1, | |
DOM_VK_H: 1, | |
DOM_VK_I: 1, | |
DOM_VK_J: 1, | |
DOM_VK_K: 1, | |
DOM_VK_L: 1, | |
DOM_VK_M: 1, | |
DOM_VK_N: 1, | |
DOM_VK_O: 1, | |
DOM_VK_P: 1, | |
DOM_VK_Q: 1, | |
DOM_VK_R: 1, | |
DOM_VK_S: 1, | |
DOM_VK_T: 1, | |
DOM_VK_U: 1, | |
DOM_VK_V: 1, | |
DOM_VK_W: 1, | |
DOM_VK_X: 1, | |
DOM_VK_Y: 1, | |
DOM_VK_Z: 1, | |
DOM_VK_CONTEXT_MENU: 1, | |
DOM_VK_NUMPAD0: 1, | |
DOM_VK_NUMPAD1: 1, | |
DOM_VK_NUMPAD2: 1, | |
DOM_VK_NUMPAD3: 1, | |
DOM_VK_NUMPAD4: 1, | |
DOM_VK_NUMPAD5: 1, | |
DOM_VK_NUMPAD6: 1, | |
DOM_VK_NUMPAD7: 1, | |
DOM_VK_NUMPAD8: 1, | |
DOM_VK_NUMPAD9: 1, | |
DOM_VK_MULTIPLY: 1, | |
DOM_VK_ADD: 1, | |
DOM_VK_SEPARATOR: 1, | |
DOM_VK_SUBTRACT: 1, | |
DOM_VK_DECIMAL: 1, | |
DOM_VK_DIVIDE: 1, | |
DOM_VK_F1: 1, | |
DOM_VK_F2: 1, | |
DOM_VK_F3: 1, | |
DOM_VK_F4: 1, | |
DOM_VK_F5: 1, | |
DOM_VK_F6: 1, | |
DOM_VK_F7: 1, | |
DOM_VK_F8: 1, | |
DOM_VK_F9: 1, | |
DOM_VK_F10: 1, | |
DOM_VK_F11: 1, | |
DOM_VK_F12: 1, | |
DOM_VK_F13: 1, | |
DOM_VK_F14: 1, | |
DOM_VK_F15: 1, | |
DOM_VK_F16: 1, | |
DOM_VK_F17: 1, | |
DOM_VK_F18: 1, | |
DOM_VK_F19: 1, | |
DOM_VK_F20: 1, | |
DOM_VK_F21: 1, | |
DOM_VK_F22: 1, | |
DOM_VK_F23: 1, | |
DOM_VK_F24: 1, | |
DOM_VK_NUM_LOCK: 1, | |
DOM_VK_SCROLL_LOCK: 1, | |
DOM_VK_COMMA: 1, | |
DOM_VK_PERIOD: 1, | |
DOM_VK_SLASH: 1, | |
DOM_VK_BACK_QUOTE: 1, | |
DOM_VK_OPEN_BRACKET: 1, | |
DOM_VK_BACK_SLASH: 1, | |
DOM_VK_CLOSE_BRACKET: 1, | |
DOM_VK_QUOTE: 1, | |
DOM_VK_META: 1, | |
SVG_ZOOMANDPAN_DISABLE: 1, | |
SVG_ZOOMANDPAN_MAGNIFY: 1, | |
SVG_ZOOMANDPAN_UNKNOWN: 1 | |
}; | |
this.cssInfo = { | |
background: ["bgRepeat", "bgAttachment", "bgPosition", "color", "systemColor", "none"], | |
"background-attachment": ["bgAttachment"], | |
"background-color": ["color", "systemColor"], | |
"background-image": ["none"], | |
"background-position": ["bgPosition"], | |
"background-repeat": ["bgRepeat"], | |
border: ["borderStyle", "thickness", "color", "systemColor", "none"], | |
"border-top": ["borderStyle", "borderCollapse", "color", "systemColor", "none"], | |
"border-right": ["borderStyle", "borderCollapse", "color", "systemColor", "none"], | |
"border-bottom": ["borderStyle", "borderCollapse", "color", "systemColor", "none"], | |
"border-left": ["borderStyle", "borderCollapse", "color", "systemColor", "none"], | |
"border-collapse": ["borderCollapse"], | |
"border-color": ["color", "systemColor"], | |
"border-top-color": ["color", "systemColor"], | |
"border-right-color": ["color", "systemColor"], | |
"border-bottom-color": ["color", "systemColor"], | |
"border-left-color": ["color", "systemColor"], | |
"border-spacing": [], | |
"border-style": ["borderStyle"], | |
"border-top-style": ["borderStyle"], | |
"border-right-style": ["borderStyle"], | |
"border-bottom-style": ["borderStyle"], | |
"border-left-style": ["borderStyle"], | |
"border-width": ["thickness"], | |
"border-top-width": ["thickness"], | |
"border-right-width": ["thickness"], | |
"border-bottom-width": ["thickness"], | |
"border-left-width": ["thickness"], | |
bottom: ["auto"], | |
"caption-side": ["captionSide"], | |
clear: ["clear", "none"], | |
clip: ["auto"], | |
color: ["color", "systemColor"], | |
content: ["content"], | |
"counter-increment": ["none"], | |
"counter-reset": ["none"], | |
cursor: ["cursor", "none"], | |
direction: ["direction"], | |
display: ["display", "none"], | |
"empty-cells": [], | |
"float": ["float", "none"], | |
font: ["fontStyle", "fontVariant", "fontWeight", "fontFamily"], | |
"font-family": ["fontFamily"], | |
"font-size": ["fontSize"], | |
"font-size-adjust": [], | |
"font-stretch": [], | |
"font-style": ["fontStyle"], | |
"font-variant": ["fontVariant"], | |
"font-weight": ["fontWeight"], | |
height: ["auto"], | |
left: ["auto"], | |
"letter-spacing": [], | |
"line-height": [], | |
"list-style": ["listStyleType", "listStylePosition", "none"], | |
"list-style-image": ["none"], | |
"list-style-position": ["listStylePosition"], | |
"list-style-type": ["listStyleType", "none"], | |
margin: [], | |
"margin-top": [], | |
"margin-right": [], | |
"margin-bottom": [], | |
"margin-left": [], | |
"marker-offset": ["auto"], | |
"min-height": ["none"], | |
"max-height": ["none"], | |
"min-width": ["none"], | |
"max-width": ["none"], | |
outline: ["borderStyle", "color", "systemColor", "none"], | |
"outline-color": ["color", "systemColor"], | |
"outline-style": ["borderStyle"], | |
"outline-width": [], | |
overflow: ["overflow", "auto"], | |
"overflow-x": ["overflow", "auto"], | |
"overflow-y": ["overflow", "auto"], | |
padding: [], | |
"padding-top": [], | |
"padding-right": [], | |
"padding-bottom": [], | |
"padding-left": [], | |
position: ["position"], | |
quotes: ["none"], | |
right: ["auto"], | |
"table-layout": ["tableLayout", "auto"], | |
"text-align": ["textAlign"], | |
"text-decoration": ["textDecoration", "none"], | |
"text-indent": [], | |
"text-shadow": [], | |
"text-transform": ["textTransform", "none"], | |
top: ["auto"], | |
"unicode-bidi": [], | |
"vertical-align": ["verticalAlign"], | |
"white-space": ["whiteSpace"], | |
width: ["auto"], | |
"word-spacing": [], | |
"z-index": [], | |
"-moz-appearance": ["mozAppearance"], | |
"-moz-border-radius": [], | |
"-moz-border-radius-bottomleft": [], | |
"-moz-border-radius-bottomright": [], | |
"-moz-border-radius-topleft": [], | |
"-moz-border-radius-topright": [], | |
"-moz-border-top-colors": ["color", "systemColor"], | |
"-moz-border-right-colors": ["color", "systemColor"], | |
"-moz-border-bottom-colors": ["color", "systemColor"], | |
"-moz-border-left-colors": ["color", "systemColor"], | |
"-moz-box-align": ["mozBoxAlign"], | |
"-moz-box-direction": ["mozBoxDirection"], | |
"-moz-box-flex": [], | |
"-moz-box-ordinal-group": [], | |
"-moz-box-orient": ["mozBoxOrient"], | |
"-moz-box-pack": ["mozBoxPack"], | |
"-moz-box-sizing": ["mozBoxSizing"], | |
"-moz-opacity": [], | |
"-moz-user-focus": ["userFocus", "none"], | |
"-moz-user-input": ["userInput"], | |
"-moz-user-modify": [], | |
"-moz-user-select": ["userSelect", "none"], | |
"-moz-background-clip": [], | |
"-moz-background-inline-policy": [], | |
"-moz-background-origin": [], | |
"-moz-binding": [], | |
"-moz-column-count": [], | |
"-moz-column-gap": [], | |
"-moz-column-width": [], | |
"-moz-image-region": [] | |
}; | |
this.inheritedStyleNames = { | |
"border-collapse": 1, | |
"border-spacing": 1, | |
"border-style": 1, | |
"caption-side": 1, | |
color: 1, | |
cursor: 1, | |
direction: 1, | |
"empty-cells": 1, | |
font: 1, | |
"font-family": 1, | |
"font-size-adjust": 1, | |
"font-size": 1, | |
"font-style": 1, | |
"font-variant": 1, | |
"font-weight": 1, | |
"letter-spacing": 1, | |
"line-height": 1, | |
"list-style": 1, | |
"list-style-image": 1, | |
"list-style-position": 1, | |
"list-style-type": 1, | |
quotes: 1, | |
"text-align": 1, | |
"text-decoration": 1, | |
"text-indent": 1, | |
"text-shadow": 1, | |
"text-transform": 1, | |
"white-space": 1, | |
"word-spacing": 1 | |
}; | |
this.cssKeywords = { | |
appearance: ["button", "button-small", "checkbox", "checkbox-container", "checkbox-small", "dialog", "listbox", "menuitem", "menulist", "menulist-button", "menulist-textfield", "menupopup", "progressbar", "radio", "radio-container", "radio-small", "resizer", "scrollbar", "scrollbarbutton-down", "scrollbarbutton-left", "scrollbarbutton-right", "scrollbarbutton-up", "scrollbartrack-horizontal", "scrollbartrack-vertical", "separator", "statusbar", "tab", "tab-left-edge", "tabpanels", "textfield", "toolbar", "toolbarbutton", "toolbox", "tooltip", "treeheadercell", "treeheadersortarrow", "treeitem", "treetwisty", "treetwistyopen", "treeview", "window"], | |
systemColor: ["ActiveBorder", "ActiveCaption", "AppWorkspace", "Background", "ButtonFace", "ButtonHighlight", "ButtonShadow", "ButtonText", "CaptionText", "GrayText", "Highlight", "HighlightText", "InactiveBorder", "InactiveCaption", "InactiveCaptionText", "InfoBackground", "InfoText", "Menu", "MenuText", "Scrollbar", "ThreeDDarkShadow", "ThreeDFace", "ThreeDHighlight", "ThreeDLightShadow", "ThreeDShadow", "Window", "WindowFrame", "WindowText", "-moz-field", "-moz-fieldtext", "-moz-workspace", "-moz-visitedhyperlinktext", "-moz-use-text-color"], | |
color: ["AliceBlue", "AntiqueWhite", "Aqua", "Aquamarine", "Azure", "Beige", "Bisque", "Black", "BlanchedAlmond", "Blue", "BlueViolet", "Brown", "BurlyWood", "CadetBlue", "Chartreuse", "Chocolate", "Coral", "CornflowerBlue", "Cornsilk", "Crimson", "Cyan", "DarkBlue", "DarkCyan", "DarkGoldenRod", "DarkGray", "DarkGreen", "DarkKhaki", "DarkMagenta", "DarkOliveGreen", "DarkOrange", "DarkOrchid", "DarkRed", "DarkSalmon", "DarkSeaGreen", "DarkSlateBlue", "DarkSlateGray", "DarkTurquoise", "DarkViolet", "DeepPink", "DarkSkyBlue", "DimGray", "DodgerBlue", "Feldspar", "FireBrick", "FloralWhite", "ForestGreen", "Fuchsia", "Gainsboro", "GhostWhite", "Gold", "GoldenRod", "Gray", "Green", "GreenYellow", "HoneyDew", "HotPink", "IndianRed", "Indigo", "Ivory", "Khaki", "Lavender", "LavenderBlush", "LawnGreen", "LemonChiffon", "LightBlue", "LightCoral", "LightCyan", "LightGoldenRodYellow", "LightGrey", "LightGreen", "LightPink", "LightSalmon", "LightSeaGreen", "LightSkyBlue", "LightSlateBlue", "LightSlateGray", "LightSteelBlue", "LightYellow", "Lime", "LimeGreen", "Linen", "Magenta", "Maroon", "MediumAquaMarine", "MediumBlue", "MediumOrchid", "MediumPurple", "MediumSeaGreen", "MediumSlateBlue", "MediumSpringGreen", "MediumTurquoise", "MediumVioletRed", "MidnightBlue", "MintCream", "MistyRose", "Moccasin", "NavajoWhite", "Navy", "OldLace", "Olive", "OliveDrab", "Orange", "OrangeRed", "Orchid", "PaleGoldenRod", "PaleGreen", "PaleTurquoise", "PaleVioletRed", "PapayaWhip", "PeachPuff", "Peru", "Pink", "Plum", "PowderBlue", "Purple", "Red", "RosyBrown", "RoyalBlue", "SaddleBrown", "Salmon", "SandyBrown", "SeaGreen", "SeaShell", "Sienna", "Silver", "SkyBlue", "SlateBlue", "SlateGray", "Snow", "SpringGreen", "SteelBlue", "Tan", "Teal", "Thistle", "Tomato", "Turquoise", "Violet", "VioletRed", "Wheat", "White", "WhiteSmoke", "Yellow", "YellowGreen", "transparent", "invert"], | |
auto: ["auto"], | |
none: ["none"], | |
captionSide: ["top", "bottom", "left", "right"], | |
clear: ["left", "right", "both"], | |
cursor: ["auto", "cell", "context-menu", "crosshair", "default", "help", "pointer", "progress", "move", "e-resize", "all-scroll", "ne-resize", "nw-resize", "n-resize", "se-resize", "sw-resize", "s-resize", "w-resize", "ew-resize", "ns-resize", "nesw-resize", "nwse-resize", "col-resize", "row-resize", "text", "vertical-text", "wait", "alias", "copy", "move", "no-drop", "not-allowed", "-moz-alias", "-moz-cell", "-moz-copy", "-moz-grab", "-moz-grabbing", "-moz-contextmenu", "-moz-zoom-in", "-moz-zoom-out", "-moz-spinning"], | |
direction: ["ltr", "rtl"], | |
bgAttachment: ["scroll", "fixed"], | |
bgPosition: ["top", "center", "bottom", "left", "right"], | |
bgRepeat: ["repeat", "repeat-x", "repeat-y", "no-repeat"], | |
borderStyle: ["hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset", "-moz-bg-inset", "-moz-bg-outset", "-moz-bg-solid"], | |
borderCollapse: ["collapse", "separate"], | |
overflow: ["visible", "hidden", "scroll", "-moz-scrollbars-horizontal", "-moz-scrollbars-none", "-moz-scrollbars-vertical"], | |
listStyleType: ["disc", "circle", "square", "decimal", "decimal-leading-zero", "lower-roman", "upper-roman", "lower-greek", "lower-alpha", "lower-latin", "upper-alpha", "upper-latin", "hebrew", "armenian", "georgian", "cjk-ideographic", "hiragana", "katakana", "hiragana-iroha", "katakana-iroha", "inherit"], | |
listStylePosition: ["inside", "outside"], | |
content: ["open-quote", "close-quote", "no-open-quote", "no-close-quote", "inherit"], | |
fontStyle: ["normal", "italic", "oblique", "inherit"], | |
fontVariant: ["normal", "small-caps", "inherit"], | |
fontWeight: ["normal", "bold", "bolder", "lighter", "inherit"], | |
fontSize: ["xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "smaller", "larger"], | |
fontFamily: ["Arial", "Comic Sans MS", "Georgia", "Tahoma", "Verdana", "Times New Roman", "Trebuchet MS", "Lucida Grande", "Helvetica", "serif", "sans-serif", "cursive", "fantasy", "monospace", "caption", "icon", "menu", "message-box", "small-caption", "status-bar", "inherit"], | |
display: ["block", "inline", "inline-block", "list-item", "marker", "run-in", "compact", "table", "inline-table", "table-row-group", "table-column", "table-column-group", "table-header-group", "table-footer-group", "table-row", "table-cell", "table-caption", "-moz-box", "-moz-compact", "-moz-deck", "-moz-grid", "-moz-grid-group", "-moz-grid-line", "-moz-groupbox", "-moz-inline-block", "-moz-inline-box", "-moz-inline-grid", "-moz-inline-stack", "-moz-inline-table", "-moz-marker", "-moz-popup", "-moz-runin", "-moz-stack"], | |
position: ["static", "relative", "absolute", "fixed", "inherit"], | |
"float": ["left", "right"], | |
textAlign: ["left", "right", "center", "justify"], | |
tableLayout: ["fixed"], | |
textDecoration: ["underline", "overline", "line-through", "blink"], | |
textTransform: ["capitalize", "lowercase", "uppercase", "inherit"], | |
unicodeBidi: ["normal", "embed", "bidi-override"], | |
whiteSpace: ["normal", "pre", "nowrap"], | |
verticalAlign: ["baseline", "sub", "super", "top", "text-top", "middle", "bottom", "text-bottom", "inherit"], | |
thickness: ["thin", "medium", "thick"], | |
userFocus: ["ignore", "normal"], | |
userInput: ["disabled", "enabled"], | |
userSelect: ["normal"], | |
mozBoxSizing: ["content-box", "padding-box", "border-box"], | |
mozBoxAlign: ["start", "center", "end", "baseline", "stretch"], | |
mozBoxDirection: ["normal", "reverse"], | |
mozBoxOrient: ["horizontal", "vertical"], | |
mozBoxPack: ["start", "center", "end"] | |
}; | |
this.nonEditableTags = { | |
HTML: 1, | |
HEAD: 1, | |
html: 1, | |
head: 1 | |
}; | |
this.innerEditableTags = { | |
BODY: 1, | |
body: 1 | |
}; | |
this.selfClosingTags = { | |
meta: 1, | |
link: 1, | |
area: 1, | |
base: 1, | |
col: 1, | |
input: 1, | |
img: 1, | |
br: 1, | |
hr: 1, | |
param: 1, | |
embed: 1 | |
}; | |
var invisibleTags = this.invisibleTags = { | |
HTML: 1, | |
HEAD: 1, | |
TITLE: 1, | |
META: 1, | |
LINK: 1, | |
STYLE: 1, | |
SCRIPT: 1, | |
NOSCRIPT: 1, | |
BR: 1, | |
PARAM: 1, | |
COL: 1, | |
html: 1, | |
head: 1, | |
title: 1, | |
meta: 1, | |
link: 1, | |
style: 1, | |
script: 1, | |
noscript: 1, | |
br: 1, | |
param: 1, | |
col: 1 | |
}; | |
if (typeof KeyEvent == "undefined") { | |
this.KeyEvent = { | |
DOM_VK_CANCEL: 3, | |
DOM_VK_HELP: 6, | |
DOM_VK_BACK_SPACE: 8, | |
DOM_VK_TAB: 9, | |
DOM_VK_CLEAR: 12, | |
DOM_VK_RETURN: 13, | |
DOM_VK_ENTER: 14, | |
DOM_VK_SHIFT: 16, | |
DOM_VK_CONTROL: 17, | |
DOM_VK_ALT: 18, | |
DOM_VK_PAUSE: 19, | |
DOM_VK_CAPS_LOCK: 20, | |
DOM_VK_ESCAPE: 27, | |
DOM_VK_SPACE: 32, | |
DOM_VK_PAGE_UP: 33, | |
DOM_VK_PAGE_DOWN: 34, | |
DOM_VK_END: 35, | |
DOM_VK_HOME: 36, | |
DOM_VK_LEFT: 37, | |
DOM_VK_UP: 38, | |
DOM_VK_RIGHT: 39, | |
DOM_VK_DOWN: 40, | |
DOM_VK_PRINTSCREEN: 44, | |
DOM_VK_INSERT: 45, | |
DOM_VK_DELETE: 46, | |
DOM_VK_0: 48, | |
DOM_VK_1: 49, | |
DOM_VK_2: 50, | |
DOM_VK_3: 51, | |
DOM_VK_4: 52, | |
DOM_VK_5: 53, | |
DOM_VK_6: 54, | |
DOM_VK_7: 55, | |
DOM_VK_8: 56, | |
DOM_VK_9: 57, | |
DOM_VK_SEMICOLON: 59, | |
DOM_VK_EQUALS: 61, | |
DOM_VK_A: 65, | |
DOM_VK_B: 66, | |
DOM_VK_C: 67, | |
DOM_VK_D: 68, | |
DOM_VK_E: 69, | |
DOM_VK_F: 70, | |
DOM_VK_G: 71, | |
DOM_VK_H: 72, | |
DOM_VK_I: 73, | |
DOM_VK_J: 74, | |
DOM_VK_K: 75, | |
DOM_VK_L: 76, | |
DOM_VK_M: 77, | |
DOM_VK_N: 78, | |
DOM_VK_O: 79, | |
DOM_VK_P: 80, | |
DOM_VK_Q: 81, | |
DOM_VK_R: 82, | |
DOM_VK_S: 83, | |
DOM_VK_T: 84, | |
DOM_VK_U: 85, | |
DOM_VK_V: 86, | |
DOM_VK_W: 87, | |
DOM_VK_X: 88, | |
DOM_VK_Y: 89, | |
DOM_VK_Z: 90, | |
DOM_VK_CONTEXT_MENU: 93, | |
DOM_VK_NUMPAD0: 96, | |
DOM_VK_NUMPAD1: 97, | |
DOM_VK_NUMPAD2: 98, | |
DOM_VK_NUMPAD3: 99, | |
DOM_VK_NUMPAD4: 100, | |
DOM_VK_NUMPAD5: 101, | |
DOM_VK_NUMPAD6: 102, | |
DOM_VK_NUMPAD7: 103, | |
DOM_VK_NUMPAD8: 104, | |
DOM_VK_NUMPAD9: 105, | |
DOM_VK_MULTIPLY: 106, | |
DOM_VK_ADD: 107, | |
DOM_VK_SEPARATOR: 108, | |
DOM_VK_SUBTRACT: 109, | |
DOM_VK_DECIMAL: 110, | |
DOM_VK_DIVIDE: 111, | |
DOM_VK_F1: 112, | |
DOM_VK_F2: 113, | |
DOM_VK_F3: 114, | |
DOM_VK_F4: 115, | |
DOM_VK_F5: 116, | |
DOM_VK_F6: 117, | |
DOM_VK_F7: 118, | |
DOM_VK_F8: 119, | |
DOM_VK_F9: 120, | |
DOM_VK_F10: 121, | |
DOM_VK_F11: 122, | |
DOM_VK_F12: 123, | |
DOM_VK_F13: 124, | |
DOM_VK_F14: 125, | |
DOM_VK_F15: 126, | |
DOM_VK_F16: 127, | |
DOM_VK_F17: 128, | |
DOM_VK_F18: 129, | |
DOM_VK_F19: 130, | |
DOM_VK_F20: 131, | |
DOM_VK_F21: 132, | |
DOM_VK_F22: 133, | |
DOM_VK_F23: 134, | |
DOM_VK_F24: 135, | |
DOM_VK_NUM_LOCK: 144, | |
DOM_VK_SCROLL_LOCK: 145, | |
DOM_VK_COMMA: 188, | |
DOM_VK_PERIOD: 190, | |
DOM_VK_SLASH: 191, | |
DOM_VK_BACK_QUOTE: 192, | |
DOM_VK_OPEN_BRACKET: 219, | |
DOM_VK_BACK_SLASH: 220, | |
DOM_VK_CLOSE_BRACKET: 221, | |
DOM_VK_QUOTE: 222, | |
DOM_VK_META: 224 | |
} | |
} | |
this.Ajax = { | |
requests: [], | |
transport: null, | |
states: ["Uninitialized", "Loading", "Loaded", "Interactive", "Complete"], | |
initialize: function() { | |
this.transport = FBL.getNativeXHRObject() | |
}, | |
getXHRObject: function() { | |
var xhrObj = false; | |
try { | |
xhrObj = new XMLHttpRequest() | |
} catch(e) { | |
var progid = ["MSXML2.XMLHTTP.5.0", "MSXML2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"]; | |
for (var i = 0; i < progid.length; ++i) { | |
try { | |
xhrObj = new ActiveXObject(progid[i]) | |
} catch(e) { | |
continue | |
} | |
break | |
} | |
} finally { | |
return xhrObj | |
} | |
}, | |
request: function(options) { | |
var o = FBL.extend({ | |
type: "get", | |
async: true, | |
dataType: "text", | |
contentType: "application/x-www-form-urlencoded" | |
}, | |
options || {}); | |
this.requests.push(o); | |
var s = this.getState(); | |
if (s == "Uninitialized" || s == "Complete" || s == "Loaded") { | |
this.sendRequest() | |
} | |
}, | |
serialize: function(data) { | |
var r = [""], | |
rl = 0; | |
if (data) { | |
if (typeof data == "string") { | |
r[rl++] = data | |
} else { | |
if (data.innerHTML && data.elements) { | |
for (var i = 0, | |
el, l = (el = data.elements).length; i < l; i++) { | |
if (el[i].name) { | |
r[rl++] = encodeURIComponent(el[i].name); | |
r[rl++] = "="; | |
r[rl++] = encodeURIComponent(el[i].value); | |
r[rl++] = "&" | |
} | |
} | |
} else { | |
for (var param in data) { | |
r[rl++] = encodeURIComponent(param); | |
r[rl++] = "="; | |
r[rl++] = encodeURIComponent(data[param]); | |
r[rl++] = "&" | |
} | |
} | |
} | |
} | |
return r.join("").replace(/&$/, "") | |
}, | |
sendRequest: function() { | |
var t = FBL.Ajax.transport, | |
r = FBL.Ajax.requests.shift(), | |
data; | |
t.open(r.type, r.url, r.async); | |
t.setRequestHeader("X-Requested-With", "XMLHttpRequest"); | |
if (data = FBL.Ajax.serialize(r.data)) { | |
t.setRequestHeader("Content-Type", r.contentType) | |
} | |
t.onreadystatechange = function() { | |
FBL.Ajax.onStateChange(r) | |
}; | |
t.send(data) | |
}, | |
onStateChange: function(options) { | |
var fn, o = options, | |
t = this.transport; | |
var state = this.getState(t); | |
if (fn = o["on" + state]) { | |
fn(this.getResponse(o), o) | |
} | |
if (state == "Complete") { | |
var success = t.status == 200, | |
response = this.getResponse(o); | |
if (fn = o.onUpdate) { | |
fn(response, o) | |
} | |
if (fn = o["on" + (success ? "Success": "Failure")]) { | |
fn(response, o) | |
} | |
t.onreadystatechange = FBL.emptyFn; | |
if (this.requests.length > 0) { | |
setTimeout(this.sendRequest, 10) | |
} | |
} | |
}, | |
getResponse: function(options) { | |
var t = this.transport, | |
type = options.dataType; | |
if (t.status != 200) { | |
return t.statusText | |
} else { | |
if (type == "text") { | |
return t.responseText | |
} else { | |
if (type == "html") { | |
return t.responseText | |
} else { | |
if (type == "xml") { | |
return t.responseXML | |
} else { | |
if (type == "json") { | |
return eval("(" + t.responseText + ")") | |
} | |
} | |
} | |
} | |
} | |
}, | |
getState: function() { | |
return this.states[this.transport.readyState] | |
} | |
}; | |
this.createCookie = function(name, value, days) { | |
if ("cookie" in document) { | |
if (days) { | |
var date = new Date(); | |
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); | |
var expires = "; expires=" + date.toGMTString() | |
} else { | |
var expires = "" | |
} | |
document.cookie = name + "=" + value + expires + "; path=/" | |
} | |
}; | |
this.readCookie = function(name) { | |
if ("cookie" in document) { | |
var nameEQ = name + "="; | |
var ca = document.cookie.split(";"); | |
for (var i = 0; i < ca.length; i++) { | |
var c = ca[i]; | |
while (c.charAt(0) == " ") { | |
c = c.substring(1, c.length) | |
} | |
if (c.indexOf(nameEQ) == 0) { | |
return c.substring(nameEQ.length, c.length) | |
} | |
} | |
} | |
return null | |
}; | |
this.removeCookie = function(name) { | |
this.createCookie(name, "", -1) | |
}; | |
var fixIE6BackgroundImageCache = function(doc) { | |
doc = doc || document; | |
try { | |
doc.execCommand("BackgroundImageCache", false, true) | |
} catch(E) {} | |
}; | |
var resetStyle = "margin:0; padding:0; border:0; position:absolute; overflow:hidden; display:block;"; | |
var calculatePixelsPerInch = function calculatePixelsPerInch(doc, body) { | |
var inch = FBL.createGlobalElement("div"); | |
inch.style.cssText = resetStyle + "width:1in; height:1in; position:absolute; top:-1234px; left:-1234px;"; | |
body.appendChild(inch); | |
FBL.pixelsPerInch = { | |
x: inch.offsetWidth, | |
y: inch.offsetHeight | |
}; | |
body.removeChild(inch) | |
}; | |
this.SourceLink = function(url, line, type, object, instance) { | |
this.href = url; | |
this.instance = instance; | |
this.line = line; | |
this.type = type; | |
this.object = object | |
}; | |
this.SourceLink.prototype = { | |
toString: function() { | |
return this.href | |
}, | |
toJSON: function() { | |
return '{"href":"' + this.href + '", ' + (this.line ? ('"line":' + this.line + ",") : "") + (this.type ? (' "type":"' + this.type + '",') : "") + "}" | |
} | |
}; | |
this.SourceText = function(lines, owner) { | |
this.lines = lines; | |
this.owner = owner | |
}; | |
this.SourceText.getLineAsHTML = function(lineNo) { | |
return escapeForSourceLine(this.lines[lineNo - 1]) | |
} | |
}).apply(FBL); | |
FBL.ns(function() { | |
with(FBL) { | |
var oSTR = { | |
NoMembersWarning: "There are no properties to show for this object.", | |
EmptyStyleSheet: "There are no rules in this stylesheet.", | |
EmptyElementCSS: "This element has no style rules.", | |
AccessRestricted: "Access to restricted URI denied.", | |
"net.label.Parameters": "Parameters", | |
"net.label.Source": "Source", | |
URLParameters: "Params", | |
EditStyle: "Edit Element Style...", | |
NewRule: "New Rule...", | |
NewProp: "New Property...", | |
EditProp: 'Edit "%s"', | |
DeleteProp: 'Delete "%s"', | |
DisableProp: 'Disable "%s"' | |
}; | |
FBL.$STR = function(name) { | |
return oSTR.hasOwnProperty(name) ? oSTR[name] : name | |
}; | |
FBL.$STRF = function(name, args) { | |
if (!oSTR.hasOwnProperty(name)) { | |
return name | |
} | |
var format = oSTR[name]; | |
var objIndex = 0; | |
var parts = parseFormat(format); | |
var trialIndex = objIndex; | |
var objects = args; | |
for (var i = 0; i < parts.length; i++) { | |
var part = parts[i]; | |
if (part && typeof(part) == "object") { | |
if (++trialIndex > objects.length) { | |
format = ""; | |
objIndex = -1; | |
parts.length = 0; | |
break | |
} | |
} | |
} | |
var result = []; | |
for (var i = 0; i < parts.length; ++i) { | |
var part = parts[i]; | |
if (part && typeof(part) == "object") { | |
result.push("" + args.shift()) | |
} else { | |
result.push(part) | |
} | |
} | |
return result.join("") | |
}; | |
var parseFormat = function parseFormat(format) { | |
var parts = []; | |
if (format.length <= 0) { | |
return parts | |
} | |
var reg = /((^%|.%)(\d+)?(\.)([a-zA-Z]))|((^%|.%)([a-zA-Z]))/; | |
for (var m = reg.exec(format); m; m = reg.exec(format)) { | |
if (m[0].substr(0, 2) == "%%") { | |
parts.push(format.substr(0, m.index)); | |
parts.push(m[0].substr(1)) | |
} else { | |
var type = m[8] ? m[8] : m[5]; | |
var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0); | |
var rep = null; | |
switch (type) { | |
case "s": | |
rep = FirebugReps.Text; | |
break; | |
case "f": | |
case "i": | |
case "d": | |
rep = FirebugReps.Number; | |
break; | |
case "o": | |
rep = null; | |
break | |
} | |
parts.push(format.substr(0, m[0][0] == "%" ? m.index: m.index + 1)); | |
parts.push({ | |
rep: rep, | |
precision: precision, | |
type: ("%" + type) | |
}) | |
} | |
format = format.substr(m.index + m[0].length) | |
} | |
parts.push(format); | |
return parts | |
} | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
var modules = []; | |
var panelTypes = []; | |
var panelTypeMap = {}; | |
var reps = []; | |
var parentPanelMap = {}; | |
FBL.Firebug = { | |
version: "Firebug Lite 1.4.0", | |
revision: "$Revision: 11967 $", | |
modules: modules, | |
panelTypes: panelTypes, | |
panelTypeMap: panelTypeMap, | |
reps: reps, | |
initialize: function() { | |
if (FBTrace.DBG_INITIALIZE) { | |
FBTrace.sysout("Firebug.initialize", "initializing application") | |
} | |
Firebug.browser = new Context(Env.browser); | |
Firebug.context = Firebug.browser; | |
Firebug.loadPrefs(); | |
Firebug.context.persistedState.isOpen = false; | |
cacheDocument(); | |
if (Firebug.Inspector && Firebug.Inspector.create) { | |
Firebug.Inspector.create() | |
} | |
if (FBL.CssAnalyzer && FBL.CssAnalyzer.processAllStyleSheets) { | |
FBL.CssAnalyzer.processAllStyleSheets(Firebug.browser.document) | |
} | |
FirebugChrome.initialize(); | |
dispatch(modules, "initialize", []); | |
if (Firebug.disableResourceFetching) { | |
Firebug.Console.logFormatted(['Some Firebug Lite features are not working because resource fetching is disabled. To enabled it set the Firebug Lite option "disableResourceFetching" to "false". More info at http://getfirebug.com/firebuglite#Options'], Firebug.context, "warn") | |
} | |
if (Env.onLoad) { | |
var onLoad = Env.onLoad; | |
delete Env.onLoad; | |
setTimeout(onLoad, 200) | |
} | |
}, | |
shutdown: function() { | |
if (Firebug.saveCookies) { | |
Firebug.savePrefs() | |
} | |
if (Firebug.Inspector) { | |
Firebug.Inspector.destroy() | |
} | |
dispatch(modules, "shutdown", []); | |
var chromeMap = FirebugChrome.chromeMap; | |
for (var name in chromeMap) { | |
if (chromeMap.hasOwnProperty(name)) { | |
try { | |
chromeMap[name].destroy() | |
} catch(E) { | |
if (FBTrace.DBG_ERRORS) { | |
FBTrace.sysout("chrome.destroy() failed to: " + name) | |
} | |
} | |
} | |
} | |
Firebug.Lite.Cache.Element.clear(); | |
Firebug.Lite.Cache.StyleSheet.clear(); | |
Firebug.browser = null; | |
Firebug.context = null | |
}, | |
registerModule: function() { | |
modules.push.apply(modules, arguments); | |
if (FBTrace.DBG_INITIALIZE) { | |
FBTrace.sysout("Firebug.registerModule") | |
} | |
}, | |
registerPanel: function() { | |
panelTypes.push.apply(panelTypes, arguments); | |
for (var i = 0, | |
panelType; panelType = arguments[i]; ++i) { | |
panelTypeMap[panelType.prototype.name] = arguments[i]; | |
if (panelType.prototype.parentPanel) { | |
parentPanelMap[panelType.prototype.parentPanel] = 1 | |
} | |
} | |
if (FBTrace.DBG_INITIALIZE) { | |
for (var i = 0; i < arguments.length; ++i) { | |
FBTrace.sysout("Firebug.registerPanel", arguments[i].prototype.name) | |
} | |
} | |
}, | |
registerRep: function() { | |
reps.push.apply(reps, arguments) | |
}, | |
unregisterRep: function() { | |
for (var i = 0; i < arguments.length; ++i) { | |
remove(reps, arguments[i]) | |
} | |
}, | |
setDefaultReps: function(funcRep, rep) { | |
FBL.defaultRep = rep; | |
FBL.defaultFuncRep = funcRep | |
}, | |
getRep: function(object) { | |
var type = typeof object; | |
if (isIE && isFunction(object)) { | |
type = "function" | |
} | |
for (var i = 0; i < reps.length; ++i) { | |
var rep = reps[i]; | |
try { | |
if (rep.supportsObject(object, type)) { | |
if (FBTrace.DBG_DOM) { | |
FBTrace.sysout("getRep type: " + type + " object: " + object, rep) | |
} | |
return rep | |
} | |
} catch(exc) { | |
if (FBTrace.DBG_ERRORS) { | |
FBTrace.sysout("firebug.getRep FAILS: ", exc.message || exc); | |
FBTrace.sysout("firebug.getRep reps[" + i + "/" + reps.length + "]: Rep=" + reps[i].className) | |
} | |
} | |
} | |
return (type == "function") ? defaultFuncRep: defaultRep | |
}, | |
getRepObject: function(node) { | |
var target = null; | |
for (var child = node; child; child = child.parentNode) { | |
if (hasClass(child, "repTarget")) { | |
target = child | |
} | |
if (child.repObject) { | |
if (!target && hasClass(child, "repIgnore")) { | |
break | |
} else { | |
return child.repObject | |
} | |
} | |
} | |
}, | |
getRepNode: function(node) { | |
for (var child = node; child; child = child.parentNode) { | |
if (child.repObject) { | |
return child | |
} | |
} | |
}, | |
getElementByRepObject: function(element, object) { | |
for (var child = element.firstChild; child; child = child.nextSibling) { | |
if (child.repObject == object) { | |
return child | |
} | |
} | |
}, | |
getPref: function(name) { | |
return Firebug[name] | |
}, | |
setPref: function(name, value) { | |
Firebug[name] = value; | |
Firebug.savePrefs() | |
}, | |
setPrefs: function(prefs) { | |
for (var name in prefs) { | |
if (prefs.hasOwnProperty(name)) { | |
Firebug[name] = prefs[name] | |
} | |
} | |
Firebug.savePrefs() | |
}, | |
restorePrefs: function() { | |
var Options = Env.DefaultOptions; | |
for (var name in Options) { | |
Firebug[name] = Options[name] | |
} | |
}, | |
loadPrefs: function() { | |
this.restorePrefs(); | |
var prefs = Store.get("FirebugLite") || {}; | |
var options = prefs.options; | |
var persistedState = prefs.persistedState || FBL.defaultPersistedState; | |
for (var name in options) { | |
if (options.hasOwnProperty(name)) { | |
Firebug[name] = options[name] | |
} | |
} | |
if (Firebug.context && persistedState) { | |
Firebug.context.persistedState = persistedState | |
} | |
}, | |
savePrefs: function() { | |
var prefs = { | |
options: {} | |
}; | |
var EnvOptions = Env.Options; | |
var options = prefs.options; | |
for (var name in EnvOptions) { | |
if (EnvOptions.hasOwnProperty(name)) { | |
options[name] = Firebug[name] | |
} | |
} | |
var persistedState = Firebug.context.persistedState; | |
if (!persistedState) { | |
persistedState = Firebug.context.persistedState = FBL.defaultPersistedState | |
} | |
prefs.persistedState = persistedState; | |
Store.set("FirebugLite", prefs) | |
}, | |
erasePrefs: function() { | |
Store.remove("FirebugLite"); | |
this.restorePrefs() | |
} | |
}; | |
Firebug.restorePrefs(); | |
window.Firebug = FBL.Firebug; | |
if (!Env.Options.enablePersistent || Env.Options.enablePersistent && Env.isChromeContext || Env.isDebugMode) { | |
Env.browser.window.Firebug = FBL.Firebug | |
} | |
FBL.cacheDocument = function cacheDocument() { | |
var ElementCache = Firebug.Lite.Cache.Element; | |
var els = Firebug.browser.document.getElementsByTagName("*"); | |
for (var i = 0, | |
l = els.length, | |
el; i < l; i++) { | |
el = els[i]; | |
ElementCache(el) | |
} | |
}; | |
Firebug.Listener = function() { | |
this.fbListeners = null | |
}; | |
Firebug.Listener.prototype = { | |
addListener: function(listener) { | |
if (!this.fbListeners) { | |
this.fbListeners = [] | |
} | |
this.fbListeners.push(listener) | |
}, | |
removeListener: function(listener) { | |
remove(this.fbListeners, listener) | |
} | |
}; | |
Firebug.Module = extend(new Firebug.Listener(), { | |
initialize: function() {}, | |
shutdown: function() {}, | |
initContext: function(context) {}, | |
reattachContext: function(browser, context) {}, | |
destroyContext: function(context, persistedState) {}, | |
showContext: function(browser, context) {}, | |
loadedContext: function(context) {}, | |
showPanel: function(browser, panel) {}, | |
showSidePanel: function(browser, panel) {}, | |
updateOption: function(name, value) {}, | |
getObjectByURL: function(context, url) {} | |
}); | |
Firebug.Panel = { | |
name: "HelloWorld", | |
title: "Hello World!", | |
parentPanel: null, | |
options: { | |
hasCommandLine: false, | |
hasStatusBar: false, | |
hasToolButtons: false, | |
isPreRendered: false, | |
innerHTMLSync: false | |
}, | |
tabNode: null, | |
panelNode: null, | |
sidePanelNode: null, | |
statusBarNode: null, | |
toolButtonsNode: null, | |
panelBarNode: null, | |
sidePanelBarBoxNode: null, | |
sidePanelBarNode: null, | |
sidePanelBar: null, | |
searchable: false, | |
editable: true, | |
order: 2147483647, | |
statusSeparator: "<", | |
create: function(context, doc) { | |
this.hasSidePanel = parentPanelMap.hasOwnProperty(this.name); | |
this.panelBarNode = $("fbPanelBar1"); | |
this.sidePanelBarBoxNode = $("fbPanelBar2"); | |
if (this.hasSidePanel) { | |
this.sidePanelBar = extend({}, | |
PanelBar); | |
this.sidePanelBar.create(this) | |
} | |
var options = this.options = extend(Firebug.Panel.options, this.options); | |
var panelId = "fb" + this.name; | |
if (options.isPreRendered) { | |
this.panelNode = $(panelId); | |
this.tabNode = $(panelId + "Tab"); | |
this.tabNode.style.display = "block"; | |
if (options.hasToolButtons) { | |
this.toolButtonsNode = $(panelId + "Buttons") | |
} | |
if (options.hasStatusBar) { | |
this.statusBarBox = $("fbStatusBarBox"); | |
this.statusBarNode = $(panelId + "StatusBar") | |
} | |
} else { | |
var containerSufix = this.parentPanel ? "2": "1"; | |
var panelNode = this.panelNode = createElement("div", { | |
id: panelId, | |
className: "fbPanel" | |
}); | |
$("fbPanel" + containerSufix).appendChild(panelNode); | |
var tabHTML = '<span class="fbTabL"></span><span class="fbTabText">' + this.title + '</span><span class="fbTabR"></span>'; | |
var tabNode = this.tabNode = createElement("a", { | |
id: panelId + "Tab", | |
className: "fbTab fbHover", | |
innerHTML: tabHTML | |
}); | |
if (isIE6) { | |
tabNode.href = "javascript:void(0)" | |
} | |
var panelBarNode = this.parentPanel ? Firebug.chrome.getPanel(this.parentPanel).sidePanelBarNode: this.panelBarNode; | |
panelBarNode.appendChild(tabNode); | |
tabNode.style.display = "block"; | |
if (options.hasToolButtons) { | |
this.toolButtonsNode = createElement("span", { | |
id: panelId + "Buttons", | |
className: "fbToolbarButtons" | |
}); | |
$("fbToolbarButtons").appendChild(this.toolButtonsNode) | |
} | |
if (options.hasStatusBar) { | |
this.statusBarBox = $("fbStatusBarBox"); | |
this.statusBarNode = createElement("span", { | |
id: panelId + "StatusBar", | |
className: "fbToolbarButtons fbStatusBar" | |
}); | |
this.statusBarBox.appendChild(this.statusBarNode) | |
} | |
} | |
this.containerNode = this.panelNode.parentNode; | |
if (FBTrace.DBG_INITIALIZE) { | |
FBTrace.sysout("Firebug.Panel.create", this.name) | |
} | |
this.onContextMenu = bind(this.onContextMenu, this) | |
}, | |
destroy: function(state) { | |
if (FBTrace.DBG_INITIALIZE) { | |
FBTrace.sysout("Firebug.Panel.destroy", this.name) | |
} | |
if (this.hasSidePanel) { | |
this.sidePanelBar.destroy(); | |
this.sidePanelBar = null | |
} | |
this.options = null; | |
this.name = null; | |
this.parentPanel = null; | |
this.tabNode = null; | |
this.panelNode = null; | |
this.containerNode = null; | |
this.toolButtonsNode = null; | |
this.statusBarBox = null; | |
this.statusBarNode = null | |
}, | |
initialize: function() { | |
if (FBTrace.DBG_INITIALIZE) { | |
FBTrace.sysout("Firebug.Panel.initialize", this.name) | |
} | |
if (this.hasSidePanel) { | |
this.sidePanelBar.initialize() | |
} | |
var options = this.options = extend(Firebug.Panel.options, this.options); | |
var panelId = "fb" + this.name; | |
this.panelNode = $(panelId); | |
this.tabNode = $(panelId + "Tab"); | |
this.tabNode.style.display = "block"; | |
if (options.hasStatusBar) { | |
this.statusBarBox = $("fbStatusBarBox"); | |
this.statusBarNode = $(panelId + "StatusBar") | |
} | |
if (options.hasToolButtons) { | |
this.toolButtonsNode = $(panelId + "Buttons") | |
} | |
this.containerNode = this.panelNode.parentNode; | |
this.containerNode.scrollTop = this.lastScrollTop; | |
addEvent(this.containerNode, "contextmenu", this.onContextMenu); | |
Firebug.chrome.currentPanel = Firebug.chrome.selectedPanel && Firebug.chrome.selectedPanel.sidePanelBar ? Firebug.chrome.selectedPanel.sidePanelBar.selectedPanel: Firebug.chrome.selectedPanel; | |
Firebug.showInfoTips = true; | |
if (Firebug.InfoTip) { | |
Firebug.InfoTip.initializeBrowser(Firebug.chrome) | |
} | |
}, | |
shutdown: function() { | |
if (FBTrace.DBG_INITIALIZE) { | |
FBTrace.sysout("Firebug.Panel.shutdown", this.name) | |
} | |
if (Firebug.InfoTip) { | |
Firebug.InfoTip.uninitializeBrowser(Firebug.chrome) | |
} | |
if (Firebug.chrome.largeCommandLineVisible) { | |
Firebug.chrome.hideLargeCommandLine() | |
} | |
if (this.hasSidePanel) {} | |
this.lastScrollTop = this.containerNode.scrollTop; | |
removeEvent(this.containerNode, "contextmenu", this.onContextMenu) | |
}, | |
detach: function(oldChrome, newChrome) { | |
if (oldChrome && oldChrome.selectedPanel && oldChrome.selectedPanel.name == this.name) { | |
this.lastScrollTop = oldChrome.selectedPanel.containerNode.scrollTop | |
} | |
}, | |
reattach: function(doc) { | |
if (this.options.innerHTMLSync) { | |
this.synchronizeUI() | |
} | |
}, | |
synchronizeUI: function() { | |
this.containerNode.scrollTop = this.lastScrollTop || 0 | |
}, | |
show: function(state) { | |
var options = this.options; | |
if (options.hasStatusBar) { | |
this.statusBarBox.style.display = "inline"; | |
this.statusBarNode.style.display = "inline" | |
} | |
if (options.hasToolButtons) { | |
this.toolButtonsNode.style.display = "inline" | |
} | |
this.panelNode.style.display = "block"; | |
this.visible = true; | |
if (!this.parentPanel) { | |
Firebug.chrome.layout(this) | |
} | |
}, | |
hide: function(state) { | |
var options = this.options; | |
if (options.hasStatusBar) { | |
this.statusBarBox.style.display = "none"; | |
this.statusBarNode.style.display = "none" | |
} | |
if (options.hasToolButtons) { | |
this.toolButtonsNode.style.display = "none" | |
} | |
this.panelNode.style.display = "none"; | |
this.visible = false | |
}, | |
watchWindow: function(win) {}, | |
unwatchWindow: function(win) {}, | |
updateOption: function(name, value) {}, | |
showToolbarButtons: function(buttonsId, show) { | |
try { | |
if (!this.context.browser) { | |
if (FBTrace.DBG_ERRORS) { | |
FBTrace.sysout("firebug.Panel showToolbarButtons this.context has no browser, this:", this) | |
} | |
return | |
} | |
var buttons = this.context.browser.chrome.$(buttonsId); | |
if (buttons) { | |
collapse(buttons, show ? "false": "true") | |
} | |
} catch(exc) { | |
if (FBTrace.DBG_ERRORS) { | |
FBTrace.dumpProperties("firebug.Panel showToolbarButtons FAILS", exc); | |
if (!this.context.browser) { | |
FBTrace.dumpStack("firebug.Panel showToolbarButtons no browser") | |
} | |
} | |
} | |
}, | |
supportsObject: function(object) { | |
return 0 | |
}, | |
hasObject: function(object) { | |
return false | |
}, | |
select: function(object, forceUpdate) { | |
if (!object) { | |
object = this.getDefaultSelection(this.context) | |
} | |
if (FBTrace.DBG_PANELS) { | |
FBTrace.sysout("firebug.select " + this.name + " forceUpdate: " + forceUpdate + " " + object + ((object == this.selection) ? "==": "!=") + this.selection) | |
} | |
if (forceUpdate || object != this.selection) { | |
this.selection = object; | |
this.updateSelection(object) | |
} | |
}, | |
updateSelection: function(object) {}, | |
markChange: function(skipSelf) { | |
if (this.dependents) { | |
if (skipSelf) { | |
for (var i = 0; i < this.dependents.length; ++i) { | |
var panelName = this.dependents[i]; | |
if (panelName != this.name) { | |
this.context.invalidatePanels(panelName) | |
} | |
} | |
} else { | |
this.context.invalidatePanels.apply(this.context, this.dependents) | |
} | |
} | |
}, | |
startInspecting: function() {}, | |
stopInspecting: function(object, cancelled) {}, | |
search: function(text, reverse) {}, | |
getSearchOptionsMenuItems: function() { | |
return [Firebug.Search.searchOptionMenu("search.Case Sensitive", "searchCaseSensitive")] | |
}, | |
navigateToNextDocument: function(match, reverse) { | |
var self = this; | |
function compare(a, b) { | |
var locA = self.getObjectDescription(a); | |
var locB = self.getObjectDescription(b); | |
if (locA.path > locB.path) { | |
return 1 | |
} | |
if (locA.path < locB.path) { | |
return - 1 | |
} | |
if (locA.name > locB.name) { | |
return 1 | |
} | |
if (locA.name < locB.name) { | |
return - 1 | |
} | |
return 0 | |
} | |
var allLocs = this.getLocationList().sort(compare); | |
for (var curPos = 0; curPos < allLocs.length && allLocs[curPos] != this.location; curPos++) {} | |
function transformIndex(index) { | |
if (reverse) { | |
var intermediate = curPos - index - 1; | |
return (intermediate < 0 ? allLocs.length: 0) + intermediate | |
} else { | |
return (curPos + index + 1) % allLocs.length | |
} | |
} | |
for (var next = 0; next < allLocs.length - 1; next++) { | |
var object = allLocs[transformIndex(next)]; | |
if (match(object)) { | |
this.navigate(object); | |
return object | |
} | |
} | |
}, | |
getOptionsMenuItems: function() { | |
return null | |
}, | |
getContextMenuItems: function(object, target) { | |
return [] | |
}, | |
getBreakOnMenuItems: function() { | |
return [] | |
}, | |
getEditor: function(target, value) {}, | |
getDefaultSelection: function() { | |
return null | |
}, | |
browseObject: function(object) {}, | |
getPopupObject: function(target) { | |
return Firebug.getRepObject(target) | |
}, | |
getTooltipObject: function(target) { | |
return Firebug.getRepObject(target) | |
}, | |
showInfoTip: function(infoTip, x, y) {}, | |
getObjectPath: function(object) { | |
return null | |
}, | |
getLocationList: function() { | |
return null | |
}, | |
getDefaultLocation: function() { | |
return null | |
}, | |
getObjectLocation: function(object) { | |
return "" | |
}, | |
getObjectDescription: function(object) { | |
var url = this.getObjectLocation(object); | |
return FBL.splitURLBase(url) | |
}, | |
highlight: function(show) { | |
var tab = this.getTab(); | |
if (!tab) { | |
return | |
} | |
if (show) { | |
tab.setAttribute("highlight", "true") | |
} else { | |
tab.removeAttribute("highlight") | |
} | |
}, | |
getTab: function() { | |
var chrome = Firebug.chrome; | |
var tab = chrome.$("fbPanelBar2").getTab(this.name); | |
if (!tab) { | |
tab = chrome.$("fbPanelBar1").getTab(this.name) | |
} | |
return tab | |
}, | |
breakOnNext: function(armed) {}, | |
shouldBreakOnNext: function() { | |
return false | |
}, | |
getBreakOnNextTooltip: function(enabled) { | |
return null | |
}, | |
onContextMenu: function(event) { | |
if (!this.getContextMenuItems) { | |
return | |
} | |
cancelEvent(event, true); | |
var target = event.target || event.srcElement; | |
var menu = this.getContextMenuItems(this.selection, target); | |
if (!menu) { | |
return | |
} | |
var contextMenu = new Menu({ | |
id: "fbPanelContextMenu", | |
items: menu | |
}); | |
contextMenu.show(event.clientX, event.clientY); | |
return true | |
} | |
}; | |
Firebug.MeasureBox = { | |
startMeasuring: function(target) { | |
if (!this.measureBox) { | |
this.measureBox = target.ownerDocument.createElement("span"); | |
this.measureBox.className = "measureBox" | |
} | |
copyTextStyles(target, this.measureBox); | |
target.ownerDocument.body.appendChild(this.measureBox) | |
}, | |
getMeasuringElement: function() { | |
return this.measureBox | |
}, | |
measureText: function(value) { | |
this.measureBox.innerHTML = value ? escapeForSourceLine(value) : "m"; | |
return { | |
width: this.measureBox.offsetWidth, | |
height: this.measureBox.offsetHeight - 1 | |
} | |
}, | |
measureInputText: function(value) { | |
value = value ? escapeForTextNode(value) : "m"; | |
if (!Firebug.showTextNodesWithWhitespace) { | |
value = value.replace(/\t/g, "mmmmmm").replace(/\ /g, "m") | |
} | |
this.measureBox.innerHTML = value; | |
return { | |
width: this.measureBox.offsetWidth, | |
height: this.measureBox.offsetHeight - 1 | |
} | |
}, | |
getBox: function(target) { | |
var style = this.measureBox.ownerDocument.defaultView.getComputedStyle(this.measureBox, ""); | |
var box = getBoxFromStyles(style, this.measureBox); | |
return box | |
}, | |
stopMeasuring: function() { | |
this.measureBox.parentNode.removeChild(this.measureBox) | |
} | |
}; | |
if (FBL.domplate) { | |
Firebug.Rep = domplate({ | |
className: "", | |
inspectable: true, | |
supportsObject: function(object, type) { | |
return false | |
}, | |
inspectObject: function(object, context) { | |
Firebug.chrome.select(object) | |
}, | |
browseObject: function(object, context) {}, | |
persistObject: function(object, context) {}, | |
getRealObject: function(object, context) { | |
return object | |
}, | |
getTitle: function(object) { | |
var label = safeToString(object); | |
var re = /\[object (.*?)\]/; | |
var m = re.exec(label); | |
if (m) { | |
return m[1] | |
} else { | |
if (isIE && (label == "[object]" || typeof object == "object" && typeof label == "undefined")) { | |
return "Object" | |
} else { | |
return label | |
} | |
} | |
}, | |
getTooltip: function(object) { | |
return null | |
}, | |
getContextMenuItems: function(object, target, context) { | |
return [] | |
}, | |
STR: function(name) { | |
return $STR(name) | |
}, | |
cropString: function(text) { | |
return cropString(text) | |
}, | |
cropMultipleLines: function(text, limit) { | |
return cropMultipleLines(text, limit) | |
}, | |
toLowerCase: function(text) { | |
return text ? text.toLowerCase() : text | |
}, | |
plural: function(n) { | |
return n == 1 ? "": "s" | |
} | |
}) | |
} | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
FBL.Controller = { | |
controllers: null, | |
controllerContext: null, | |
initialize: function(context) { | |
this.controllers = []; | |
this.controllerContext = context || Firebug.chrome | |
}, | |
shutdown: function() { | |
this.removeControllers() | |
}, | |
addController: function() { | |
for (var i = 0, | |
arg; arg = arguments[i]; i++) { | |
if (typeof arg[0] == "string") { | |
arg[0] = $$(arg[0], this.controllerContext) | |
} | |
var handler = arg[2]; | |
arg[2] = bind(handler, this); | |
arg[3] = handler; | |
this.controllers.push(arg); | |
addEvent.apply(this, arg) | |
} | |
}, | |
removeController: function() { | |
for (var i = 0, | |
arg; arg = arguments[i]; i++) { | |
for (var j = 0, | |
c; c = this.controllers[j]; j++) { | |
if (arg[0] == c[0] && arg[1] == c[1] && arg[2] == c[3]) { | |
removeEvent.apply(this, c) | |
} | |
} | |
} | |
}, | |
removeControllers: function() { | |
for (var i = 0, | |
c; c = this.controllers[i]; i++) { | |
removeEvent.apply(this, c) | |
} | |
} | |
}; | |
FBL.PanelBar = { | |
panelMap: null, | |
selectedPanel: null, | |
parentPanelName: null, | |
create: function(ownerPanel) { | |
this.panelMap = {}; | |
this.ownerPanel = ownerPanel; | |
if (ownerPanel) { | |
ownerPanel.sidePanelBarNode = createElement("span"); | |
ownerPanel.sidePanelBarNode.style.display = "none"; | |
ownerPanel.sidePanelBarBoxNode.appendChild(ownerPanel.sidePanelBarNode) | |
} | |
var panels = Firebug.panelTypes; | |
for (var i = 0, | |
p; p = panels[i]; i++) { | |
if (!ownerPanel && !p.prototype.parentPanel || ownerPanel && p.prototype.parentPanel && ownerPanel.name == p.prototype.parentPanel) { | |
this.addPanel(p.prototype.name) | |
} | |
} | |
}, | |
destroy: function() { | |
PanelBar.shutdown.call(this); | |
for (var name in this.panelMap) { | |
this.removePanel(name); | |
var panel = this.panelMap[name]; | |
panel.destroy(); | |
this.panelMap[name] = null; | |
delete this.panelMap[name] | |
} | |
this.panelMap = null; | |
this.ownerPanel = null | |
}, | |
initialize: function() { | |
if (this.ownerPanel) { | |
this.ownerPanel.sidePanelBarNode.style.display = "inline" | |
} | |
for (var name in this.panelMap) { (function(self, name) { | |
var onTabClick = function onTabClick() { | |
self.selectPanel(name); | |
return false | |
}; | |
Firebug.chrome.addController([self.panelMap[name].tabNode, "mousedown", onTabClick]) | |
})(this, name) | |
} | |
}, | |
shutdown: function() { | |
var selectedPanel = this.selectedPanel; | |
if (selectedPanel) { | |
removeClass(selectedPanel.tabNode, "fbSelectedTab"); | |
selectedPanel.hide(); | |
selectedPanel.shutdown() | |
} | |
if (this.ownerPanel) { | |
this.ownerPanel.sidePanelBarNode.style.display = "none" | |
} | |
this.selectedPanel = null | |
}, | |
addPanel: function(panelName, parentPanel) { | |
var PanelType = Firebug.panelTypeMap[panelName]; | |
var panel = this.panelMap[panelName] = new PanelType(); | |
panel.create() | |
}, | |
removePanel: function(panelName) { | |
var panel = this.panelMap[panelName]; | |
if (panel.hasOwnProperty(panelName)) { | |
panel.destroy() | |
} | |
}, | |
selectPanel: function(panelName) { | |
var selectedPanel = this.selectedPanel; | |
var panel = this.panelMap[panelName]; | |
if (panel && selectedPanel != panel) { | |
if (selectedPanel) { | |
removeClass(selectedPanel.tabNode, "fbSelectedTab"); | |
selectedPanel.shutdown(); | |
selectedPanel.hide() | |
} | |
if (!panel.parentPanel) { | |
Firebug.context.persistedState.selectedPanelName = panelName | |
} | |
this.selectedPanel = panel; | |
setClass(panel.tabNode, "fbSelectedTab"); | |
panel.show(); | |
panel.initialize() | |
} | |
}, | |
getPanel: function(panelName) { | |
var panel = this.panelMap[panelName]; | |
return panel | |
} | |
}; | |
FBL.Button = function(options) { | |
options = options || {}; | |
append(this, options); | |
this.state = "unpressed"; | |
this.display = "unpressed"; | |
if (this.element) { | |
this.container = this.element.parentNode | |
} else { | |
this.shouldDestroy = true; | |
this.container = this.owner.getPanel().toolButtonsNode; | |
this.element = createElement("a", { | |
className: this.baseClassName + " " + this.className + " fbHover", | |
innerHTML: this.caption | |
}); | |
if (this.title) { | |
this.element.title = this.title | |
} | |
this.container.appendChild(this.element) | |
} | |
}; | |
Button.prototype = extend(Controller, { | |
type: "normal", | |
caption: "caption", | |
title: null, | |
className: "", | |
baseClassName: "fbButton", | |
pressedClassName: "fbBtnPressed", | |
element: null, | |
container: null, | |
owner: null, | |
state: null, | |
display: null, | |
destroy: function() { | |
this.shutdown(); | |
if (this.shouldDestroy) { | |
this.container.removeChild(this.element) | |
} | |
this.element = null; | |
this.container = null; | |
this.owner = null | |
}, | |
initialize: function() { | |
Controller.initialize.apply(this); | |
var element = this.element; | |
this.addController([element, "mousedown", this.handlePress]); | |
if (this.type == "normal") { | |
this.addController([element, "mouseup", this.handleUnpress], [element, "mouseout", this.handleUnpress], [element, "click", this.handleClick]) | |
} | |
}, | |
shutdown: function() { | |
Controller.shutdown.apply(this) | |
}, | |
restore: function() { | |
this.changeState("unpressed") | |
}, | |
changeState: function(state) { | |
this.state = state; | |
this.changeDisplay(state) | |
}, | |
changeDisplay: function(display) { | |
if (display != this.display) { | |
if (display == "pressed") { | |
setClass(this.element, this.pressedClassName) | |
} else { | |
if (display == "unpressed") { | |
removeClass(this.element, this.pressedClassName) | |
} | |
} | |
this.display = display | |
} | |
}, | |
handlePress: function(event) { | |
cancelEvent(event, true); | |
if (this.type == "normal") { | |
this.changeDisplay("pressed"); | |
this.beforeClick = true | |
} else { | |
if (this.type == "toggle") { | |
if (this.state == "pressed") { | |
this.changeState("unpressed"); | |
if (this.onUnpress) { | |
this.onUnpress.apply(this.owner, arguments) | |
} | |
} else { | |
this.changeState("pressed"); | |
if (this.onPress) { | |
this.onPress.apply(this.owner, arguments) | |
} | |
} | |
if (this.onClick) { | |
this.onClick.apply(this.owner, arguments) | |
} | |
} | |
} | |
return false | |
}, | |
handleUnpress: function(event) { | |
cancelEvent(event, true); | |
if (this.beforeClick) { | |
this.changeDisplay("unpressed") | |
} | |
return false | |
}, | |
handleClick: function(event) { | |
cancelEvent(event, true); | |
if (this.type == "normal") { | |
if (this.onClick) { | |
this.onClick.apply(this.owner) | |
} | |
this.changeState("unpressed") | |
} | |
this.beforeClick = false; | |
return false | |
} | |
}); | |
FBL.IconButton = function() { | |
Button.apply(this, arguments) | |
}; | |
IconButton.prototype = extend(Button.prototype, { | |
baseClassName: "fbIconButton", | |
pressedClassName: "fbIconPressed" | |
}); | |
var menuItemProps = { | |
"class": "$item.className", | |
type: "$item.type", | |
value: "$item.value", | |
_command: "$item.command" | |
}; | |
if (isIE6) { | |
menuItemProps.href = "javascript:void(0)" | |
} | |
if (FBL.domplate) { | |
var MenuPlate = domplate(Firebug.Rep, { | |
tag: DIV({ | |
"class": "fbMenu fbShadow" | |
}, | |
DIV({ | |
"class": "fbMenuContent fbShadowContent" | |
}, | |
FOR("item", "$object.items|memberIterator", TAG("$item.tag", { | |
item: "$item" | |
})))), | |
itemTag: A(menuItemProps, "$item.label"), | |
checkBoxTag: A(extend(menuItemProps, { | |
checked: "$item.checked" | |
}), "$item.label"), | |
radioButtonTag: A(extend(menuItemProps, { | |
selected: "$item.selected" | |
}), "$item.label"), | |
groupTag: A(extend(menuItemProps, { | |
child: "$item.child" | |
}), "$item.label"), | |
shortcutTag: A(menuItemProps, "$item.label", SPAN({ | |
"class": "fbMenuShortcutKey" | |
}, | |
"$item.key")), | |
separatorTag: SPAN({ | |
"class": "fbMenuSeparator" | |
}), | |
memberIterator: function(items) { | |
var result = []; | |
for (var i = 0, | |
length = items.length; i < length; i++) { | |
var item = items[i]; | |
if (typeof item == "string" && item.indexOf("-") == 0) { | |
result.push({ | |
tag: this.separatorTag | |
}); | |
continue | |
} | |
item = extend(item, {}); | |
item.type = item.type || ""; | |
item.value = item.value || ""; | |
var type = item.type; | |
item.tag = this.itemTag; | |
var className = item.className || ""; | |
className += "fbMenuOption fbHover "; | |
if (type == "checkbox") { | |
className += "fbMenuCheckBox "; | |
item.tag = this.checkBoxTag | |
} else { | |
if (type == "radiobutton") { | |
className += "fbMenuRadioButton "; | |
item.tag = this.radioButtonTag | |
} else { | |
if (type == "group") { | |
className += "fbMenuGroup "; | |
item.tag = this.groupTag | |
} else { | |
if (type == "shortcut") { | |
className += "fbMenuShortcut "; | |
item.tag = this.shortcutTag | |
} | |
} | |
} | |
} | |
if (item.checked) { | |
className += "fbMenuChecked " | |
} else { | |
if (item.selected) { | |
className += "fbMenuRadioSelected " | |
} | |
} | |
if (item.disabled) { | |
className += "fbMenuDisabled " | |
} | |
item.className = className; | |
item.label = $STR(item.label); | |
result.push(item) | |
} | |
return result | |
} | |
}) | |
} | |
FBL.Menu = function(options) { | |
if (!options.element) { | |
if (options.getItems) { | |
options.items = options.getItems() | |
} | |
options.element = MenuPlate.tag.append({ | |
object: options | |
}, | |
getElementByClass(Firebug.chrome.document, "fbBody"), MenuPlate) | |
} | |
append(this, options); | |
if (typeof this.element == "string") { | |
this.id = this.element; | |
this.element = $(this.id) | |
} else { | |
if (this.id) { | |
this.element.id = this.id | |
} | |
} | |
this.element.firebugIgnore = true; | |
this.elementStyle = this.element.style; | |
this.isVisible = false; | |
this.handleMouseDown = bind(this.handleMouseDown, this); | |
this.handleMouseOver = bind(this.handleMouseOver, this); | |
this.handleMouseOut = bind(this.handleMouseOut, this); | |
this.handleWindowMouseDown = bind(this.handleWindowMouseDown, this) | |
}; | |
var menuMap = {}; | |
Menu.prototype = extend(Controller, { | |
destroy: function() { | |
this.hide(); | |
if (this.parentMenu) { | |
this.parentMenu.childMenu = null | |
} | |
this.element.parentNode.removeChild(this.element); | |
this.element = null; | |
this.elementStyle = null; | |
this.parentMenu = null; | |
this.parentTarget = null | |
}, | |
initialize: function() { | |
Controller.initialize.call(this); | |
this.addController([this.element, "mousedown", this.handleMouseDown], [this.element, "mouseover", this.handleMouseOver]) | |
}, | |
shutdown: function() { | |
Controller.shutdown.call(this) | |
}, | |
show: function(x, y) { | |
this.initialize(); | |
if (this.isVisible) { | |
return | |
} | |
x = x || 0; | |
y = y || 0; | |
if (this.parentMenu) { | |
var oldChildMenu = this.parentMenu.childMenu; | |
if (oldChildMenu && oldChildMenu != this) { | |
oldChildMenu.destroy() | |
} | |
this.parentMenu.childMenu = this | |
} else { | |
addEvent(Firebug.chrome.document, "mousedown", this.handleWindowMouseDown) | |
} | |
this.elementStyle.display = "block"; | |
this.elementStyle.visibility = "hidden"; | |
var size = Firebug.chrome.getSize(); | |
x = Math.min(x, size.width - this.element.clientWidth - 10); | |
x = Math.max(x, 0); | |
y = Math.min(y, size.height - this.element.clientHeight - 10); | |
y = Math.max(y, 0); | |
this.elementStyle.left = x + "px"; | |
this.elementStyle.top = y + "px"; | |
this.elementStyle.visibility = "visible"; | |
this.isVisible = true; | |
if (isFunction(this.onShow)) { | |
this.onShow.apply(this, arguments) | |
} | |
}, | |
hide: function() { | |
this.clearHideTimeout(); | |
this.clearShowChildTimeout(); | |
if (!this.isVisible) { | |
return | |
} | |
this.elementStyle.display = "none"; | |
if (this.childMenu) { | |
this.childMenu.destroy(); | |
this.childMenu = null | |
} | |
if (this.parentTarget) { | |
removeClass(this.parentTarget, "fbMenuGroupSelected") | |
} | |
this.isVisible = false; | |
this.shutdown(); | |
if (isFunction(this.onHide)) { | |
this.onHide.apply(this, arguments) | |
} | |
}, | |
showChildMenu: function(target) { | |
var id = target.getAttribute("child"); | |
var parent = this; | |
var target = target; | |
this.showChildTimeout = Firebug.chrome.window.setTimeout(function() { | |
var box = Firebug.chrome.getElementBox(target); | |
var childMenuObject = menuMap.hasOwnProperty(id) ? menuMap[id] : { | |
element: $(id) | |
}; | |
var childMenu = new Menu(extend(childMenuObject, { | |
parentMenu: parent, | |
parentTarget: target | |
})); | |
var offsetLeft = isIE6 ? -1 : -6; | |
childMenu.show(box.left + box.width + offsetLeft, box.top - 6); | |
setClass(target, "fbMenuGroupSelected") | |
}, | |
350) | |
}, | |
clearHideTimeout: function() { | |
if (this.hideTimeout) { | |
Firebug.chrome.window.clearTimeout(this.hideTimeout); | |
delete this.hideTimeout | |
} | |
}, | |
clearShowChildTimeout: function() { | |
if (this.showChildTimeout) { | |
Firebug.chrome.window.clearTimeout(this.showChildTimeout); | |
this.showChildTimeout = null | |
} | |
}, | |
handleMouseDown: function(event) { | |
cancelEvent(event, true); | |
var topParent = this; | |
while (topParent.parentMenu) { | |
topParent = topParent.parentMenu | |
} | |
var target = event.target || event.srcElement; | |
target = getAncestorByClass(target, "fbMenuOption"); | |
if (!target || hasClass(target, "fbMenuGroup")) { | |
return false | |
} | |
if (target && !hasClass(target, "fbMenuDisabled")) { | |
var type = target.getAttribute("type"); | |
if (type == "checkbox") { | |
var checked = target.getAttribute("checked"); | |
var value = target.getAttribute("value"); | |
var wasChecked = hasClass(target, "fbMenuChecked"); | |
if (wasChecked) { | |
removeClass(target, "fbMenuChecked"); | |
target.setAttribute("checked", "") | |
} else { | |
setClass(target, "fbMenuChecked"); | |
target.setAttribute("checked", "true") | |
} | |
if (isFunction(this.onCheck)) { | |
this.onCheck.call(this, target, value, !wasChecked) | |
} | |
} | |
if (type == "radiobutton") { | |
var selectedRadios = getElementsByClass(target.parentNode, "fbMenuRadioSelected"); | |
var group = target.getAttribute("group"); | |
for (var i = 0, | |
length = selectedRadios.length; i < length; i++) { | |
radio = selectedRadios[i]; | |
if (radio.getAttribute("group") == group) { | |
removeClass(radio, "fbMenuRadioSelected"); | |
radio.setAttribute("selected", "") | |
} | |
} | |
setClass(target, "fbMenuRadioSelected"); | |
target.setAttribute("selected", "true") | |
} | |
var handler = null; | |
var cmd = target.command; | |
if (isFunction(cmd)) { | |
handler = cmd | |
} else { | |
if (typeof cmd == "string") { | |
handler = this[cmd] | |
} | |
} | |
var closeMenu = true; | |
if (handler) { | |
closeMenu = handler.call(this, target) !== false | |
} | |
if (closeMenu) { | |
topParent.hide() | |
} | |
} | |
return false | |
}, | |
handleWindowMouseDown: function(event) { | |
var target = event.target || event.srcElement; | |
target = getAncestorByClass(target, "fbMenu"); | |
if (!target) { | |
removeEvent(Firebug.chrome.document, "mousedown", this.handleWindowMouseDown); | |
this.hide() | |
} | |
}, | |
handleMouseOver: function(event) { | |
this.clearHideTimeout(); | |
this.clearShowChildTimeout(); | |
var target = event.target || event.srcElement; | |
target = getAncestorByClass(target, "fbMenuOption"); | |
if (!target) { | |
return | |
} | |
var childMenu = this.childMenu; | |
if (childMenu) { | |
removeClass(childMenu.parentTarget, "fbMenuGroupSelected"); | |
if (childMenu.parentTarget != target && childMenu.isVisible) { | |
childMenu.clearHideTimeout(); | |
childMenu.hideTimeout = Firebug.chrome.window.setTimeout(function() { | |
childMenu.destroy() | |
}, | |
300) | |
} | |
} | |
if (hasClass(target, "fbMenuGroup")) { | |
this.showChildMenu(target) | |
} | |
} | |
}); | |
append(Menu, { | |
register: function(object) { | |
menuMap[object.id] = object | |
}, | |
check: function(element) { | |
setClass(element, "fbMenuChecked"); | |
element.setAttribute("checked", "true") | |
}, | |
uncheck: function(element) { | |
removeClass(element, "fbMenuChecked"); | |
element.setAttribute("checked", "") | |
}, | |
disable: function(element) { | |
setClass(element, "fbMenuDisabled") | |
}, | |
enable: function(element) { | |
removeClass(element, "fbMenuDisabled") | |
} | |
}); | |
function StatusBar() {} | |
StatusBar.prototype = extend(Controller, {}) | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
var refreshDelay = 300; | |
var shouldFixElementFromPoint = isOpera || isSafari && browserVersion < "532"; | |
var evalError = "___firebug_evaluation_error___"; | |
var pixelsPerInch; | |
var resetStyle = "margin:0; padding:0; border:0; position:absolute; overflow:hidden; display:block;"; | |
var offscreenStyle = resetStyle + "top:-1234px; left:-1234px;"; | |
FBL.Context = function(win) { | |
this.window = win.window; | |
this.document = win.document; | |
this.browser = Env.browser; | |
if (isIE && !this.window.eval) { | |
this.window.execScript("null"); | |
if (!this.window.eval) { | |
throw new Error("Firebug Error: eval() method not found in this window") | |
} | |
} | |
this.eval = this.window.eval("new Function('try{ return window.eval.apply(window,arguments) }catch(E){ E." + evalError + "=true; return E }')") | |
}; | |
FBL.Context.prototype = { | |
browser: null, | |
loaded: true, | |
setTimeout: function(fn, delay) { | |
var win = this.window; | |
if (win.setTimeout == this.setTimeout) { | |
throw new Error("setTimeout recursion") | |
} | |
var timeout = win.setTimeout.apply ? win.setTimeout.apply(win, arguments) : win.setTimeout(fn, delay); | |
if (!this.timeouts) { | |
this.timeouts = {} | |
} | |
this.timeouts[timeout] = 1; | |
return timeout | |
}, | |
clearTimeout: function(timeout) { | |
clearTimeout(timeout); | |
if (this.timeouts) { | |
delete this.timeouts[timeout] | |
} | |
}, | |
setInterval: function(fn, delay) { | |
var win = this.window; | |
var timeout = win.setInterval.apply ? win.setInterval.apply(win, arguments) : win.setInterval(fn, delay); | |
if (!this.intervals) { | |
this.intervals = {} | |
} | |
this.intervals[timeout] = 1; | |
return timeout | |
}, | |
clearInterval: function(timeout) { | |
clearInterval(timeout); | |
if (this.intervals) { | |
delete this.intervals[timeout] | |
} | |
}, | |
invalidatePanels: function() { | |
if (!this.invalidPanels) { | |
this.invalidPanels = {} | |
} | |
for (var i = 0; i < arguments.length; ++i) { | |
var panelName = arguments[i]; | |
if (!Firebug.chrome || !Firebug.chrome.selectedPanel) { | |
return | |
} | |
var panel = Firebug.chrome.selectedPanel.sidePanelBar ? Firebug.chrome.selectedPanel.sidePanelBar.getPanel(panelName, true) : null; | |
if (panel && !panel.noRefresh) { | |
this.invalidPanels[panelName] = 1 | |
} | |
} | |
if (this.refreshTimeout) { | |
this.clearTimeout(this.refreshTimeout); | |
delete this.refreshTimeout | |
} | |
this.refreshTimeout = this.setTimeout(bindFixed(function() { | |
var invalids = []; | |
for (var panelName in this.invalidPanels) { | |
var panel = Firebug.chrome.selectedPanel.sidePanelBar ? Firebug.chrome.selectedPanel.sidePanelBar.getPanel(panelName, true) : null; | |
if (panel) { | |
if (panel.visible && !panel.editing) { | |
panel.refresh() | |
} else { | |
panel.needsRefresh = true | |
} | |
if (panel.editing) { | |
invalids.push(panelName) | |
} | |
} | |
} | |
delete this.invalidPanels; | |
delete this.refreshTimeout; | |
if (invalids.length) { | |
this.invalidatePanels.apply(this, invalids) | |
} | |
}, | |
this), refreshDelay) | |
}, | |
evaluate: function(expr, context, api, errorHandler) { | |
context = context || "window"; | |
var isObjectLiteral = trim(expr).indexOf("{") == 0, | |
cmd, | |
result; | |
if (context == "window") { | |
if (isObjectLiteral) { | |
cmd = api ? "with(" + api + "){ (" + expr + ") }": "(" + expr + ")" | |
} else { | |
cmd = api ? "with(" + api + "){ " + expr + " }": expr | |
} | |
} else { | |
cmd = api ? "(function(arguments){ with(" + api + "){ " + expr + " } }).call(" + context + ",undefined)": "(function(arguments){ " + expr + " }).call(" + context + ",undefined)" | |
} | |
result = this.eval(cmd); | |
if (result && result[evalError]) { | |
var msg = result.name ? (result.name + ": ") : ""; | |
msg += result.message || result; | |
if (errorHandler) { | |
result = errorHandler(msg) | |
} else { | |
result = msg | |
} | |
} | |
return result | |
}, | |
getWindowSize: function() { | |
var width = 0, | |
height = 0, | |
el; | |
if (typeof this.window.innerWidth == "number") { | |
width = this.window.innerWidth; | |
height = this.window.innerHeight | |
} else { | |
if ((el = this.document.documentElement) && (el.clientHeight || el.clientWidth)) { | |
width = el.clientWidth; | |
height = el.clientHeight | |
} else { | |
if ((el = this.document.body) && (el.clientHeight || el.clientWidth)) { | |
width = el.clientWidth; | |
height = el.clientHeight | |
} | |
} | |
} | |
return { | |
width: width, | |
height: height | |
} | |
}, | |
getWindowScrollSize: function() { | |
var width = 0, | |
height = 0, | |
el; | |
if (!isIEQuiksMode && (el = this.document.documentElement) && (el.scrollHeight || el.scrollWidth)) { | |
width = el.scrollWidth; | |
height = el.scrollHeight | |
} | |
if ((el = this.document.body) && (el.scrollHeight || el.scrollWidth) && (el.scrollWidth > 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 | |
} | |
}, | |
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(); | |
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 | |
}, | |
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) | |
} else { | |
if (unit == "em") { | |
return this.emToPixels(el, value) | |
} else { | |
if (unit == "%") { | |
return this.percentToPixels(el, value) | |
} else { | |
if (unit == "ex") { | |
return this.exToPixels(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; 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 | |
} | |
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 rate = 200 / 225; | |
var value = computeDirtyFontSize(el); | |
return value * rate | |
}, | |
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 | |
} | |
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 | |
} | |
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 | |
} | |
} | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
var WindowDefaultOptions = { | |
type: "frame", | |
id: "FirebugUI" | |
}, | |
commandLine, | |
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, | |
topHeight, | |
topPartialHeight, | |
chromeRedrawSkipRate = isIE ? 75 : isOpera ? 80 : 75, | |
lastSelectedPanelName, | |
focusCommandLineState = 0, | |
lastFocusedPanelName, | |
lastHSplitterMouseMove = 0, | |
onHSplitterMouseMoveBuffer = null, | |
onHSplitterMouseMoveTimer = null, | |
lastVSplitterMouseMove = 0; | |
FBL.defaultPersistedState = { | |
isOpen: false, | |
height: 300, | |
sidePanelWidth: 350, | |
selectedPanelName: "Console", | |
selectedHTMLElementId: null, | |
htmlSelectionStack: [] | |
}; | |
FBL.FirebugChrome = { | |
chromeMap: {}, | |
htmlSelectionStack: [], | |
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") { | |
var frame = FirebugChrome.chromeMap.frame; | |
if (frame) { | |
frame.close() | |
} | |
chrome.initialize() | |
} | |
}, | |
clone: function(FBChrome) { | |
for (var name in FBChrome) { | |
var prop = FBChrome[name]; | |
if (FBChrome.hasOwnProperty(name) && !isFunction(prop)) { | |
this[name] = prop | |
} | |
} | |
} | |
}; | |
var createChromeWindow = function(options) { | |
options = extend(WindowDefaultOptions, options || {}); | |
var browserWin = Env.browser.window; | |
var browserContext = new Context(browserWin); | |
var prefs = Store.get("FirebugLite"); | |
var persistedState = prefs && prefs.persistedState || defaultPersistedState; | |
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", | |
body = context.document.getElementsByTagName("body")[0], | |
formatNode = function(node) { | |
if (!Env.isDebugMode) { | |
node.firebugIgnore = true | |
} | |
var browserWinSize = browserContext.getWindowSize(); | |
var height = persistedState.height || 300; | |
height = Math.min(browserWinSize.height, height); | |
height = Math.max(200, height); | |
node.style.border = "0"; | |
node.style.visibility = "hidden"; | |
node.style.zIndex = "2147483647"; | |
node.style.position = noFixedPosition ? "absolute": "fixed"; | |
node.style.width = "100%"; | |
node.style.left = "0"; | |
node.style.bottom = noFixedPosition ? "-1px": "0"; | |
node.style.height = height + "px" | |
}, | |
createChromeDiv = function() { | |
var node = chrome.node = createGlobalElement("div"), | |
style = createGlobalElement("style"), | |
css = FirebugChrome.Skin.CSS, | |
rules = ".fbBody *{margin:0;padding:0;font-size:11px;line-height:13px;color:inherit;}" + css + ".fbBody #fbHSplitter{position:absolute !important;} .fbBody #fbHTML span{line-height:14px;} .fbBody .lineNo div{line-height:inherit !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) { | |
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 { | |
if (type == "div") { | |
createChromeDiv(); | |
return | |
} else { | |
if (isChromeFrame) { | |
var node = chrome.node = createGlobalElement("iframe"); | |
node.setAttribute("src", url); | |
node.setAttribute("frameBorder", "0"); | |
formatNode(node); | |
body.appendChild(node); | |
node.id = options.id | |
} else { | |
var height = persistedState.popupHeight || 300; | |
var browserWinSize = browserContext.getWindowSize(); | |
var browserWinLeft = typeof browserWin.screenX == "number" ? browserWin.screenX: browserWin.screenLeft; | |
var popupLeft = typeof persistedState.popupLeft == "number" ? persistedState.popupLeft: browserWinLeft; | |
var browserWinTop = typeof browserWin.screenY == "number" ? browserWin.screenY: browserWin.screenTop; | |
var popupTop = typeof persistedState.popupTop == "number" ? persistedState.popupTop: Math.max(0, Math.min(browserWinTop + browserWinSize.height - height, screen.availHeight - height - 61)); | |
var popupWidth = typeof persistedState.popupWidth == "number" ? persistedState.popupWidth: Math.max(0, Math.min(browserWinSize.width, screen.availWidth - 10)); | |
var popupHeight = typeof persistedState.popupHeight == "number" ? persistedState.popupHeight: 300; | |
var options = ["true,top=", popupTop, ",left=", popupLeft, ",height=", popupHeight, ",width=", popupWidth, ",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 | |
} | |
} | |
} | |
if (!useLocalSkin) { | |
var tpl = getChromeTemplate(!isChromeFrame), | |
doc = isChromeFrame ? node.contentWindow.document: node.document; | |
doc.write(tpl); | |
doc.close() | |
} | |
var win, waitDelay = useLocalSkin ? isChromeFrame ? 200 : 300 : 100, | |
waitForWindow = function() { | |
if (isChromeFrame && (win = node.contentWindow) && node.contentWindow.document.getElementById("fbCommandLine") || !isChromeFrame && (win = node.window) && node.document && node.document.getElementById("fbCommandLine")) { | |
chrome.window = win.window; | |
chrome.document = win.document; | |
setTimeout(function() { | |
onChromeLoad(chrome) | |
}, | |
useLocalSkin ? 200 : 0) | |
} else { | |
setTimeout(waitForWindow, waitDelay) | |
} | |
}; | |
waitForWindow() | |
} catch(e) { | |
var msg = e.message || e; | |
if (/access/i.test(msg)) { | |
if (isChromeFrame) { | |
body.removeChild(node) | |
} else { | |
if (type == "popup") { | |
node.close() | |
} | |
} | |
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) { | |
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") { | |
setTimeout(function() { | |
FBL.Firebug.initialize() | |
}, | |
0) | |
} else { | |
if (chrome.type == "popup") { | |
var oldChrome = FirebugChrome.chromeMap.frame; | |
var newChrome = new Chrome(chrome); | |
dispatch(newChrome.panelMap, "detach", [oldChrome, newChrome]); | |
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] = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/DTD/strict.dtd">'; | |
r[++i] = "<html><head><title>"; | |
r[++i] = Firebug.version; | |
r[++i] = "</title><style>html,body{margin:0;padding:0;overflow:hidden;}"; | |
r[++i] = tpl.CSS; | |
r[++i] = "</style>"; | |
r[++i] = '</head><body class="fbBody' + (isPopup ? " FirebugPopup": "") + '">'; | |
r[++i] = tpl.HTML; | |
r[++i] = "</body></html>"; | |
return r.join("") | |
}; | |
var Chrome = function Chrome(chrome) { | |
var type = chrome.type; | |
var Base = type == "frame" || type == "div" ? ChromeFrameBase: ChromePopupBase; | |
append(this, Base); | |
append(this, chrome); | |
append(this, new Context(chrome.window)); | |
FirebugChrome.chromeMap[type] = this; | |
Firebug.chrome = this; | |
Env.chrome = chrome.window; | |
this.commandLineVisible = false; | |
this.sidePanelVisible = false; | |
this.create(); | |
return this | |
}; | |
var ChromeBase = {}; | |
append(ChromeBase, Controller); | |
append(ChromeBase, PanelBar); | |
append(ChromeBase, { | |
node: null, | |
type: null, | |
document: null, | |
window: null, | |
sidePanelVisible: false, | |
commandLineVisible: false, | |
largeCommandLineVisible: false, | |
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) | |
} | |
}); | |
var firebugOptionsMenu = { | |
id: "fbFirebugOptionsMenu", | |
getItems: function() { | |
var cookiesDisabled = !Firebug.saveCookies; | |
return [{ | |
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: "Disable Resource Fetching", | |
type: "checkbox", | |
value: "disableResourceFetching", | |
checked: Firebug.disableResourceFetching, | |
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) | |
}, | |
restorePrefs: function(target) { | |
Firebug.erasePrefs(); | |
if (target) { | |
this.updateMenu(target) | |
} | |
}, | |
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) { | |
cancelEvent(event, true); | |
var target = event.target || event.srcElement; | |
if (menu.isVisible) { | |
menu.hide() | |
} else { | |
var offsetLeft = isIE6 ? 1 : -4, | |
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() | |
}, | |
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") | |
} | |
Controller.initialize.call(this); | |
PanelBar.initialize.call(this); | |
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"); | |
topHeight = fbTop.offsetHeight; | |
topPartialHeight = fbToolbar.offsetHeight; | |
disableTextSelection($("fbToolbar")); | |
disableTextSelection($("fbPanelBarBox")); | |
disableTextSelection($("fbPanelBar1")); | |
disableTextSelection($("fbPanelBar2")); | |
if (isIE6 && Firebug.Selector) { | |
var as = $$(".fbHover"); | |
for (var i = 0, | |
a; a = as[i]; i++) { | |
a.setAttribute("href", "javascript:void(0)") | |
} | |
} | |
if (Firebug.Inspector) { | |
this.inspectButton.initialize() | |
} | |
this.addController([$("fbLargeCommandLineIcon"), "click", this.showLargeCommandLine]); | |
var self = this; | |
setTimeout(function() { | |
self.selectPanel(Firebug.context.persistedState.selectedPanelName); | |
if (Firebug.context.persistedState.selectedPanelName == "Console" && Firebug.CommandLine) { | |
Firebug.chrome.focusCommandLine() | |
} | |
}, | |
0); | |
var onPanelMouseDown = function onPanelMouseDown(event) { | |
var target = event.target || event.srcElement; | |
if (FBL.isLeftClick(event)) { | |
var editable = FBL.getAncestorByClass(target, "editable"); | |
if (editable) { | |
Firebug.Editor.startEditing(editable); | |
FBL.cancelEvent(event) | |
} else { | |
if (!hasClass(target, "textEditorInner")) { | |
Firebug.Editor.stopEditing() | |
} | |
} | |
} else { | |
if (FBL.isMiddleClick(event) && Firebug.getRepNode(target)) { | |
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 | |
}; | |
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); | |
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 | |
}; | |
Firebug.chrome.keyIgnore = function(keyCode) { | |
onKeyCodeListenersMap[keyCode] = null; | |
delete onKeyCodeListenersMap[keyCode] | |
}; | |
this.addController([fbPanel1, "mousedown", onPanelMouseDown], [fbPanel2, "mousedown", onPanelMouseDown]); | |
if (FBL.domplate) { | |
this.testMenu() | |
} | |
}, | |
shutdown: function() { | |
if (Firebug.Inspector) { | |
this.inspectButton.shutdown() | |
} | |
restoreTextSelection($("fbToolbar")); | |
restoreTextSelection($("fbPanelBarBox")); | |
restoreTextSelection($("fbPanelBar1")); | |
restoreTextSelection($("fbPanelBar2")); | |
Controller.shutdown.call(this); | |
PanelBar.shutdown.call(this); | |
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; | |
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 (Firebug.chrome.type == "popup") { | |
return | |
} | |
var shouldOpen = forceOpen || !Firebug.context.persistedState.isOpen; | |
if (shouldOpen) { | |
this.open() | |
} else { | |
this.close() | |
} | |
} | |
}, | |
detach: function() { | |
if (!FirebugChrome.chromeMap.popup) { | |
this.close(); | |
createChromeWindow({ | |
type: "popup" | |
}) | |
} | |
}, | |
reattach: function(oldChrome, newChrome) { | |
Firebug.browser.window.Firebug = Firebug; | |
var newPanelMap = newChrome.panelMap; | |
var oldPanelMap = oldChrome.panelMap; | |
var panel; | |
for (var name in newPanelMap) { | |
panel = newPanelMap[name]; | |
if (panel.options.innerHTMLSync) { | |
panel.panelNode.innerHTML = oldPanelMap[name].panelNode.innerHTML | |
} | |
} | |
Firebug.chrome = newChrome; | |
if (newChrome.type == "popup") { | |
newChrome.initialize() | |
} else { | |
Firebug.context.persistedState.selectedPanelName = oldChrome.selectedPanel.name | |
} | |
dispatch(newPanelMap, "reattach", [oldChrome, newChrome]) | |
}, | |
draw: function() { | |
var size = this.getSize(); | |
var commandLineHeight = Firebug.chrome.commandLineVisible ? fbCommandLine.offsetHeight: 0, | |
y = Math.max(size.height, topHeight), | |
heightValue = Math.max(y - topHeight - commandLineHeight, 0), | |
height = heightValue + "px", | |
sideWidthValue = Firebug.chrome.sidePanelVisible ? Firebug.context.persistedState.sidePanelWidth: 0, | |
width = Math.max(size.width - sideWidthValue, 0) + "px"; | |
fbPanelBox1Style.height = height; | |
fbPanel1Style.height = height; | |
if (isIE || isOpera) { | |
fbVSplitterStyle.height = Math.max(y - topPartialHeight - commandLineHeight, 0) + "px" | |
} | |
fbPanelBox1Style.width = width; | |
fbPanel1Style.width = width; | |
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; | |
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) {} | |
focusCommandLineState = ++focusCommandLineState % 2 | |
} | |
}); | |
var ChromeFrameBase = extend(ChromeBase, { | |
create: function() { | |
ChromeBase.create.call(this); | |
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() { | |
var size = Firebug.chrome.getWindowSize(); | |
Firebug.context.persistedState.height = size.height; | |
if (Firebug.saveCookies) { | |
Firebug.savePrefs() | |
} | |
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() { | |
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 (!Firebug.context.persistedState.isOpen) { | |
Firebug.context.persistedState.isOpen = true; | |
if (Env.isChromeExtension) { | |
localStorage.setItem("Firebug", "1,1") | |
} | |
var node = this.node; | |
node.style.visibility = "hidden"; | |
if (Firebug.showIconWhenHidden) { | |
if (ChromeMini.isInitialized) { | |
ChromeMini.shutdown() | |
} | |
} else { | |
node.style.display = "block" | |
} | |
var main = $("fbChrome"); | |
main.style.display = ""; | |
var self = this; | |
node.style.visibility = "visible"; | |
setTimeout(function() { | |
self.initialize(); | |
if (noFixedPosition) { | |
self.fixIEPosition() | |
} | |
self.draw() | |
}, | |
10) | |
} | |
}, | |
close: function() { | |
if (Firebug.context.persistedState.isOpen) { | |
if (this.isInitialized) { | |
this.shutdown() | |
} | |
Firebug.context.persistedState.isOpen = false; | |
if (Env.isChromeExtension) { | |
localStorage.setItem("Firebug", "1,0") | |
} | |
var node = this.node; | |
if (Firebug.showIconWhenHidden) { | |
node.style.visibility = "hidden"; | |
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 (Env.isChromeExtension) { | |
localStorage.removeItem("Firebug"); | |
Firebug.GoogleChrome.dispatch("FB_deactivate"); | |
Firebug.chrome.close() | |
} else { | |
Firebug.shutdown() | |
} | |
}, | |
fixIEPosition: function() { | |
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 = Firebug.context.persistedState.sidePanelWidth + "px" | |
} | |
this.draw() | |
} | |
}); | |
var ChromeMini = extend(Controller, { | |
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 = Firebug.context.persistedState.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 | |
}); | |
var ChromePopupBase = extend(ChromeBase, { | |
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() { | |
var chromeWin = Firebug.chrome.window; | |
var left = chromeWin.screenX || chromeWin.screenLeft; | |
var top = chromeWin.screenY || chromeWin.screenTop; | |
var size = Firebug.chrome.getWindowSize(); | |
Firebug.context.persistedState.popupTop = top; | |
Firebug.context.persistedState.popupLeft = left; | |
Firebug.context.persistedState.popupWidth = size.width; | |
Firebug.context.persistedState.popupHeight = size.height; | |
if (Firebug.saveCookies) { | |
Firebug.savePrefs() | |
} | |
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)) { | |
try { | |
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); | |
Firebug.loadPrefs(); | |
registerConsole(); | |
var persistDelay = new Date().getTime() - persistTimeStart; | |
var chrome = Firebug.chrome; | |
addEvent(Firebug.browser.window, "unload", chrome.persist); | |
FBL.cacheDocument(); | |
Firebug.Inspector.create(); | |
Firebug.Console.logFormatted(["Firebug could not capture console calls during " + persistDelay + "ms"], Firebug.context, "info"); | |
setTimeout(function() { | |
var htmlPanel = chrome.getPanel("HTML"); | |
htmlPanel.createUI() | |
}, | |
50) | |
} catch(pE) { | |
alert("persist error: " + (pE.message || pE)) | |
} | |
} else { | |
window.setTimeout(waitMainWindow, 0) | |
} | |
} catch(E) { | |
window.close() | |
} | |
}; | |
waitMainWindow() | |
}, | |
close: function() { | |
this.destroy() | |
} | |
}); | |
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" | |
} | |
}; | |
var onGlobalKeyDown = function onGlobalKeyDown(event) { | |
var keyCode = event.keyCode; | |
var shiftKey = event.shiftKey; | |
var ctrlKey = event.ctrlKey; | |
if (keyCode == 123 && (!isFirefox && !shiftKey || shiftKey && isFirefox)) { | |
Firebug.chrome.toggle(false, ctrlKey); | |
cancelEvent(event, true); | |
if (Env.isChromeExtension) { | |
Firebug.GoogleChrome.dispatch("FB_enableIcon") | |
} | |
} else { | |
if (keyCode == 67 && ctrlKey && shiftKey) { | |
Firebug.Inspector.toggleInspect(); | |
cancelEvent(event, true) | |
} else { | |
if (keyCode == 76 && ctrlKey && shiftKey) { | |
Firebug.chrome.focusCommandLine(); | |
cancelEvent(event, true) | |
} | |
} | |
} | |
}; | |
var onMiniIconClick = function onMiniIconClick(event) { | |
Firebug.chrome.toggle(false, event.ctrlKey); | |
cancelEvent(event, true) | |
}; | |
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.defaultView || 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 | |
} | |
onHSplitterMouseMoveBuffer = clientY; | |
if (new Date().getTime() - lastHSplitterMouseMove > chromeRedrawSkipRate) { | |
lastHSplitterMouseMove = new Date().getTime(); | |
handleHSplitterMouseMove() | |
} else { | |
if (!onHSplitterMouseMoveTimer) { | |
onHSplitterMouseMoveTimer = setTimeout(handleHSplitterMouseMove, chromeRedrawSkipRate) | |
} | |
} | |
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(); | |
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 = windowSize.height; | |
var chromeHeight = Math.max(height - clientY + 5 - scrollbarSize, fixedHeight); | |
chromeHeight = Math.min(chromeHeight, windowSize.height - scrollbarSize); | |
Firebug.context.persistedState.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(); | |
return false | |
}; | |
var onVSplitterMouseDown = function onVSplitterMouseDown(event) { | |
addGlobalEvent("mousemove", onVSplitterMouseMove); | |
addGlobalEvent("mouseup", onVSplitterMouseUp); | |
return false | |
}; | |
var onVSplitterMouseMove = function onVSplitterMouseMove(event) { | |
if (new Date().getTime() - lastVSplitterMouseMove > chromeRedrawSkipRate) { | |
var target = event.target || event.srcElement; | |
if (target && target.ownerDocument) { | |
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); | |
Firebug.context.persistedState.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() | |
} | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
Firebug.Lite = {} | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
Firebug.Lite.Cache = { | |
ID: "firebug-" + new Date().getTime() | |
}; | |
var cacheUID = 0; | |
var createCache = function() { | |
var map = {}; | |
var data = {}; | |
var CID = Firebug.Lite.Cache.ID; | |
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) { | |
if (value) { | |
if (!name) { | |
return null | |
} | |
var id = cacheAPI.set(element); | |
return data[id][name] = value | |
} 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 (!supportsDeleteExpando && id && map.hasOwnProperty(id) && map[id] != element) { | |
element.removeAttribute(CID); | |
id = null | |
} | |
return id | |
}; | |
FBL.append(cacheFunction, cacheAPI); | |
return cacheFunction | |
}; | |
Firebug.Lite.Cache.StyleSheet = createCache(); | |
Firebug.Lite.Cache.Element = createCache(); | |
Firebug.Lite.Cache.Event = createCache() | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
var sourceMap = {}; | |
Firebug.Lite.Proxy = { | |
_callbacks: {}, | |
load: function(url) { | |
var resourceDomain = getDomain(url); | |
var isLocalResource = !resourceDomain || resourceDomain == Firebug.context.window.location.host; | |
return isLocalResource ? fetchResource(url) : fetchProxyResource(url) | |
}, | |
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) | |
} | |
}, | |
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]; | |
var match = /<body>\s+<p>([\s\S]+)<\/p>\s+<\/body>$/.exec(source); | |
if (match) { | |
source = match[1] | |
} | |
console.log(source) | |
}) | |
} | |
}; | |
Firebug.Lite.Proxy.fetchResourceDisabledMessage = '/* Firebug Lite resource fetching is disabled.\nTo enabled it set the Firebug Lite option "disableResourceFetching" to "false".\nMore info at http://getfirebug.com/firebuglite#Options */'; | |
var fetchResource = function(url) { | |
if (Firebug.disableResourceFetching) { | |
var source = sourceMap[url] = Firebug.Lite.Proxy.fetchResourceDisabledMessage; | |
return source | |
} | |
if (sourceMap.hasOwnProperty(url)) { | |
return sourceMap[url] | |
} | |
var xhr = FBL.getNativeXHRObject(); | |
xhr.open("get", url, false); | |
xhr.send(); | |
var source = sourceMap[url] = xhr.responseText; | |
return source | |
}; | |
var fetchProxyResource = function(url) { | |
if (sourceMap.hasOwnProperty(url)) { | |
return sourceMap[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." | |
} | |
var source = data ? data.contents: ""; | |
return source | |
} | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
Firebug.Lite.Style = {} | |
} | |
}); | |
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" | |
} | |
} | |
} | |
}); | |
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" | |
} | |
} | |
} | |
}); | |
var JSON = window.JSON || {}; (function() { | |
function f(n) { | |
return n < 10 ? "0" + n: n | |
} | |
if (typeof Date.prototype.toJSON !== "function") { | |
Date.prototype.toJSON = function(key) { | |
return isFinite(this.valueOf()) ? this.getUTCFullYear() + "-" + f(this.getUTCMonth() + 1) + "-" + f(this.getUTCDate()) + "T" + f(this.getUTCHours()) + ":" + f(this.getUTCMinutes()) + ":" + f(this.getUTCSeconds()) + "Z": null | |
}; | |
String.prototype.toJSON = Number.prototype.toJSON = Boolean.prototype.toJSON = function(key) { | |
return this.valueOf() | |
} | |
} | |
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, | |
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, | |
gap, indent, meta = { | |
"\b": "\\b", | |
"\t": "\\t", | |
"\n": "\\n", | |
"\f": "\\f", | |
"\r": "\\r", | |
'"': '\\"', | |
"\\": "\\\\" | |
}, | |
rep; | |
function quote(string) { | |
escapable.lastIndex = 0; | |
return escapable.test(string) ? '"' + string.replace(escapable, | |
function(a) { | |
var c = meta[a]; | |
return typeof c === "string" ? c: "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice( - 4) | |
}) + '"': '"' + string + '"' | |
} | |
function str(key, holder) { | |
var i, k, v, length, mind = gap, | |
partial, value = holder[key]; | |
if (value && typeof value === "object" && typeof value.toJSON === "function") { | |
value = value.toJSON(key) | |
} | |
if (typeof rep === "function") { | |
value = rep.call(holder, key, value) | |
} | |
switch (typeof value) { | |
case "string": | |
return quote(value); | |
case "number": | |
return isFinite(value) ? String(value) : "null"; | |
case "boolean": | |
case "null": | |
return String(value); | |
case "object": | |
if (!value) { | |
return "null" | |
} | |
gap += indent; | |
partial = []; | |
if (Object.prototype.toString.apply(value) === "[object Array]") { | |
length = value.length; | |
for (i = 0; i < length; i += 1) { | |
partial[i] = str(i, value) || "null" | |
} | |
v = partial.length === 0 ? "[]": gap ? "[\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "]": "[" + partial.join(",") + "]"; | |
gap = mind; | |
return v | |
} | |
if (rep && typeof rep === "object") { | |
length = rep.length; | |
for (i = 0; i < length; i += 1) { | |
k = rep[i]; | |
if (typeof k === "string") { | |
v = str(k, value); | |
if (v) { | |
partial.push(quote(k) + (gap ? ": ": ":") + v) | |
} | |
} | |
} | |
} else { | |
for (k in value) { | |
if (Object.hasOwnProperty.call(value, k)) { | |
v = str(k, value); | |
if (v) { | |
partial.push(quote(k) + (gap ? ": ": ":") + v) | |
} | |
} | |
} | |
} | |
v = partial.length === 0 ? "{}": gap ? "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}": "{" + partial.join(",") + "}"; | |
gap = mind; | |
return v | |
} | |
} | |
if (typeof JSON.stringify !== "function") { | |
JSON.stringify = function(value, replacer, space) { | |
var i; | |
gap = ""; | |
indent = ""; | |
if (typeof space === "number") { | |
for (i = 0; i < space; i += 1) { | |
indent += " " | |
} | |
} else { | |
if (typeof space === "string") { | |
indent = space | |
} | |
} | |
rep = replacer; | |
if (replacer && typeof replacer !== "function" && (typeof replacer !== "object" || typeof replacer.length !== "number")) { | |
throw new Error("JSON.stringify") | |
} | |
return str("", { | |
"": value | |
}) | |
} | |
} | |
if (typeof JSON.parse !== "function") { | |
JSON.parse = function(text, reviver) { | |
var j; | |
function walk(holder, key) { | |
var k, v, value = holder[key]; | |
if (value && typeof value === "object") { | |
for (k in value) { | |
if (Object.hasOwnProperty.call(value, k)) { | |
v = walk(value, k); | |
if (v !== undefined) { | |
value[k] = v | |
} else { | |
delete value[k] | |
} | |
} | |
} | |
} | |
return reviver.call(holder, key, value) | |
} | |
text = String(text); | |
cx.lastIndex = 0; | |
if (cx.test(text)) { | |
text = text.replace(cx, | |
function(a) { | |
return "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice( - 4) | |
}) | |
} | |
if (/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]").replace(/(?:^|:|,)(?:\s*\[)+/g, ""))) { | |
j = eval("(" + text + ")"); | |
return typeof reviver === "function" ? walk({ | |
"": j | |
}, | |
"") : j | |
} | |
throw new SyntaxError("JSON.parse") | |
} | |
} | |
FBL.JSON = JSON | |
} ()); (function() { | |
var store = (function() { | |
var api = {}, | |
win = window, | |
doc = win.document, | |
localStorageName = "localStorage", | |
globalStorageName = "globalStorage", | |
namespace = "__firebug__storejs__", | |
storage; | |
api.disabled = false; | |
api.set = function(key, value) {}; | |
api.get = function(key) {}; | |
api.remove = function(key) {}; | |
api.clear = function() {}; | |
api.transact = function(key, transactionFn) { | |
var val = api.get(key); | |
if (typeof val == "undefined") { | |
val = {} | |
} | |
transactionFn(val); | |
api.set(key, val) | |
}; | |
api.serialize = function(value) { | |
return JSON.stringify(value) | |
}; | |
api.deserialize = function(value) { | |
if (typeof value != "string") { | |
return undefined | |
} | |
return JSON.parse(value) | |
}; | |
function isLocalStorageNameSupported() { | |
try { | |
return (localStorageName in win && win[localStorageName]) | |
} catch(err) { | |
return false | |
} | |
} | |
function isGlobalStorageNameSupported() { | |
try { | |
return (globalStorageName in win && win[globalStorageName] && win[globalStorageName][win.location.hostname]) | |
} catch(err) { | |
return false | |
} | |
} | |
if (isLocalStorageNameSupported()) { | |
storage = win[localStorageName]; | |
api.set = function(key, val) { | |
storage.setItem(key, api.serialize(val)) | |
}; | |
api.get = function(key) { | |
return api.deserialize(storage.getItem(key)) | |
}; | |
api.remove = function(key) { | |
storage.removeItem(key) | |
}; | |
api.clear = function() { | |
storage.clear() | |
} | |
} else { | |
if (isGlobalStorageNameSupported()) { | |
storage = win[globalStorageName][win.location.hostname]; | |
api.set = function(key, val) { | |
storage[key] = api.serialize(val) | |
}; | |
api.get = function(key) { | |
return api.deserialize(storage[key] && storage[key].value) | |
}; | |
api.remove = function(key) { | |
delete storage[key] | |
}; | |
api.clear = function() { | |
for (var key in storage) { | |
delete storage[key] | |
} | |
} | |
} else { | |
if (doc.documentElement.addBehavior) { | |
var storage = doc.createElement("div"); | |
function withIEStorage(storeFunction) { | |
return function() { | |
var args = Array.prototype.slice.call(arguments, 0); | |
args.unshift(storage); | |
doc.documentElement.appendChild(storage); | |
storage.addBehavior("#default#userData"); | |
storage.load(localStorageName); | |
var result = storeFunction.apply(api, args); | |
doc.documentElement.removeChild(storage); | |
return result | |
} | |
} | |
api.set = withIEStorage(function(storage, key, val) { | |
storage.setAttribute(key, api.serialize(val)); | |
storage.save(localStorageName) | |
}); | |
api.get = withIEStorage(function(storage, key) { | |
return api.deserialize(storage.getAttribute(key)) | |
}); | |
api.remove = withIEStorage(function(storage, key) { | |
storage.removeAttribute(key); | |
storage.save(localStorageName) | |
}); | |
api.clear = withIEStorage(function(storage) { | |
var attributes = storage.XMLDocument.documentElement.attributes; | |
storage.load(localStorageName); | |
for (var i = 0, | |
attr; attr = attributes[i]; i++) { | |
storage.removeAttribute(attr.name) | |
} | |
storage.save(localStorageName) | |
}) | |
} | |
} | |
} | |
try { | |
api.set(namespace, namespace); | |
if (api.get(namespace) != namespace) { | |
api.disabled = true | |
} | |
api.remove(namespace) | |
} catch(e) { | |
api.disabled = true | |
} | |
return api | |
})(); | |
if (typeof module != "undefined") { | |
module.exports = store | |
} | |
FBL.Store = store | |
})(); | |
FBL.ns(function() { | |
with(FBL) { | |
var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, | |
done = 0, | |
toString = Object.prototype.toString, | |
hasDuplicate = false, | |
baseHasDuplicate = true; [0, 0].sort(function() { | |
baseHasDuplicate = false; | |
return 0 | |
}); | |
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; | |
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 { | |
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 | |
} | |
} | |
} | |
if (expr == old) { | |
if (anyFound == null) { | |
throw "Syntax error, unrecognized expression: " + expr | |
} else { | |
break | |
} | |
} | |
old = expr | |
} | |
return curLoop | |
}; | |
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") { | |
var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" || !/\D/.test(match[2]) && "0n+" + match[2] || match[2]); | |
match[2] = (test[1] + (test[2] || 1)) - 0; | |
match[3] = test[3] - 0 | |
} | |
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 ((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) { | |
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 | |
}; | |
try { | |
Array.prototype.slice.call(document.documentElement.childNodes, 0) | |
} 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 | |
} | |
} | |
} | |
} (function() { | |
var form = document.createElement("div"), | |
id = "script" + (new Date).getTime(); | |
form.innerHTML = "<a name='" + id + "'/>"; | |
var root = document.documentElement; | |
root.insertBefore(form, root.firstChild); | |
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 | |
})(); (function() { | |
var div = document.createElement("div"); | |
div.appendChild(document.createComment("")); | |
if (div.getElementsByTagName("*").length > 0) { | |
Expr.find.TAG = function(match, context) { | |
var results = context.getElementsByTagName(match[1]); | |
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 | |
} | |
} | |
div.innerHTML = "<a href='#'></a>"; | |
if (div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && div.firstChild.getAttribute("href") !== "#") { | |
Expr.attrHandle.href = function(elem) { | |
return elem.getAttribute("href", 2) | |
} | |
} | |
div = null | |
})(); | |
if (document.querySelectorAll) { (function() { | |
var oldSizzle = Sizzle, | |
div = document.createElement("div"); | |
div.innerHTML = "<p class='TEST'></p>"; | |
if (div.querySelectorAll && div.querySelectorAll(".TEST").length === 0) { | |
return | |
} | |
Sizzle = function(query, context, extra, seed) { | |
context = context || document; | |
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 | |
})() | |
} | |
if (document.getElementsByClassName && document.documentElement.getElementsByClassName) { (function() { | |
var div = document.createElement("div"); | |
div.innerHTML = "<div class='test e'></div><div class='test'></div>"; | |
if (div.getElementsByClassName("e").length === 0) { | |
return | |
} | |
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 | |
})() | |
} | |
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; | |
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) | |
}; | |
Firebug.Selector = Sizzle | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
var ElementCache = Firebug.Lite.Cache.Element; | |
var inspectorTS, inspectorTimer, isInspecting; | |
Firebug.Inspector = { | |
create: function() { | |
offlineFragment = Env.browser.document.createDocumentFragment(); | |
createBoxModelInspector(); | |
createOutlineInspector() | |
}, | |
destroy: function() { | |
destroyBoxModelInspector(); | |
destroyOutlineInspector(); | |
offlineFragment = null | |
}, | |
toggleInspect: function() { | |
if (isInspecting) { | |
this.stopInspecting() | |
} else { | |
Firebug.chrome.inspectButton.changeState("pressed"); | |
this.startInspecting() | |
} | |
}, | |
startInspecting: function() { | |
isInspecting = true; | |
Firebug.chrome.selectPanel("HTML"); | |
createInspectorFrame(); | |
var size = Firebug.browser.getWindowScrollSize(); | |
fbInspectFrame.style.width = size.width + "px"; | |
fbInspectFrame.style.height = size.height + "px"; | |
addEvent(fbInspectFrame, "mousemove", Firebug.Inspector.onInspecting); | |
addEvent(fbInspectFrame, "mousedown", Firebug.Inspector.onInspectingClick) | |
}, | |
stopInspecting: function() { | |
isInspecting = false; | |
if (outlineVisible) { | |
this.hideOutline() | |
} | |
removeEvent(fbInspectFrame, "mousemove", Firebug.Inspector.onInspecting); | |
removeEvent(fbInspectFrame, "mousedown", Firebug.Inspector.onInspectingClick); | |
destroyInspectorFrame(); | |
Firebug.chrome.inspectButton.restore(); | |
if (Firebug.chrome.type == "popup") { | |
Firebug.chrome.node.focus() | |
} | |
}, | |
onInspectingClick: function(e) { | |
fbInspectFrame.style.display = "none"; | |
var targ = Firebug.browser.getElementFromPoint(e.clientX, e.clientY); | |
fbInspectFrame.style.display = "block"; | |
var id = targ.id; | |
if (id && /^fbOutline\w$/.test(id)) { | |
return | |
} | |
if (id == "FirebugUI") { | |
return | |
} | |
while (targ.nodeType != 1) { | |
targ = targ.parentNode | |
} | |
Firebug.Inspector.stopInspecting() | |
}, | |
onInspecting: function(e) { | |
if (new Date().getTime() - lastInspecting > 30) { | |
fbInspectFrame.style.display = "none"; | |
var targ = Firebug.browser.getElementFromPoint(e.clientX, e.clientY); | |
fbInspectFrame.style.display = "block"; | |
var id = targ.id; | |
if (id && /^fbOutline\w$/.test(id)) { | |
return | |
} | |
if (id == "FirebugUI") { | |
return | |
} | |
while (targ.nodeType != 1) { | |
targ = targ.parentNode | |
} | |
if (targ.nodeName.toLowerCase() == "body") { | |
return | |
} | |
Firebug.Inspector.drawOutline(targ); | |
if (ElementCache(targ)) { | |
var target = "" + ElementCache.key(targ); | |
var lazySelect = function() { | |
inspectorTS = new Date().getTime(); | |
if (Firebug.HTML) { | |
Firebug.HTML.selectTreeNode("" + ElementCache.key(targ)) | |
} | |
}; | |
if (inspectorTimer) { | |
clearTimeout(inspectorTimer); | |
inspectorTimer = null | |
} | |
if (new Date().getTime() - inspectorTS > 200) { | |
setTimeout(lazySelect, 0) | |
} else { | |
inspectorTimer = setTimeout(lazySelect, 300) | |
} | |
} | |
lastInspecting = new Date().getTime() | |
} | |
}, | |
onInspectingBody: function(e) { | |
if (new Date().getTime() - lastInspecting > 30) { | |
var targ = e.target; | |
var id = targ.id; | |
if (id && /^fbOutline\w$/.test(id)) { | |
return | |
} | |
if (id == "FirebugUI") { | |
return | |
} | |
while (targ.nodeType != 1) { | |
targ = targ.parentNode | |
} | |
if (targ.nodeName.toLowerCase() == "body") { | |
return | |
} | |
Firebug.Inspector.drawOutline(targ); | |
if (ElementCache.has(targ)) { | |
FBL.Firebug.HTML.selectTreeNode("" + ElementCache.key(targ)) | |
} | |
lastInspecting = new Date().getTime() | |
} | |
}, | |
drawOutline: function(el) { | |
var border = 2; | |
var scrollbarSize = 17; | |
var windowSize = Firebug.browser.getWindowSize(); | |
var scrollSize = Firebug.browser.getWindowScrollSize(); | |
var scrollPosition = Firebug.browser.getWindowScrollPosition(); | |
var box = Firebug.browser.getElementBox(el); | |
var top = box.top; | |
var left = box.left; | |
var height = box.height; | |
var width = box.width; | |
var freeHorizontalSpace = scrollPosition.left + windowSize.width - left - width - (!isIE && scrollSize.height > windowSize.height ? scrollbarSize: 0); | |
var freeVerticalSpace = scrollPosition.top + windowSize.height - top - height - (!isIE && scrollSize.width > windowSize.width ? scrollbarSize: 0); | |
var numVerticalBorders = freeVerticalSpace > 0 ? 2 : 1; | |
var o = outlineElements; | |
var style; | |
style = o.fbOutlineT.style; | |
style.top = top - border + "px"; | |
style.left = left + "px"; | |
style.height = border + "px"; | |
style.width = width + "px"; | |
style = o.fbOutlineL.style; | |
style.top = top - border + "px"; | |
style.left = left - border + "px"; | |
style.height = height + numVerticalBorders * border + "px"; | |
style.width = border + "px"; | |
style = o.fbOutlineB.style; | |
if (freeVerticalSpace > 0) { | |
style.top = top + height + "px"; | |
style.left = left + "px"; | |
style.width = width + "px" | |
} else { | |
style.top = -2 * border + "px"; | |
style.left = -2 * border + "px"; | |
style.width = border + "px" | |
} | |
style = o.fbOutlineR.style; | |
if (freeHorizontalSpace > 0) { | |
style.top = top - border + "px"; | |
style.left = left + width + "px"; | |
style.height = height + numVerticalBorders * border + "px"; | |
style.width = (freeHorizontalSpace < border ? freeHorizontalSpace: border) + "px" | |
} else { | |
style.top = -2 * border + "px"; | |
style.left = -2 * border + "px"; | |
style.height = border + "px"; | |
style.width = border + "px" | |
} | |
if (!outlineVisible) { | |
this.showOutline() | |
} | |
}, | |
hideOutline: function() { | |
if (!outlineVisible) { | |
return | |
} | |
for (var name in outline) { | |
offlineFragment.appendChild(outlineElements[name]) | |
} | |
outlineVisible = false | |
}, | |
showOutline: function() { | |
if (outlineVisible) { | |
return | |
} | |
if (boxModelVisible) { | |
this.hideBoxModel() | |
} | |
for (var name in outline) { | |
Firebug.browser.document.getElementsByTagName("body")[0].appendChild(outlineElements[name]) | |
} | |
outlineVisible = true | |
}, | |
drawBoxModel: function(el) { | |
if (!el || !el.parentNode) { | |
return | |
} | |
var box = Firebug.browser.getElementBox(el); | |
var windowSize = Firebug.browser.getWindowSize(); | |
var scrollPosition = Firebug.browser.getWindowScrollPosition(); | |
var offsetHeight = Firebug.chrome.type == "frame" ? Firebug.context.persistedState.height: 0; | |
if (box.top > scrollPosition.top + windowSize.height - offsetHeight || box.left > scrollPosition.left + windowSize.width || scrollPosition.top > box.top + box.height || scrollPosition.left > box.left + box.width) { | |
return | |
} | |
var top = box.top; | |
var left = box.left; | |
var height = box.height; | |
var width = box.width; | |
var margin = Firebug.browser.getMeasurementBox(el, "margin"); | |
var padding = Firebug.browser.getMeasurementBox(el, "padding"); | |
var border = Firebug.browser.getMeasurementBox(el, "border"); | |
boxModelStyle.top = top - margin.top + "px"; | |
boxModelStyle.left = left - margin.left + "px"; | |
boxModelStyle.height = height + margin.top + margin.bottom + "px"; | |
boxModelStyle.width = width + margin.left + margin.right + "px"; | |
boxBorderStyle.top = margin.top + "px"; | |
boxBorderStyle.left = margin.left + "px"; | |
boxBorderStyle.height = height + "px"; | |
boxBorderStyle.width = width + "px"; | |
boxPaddingStyle.top = margin.top + border.top + "px"; | |
boxPaddingStyle.left = margin.left + border.left + "px"; | |
boxPaddingStyle.height = height - border.top - border.bottom + "px"; | |
boxPaddingStyle.width = width - border.left - border.right + "px"; | |
boxContentStyle.top = margin.top + border.top + padding.top + "px"; | |
boxContentStyle.left = margin.left + border.left + padding.left + "px"; | |
boxContentStyle.height = height - border.top - padding.top - padding.bottom - border.bottom + "px"; | |
boxContentStyle.width = width - border.left - padding.left - padding.right - border.right + "px"; | |
if (!boxModelVisible) { | |
this.showBoxModel() | |
} | |
}, | |
hideBoxModel: function() { | |
if (!boxModelVisible) { | |
return | |
} | |
offlineFragment.appendChild(boxModel); | |
boxModelVisible = false | |
}, | |
showBoxModel: function() { | |
if (boxModelVisible) { | |
return | |
} | |
if (outlineVisible) { | |
this.hideOutline() | |
} | |
Firebug.browser.document.getElementsByTagName("body")[0].appendChild(boxModel); | |
boxModelVisible = true | |
} | |
}; | |
var offlineFragment = null; | |
var boxModelVisible = false; | |
var boxModel, boxModelStyle, boxMargin, boxMarginStyle, boxBorder, boxBorderStyle, boxPadding, boxPaddingStyle, boxContent, boxContentStyle; | |
var resetStyle = "margin:0; padding:0; border:0; position:absolute; overflow:hidden; display:block;"; | |
var offscreenStyle = resetStyle + "top:-1234px; left:-1234px;"; | |
var inspectStyle = resetStyle + "z-index: 2147483500;"; | |
var inspectFrameStyle = resetStyle + "z-index: 2147483550; top:0; left:0; background:url(" + Env.Location.skinDir + "pixel_transparent.gif);"; | |
var inspectModelOpacity = isIE ? "filter:alpha(opacity=80);": "opacity:0.8;"; | |
var inspectModelStyle = inspectStyle + inspectModelOpacity; | |
var inspectMarginStyle = inspectStyle + "background: #EDFF64; height:100%; width:100%;"; | |
var inspectBorderStyle = inspectStyle + "background: #666;"; | |
var inspectPaddingStyle = inspectStyle + "background: SlateBlue;"; | |
var inspectContentStyle = inspectStyle + "background: SkyBlue;"; | |
var outlineStyle = { | |
fbHorizontalLine: "background: #3875D7;height: 2px;", | |
fbVerticalLine: "background: #3875D7;width: 2px;" | |
}; | |
var lastInspecting = 0; | |
var fbInspectFrame = null; | |
var outlineVisible = false; | |
var outlineElements = {}; | |
var outline = { | |
fbOutlineT: "fbHorizontalLine", | |
fbOutlineL: "fbVerticalLine", | |
fbOutlineB: "fbHorizontalLine", | |
fbOutlineR: "fbVerticalLine" | |
}; | |
var getInspectingTarget = function() {}; | |
var createInspectorFrame = function createInspectorFrame() { | |
fbInspectFrame = createGlobalElement("div"); | |
fbInspectFrame.id = "fbInspectFrame"; | |
fbInspectFrame.firebugIgnore = true; | |
fbInspectFrame.style.cssText = inspectFrameStyle; | |
Firebug.browser.document.getElementsByTagName("body")[0].appendChild(fbInspectFrame) | |
}; | |
var destroyInspectorFrame = function destroyInspectorFrame() { | |
if (fbInspectFrame) { | |
Firebug.browser.document.getElementsByTagName("body")[0].removeChild(fbInspectFrame); | |
fbInspectFrame = null | |
} | |
}; | |
var createOutlineInspector = function createOutlineInspector() { | |
for (var name in outline) { | |
var el = outlineElements[name] = createGlobalElement("div"); | |
el.id = name; | |
el.firebugIgnore = true; | |
el.style.cssText = inspectStyle + outlineStyle[outline[name]]; | |
offlineFragment.appendChild(el) | |
} | |
}; | |
var destroyOutlineInspector = function destroyOutlineInspector() { | |
for (var name in outline) { | |
var el = outlineElements[name]; | |
el.parentNode.removeChild(el) | |
} | |
}; | |
var createBoxModelInspector = function createBoxModelInspector() { | |
boxModel = createGlobalElement("div"); | |
boxModel.id = "fbBoxModel"; | |
boxModel.firebugIgnore = true; | |
boxModelStyle = boxModel.style; | |
boxModelStyle.cssText = inspectModelStyle; | |
boxMargin = createGlobalElement("div"); | |
boxMargin.id = "fbBoxMargin"; | |
boxMarginStyle = boxMargin.style; | |
boxMarginStyle.cssText = inspectMarginStyle; | |
boxModel.appendChild(boxMargin); | |
boxBorder = createGlobalElement("div"); | |
boxBorder.id = "fbBoxBorder"; | |
boxBorderStyle = boxBorder.style; | |
boxBorderStyle.cssText = inspectBorderStyle; | |
boxModel.appendChild(boxBorder); | |
boxPadding = createGlobalElement("div"); | |
boxPadding.id = "fbBoxPadding"; | |
boxPaddingStyle = boxPadding.style; | |
boxPaddingStyle.cssText = inspectPaddingStyle; | |
boxModel.appendChild(boxPadding); | |
boxContent = createGlobalElement("div"); | |
boxContent.id = "fbBoxContent"; | |
boxContentStyle = boxContent.style; | |
boxContentStyle.cssText = inspectContentStyle; | |
boxModel.appendChild(boxContent); | |
offlineFragment.appendChild(boxModel) | |
}; | |
var destroyBoxModelInspector = function destroyBoxModelInspector() { | |
boxModel.parentNode.removeChild(boxModel) | |
} | |
} | |
}); (function() { | |
FBL.DomplateTag = function DomplateTag(tagName) { | |
this.tagName = tagName | |
}; | |
FBL.DomplateEmbed = function DomplateEmbed() {}; | |
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() | |
}, | |
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); | |
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]) | |
} | |
return nodeCount | |
} | |
function __path__(parent, offset) { | |
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] | |
} | |
} | |
return parent | |
} | |
var js = fnBlock.join(""); | |
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('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, { | |
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("});") | |
}, | |
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, { | |
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 | |
} | |
}); | |
function Variable(name, format) { | |
this.name = name; | |
this.format = format | |
} | |
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) | |
} | |
} | |
function ArrayIterator(array) { | |
var index = -1; | |
this.next = function() { | |
if (++index >= array.length) { | |
throw StopIteration | |
} | |
return array[index] | |
} | |
} | |
function StopIteration() {} | |
FBL.$break = function() { | |
throw StopIteration | |
}; | |
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 = "<table><tbody>" + html + "</tbody></table>"; | |
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); | |
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); | |
this.tag.renderDOM.apply(self ? self: this.tag.subject, 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 | |
} | |
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 (!womb || womb.ownerDocument != parent.ownerDocument) { | |
womb = parent.ownerDocument.createElement("div") | |
} | |
womb.innerHTML = html; | |
var root = womb.firstChild; | |
while (womb.firstChild) { | |
parent.appendChild(womb.firstChild) | |
} | |
womb = null; | |
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 | |
} | |
}; | |
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") | |
})(); | |
var FirebugReps = FBL.ns(function() { | |
with(FBL) { | |
var OBJECTBOX = this.OBJECTBOX = SPAN({ | |
"class": "objectBox objectBox-$className" | |
}); | |
var OBJECTBLOCK = this.OBJECTBLOCK = DIV({ | |
"class": "objectBox objectBox-$className" | |
}); | |
var OBJECTLINK = this.OBJECTLINK = isIE6 ? A({ | |
"class": "objectLink objectLink-$className a11yFocus", | |
href: "javascript:void(0)", | |
title: "$object|FBL.getElementXPath", | |
_repObject: "$object" | |
}) : A({ | |
"class": "objectLink objectLink-$className a11yFocus", | |
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.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) { | |
var maxLength = 55; | |
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: "...", | |
tag: FirebugReps.Caption.tag, | |
name: "", | |
equal: "", | |
delim: "" | |
}) | |
} else { | |
if (props.length > 0) { | |
props[props.length - 1].delim = "" | |
} | |
} | |
} catch(exc) {} | |
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...", | |
tag: FirebugReps.Caption.tag, | |
name: "", | |
equal: "", | |
delim: "" | |
} | |
} else { | |
if (props.length > 0) { | |
props[props.length - 1].delim = "" | |
} | |
} | |
} catch(exc) {} | |
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")), 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) | |
}, | |
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)) { | |
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); | |
FBTrace.sysout("isArray Fails on obj", obj) | |
} | |
} | |
return false | |
}, | |
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) { | |
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]; | |
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 || elt.style.cssText.replace(/([^\s]+)\s*:/g, | |
function(m, g) { | |
return g.toLowerCase() + ":" | |
}) | |
}) | |
} else { | |
attrs.push(attr) | |
} | |
} | |
} | |
} | |
} | |
} | |
if (classAttr) { | |
attrs.splice(0, 0, classAttr) | |
} | |
if (idAttr) { | |
attrs.splice(0, 0, idAttr) | |
} | |
return attrs | |
}, | |
shortAttrIterator: function(elt) { | |
var attrs = []; | |
if (elt.attributes) { | |
for (var i = 0; i < elt.attributes.length; ++i) { | |
var attr = elt.attributes[i]; | |
if (attr.nodeName == "id" || attr.nodeName == "class") { | |
attrs.push(attr) | |
} | |
} | |
} | |
return attrs | |
}, | |
getHidden: function(elt) { | |
return isVisible(elt) ? "": "nodeHidden" | |
}, | |
getXPath: function(elt) { | |
return getElementTreeXPath(elt) | |
}, | |
getNodeText: function(element) { | |
var text = element.textContent; | |
if (Firebug.showFullTextNodes) { | |
return text | |
} else { | |
return cropString(text, 50) | |
} | |
}, | |
getNodeTextGroups: function(element) { | |
var text = element.textContent; | |
if (!Firebug.showFullTextNodes) { | |
text = cropString(text, 50) | |
} | |
var escapeGroups = []; | |
if (Firebug.showTextNodesWithWhitespace) { | |
escapeGroups.push({ | |
group: "whitespace", | |
"class": "nodeWhiteSpace", | |
extra: { | |
"\t": "_Tab", | |
"\n": "_Para", | |
" ": "_Space" | |
} | |
}) | |
} | |
if (Firebug.showTextNodesWithEntities) { | |
escapeGroups.push({ | |
group: "text", | |
"class": "nodeTextEntity", | |
extra: {} | |
}) | |
} | |
if (escapeGroups.length) { | |
return escapeGroupsForEntities(text, escapeGroups) | |
} else { | |
return [{ | |
str: text, | |
"class": "", | |
extra: "" | |
}] | |
} | |
}, | |
copyHTML: function(elt) { | |
var html = getElementXML(elt); | |
copyToClipboard(html) | |
}, | |
copyInnerHTML: function(elt) { | |
copyToClipboard(elt.innerHTML) | |
}, | |
copyXPath: function(elt) { | |
var xpath = getElementXPath(elt); | |
copyToClipboard(xpath) | |
}, | |
persistor: function(context, xpath) { | |
var elts = xpath ? getElementsByXPath(context.window.document, xpath) : null; | |
return elts && elts.length ? elts[0] : null | |
}, | |
className: "element", | |
supportsObject: function(object) { | |
return instanceOf(object, "Element") | |
}, | |
browseObject: function(elt, context) { | |
var tag = elt.nodeName.toLowerCase(); | |
if (tag == "script") { | |
openNewTab(elt.src) | |
} else { | |
if (tag == "link") { | |
openNewTab(elt.href) | |
} else { | |
if (tag == "a") { | |
openNewTab(elt.href) | |
} else { | |
if (tag == "img") { | |
openNewTab(elt.src) | |
} | |
} | |
} | |
} | |
return true | |
}, | |
persistObject: function(elt, context) { | |
var xpath = getElementXPath(elt); | |
return bind(this.persistor, top, xpath) | |
}, | |
getTitle: function(element, context) { | |
return getElementCSSSelector(element) | |
}, | |
getTooltip: function(elt) { | |
return this.getXPath(elt) | |
}, | |
getContextMenuItems: function(elt, target, context) { | |
var monitored = areEventsMonitored(elt, null, context); | |
return [{ | |
label: "CopyHTML", | |
command: bindFixed(this.copyHTML, this, elt) | |
}, | |
{ | |
label: "CopyInnerHTML", | |
command: bindFixed(this.copyInnerHTML, this, elt) | |
}, | |
{ | |
label: "CopyXPath", | |
command: bindFixed(this.copyXPath, this, elt) | |
}, | |
"-", { | |
label: "ShowEventsInConsole", | |
type: "checkbox", | |
checked: monitored, | |
command: bindFixed(toggleMonitorEvents, FBL, elt, null, monitored, context) | |
}, | |
"-", { | |
label: "ScrollIntoView", | |
command: bindFixed(elt.scrollIntoView, elt) | |
}] | |
} | |
}); | |
this.TextNode = domplate(Firebug.Rep, { | |
tag: OBJECTLINK("<", SPAN({ | |
"class": "nodeTag" | |
}, | |
"TextNode"), " textContent="", SPAN({ | |
"class": "nodeValue" | |
}, | |
"$object.textContent|cropString"), """, ">"), | |
className: "textNode", | |
supportsObject: function(object) { | |
return object instanceof Text | |
} | |
}); | |
this.Document = domplate(Firebug.Rep, { | |
tag: OBJECTLINK("Document ", SPAN({ | |
"class": "objectPropValue" | |
}, | |
"$object|getLocation")), | |
getLocation: function(doc) { | |
return doc.location ? getFileName(doc.location.href) : "" | |
}, | |
className: "object", | |
supportsObject: function(object) { | |
return instanceOf(object, "Document") | |
}, | |
browseObject: function(doc, context) { | |
openNewTab(doc.location.href); | |
return true | |
}, | |
persistObject: function(doc, context) { | |
return this.persistor | |
}, | |
persistor: function(context) { | |
return context.window.document | |
}, | |
getTitle: function(win, context) { | |
return "document" | |
}, | |
getTooltip: function(doc) { | |
return doc.location.href | |
} | |
}); | |
this.StyleSheet = domplate(Firebug.Rep, { | |
tag: OBJECTLINK("StyleSheet ", SPAN({ | |
"class": "objectPropValue" | |
}, | |
"$object|getLocation")), | |
getLocation: function(styleSheet) { | |
return getFileName(styleSheet.href) | |
}, | |
copyURL: function(styleSheet) { | |
copyToClipboard(styleSheet.href) | |
}, | |
openInTab: function(styleSheet) { | |
openNewTab(styleSheet.href) | |
}, | |
className: "object", | |
supportsObject: function(object) { | |
return instanceOf(object, "CSSStyleSheet") | |
}, | |
browseObject: function(styleSheet, context) { | |
openNewTab(styleSheet.href); | |
return true | |
}, | |
persistObject: function(styleSheet, context) { | |
return bind(this.persistor, top, styleSheet.href) | |
}, | |
getTooltip: function(styleSheet) { | |
return styleSheet.href | |
}, | |
getContextMenuItems: function(styleSheet, target, context) { | |
return [{ | |
label: "CopyLocation", | |
command: bindFixed(this.copyURL, this, styleSheet) | |
}, | |
"-", { | |
label: "OpenInTab", | |
command: bindFixed(this.openInTab, this, styleSheet) | |
}] | |
}, | |
persistor: function(context, href) { | |
return getStyleSheetByHref(href, context) | |
} | |
}); | |
this.Window = domplate(Firebug.Rep, { | |
tag: OBJECTLINK("Window ", SPAN({ | |
"class": "objectPropValue" | |
}, | |
"$object|getLocation")), | |
getLocation: function(win) { | |
try { | |
return (win && win.location && !win.closed) ? getFileName(win.location.href) : "" | |
} catch(exc) { | |
if (FBTrace.DBG_ERRORS) { | |
FBTrace.sysout("reps.Window window closed?") | |
} | |
} | |
}, | |
className: "object", | |
supportsObject: function(object) { | |
return instanceOf(object, "Window") | |
}, | |
browseObject: function(win, context) { | |
openNewTab(win.location.href); | |
return true | |
}, | |
persistObject: function(win, context) { | |
return this.persistor | |
}, | |
persistor: function(context) { | |
return context.window | |
}, | |
getTitle: function(win, context) { | |
return "window" | |
}, | |
getTooltip: function(win) { | |
if (win && !win.closed) { | |
return win.location.href | |
} | |
} | |
}); | |
this.Event = domplate(Firebug.Rep, { | |
tag: TAG("$copyEventTag", { | |
object: "$object|copyEvent" | |
}), | |
copyEventTag: OBJECTLINK("$object|summarizeEvent"), | |
summarizeEvent: function(event) { | |
var info = [event.type, " "]; | |
var eventFamily = getEventFamily(event.type); | |
if (eventFamily == "mouse") { | |
info.push("clientX=", event.clientX, ", clientY=", event.clientY) | |
} else { | |
if (eventFamily == "key") { | |
info.push("charCode=", event.charCode, ", keyCode=", event.keyCode) | |
} | |
} | |
return info.join("") | |
}, | |
copyEvent: function(event) { | |
return new EventCopy(event) | |
}, | |
className: "object", | |
supportsObject: function(object) { | |
return instanceOf(object, "Event") || instanceOf(object, "EventCopy") | |
}, | |
getTitle: function(event, context) { | |
return "Event " + event.type | |
} | |
}); | |
this.SourceLink = domplate(Firebug.Rep, { | |
tag: OBJECTLINK({ | |
$collapsed: "$object|hideSourceLink" | |
}, | |
"$object|getSourceLinkTitle"), | |
hideSourceLink: function(sourceLink) { | |
return sourceLink ? sourceLink.href.indexOf("XPCSafeJSObjectWrapper") != -1 : true | |
}, | |
getSourceLinkTitle: function(sourceLink) { | |
if (!sourceLink) { | |
return "" | |
} | |
try { | |
var fileName = getFileName(sourceLink.href); | |
fileName = decodeURIComponent(fileName); | |
fileName = cropString(fileName, 17) | |
} catch(exc) { | |
if (FBTrace.DBG_ERRORS) { | |
FBTrace.sysout("reps.getSourceLinkTitle decodeURIComponent fails for '" + fileName + "': " + exc, exc) | |
} | |
} | |
return typeof sourceLink.line == "number" ? fileName + " (line " + sourceLink.line + ")": fileName | |
}, | |
copyLink: function(sourceLink) { | |
copyToClipboard(sourceLink.href) | |
}, | |
openInTab: function(sourceLink) { | |
openNewTab(sourceLink.href) | |
}, | |
className: "sourceLink", | |
supportsObject: function(object) { | |
return object instanceof SourceLink | |
}, | |
getTooltip: function(sourceLink) { | |
return decodeURI(sourceLink.href) | |
}, | |
inspectObject: function(sourceLink, context) { | |
if (sourceLink.type == "js") { | |
var scriptFile = getSourceFileByHref(sourceLink.href, context); | |
if (scriptFile) { | |
return Firebug.chrome.select(sourceLink) | |
} | |
} else { | |
if (sourceLink.type == "css") { | |
if (sourceLink.object) { | |
Firebug.chrome.select(sourceLink.object); | |
return | |
} | |
var stylesheet = getStyleSheetByHref(sourceLink.href, context); | |
if (stylesheet) { | |
var ownerNode = stylesheet.ownerNode; | |
if (ownerNode) { | |
Firebug.chrome.select(sourceLink, "html"); | |
return | |
} | |
var panel = context.getPanel("stylesheet"); | |
if (panel && panel.getRuleByLine(stylesheet, sourceLink.line)) { | |
return Firebug.chrome.select(sourceLink) | |
} | |
} | |
} | |
} | |
viewSource(sourceLink.href, sourceLink.line) | |
}, | |
browseObject: function(sourceLink, context) { | |
openNewTab(sourceLink.href); | |
return true | |
}, | |
getContextMenuItems: function(sourceLink, target, context) { | |
return [{ | |
label: "CopyLocation", | |
command: bindFixed(this.copyLink, this, sourceLink) | |
}, | |
"-", { | |
label: "OpenInTab", | |
command: bindFixed(this.openInTab, this, sourceLink) | |
}] | |
} | |
}); | |
this.SourceFile = domplate(this.SourceLink, { | |
tag: OBJECTLINK({ | |
$collapsed: "$object|hideSourceLink" | |
}, | |
"$object|getSourceLinkTitle"), | |
persistor: function(context, href) { | |
return getSourceFileByHref(href, context) | |
}, | |
className: "sourceFile", | |
supportsObject: function(object) { | |
return object instanceof SourceFile | |
}, | |
persistObject: function(sourceFile) { | |
return bind(this.persistor, top, sourceFile.href) | |
}, | |
browseObject: function(sourceLink, context) {}, | |
getTooltip: function(sourceFile) { | |
return sourceFile.href | |
} | |
}); | |
this.StackFrame = domplate(Firebug.Rep, { | |
tag: OBJECTBLOCK(A({ | |
"class": "objectLink objectLink-function focusRow a11yFocus", | |
_repObject: "$object.fn" | |
}, | |
"$object|getCallName"), " ( ", FOR("arg", "$object|argIterator", TAG("$arg.tag", { | |
object: "$arg.value" | |
}), SPAN({ | |
"class": "arrayComma" | |
}, | |
"$arg.delim")), " )", SPAN({ | |
"class": "objectLink-sourceLink objectLink" | |
}, | |
"$object|getSourceLinkTitle")), | |
getCallName: function(frame) { | |
return frame.name || "anonymous" | |
}, | |
getSourceLinkTitle: function(frame) { | |
var fileName = cropString(getFileName(frame.href), 20); | |
return fileName + (frame.lineNo ? " (line " + frame.lineNo + ")": ""); | |
var fileName = cropString(getFileName(frame.href), 17); | |
return $STRF("Line", [fileName, frame.lineNo]) | |
}, | |
argIterator: function(frame) { | |
if (!frame.args) { | |
return [] | |
} | |
var items = []; | |
for (var i = 0; i < frame.args.length; ++i) { | |
var arg = frame.args[i]; | |
if (!arg) { | |
break | |
} | |
var rep = Firebug.getRep(arg.value); | |
var tag = rep.shortTag ? rep.shortTag: rep.tag; | |
var delim = (i == frame.args.length - 1 ? "": ", "); | |
items.push({ | |
name: arg.name, | |
value: arg.value, | |
tag: tag, | |
delim: delim | |
}) | |
} | |
return items | |
}, | |
className: "stackFrame", | |
supportsObject: function(object) { | |
return object instanceof StackFrame | |
}, | |
inspectObject: function(stackFrame, context) { | |
var sourceLink = new SourceLink(stackFrame.href, stackFrame.lineNo, "js"); | |
Firebug.chrome.select(sourceLink) | |
}, | |
getTooltip: function(stackFrame, context) { | |
return $STRF("Line", [stackFrame.href, stackFrame.lineNo]) | |
} | |
}); | |
this.StackTrace = domplate(Firebug.Rep, { | |
tag: FOR("frame", "$object.frames focusRow", TAG(this.StackFrame.tag, { | |
object: "$frame" | |
})), | |
className: "stackTrace", | |
supportsObject: function(object) { | |
return object instanceof StackTrace | |
} | |
}); | |
this.jsdStackFrame = domplate(Firebug.Rep, { | |
inspectable: false, | |
supportsObject: function(object) { | |
return (object instanceof jsdIStackFrame) && (object.isValid) | |
}, | |
getTitle: function(frame, context) { | |
if (!frame.isValid) { | |
return "(invalid frame)" | |
} | |
return getFunctionName(frame.script, context) | |
}, | |
getTooltip: function(frame, context) { | |
if (!frame.isValid) { | |
return "(invalid frame)" | |
} | |
var sourceInfo = FBL.getSourceFileAndLineByScript(context, frame.script, frame); | |
if (sourceInfo) { | |
return $STRF("Line", [sourceInfo.sourceFile.href, sourceInfo.lineNo]) | |
} else { | |
return $STRF("Line", [frame.script.fileName, frame.line]) | |
} | |
}, | |
getContextMenuItems: function(frame, target, context) { | |
var fn = frame.script.functionObject.getWrappedValue(); | |
return FirebugReps.Func.getContextMenuItems(fn, target, context, frame.script) | |
} | |
}); | |
this.ErrorMessage = domplate(Firebug.Rep, { | |
tag: OBJECTBOX({ | |
$hasTwisty: "$object|hasStackTrace", | |
$hasBreakSwitch: "$object|hasBreakSwitch", | |
$breakForError: "$object|hasErrorBreak", | |
_repObject: "$object", | |
_stackTrace: "$object|getLastErrorStackTrace", | |
onclick: "$onToggleError" | |
}, | |
DIV({ | |
"class": "errorTitle a11yFocus", | |
role: "checkbox", | |
"aria-checked": "false" | |
}, | |
"$object.message|getMessage"), DIV({ | |
"class": "errorTrace" | |
}), DIV({ | |
"class": "errorSourceBox errorSource-$object|getSourceType" | |
}, | |
IMG({ | |
"class": "errorBreak a11yFocus", | |
src: "blank.gif", | |
role: "checkbox", | |
"aria-checked": "false", | |
title: "Break on this error" | |
}), A({ | |
"class": "errorSource a11yFocus" | |
}, | |
"$object|getLine")), TAG(this.SourceLink.tag, { | |
object: "$object|getSourceLink" | |
})), | |
getLastErrorStackTrace: function(error) { | |
return error.trace | |
}, | |
hasStackTrace: function(error) { | |
var url = error.href.toString(); | |
var fromCommandLine = (url.indexOf("XPCSafeJSObjectWrapper") != -1); | |
return ! fromCommandLine && error.trace | |
}, | |
hasBreakSwitch: function(error) { | |
return error.href && error.lineNo > 0 | |
}, | |
hasErrorBreak: function(error) { | |
return fbs.hasErrorBreakpoint(error.href, error.lineNo) | |
}, | |
getMessage: function(message) { | |
var re = /\[Exception... "(.*?)" nsresult:/; | |
var m = re.exec(message); | |
return m ? m[1] : message | |
}, | |
getLine: function(error) { | |
if (error.category == "js") { | |
if (error.source) { | |
return cropString(error.source, 80) | |
} else { | |
if (error.href && error.href.indexOf("XPCSafeJSObjectWrapper") == -1) { | |
return cropString(error.getSourceLine(), 80) | |
} | |
} | |
} | |
}, | |
getSourceLink: function(error) { | |
var ext = error.category == "css" ? "css": "js"; | |
return error.lineNo ? new SourceLink(error.href, error.lineNo, ext) : null | |
}, | |
getSourceType: function(error) { | |
if (error.source) { | |
return "syntax" | |
} else { | |
if (error.lineNo == 1 && getFileExtension(error.href) != "js") { | |
return "none" | |
} else { | |
if (error.category == "css") { | |
return "none" | |
} else { | |
if (!error.href || !error.lineNo) { | |
return "none" | |
} else { | |
return "exec" | |
} | |
} | |
} | |
} | |
}, | |
onToggleError: function(event) { | |
var target = event.currentTarget; | |
if (hasClass(event.target, "errorBreak")) { | |
this.breakOnThisError(target.repObject) | |
} else { | |
if (hasClass(event.target, "errorSource")) { | |
var panel = Firebug.getElementPanel(event.target); | |
this.inspectObject(target.repObject, panel.context) | |
} else { | |
if (hasClass(event.target, "errorTitle")) { | |
var traceBox = target.childNodes[1]; | |
toggleClass(target, "opened"); | |
event.target.setAttribute("aria-checked", hasClass(target, "opened")); | |
if (hasClass(target, "opened")) { | |
if (target.stackTrace) { | |
var node = FirebugReps.StackTrace.tag.append({ | |
object: target.stackTrace | |
}, | |
traceBox) | |
} | |
if (Firebug.A11yModel.enabled) { | |
var panel = Firebug.getElementPanel(event.target); | |
dispatch([Firebug.A11yModel], "onLogRowContentCreated", [panel, traceBox]) | |
} | |
} else { | |
clearNode(traceBox) | |
} | |
} | |
} | |
} | |
}, | |
copyError: function(error) { | |
var message = [this.getMessage(error.message), error.href, "Line " + error.lineNo]; | |
copyToClipboard(message.join("\n")) | |
}, | |
breakOnThisError: function(error) { | |
if (this.hasErrorBreak(error)) { | |
Firebug.Debugger.clearErrorBreakpoint(error.href, error.lineNo) | |
} else { | |
Firebug.Debugger.setErrorBreakpoint(error.href, error.lineNo) | |
} | |
}, | |
className: "errorMessage", | |
inspectable: false, | |
supportsObject: function(object) { | |
return object instanceof ErrorMessage | |
}, | |
inspectObject: function(error, context) { | |
var sourceLink = this.getSourceLink(error); | |
FirebugReps.SourceLink.inspectObject(sourceLink, context) | |
}, | |
getContextMenuItems: function(error, target, context) { | |
var breakOnThisError = this.hasErrorBreak(error); | |
var items = [{ | |
label: "CopyError", | |
command: bindFixed(this.copyError, this, error) | |
}]; | |
if (error.category == "css") { | |
items.push("-", { | |
label: "BreakOnThisError", | |
type: "checkbox", | |
checked: breakOnThisError, | |
command: bindFixed(this.breakOnThisError, this, error) | |
}, | |
optionMenu("BreakOnAllErrors", "breakOnErrors")) | |
} | |
return items | |
} | |
}); | |
this.Assert = domplate(Firebug.Rep, { | |
tag: DIV(DIV({ | |
"class": "errorTitle" | |
}), DIV({ | |
"class": "assertDescription" | |
})), | |
className: "assert", | |
inspectObject: function(error, context) { | |
var sourceLink = this.getSourceLink(error); | |
Firebug.chrome.select(sourceLink) | |
}, | |
getContextMenuItems: function(error, target, context) { | |
var breakOnThisError = this.hasErrorBreak(error); | |
return [{ | |
label: "CopyError", | |
command: bindFixed(this.copyError, this, error) | |
}, | |
"-", { | |
label: "BreakOnThisError", | |
type: "checkbox", | |
checked: breakOnThisError, | |
command: bindFixed(this.breakOnThisError, this, error) | |
}, | |
{ | |
label: "BreakOnAllErrors", | |
type: "checkbox", | |
checked: Firebug.breakOnErrors, | |
command: bindFixed(this.breakOnAllErrors, this, error) | |
}] | |
} | |
}); | |
this.SourceText = domplate(Firebug.Rep, { | |
tag: DIV(FOR("line", "$object|lineIterator", DIV({ | |
"class": "sourceRow", | |
role: "presentation" | |
}, | |
SPAN({ | |
"class": "sourceLine", | |
role: "presentation" | |
}, | |
"$line.lineNo"), SPAN({ | |
"class": "sourceRowText", | |
role: "presentation" | |
}, | |
"$line.text")))), | |
lineIterator: function(sourceText) { | |
var maxLineNoChars = (sourceText.lines.length + "").length; | |
var list = []; | |
for (var i = 0; i < sourceText.lines.length; ++i) { | |
var lineNo = (i + 1) + ""; | |
while (lineNo.length < maxLineNoChars) { | |
lineNo = " " + lineNo | |
} | |
list.push({ | |
lineNo: lineNo, | |
text: sourceText.lines[i] | |
}) | |
} | |
return list | |
}, | |
getHTML: function(sourceText) { | |
return getSourceLineRange(sourceText, 1, sourceText.lines.length) | |
} | |
}); | |
this.nsIDOMHistory = domplate(Firebug.Rep, { | |
tag: OBJECTBOX({ | |
onclick: "$showHistory" | |
}, | |
OBJECTLINK("$object|summarizeHistory")), | |
className: "nsIDOMHistory", | |
summarizeHistory: function(history) { | |
try { | |
var items = history.length; | |
return items + " history entries" | |
} catch(exc) { | |
return "object does not support history (nsIDOMHistory)" | |
} | |
}, | |
showHistory: function(history) { | |
try { | |
var items = history.length; | |
Firebug.chrome.select(history) | |
} catch(exc) {} | |
}, | |
supportsObject: function(object, type) { | |
return (object instanceof Ci.nsIDOMHistory) | |
} | |
}); | |
this.ApplicationCache = domplate(Firebug.Rep, { | |
tag: OBJECTBOX({ | |
onclick: "$showApplicationCache" | |
}, | |
OBJECTLINK("$object|summarizeCache")), | |
summarizeCache: function(applicationCache) { | |
try { | |
return applicationCache.length + " items in offline cache" | |
} catch(exc) { | |
return "https://bugzilla.mozilla.org/show_bug.cgi?id=422264" | |
} | |
}, | |
showApplicationCache: function(event) { | |
openNewTab("https://bugzilla.mozilla.org/show_bug.cgi?id=422264") | |
}, | |
className: "applicationCache", | |
supportsObject: function(object, type) { | |
if (Ci.nsIDOMOfflineResourceList) { | |
return (object instanceof Ci.nsIDOMOfflineResourceList) | |
} | |
} | |
}); | |
this.Storage = domplate(Firebug.Rep, { | |
tag: OBJECTBOX({ | |
onclick: "$show" | |
}, | |
OBJECTLINK("$object|summarize")), | |
summarize: function(storage) { | |
return storage.length + " items in Storage" | |
}, | |
show: function(storage) { | |
openNewTab("http://dev.w3.org/html5/webstorage/#storage-0") | |
}, | |
className: "Storage", | |
supportsObject: function(object, type) { | |
return (object instanceof Storage) | |
} | |
}); | |
Firebug.registerRep(this.Undefined, this.Null, this.Number, this.String, this.Window, this.Element, this.Document, this.StyleSheet, this.Event, this.Property, this.Except, this.Arr); | |
Firebug.setDefaultReps(this.Func, this.Obj) | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
var saveTimeout = 400; | |
var pageAmount = 10; | |
var currentTarget = null; | |
var currentGroup = null; | |
var currentPanel = null; | |
var currentEditor = null; | |
var defaultEditor = null; | |
var originalClassName = null; | |
var originalValue = null; | |
var defaultValue = null; | |
var previousValue = null; | |
var invalidEditor = false; | |
var ignoreNextInput = false; | |
Firebug.Editor = extend(Firebug.Module, { | |
supportsStopEvent: true, | |
dispatchName: "editor", | |
tabCharacter: " ", | |
startEditing: function(target, value, editor) { | |
this.stopEditing(); | |
if (hasClass(target, "insertBefore") || hasClass(target, "insertAfter")) { | |
return | |
} | |
var panel = Firebug.getElementPanel(target); | |
if (!panel.editable) { | |
return | |
} | |
if (FBTrace.DBG_EDITOR) { | |
FBTrace.sysout("editor.startEditing " + value, target) | |
} | |
defaultValue = target.getAttribute("defaultValue"); | |
if (value == undefined) { | |
var textContent = isIE ? "innerText": "textContent"; | |
value = target[textContent]; | |
if (value == defaultValue) { | |
value = "" | |
} | |
} | |
originalValue = previousValue = value; | |
invalidEditor = false; | |
currentTarget = target; | |
currentPanel = panel; | |
currentGroup = getAncestorByClass(target, "editGroup"); | |
currentPanel.editing = true; | |
var panelEditor = currentPanel.getEditor(target, value); | |
currentEditor = editor ? editor: panelEditor; | |
if (!currentEditor) { | |
currentEditor = getDefaultEditor(currentPanel) | |
} | |
var inlineParent = getInlineParent(target); | |
var targetSize = getOffsetSize(inlineParent); | |
setClass(panel.panelNode, "editing"); | |
setClass(target, "editing"); | |
if (currentGroup) { | |
setClass(currentGroup, "editing") | |
} | |
currentEditor.show(target, currentPanel, value, targetSize); | |
currentEditor.beginEditing(target, value); | |
if (FBTrace.DBG_EDITOR) { | |
FBTrace.sysout("Editor start panel " + currentPanel.name) | |
} | |
this.attachListeners(currentEditor, panel.context) | |
}, | |
stopEditing: function(cancel) { | |
if (!currentTarget) { | |
return | |
} | |
if (FBTrace.DBG_EDITOR) { | |
FBTrace.sysout("editor.stopEditing cancel:" + cancel + " saveTimeout: " + this.saveTimeout) | |
} | |
clearTimeout(this.saveTimeout); | |
delete this.saveTimeout; | |
this.detachListeners(currentEditor, currentPanel.context); | |
removeClass(currentPanel.panelNode, "editing"); | |
removeClass(currentTarget, "editing"); | |
if (currentGroup) { | |
removeClass(currentGroup, "editing") | |
} | |
var value = currentEditor.getValue(); | |
if (value == defaultValue) { | |
value = "" | |
} | |
var removeGroup = currentEditor.endEditing(currentTarget, value, cancel); | |
try { | |
if (cancel) { | |
if (value != originalValue) { | |
this.saveEditAndNotifyListeners(currentTarget, originalValue, previousValue) | |
} | |
if (removeGroup && !originalValue && currentGroup) { | |
currentGroup.parentNode.removeChild(currentGroup) | |
} | |
} else { | |
if (!value) { | |
this.saveEditAndNotifyListeners(currentTarget, null, previousValue); | |
if (removeGroup && currentGroup) { | |
currentGroup.parentNode.removeChild(currentGroup) | |
} | |
} else { | |
this.save(value) | |
} | |
} | |
} catch(exc) {} | |
currentEditor.hide(); | |
currentPanel.editing = false; | |
currentTarget = null; | |
currentGroup = null; | |
currentPanel = null; | |
currentEditor = null; | |
originalValue = null; | |
invalidEditor = false; | |
return value | |
}, | |
cancelEditing: function() { | |
return this.stopEditing(true) | |
}, | |
update: function(saveNow) { | |
if (this.saveTimeout) { | |
clearTimeout(this.saveTimeout) | |
} | |
invalidEditor = true; | |
currentEditor.layout(); | |
if (saveNow) { | |
this.save() | |
} else { | |
var context = currentPanel.context; | |
this.saveTimeout = context.setTimeout(bindFixed(this.save, this), saveTimeout); | |
if (FBTrace.DBG_EDITOR) { | |
FBTrace.sysout("editor.update saveTimeout: " + this.saveTimeout) | |
} | |
} | |
}, | |
save: function(value) { | |
if (!invalidEditor) { | |
return | |
} | |
if (value == undefined) { | |
value = currentEditor.getValue() | |
} | |
if (FBTrace.DBG_EDITOR) { | |
FBTrace.sysout("editor.save saveTimeout: " + this.saveTimeout + " currentPanel: " + (currentPanel ? currentPanel.name: "null")) | |
} | |
try { | |
this.saveEditAndNotifyListeners(currentTarget, value, previousValue); | |
previousValue = value; | |
invalidEditor = false | |
} catch(exc) { | |
if (FBTrace.DBG_ERRORS) { | |
FBTrace.sysout("editor.save FAILS " + exc, exc) | |
} | |
} | |
}, | |
saveEditAndNotifyListeners: function(currentTarget, value, previousValue) { | |
currentEditor.saveEdit(currentTarget, value, previousValue) | |
}, | |
setEditTarget: function(element) { | |
if (!element) { | |
dispatch([Firebug.A11yModel], "onInlineEditorClose", [currentPanel, currentTarget, true]); | |
this.stopEditing() | |
} else { | |
if (hasClass(element, "insertBefore")) { | |
this.insertRow(element, "before") | |
} else { | |
if (hasClass(element, "insertAfter")) { | |
this.insertRow(element, "after") | |
} else { | |
this.startEditing(element) | |
} | |
} | |
} | |
}, | |
tabNextEditor: function() { | |
if (!currentTarget) { | |
return | |
} | |
var value = currentEditor.getValue(); | |
var nextEditable = currentTarget; | |
do { | |
nextEditable = !value && currentGroup ? getNextOutsider(nextEditable, currentGroup) : getNextByClass(nextEditable, "editable") | |
} while ( nextEditable && ! nextEditable . offsetHeight ); | |
this.setEditTarget(nextEditable) | |
}, | |
tabPreviousEditor: function() { | |
if (!currentTarget) { | |
return | |
} | |
var value = currentEditor.getValue(); | |
var prevEditable = currentTarget; | |
do { | |
prevEditable = !value && currentGroup ? getPreviousOutsider(prevEditable, currentGroup) : getPreviousByClass(prevEditable, "editable") | |
} while ( prevEditable && ! prevEditable . offsetHeight ); | |
this.setEditTarget(prevEditable) | |
}, | |
insertRow: function(relative, insertWhere) { | |
var group = relative || getAncestorByClass(currentTarget, "editGroup") || currentTarget; | |
var value = this.stopEditing(); | |
currentPanel = Firebug.getElementPanel(group); | |
currentEditor = currentPanel.getEditor(group, value); | |
if (!currentEditor) { | |
currentEditor = getDefaultEditor(currentPanel) | |
} | |
currentGroup = currentEditor.insertNewRow(group, insertWhere); | |
if (!currentGroup) { | |
return | |
} | |
var editable = hasClass(currentGroup, "editable") ? currentGroup: getNextByClass(currentGroup, "editable"); | |
if (editable) { | |
this.setEditTarget(editable) | |
} | |
}, | |
insertRowForObject: function(relative) { | |
var container = getAncestorByClass(relative, "insertInto"); | |
if (container) { | |
relative = getChildByClass(container, "insertBefore"); | |
if (relative) { | |
this.insertRow(relative, "before") | |
} | |
} | |
}, | |
attachListeners: function(editor, context) { | |
var win = isIE ? currentTarget.ownerDocument.parentWindow: currentTarget.ownerDocument.defaultView; | |
addEvent(win, "resize", this.onResize); | |
addEvent(win, "blur", this.onBlur); | |
var chrome = Firebug.chrome; | |
this.listeners = [chrome.keyCodeListen("ESCAPE", null, bind(this.cancelEditing, this))]; | |
if (editor.arrowCompletion) { | |
this.listeners.push(chrome.keyCodeListen("UP", null, bindFixed(editor.completeValue, editor, -1)), chrome.keyCodeListen("DOWN", null, bindFixed(editor.completeValue, editor, 1)), chrome.keyCodeListen("PAGE_UP", null, bindFixed(editor.completeValue, editor, -pageAmount)), chrome.keyCodeListen("PAGE_DOWN", null, bindFixed(editor.completeValue, editor, pageAmount))) | |
} | |
if (currentEditor.tabNavigation) { | |
this.listeners.push(chrome.keyCodeListen("RETURN", null, bind(this.tabNextEditor, this)), chrome.keyCodeListen("RETURN", isControl, bind(this.insertRow, this, null, "after")), chrome.keyCodeListen("TAB", null, bind(this.tabNextEditor, this)), chrome.keyCodeListen("TAB", isShift, bind(this.tabPreviousEditor, this))) | |
} else { | |
if (currentEditor.multiLine) { | |
this.listeners.push(chrome.keyCodeListen("TAB", null, insertTab)) | |
} else { | |
this.listeners.push(chrome.keyCodeListen("RETURN", null, bindFixed(this.stopEditing, this))); | |
if (currentEditor.tabCompletion) { | |
this.listeners.push(chrome.keyCodeListen("TAB", null, bind(editor.completeValue, editor, 1)), chrome.keyCodeListen("TAB", isShift, bind(editor.completeValue, editor, -1))) | |
} | |
} | |
} | |
}, | |
detachListeners: function(editor, context) { | |
if (!this.listeners) { | |
return | |
} | |
var win = isIE ? currentTarget.ownerDocument.parentWindow: currentTarget.ownerDocument.defaultView; | |
removeEvent(win, "resize", this.onResize); | |
removeEvent(win, "blur", this.onBlur); | |
var chrome = Firebug.chrome; | |
if (chrome) { | |
for (var i = 0; i < this.listeners.length; ++i) { | |
chrome.keyIgnore(this.listeners[i]) | |
} | |
} | |
delete this.listeners | |
}, | |
onResize: function(event) { | |
currentEditor.layout(true) | |
}, | |
onBlur: function(event) { | |
if (currentEditor.enterOnBlur && isAncestor(event.target, currentEditor.box)) { | |
this.stopEditing() | |
} | |
}, | |
initialize: function() { | |
Firebug.Module.initialize.apply(this, arguments); | |
this.onResize = bindFixed(this.onResize, this); | |
this.onBlur = bind(this.onBlur, this) | |
}, | |
disable: function() { | |
this.stopEditing() | |
}, | |
showContext: function(browser, context) { | |
this.stopEditing() | |
}, | |
showPanel: function(browser, panel) { | |
this.stopEditing() | |
} | |
}); | |
Firebug.BaseEditor = extend(Firebug.MeasureBox, { | |
getValue: function() {}, | |
setValue: function(value) {}, | |
show: function(target, panel, value, textSize, targetSize) {}, | |
hide: function() {}, | |
layout: function(forceAll) {}, | |
getContextMenuItems: function(target) { | |
var items = []; | |
items.push({ | |
label: "Cut", | |
commandID: "cmd_cut" | |
}); | |
items.push({ | |
label: "Copy", | |
commandID: "cmd_copy" | |
}); | |
items.push({ | |
label: "Paste", | |
commandID: "cmd_paste" | |
}); | |
return items | |
}, | |
beginEditing: function(target, value) {}, | |
saveEdit: function(target, value, previousValue) {}, | |
endEditing: function(target, value, cancel) { | |
return true | |
}, | |
insertNewRow: function(target, insertWhere) {} | |
}); | |
var inlineEditorAttributes = { | |
"class": "textEditorInner", | |
type: "text", | |
spellcheck: "false", | |
onkeypress: "$onKeyPress", | |
onoverflow: "$onOverflow", | |
oncontextmenu: "$onContextMenu" | |
}; | |
if (isIE) { | |
inlineEditorAttributes.onpropertychange = "$onInput"; | |
inlineEditorAttributes.onkeydown = "$onKeyDown" | |
} else { | |
inlineEditorAttributes.oninput = "$onInput" | |
} | |
Firebug.InlineEditor = function(doc) { | |
this.initializeInline(doc) | |
}; | |
Firebug.InlineEditor.prototype = domplate(Firebug.BaseEditor, { | |
enterOnBlur: true, | |
outerMargin: 8, | |
shadowExpand: 7, | |
tag: DIV({ | |
"class": "inlineEditor" | |
}, | |
DIV({ | |
"class": "textEditorTop1" | |
}, | |
DIV({ | |
"class": "textEditorTop2" | |
})), DIV({ | |
"class": "textEditorInner1" | |
}, | |
DIV({ | |
"class": "textEditorInner2" | |
}, | |
INPUT(inlineEditorAttributes))), DIV({ | |
"class": "textEditorBottom1" | |
}, | |
DIV({ | |
"class": "textEditorBottom2" | |
}))), | |
inputTag: INPUT({ | |
"class": "textEditorInner", | |
type: "text", | |
onkeypress: "$onKeyPress", | |
onoverflow: "$onOverflow" | |
}), | |
expanderTag: IMG({ | |
"class": "inlineExpander", | |
src: "blank.gif" | |
}), | |
initialize: function() { | |
this.fixedWidth = false; | |
this.completeAsYouType = true; | |
this.tabNavigation = true; | |
this.multiLine = false; | |
this.tabCompletion = false; | |
this.arrowCompletion = true; | |
this.noWrap = true; | |
this.numeric = false | |
}, | |
destroy: function() { | |
this.destroyInput() | |
}, | |
initializeInline: function(doc) { | |
if (FBTrace.DBG_EDITOR) { | |
FBTrace.sysout("Firebug.InlineEditor initializeInline()") | |
} | |
this.box = this.tag.append({}, | |
doc.body, this); | |
this.input = this.box.getElementsByTagName("input")[0]; | |
if (isIElt8) { | |
this.input.style.top = "-8px" | |
} | |
this.expander = this.expanderTag.replace({}, | |
doc, this); | |
this.initialize() | |
}, | |
destroyInput: function() {}, | |
getValue: function() { | |
return this.input.value | |
}, | |
setValue: function(value) { | |
return this.input.value = stripNewLines(value) | |
}, | |
show: function(target, panel, value, targetSize) { | |
this.target = target; | |
this.panel = panel; | |
this.targetSize = targetSize; | |
var innerHTML = target.innerHTML; | |
var isEmptyElement = !innerHTML; | |
if (isEmptyElement) { | |
target.innerHTML = "." | |
} | |
this.targetOffset = { | |
x: target.offsetLeft, | |
y: target.offsetTop | |
}; | |
if (isEmptyElement) { | |
target.innerHTML = innerHTML | |
} | |
this.originalClassName = this.box.className; | |
var classNames = target.className.split(" "); | |
for (var i = 0; i < classNames.length; ++i) { | |
setClass(this.box, "editor-" + classNames[i]) | |
} | |
copyTextStyles(target, this.box); | |
this.setValue(value); | |
if (this.fixedWidth) { | |
this.updateLayout(true) | |
} else { | |
this.startMeasuring(target); | |
this.textSize = this.measureInputText(value); | |
var parent = this.input.parentNode; | |
if (hasClass(parent, "textEditorInner2")) { | |
var yDiff = this.textSize.height - this.shadowExpand; | |
if (isIE6) { | |
yDiff -= 2 | |
} | |
parent.style.height = yDiff + "px"; | |
parent.parentNode.style.height = yDiff + "px" | |
} | |
this.updateLayout(true) | |
} | |
this.getAutoCompleter().reset(); | |
if (isIElt8) { | |
panel.panelNode.appendChild(this.box) | |
} else { | |
target.offsetParent.appendChild(this.box) | |
} | |
if (isIE) { | |
this.input.style.fontFamily = "Monospace"; | |
this.input.style.fontSize = "11px" | |
} | |
if (!this.fixedWidth) { | |
copyBoxStyles(target, this.expander); | |
target.parentNode.replaceChild(this.expander, target); | |
collapse(target, true); | |
this.expander.parentNode.insertBefore(target, this.expander) | |
} | |
this.box.style.display = "block"; | |
var self = this; | |
setTimeout(function() { | |
self.input.focus(); | |
self.input.select() | |
}, | |
0) | |
}, | |
hide: function() { | |
this.box.className = this.originalClassName; | |
if (!this.fixedWidth) { | |
this.stopMeasuring(); | |
collapse(this.target, false); | |
if (this.expander.parentNode) { | |
this.expander.parentNode.removeChild(this.expander) | |
} | |
} | |
if (this.box.parentNode) { | |
this.input.blur(); | |
this.box.parentNode.removeChild(this.box) | |
} | |
delete this.target; | |
delete this.panel | |
}, | |
layout: function(forceAll) { | |
if (!this.fixedWidth) { | |
this.textSize = this.measureInputText(this.input.value) | |
} | |
if (forceAll) { | |
this.targetOffset = getClientOffset(this.expander) | |
} | |
this.updateLayout(false, forceAll) | |
}, | |
beginEditing: function(target, value) {}, | |
saveEdit: function(target, value, previousValue) {}, | |
endEditing: function(target, value, cancel) { | |
return true | |
}, | |
insertNewRow: function(target, insertWhere) {}, | |
advanceToNext: function(target, charCode) { | |
return false | |
}, | |
getAutoCompleteRange: function(value, offset) {}, | |
getAutoCompleteList: function(preExpr, expr, postExpr) {}, | |
getAutoCompleter: function() { | |
if (!this.autoCompleter) { | |
this.autoCompleter = new Firebug.AutoCompleter(null, bind(this.getAutoCompleteRange, this), bind(this.getAutoCompleteList, this), true, false) | |
} | |
return this.autoCompleter | |
}, | |
completeValue: function(amt) { | |
var selectRangeCallback = this.getAutoCompleter().complete(currentPanel.context, this.input, true, amt < 0); | |
if (selectRangeCallback) { | |
Firebug.Editor.update(true); | |
if (isSafari) { | |
setTimeout(selectRangeCallback, 0) | |
} else { | |
selectRangeCallback() | |
} | |
} else { | |
this.incrementValue(amt) | |
} | |
}, | |
incrementValue: function(amt) { | |
var value = this.input.value; | |
if (isIE) { | |
var start = getInputSelectionStart(this.input), | |
end = start | |
} else { | |
var start = this.input.selectionStart, | |
end = this.input.selectionEnd | |
} | |
var range = this.getAutoCompleteRange(value, start); | |
if (!range || range.type != "int") { | |
range = { | |
start: 0, | |
end: value.length - 1 | |
} | |
} | |
var expr = value.substr(range.start, range.end - range.start + 1); | |
preExpr = value.substr(0, range.start); | |
postExpr = value.substr(range.end + 1); | |
var intValue = parseInt(expr); | |
if ( !! intValue || intValue == 0) { | |
var m = /\d+/.exec(expr); | |
var digitPost = expr.substr(m.index + m[0].length); | |
var completion = intValue - amt; | |
this.input.value = preExpr + completion + digitPost + postExpr; | |
setSelectionRange(this.input, start, end); | |
Firebug.Editor.update(true); | |
return true | |
} else { | |
return false | |
} | |
}, | |
onKeyPress: function(event) { | |
if (event.keyCode == 27 && !this.completeAsYouType) { | |
var reverted = this.getAutoCompleter().revert(this.input); | |
if (reverted) { | |
cancelEvent(event) | |
} | |
} else { | |
if (event.charCode && this.advanceToNext(this.target, event.charCode)) { | |
Firebug.Editor.tabNextEditor(); | |
cancelEvent(event) | |
} else { | |
if (this.numeric && event.charCode && (event.charCode < 48 || event.charCode > 57) && event.charCode != 45 && event.charCode != 46) { | |
FBL.cancelEvent(event) | |
} else { | |
this.ignoreNextInput = event.keyCode == 8 | |
} | |
} | |
} | |
}, | |
onOverflow: function() { | |
this.updateLayout(false, false, 3) | |
}, | |
onKeyDown: function(event) { | |
if (event.keyCode > 46 || event.keyCode == 32 || event.keyCode == 8) { | |
this.keyDownPressed = true | |
} | |
}, | |
onInput: function(event) { | |
if (isIE) { | |
if (event.propertyName != "value" || !isVisible(this.input) || !this.keyDownPressed) { | |
return | |
} | |
this.keyDownPressed = false | |
} | |
var selectRangeCallback; | |
if (this.ignoreNextInput) { | |
this.ignoreNextInput = false; | |
this.getAutoCompleter().reset() | |
} else { | |
if (this.completeAsYouType) { | |
selectRangeCallback = this.getAutoCompleter().complete(currentPanel.context, this.input, false) | |
} else { | |
this.getAutoCompleter().reset() | |
} | |
} | |
Firebug.Editor.update(); | |
if (selectRangeCallback) { | |
if (isSafari) { | |
setTimeout(selectRangeCallback, 0) | |
} else { | |
selectRangeCallback() | |
} | |
} | |
}, | |
onContextMenu: function(event) { | |
cancelEvent(event); | |
var popup = $("fbInlineEditorPopup"); | |
FBL.eraseNode(popup); | |
var target = event.target || event.srcElement; | |
var menu = this.getContextMenuItems(target); | |
if (menu) { | |
for (var i = 0; i < menu.length; ++i) { | |
FBL.createMenuItem(popup, menu[i]) | |
} | |
} | |
if (!popup.firstChild) { | |
return false | |
} | |
popup.openPopupAtScreen(event.screenX, event.screenY, true); | |
return true | |
}, | |
updateLayout: function(initial, forceAll, extraWidth) { | |
if (this.fixedWidth) { | |
this.box.style.left = (this.targetOffset.x) + "px"; | |
this.box.style.top = (this.targetOffset.y) + "px"; | |
var w = this.target.offsetWidth; | |
var h = this.target.offsetHeight; | |
this.input.style.width = w + "px"; | |
this.input.style.height = (h - 3) + "px" | |
} else { | |
if (initial || forceAll) { | |
this.box.style.left = this.targetOffset.x + "px"; | |
this.box.style.top = this.targetOffset.y + "px" | |
} | |
var approxTextWidth = this.textSize.width; | |
var maxWidth = (currentPanel.panelNode.scrollWidth - this.targetOffset.x) - this.outerMargin; | |
var wrapped = initial ? this.noWrap && this.targetSize.height > this.textSize.height + 3 : this.noWrap && approxTextWidth > maxWidth; | |
if (wrapped) { | |
var style = isIE ? this.target.currentStyle: this.target.ownerDocument.defaultView.getComputedStyle(this.target, ""); | |
targetMargin = parseInt(style.marginLeft) + parseInt(style.marginRight); | |
approxTextWidth = maxWidth - targetMargin; | |
this.input.style.width = "100%"; | |
this.box.style.width = approxTextWidth + "px" | |
} else { | |
var charWidth = this.measureInputText("m").width; | |
if (extraWidth) { | |
charWidth *= extraWidth | |
} | |
var inputWidth = approxTextWidth + charWidth; | |
if (initial) { | |
if (isIE) { | |
var xDiff = 13; | |
this.box.style.width = (inputWidth + xDiff) + "px" | |
} else { | |
this.box.style.width = "auto" | |
} | |
} else { | |
var xDiff = isIE ? 13 : this.box.scrollWidth - this.input.offsetWidth; | |
this.box.style.width = (inputWidth + xDiff) + "px" | |
} | |
this.input.style.width = inputWidth + "px" | |
} | |
this.expander.style.width = approxTextWidth + "px"; | |
this.expander.style.height = Math.max(this.textSize.height - 3, 0) + "px" | |
} | |
if (forceAll) { | |
scrollIntoCenterView(this.box, null, true) | |
} | |
} | |
}); | |
Firebug.AutoCompleter = function(getExprOffset, getRange, evaluator, selectMode, caseSensitive) { | |
var candidates = null; | |
var originalValue = null; | |
var originalOffset = -1; | |
var lastExpr = null; | |
var lastOffset = -1; | |
var exprOffset = 0; | |
var lastIndex = 0; | |
var preParsed = null; | |
var preExpr = null; | |
var postExpr = null; | |
this.revert = function(textBox) { | |
if (originalOffset != -1) { | |
textBox.value = originalValue; | |
setSelectionRange(textBox, originalOffset, originalOffset); | |
this.reset(); | |
return true | |
} else { | |
this.reset(); | |
return false | |
} | |
}; | |
this.reset = function() { | |
candidates = null; | |
originalValue = null; | |
originalOffset = -1; | |
lastExpr = null; | |
lastOffset = 0; | |
exprOffset = 0 | |
}; | |
this.complete = function(context, textBox, cycle, reverse) { | |
var value = textBox.value; | |
var offset = getInputSelectionStart(textBox); | |
if (isSafari && !cycle && offset >= 0) { | |
offset++ | |
} | |
if (!selectMode && originalOffset != -1) { | |
offset = originalOffset | |
} | |
if (!candidates || !cycle || offset != lastOffset) { | |
originalOffset = offset; | |
originalValue = value; | |
var parseStart = getExprOffset ? getExprOffset(value, offset, context) : 0; | |
preParsed = value.substr(0, parseStart); | |
var parsed = value.substr(parseStart); | |
var range = getRange ? getRange(parsed, offset - parseStart, context) : null; | |
if (!range) { | |
range = { | |
start: 0, | |
end: parsed.length - 1 | |
} | |
} | |
var expr = parsed.substr(range.start, range.end - range.start + 1); | |
preExpr = parsed.substr(0, range.start); | |
postExpr = parsed.substr(range.end + 1); | |
exprOffset = parseStart + range.start; | |
if (!cycle) { | |
if (!expr) { | |
return | |
} else { | |
if (lastExpr && lastExpr.indexOf(expr) != 0) { | |
candidates = null | |
} else { | |
if (lastExpr && lastExpr.length >= expr.length) { | |
candidates = null; | |
lastExpr = expr; | |
return | |
} | |
} | |
} | |
} | |
lastExpr = expr; | |
lastOffset = offset; | |
var searchExpr; | |
if (expr && offset != parseStart + range.end + 1) { | |
if (cycle) { | |
offset = range.start; | |
searchExpr = expr; | |
expr = "" | |
} else { | |
return | |
} | |
} | |
var values = evaluator(preExpr, expr, postExpr, context); | |
if (!values) { | |
return | |
} | |
if (expr) { | |
candidates = []; | |
if (caseSensitive) { | |
for (var i = 0; i < values.length; ++i) { | |
var name = values[i]; | |
if (name.indexOf && name.indexOf(expr) == 0) { | |
candidates.push(name) | |
} | |
} | |
} else { | |
var lowerExpr = caseSensitive ? expr: expr.toLowerCase(); | |
for (var i = 0; i < values.length; ++i) { | |
var name = values[i]; | |
if (name.indexOf && name.toLowerCase().indexOf(lowerExpr) == 0) { | |
candidates.push(name) | |
} | |
} | |
} | |
lastIndex = reverse ? candidates.length - 1 : 0 | |
} else { | |
if (searchExpr) { | |
var searchIndex = -1; | |
if (caseSensitive) { | |
searchIndex = values.indexOf(expr) | |
} else { | |
var lowerExpr = searchExpr.toLowerCase(); | |
for (var i = 0; i < values.length; ++i) { | |
var name = values[i]; | |
if (name && name.toLowerCase().indexOf(lowerExpr) == 0) { | |
searchIndex = i; | |
break | |
} | |
} | |
} | |
if (searchIndex == -1) { | |
return this.reset() | |
} | |
expr = searchExpr; | |
candidates = cloneArray(values); | |
lastIndex = searchIndex | |
} else { | |
expr = ""; | |
candidates = []; | |
for (var i = 0; i < values.length; ++i) { | |
if (values[i].substr) { | |
candidates.push(values[i]) | |
} | |
} | |
lastIndex = -1 | |
} | |
} | |
} | |
if (cycle) { | |
expr = lastExpr; | |
lastIndex += reverse ? -1 : 1 | |
} | |
if (!candidates.length) { | |
return | |
} | |
if (lastIndex >= candidates.length) { | |
lastIndex = 0 | |
} else { | |
if (lastIndex < 0) { | |
lastIndex = candidates.length - 1 | |
} | |
} | |
var completion = candidates[lastIndex]; | |
var preCompletion = expr.substr(0, offset - exprOffset); | |
var postCompletion = completion.substr(offset - exprOffset); | |
textBox.value = preParsed + preExpr + preCompletion + postCompletion + postExpr; | |
var offsetEnd = preParsed.length + preExpr.length + completion.length; | |
return function() { | |
if (selectMode) { | |
setSelectionRange(textBox, offset, offsetEnd) | |
} else { | |
setSelectionRange(textBox, offsetEnd, offsetEnd) | |
} | |
} | |
} | |
}; | |
var getDefaultEditor = function getDefaultEditor(panel) { | |
if (!defaultEditor) { | |
var doc = panel.document; | |
defaultEditor = new Firebug.InlineEditor(doc) | |
} | |
return defaultEditor | |
}; | |
var getOutsider = function getOutsider(element, group, stepper) { | |
var parentGroup = getAncestorByClass(group.parentNode, "editGroup"); | |
var next; | |
do { | |
next = stepper(next || element) | |
} while ( isAncestor ( next , group ) || isGroupInsert(next, parentGroup)); | |
return next | |
}; | |
var isGroupInsert = function isGroupInsert(next, group) { | |
return (!group || isAncestor(next, group)) && (hasClass(next, "insertBefore") || hasClass(next, "insertAfter")) | |
}; | |
var getNextOutsider = function getNextOutsider(element, group) { | |
return getOutsider(element, group, bind(getNextByClass, FBL, "editable")) | |
}; | |
var getPreviousOutsider = function getPreviousOutsider(element, group) { | |
return getOutsider(element, group, bind(getPreviousByClass, FBL, "editable")) | |
}; | |
var getInlineParent = function getInlineParent(element) { | |
var lastInline = element; | |
for (; element; element = element.parentNode) { | |
var s = isIE ? element.currentStyle: element.ownerDocument.defaultView.getComputedStyle(element, ""); | |
if (s.display != "inline") { | |
return lastInline | |
} else { | |
lastInline = element | |
} | |
} | |
return null | |
}; | |
var insertTab = function insertTab() { | |
insertTextIntoElement(currentEditor.input, Firebug.Editor.tabCharacter) | |
}; | |
Firebug.registerModule(Firebug.Editor) | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
if (Env.Options.disableXHRListener) { | |
return | |
} | |
var XHRSpy = function() { | |
this.requestHeaders = []; | |
this.responseHeaders = [] | |
}; | |
XHRSpy.prototype = { | |
method: null, | |
url: null, | |
async: null, | |
xhrRequest: null, | |
href: null, | |
loaded: false, | |
logRow: null, | |
responseText: null, | |
requestHeaders: null, | |
responseHeaders: null, | |
sourceLink: null, | |
getURL: function() { | |
return this.href | |
} | |
}; | |
var XMLHttpRequestWrapper = function(activeXObject) { | |
var xhrRequest = typeof activeXObject != "undefined" ? activeXObject: new _XMLHttpRequest(), | |
spy = new XHRSpy(), | |
self = this, | |
reqType, | |
reqUrl, | |
reqStartTS; | |
var updateSelfPropertiesIgnore = { | |
abort: 1, | |
channel: 1, | |
getAllResponseHeaders: 1, | |
getInterface: 1, | |
getResponseHeader: 1, | |
mozBackgroundRequest: 1, | |
multipart: 1, | |
onreadystatechange: 1, | |
open: 1, | |
send: 1, | |
setRequestHeader: 1 | |
}; | |
var updateSelfProperties = function() { | |
if (supportsXHRIterator) { | |
for (var propName in xhrRequest) { | |
if (propName in updateSelfPropertiesIgnore) { | |
continue | |
} | |
try { | |
var propValue = xhrRequest[propName]; | |
if (propValue && !isFunction(propValue)) { | |
self[propName] = propValue | |
} | |
} catch(E) {} | |
} | |
} else { | |
if (xhrRequest.readyState == 4) { | |
self.status = xhrRequest.status; | |
self.statusText = xhrRequest.statusText; | |
self.responseText = xhrRequest.responseText; | |
self.responseXML = xhrRequest.responseXML | |
} | |
} | |
}; | |
var updateXHRPropertiesIgnore = { | |
channel: 1, | |
onreadystatechange: 1, | |
readyState: 1, | |
responseBody: 1, | |
responseText: 1, | |
responseXML: 1, | |
status: 1, | |
statusText: 1, | |
upload: 1 | |
}; | |
var updateXHRProperties = function() { | |
for (var propName in self) { | |
if (propName in updateXHRPropertiesIgnore) { | |
continue | |
} | |
try { | |
var propValue = self[propName]; | |
if (propValue && !xhrRequest[propName]) { | |
xhrRequest[propName] = propValue | |
} | |
} catch(E) {} | |
} | |
}; | |
var logXHR = function() { | |
var row = Firebug.Console.log(spy, null, "spy", Firebug.Spy.XHR); | |
if (row) { | |
setClass(row, "loading"); | |
spy.logRow = row | |
} | |
}; | |
var finishXHR = function() { | |
var duration = new Date().getTime() - reqStartTS; | |
var success = xhrRequest.status == 200; | |
var responseHeadersText = xhrRequest.getAllResponseHeaders(); | |
var responses = responseHeadersText ? responseHeadersText.split(/[\n\r]/) : []; | |
var reHeader = /^(\S+):\s*(.*)/; | |
for (var i = 0, | |
l = responses.length; i < l; i++) { | |
var text = responses[i]; | |
var match = text.match(reHeader); | |
if (match) { | |
var name = match[1]; | |
var value = match[2]; | |
if (name == "Content-Type") { | |
spy.mimeType = value | |
} | |
spy.responseHeaders.push({ | |
name: [name], | |
value: [value] | |
}) | |
} | |
} | |
with({ | |
row: spy.logRow, | |
status: xhrRequest.status == 0 ? "": xhrRequest.status + " " + xhrRequest.statusText, | |
time: duration, | |
success: success | |
}) { | |
setTimeout(function() { | |
spy.responseText = xhrRequest.responseText; | |
row = row || spy.logRow; | |
if (!row) { | |
return | |
} | |
handleRequestStatus(success, status, time) | |
}, | |
200) | |
} | |
spy.loaded = true; | |
updateSelfProperties() | |
}; | |
var handleStateChange = function() { | |
self.readyState = xhrRequest.readyState; | |
if (xhrRequest.readyState == 4) { | |
finishXHR(); | |
xhrRequest.onreadystatechange = function() {} | |
} | |
self.onreadystatechange() | |
}; | |
var handleRequestStatus = function(success, status, time) { | |
var row = spy.logRow; | |
FBL.removeClass(row, "loading"); | |
if (!success) { | |
FBL.setClass(row, "error") | |
} | |
var item = FBL.$$(".spyStatus", row)[0]; | |
item.innerHTML = status; | |
if (time) { | |
var item = FBL.$$(".spyTime", row)[0]; | |
item.innerHTML = time + "ms" | |
} | |
}; | |
this.readyState = 0; | |
this.onreadystatechange = function() {}; | |
this.open = function(method, url, async, user, password) { | |
updateSelfProperties(); | |
if (spy.loaded) { | |
spy = new XHRSpy() | |
} | |
spy.method = method; | |
spy.url = url; | |
spy.async = async; | |
spy.href = url; | |
spy.xhrRequest = xhrRequest; | |
spy.urlParams = parseURLParamsArray(url); | |
try { | |
if (supportsApply) { | |
xhrRequest.open.apply(xhrRequest, arguments) | |
} else { | |
xhrRequest.open(method, url, async, user, password) | |
} | |
} catch(e) {} | |
xhrRequest.onreadystatechange = handleStateChange | |
}; | |
this.send = function(data) { | |
spy.data = data; | |
reqStartTS = new Date().getTime(); | |
updateXHRProperties(); | |
try { | |
xhrRequest.send(data) | |
} catch(e) {} finally { | |
logXHR(); | |
if (!spy.async) { | |
self.readyState = xhrRequest.readyState; | |
try { | |
finishXHR() | |
} catch(E) {} | |
} | |
} | |
}; | |
this.setRequestHeader = function(header, value) { | |
spy.requestHeaders.push({ | |
name: [header], | |
value: [value] | |
}); | |
return xhrRequest.setRequestHeader(header, value) | |
}; | |
this.abort = function() { | |
xhrRequest.abort(); | |
updateSelfProperties(); | |
handleRequestStatus(false, "Aborted") | |
}; | |
this.getResponseHeader = function(header) { | |
return xhrRequest.getResponseHeader(header) | |
}; | |
this.getAllResponseHeaders = function() { | |
return xhrRequest.getAllResponseHeaders() | |
}; | |
var supportsApply = !isIE6 && xhrRequest && xhrRequest.open && typeof xhrRequest.open.apply != "undefined"; | |
var numberOfXHRProperties = 0; | |
for (var propName in xhrRequest) { | |
numberOfXHRProperties++; | |
if (propName in updateSelfPropertiesIgnore) { | |
continue | |
} | |
try { | |
var propValue = xhrRequest[propName]; | |
if (isFunction(propValue)) { | |
if (typeof self[propName] == "undefined") { | |
this[propName] = (function(name, xhr) { | |
return supportsApply ? | |
function() { | |
return xhr[name].apply(xhr, arguments) | |
}: function(a, b, c, d, e) { | |
return xhr[name](a, b, c, d, e) | |
} | |
})(propName, xhrRequest) | |
} | |
} else { | |
this[propName] = propValue | |
} | |
} catch(E) {} | |
} | |
var supportsXHRIterator = numberOfXHRProperties > 0; | |
return this | |
}; | |
var _ActiveXObject; | |
var isIE6 = /msie 6/i.test(navigator.appVersion); | |
if (isIE6) { | |
_ActiveXObject = window.ActiveXObject; | |
var xhrObjects = " MSXML2.XMLHTTP.5.0 MSXML2.XMLHTTP.4.0 MSXML2.XMLHTTP.3.0 MSXML2.XMLHTTP Microsoft.XMLHTTP "; | |
window.ActiveXObject = function(name) { | |
var error = null; | |
try { | |
var activeXObject = new _ActiveXObject(name) | |
} catch(e) { | |
error = e | |
} finally { | |
if (!error) { | |
if (xhrObjects.indexOf(" " + name + " ") != -1) { | |
return new XMLHttpRequestWrapper(activeXObject) | |
} else { | |
return activeXObject | |
} | |
} else { | |
throw error.message | |
} | |
} | |
} | |
} | |
if (!isIE6) { | |
var _XMLHttpRequest = XMLHttpRequest; | |
window.XMLHttpRequest = function() { | |
return new XMLHttpRequestWrapper() | |
} | |
} | |
FBL.getNativeXHRObject = function() { | |
var xhrObj = false; | |
try { | |
xhrObj = new _XMLHttpRequest() | |
} catch(e) { | |
var progid = ["MSXML2.XMLHTTP.5.0", "MSXML2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"]; | |
for (var i = 0; i < progid.length; ++i) { | |
try { | |
xhrObj = new _ActiveXObject(progid[i]) | |
} catch(e) { | |
continue | |
} | |
break | |
} | |
} finally { | |
return xhrObj | |
} | |
} | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
var reIgnore = /about:|javascript:|resource:|chrome:|jar:/; | |
var layoutInterval = 300; | |
var indentWidth = 18; | |
var cacheSession = null; | |
var contexts = new Array(); | |
var panelName = "net"; | |
var maxQueueRequests = 500; | |
var activeRequests = []; | |
var mimeExtensionMap = { | |
txt: "text/plain", | |
html: "text/html", | |
htm: "text/html", | |
xhtml: "text/html", | |
xml: "text/xml", | |
css: "text/css", | |
js: "application/x-javascript", | |
jss: "application/x-javascript", | |
jpg: "image/jpg", | |
jpeg: "image/jpeg", | |
gif: "image/gif", | |
png: "image/png", | |
bmp: "image/bmp", | |
swf: "application/x-shockwave-flash", | |
flv: "video/x-flv" | |
}; | |
var fileCategories = { | |
"undefined": 1, | |
html: 1, | |
css: 1, | |
js: 1, | |
xhr: 1, | |
image: 1, | |
flash: 1, | |
txt: 1, | |
bin: 1 | |
}; | |
var textFileCategories = { | |
txt: 1, | |
html: 1, | |
xhr: 1, | |
css: 1, | |
js: 1 | |
}; | |
var binaryFileCategories = { | |
bin: 1, | |
flash: 1 | |
}; | |
var mimeCategoryMap = { | |
"text/plain": "txt", | |
"application/octet-stream": "bin", | |
"text/html": "html", | |
"text/xml": "html", | |
"text/css": "css", | |
"application/x-javascript": "js", | |
"text/javascript": "js", | |
"application/javascript": "js", | |
"image/jpeg": "image", | |
"image/jpg": "image", | |
"image/gif": "image", | |
"image/png": "image", | |
"image/bmp": "image", | |
"application/x-shockwave-flash": "flash", | |
"video/x-flv": "flash" | |
}; | |
var binaryCategoryMap = { | |
image: 1, | |
flash: 1 | |
}; | |
Firebug.NetMonitor = extend(Firebug.ActivableModule, { | |
dispatchName: "netMonitor", | |
clear: function(context) { | |
var panel = context.getPanel(panelName, true); | |
if (panel) { | |
panel.clear() | |
} | |
}, | |
initialize: function() { | |
return; | |
this.panelName = panelName; | |
Firebug.ActivableModule.initialize.apply(this, arguments); | |
if (Firebug.TraceModule) { | |
Firebug.TraceModule.addListener(this.TraceListener) | |
} | |
NetHttpObserver.registerObserver(); | |
NetHttpActivityObserver.registerObserver(); | |
Firebug.Debugger.addListener(this.DebuggerListener) | |
}, | |
shutdown: function() { | |
return; | |
prefs.removeObserver(Firebug.prefDomain, this, false); | |
if (Firebug.TraceModule) { | |
Firebug.TraceModule.removeListener(this.TraceListener) | |
} | |
NetHttpObserver.unregisterObserver(); | |
NetHttpActivityObserver.unregisterObserver(); | |
Firebug.Debugger.removeListener(this.DebuggerListener) | |
} | |
}); | |
Firebug.NetMonitor.NetInfoBody = domplate(Firebug.Rep, new Firebug.Listener(), { | |
tag: DIV({ | |
"class": "netInfoBody", | |
_repObject: "$file" | |
}, | |
TAG("$infoTabs", { | |
file: "$file" | |
}), TAG("$infoBodies", { | |
file: "$file" | |
})), | |
infoTabs: DIV({ | |
"class": "netInfoTabs focusRow subFocusRow", | |
role: "tablist" | |
}, | |
A({ | |
"class": "netInfoParamsTab netInfoTab a11yFocus", | |
onclick: "$onClickTab", | |
role: "tab", | |
view: "Params", | |
$collapsed: "$file|hideParams" | |
}, | |
$STR("URLParameters")), A({ | |
"class": "netInfoHeadersTab netInfoTab a11yFocus", | |
onclick: "$onClickTab", | |
role: "tab", | |
view: "Headers" | |
}, | |
$STR("Headers")), A({ | |
"class": "netInfoPostTab netInfoTab a11yFocus", | |
onclick: "$onClickTab", | |
role: "tab", | |
view: "Post", | |
$collapsed: "$file|hidePost" | |
}, | |
$STR("Post")), A({ | |
"class": "netInfoPutTab netInfoTab a11yFocus", | |
onclick: "$onClickTab", | |
role: "tab", | |
view: "Put", | |
$collapsed: "$file|hidePut" | |
}, | |
$STR("Put")), A({ | |
"class": "netInfoResponseTab netInfoTab a11yFocus", | |
onclick: "$onClickTab", | |
role: "tab", | |
view: "Response", | |
$collapsed: "$file|hideResponse" | |
}, | |
$STR("Response")), A({ | |
"class": "netInfoCacheTab netInfoTab a11yFocus", | |
onclick: "$onClickTab", | |
role: "tab", | |
view: "Cache", | |
$collapsed: "$file|hideCache" | |
}, | |
$STR("Cache")), A({ | |
"class": "netInfoHtmlTab netInfoTab a11yFocus", | |
onclick: "$onClickTab", | |
role: "tab", | |
view: "Html", | |
$collapsed: "$file|hideHtml" | |
}, | |
$STR("HTML"))), | |
infoBodies: DIV({ | |
"class": "netInfoBodies outerFocusRow" | |
}, | |
TABLE({ | |
"class": "netInfoParamsText netInfoText netInfoParamsTable", | |
role: "tabpanel", | |
cellpadding: 0, | |
cellspacing: 0 | |
}, | |
TBODY()), DIV({ | |
"class": "netInfoHeadersText netInfoText", | |
role: "tabpanel" | |
}), DIV({ | |
"class": "netInfoPostText netInfoText", | |
role: "tabpanel" | |
}), DIV({ | |
"class": "netInfoPutText netInfoText", | |
role: "tabpanel" | |
}), PRE({ | |
"class": "netInfoResponseText netInfoText", | |
role: "tabpanel" | |
}), DIV({ | |
"class": "netInfoCacheText netInfoText", | |
role: "tabpanel" | |
}, | |
TABLE({ | |
"class": "netInfoCacheTable", | |
cellpadding: 0, | |
cellspacing: 0, | |
role: "presentation" | |
}, | |
TBODY({ | |
role: "list", | |
"aria-label": $STR("Cache") | |
}))), DIV({ | |
"class": "netInfoHtmlText netInfoText", | |
role: "tabpanel" | |
}, | |
IFRAME({ | |
"class": "netInfoHtmlPreview", | |
role: "document" | |
}))), | |
headerDataTag: FOR("param", "$headers", TR({ | |
role: "listitem" | |
}, | |
TD({ | |
"class": "netInfoParamName", | |
role: "presentation" | |
}, | |
TAG("$param|getNameTag", { | |
param: "$param" | |
})), TD({ | |
"class": "netInfoParamValue", | |
role: "list", | |
"aria-label": "$param.name" | |
}, | |
FOR("line", "$param|getParamValueIterator", CODE({ | |
"class": "focusRow subFocusRow", | |
role: "listitem" | |
}, | |
"$line"))))), | |
customTab: A({ | |
"class": "netInfo$tabId\\Tab netInfoTab", | |
onclick: "$onClickTab", | |
view: "$tabId", | |
role: "tab" | |
}, | |
"$tabTitle"), | |
customBody: DIV({ | |
"class": "netInfo$tabId\\Text netInfoText", | |
role: "tabpanel" | |
}), | |
nameTag: SPAN("$param|getParamName"), | |
nameWithTooltipTag: SPAN({ | |
title: "$param.name" | |
}, | |
"$param|getParamName"), | |
getNameTag: function(param) { | |
return (this.getParamName(param) == param.name) ? this.nameTag: this.nameWithTooltipTag | |
}, | |
getParamName: function(param) { | |
var limit = 25; | |
var name = param.name; | |
if (name.length > limit) { | |
name = name.substr(0, limit) + "..." | |
} | |
return name | |
}, | |
getParamTitle: function(param) { | |
var limit = 25; | |
var name = param.name; | |
if (name.length > limit) { | |
return name | |
} | |
return "" | |
}, | |
hideParams: function(file) { | |
return ! file.urlParams || !file.urlParams.length | |
}, | |
hidePost: function(file) { | |
return file.method.toUpperCase() != "POST" | |
}, | |
hidePut: function(file) { | |
return file.method.toUpperCase() != "PUT" | |
}, | |
hideResponse: function(file) { | |
return false | |
}, | |
hideCache: function(file) { | |
return true; | |
return ! file.cacheEntry | |
}, | |
hideHtml: function(file) { | |
return (file.mimeType != "text/html") && (file.mimeType != "application/xhtml+xml") | |
}, | |
onClickTab: function(event) { | |
this.selectTab(event.currentTarget || event.srcElement) | |
}, | |
getParamValueIterator: function(param) { | |
return param.value; | |
return wrapText(param.value, true) | |
}, | |
appendTab: function(netInfoBox, tabId, tabTitle) { | |
var args = { | |
tabId: tabId, | |
tabTitle: tabTitle | |
}; | |
this.customTab.append(args, $$(".netInfoTabs", netInfoBox)[0]); | |
this.customBody.append(args, $$(".netInfoBodies", netInfoBox)[0]) | |
}, | |
selectTabByName: function(netInfoBox, tabName) { | |
var tab = getChildByClass(netInfoBox, "netInfoTabs", "netInfo" + tabName + "Tab"); | |
if (tab) { | |
this.selectTab(tab) | |
} | |
}, | |
selectTab: function(tab) { | |
var view = tab.getAttribute("view"); | |
var netInfoBox = getAncestorByClass(tab, "netInfoBody"); | |
var selectedTab = netInfoBox.selectedTab; | |
if (selectedTab) { | |
removeClass(netInfoBox.selectedText, "netInfoTextSelected"); | |
removeClass(selectedTab, "netInfoTabSelected"); | |
selectedTab.setAttribute("aria-selected", "false") | |
} | |
var textBodyName = "netInfo" + view + "Text"; | |
selectedTab = netInfoBox.selectedTab = tab; | |
netInfoBox.selectedText = $$("." + textBodyName, netInfoBox)[0]; | |
setClass(netInfoBox.selectedText, "netInfoTextSelected"); | |
setClass(selectedTab, "netInfoTabSelected"); | |
selectedTab.setAttribute("selected", "true"); | |
selectedTab.setAttribute("aria-selected", "true"); | |
var file = Firebug.getRepObject(netInfoBox); | |
var context = Firebug.chrome; | |
this.updateInfo(netInfoBox, file, context) | |
}, | |
updateInfo: function(netInfoBox, file, context) { | |
if (FBTrace.DBG_NET) { | |
FBTrace.sysout("net.updateInfo; file", file) | |
} | |
if (!netInfoBox) { | |
if (FBTrace.DBG_NET || FBTrace.DBG_ERRORS) { | |
FBTrace.sysout("net.updateInfo; ERROR netInfo == null " + file.href, file) | |
} | |
return | |
} | |
var tab = netInfoBox.selectedTab; | |
if (hasClass(tab, "netInfoParamsTab")) { | |
if (file.urlParams && !netInfoBox.urlParamsPresented) { | |
netInfoBox.urlParamsPresented = true; | |
this.insertHeaderRows(netInfoBox, file.urlParams, "Params") | |
} | |
} else { | |
if (hasClass(tab, "netInfoHeadersTab")) { | |
var headersText = $$(".netInfoHeadersText", netInfoBox)[0]; | |
if (file.responseHeaders && !netInfoBox.responseHeadersPresented) { | |
netInfoBox.responseHeadersPresented = true; | |
NetInfoHeaders.renderHeaders(headersText, file.responseHeaders, "ResponseHeaders") | |
} | |
if (file.requestHeaders && !netInfoBox.requestHeadersPresented) { | |
netInfoBox.requestHeadersPresented = true; | |
NetInfoHeaders.renderHeaders(headersText, file.requestHeaders, "RequestHeaders") | |
} | |
} else { | |
if (hasClass(tab, "netInfoPostTab")) { | |
if (!netInfoBox.postPresented) { | |
netInfoBox.postPresented = true; | |
var postText = $$(".netInfoPostText", netInfoBox)[0]; | |
NetInfoPostData.render(context, postText, file) | |
} | |
} else { | |
if (hasClass(tab, "netInfoPutTab")) { | |
if (!netInfoBox.putPresented) { | |
netInfoBox.putPresented = true; | |
var putText = $$(".netInfoPutText", netInfoBox)[0]; | |
NetInfoPostData.render(context, putText, file) | |
} | |
} else { | |
if (hasClass(tab, "netInfoResponseTab") && file.loaded && !netInfoBox.responsePresented) { | |
var responseTextBox = $$(".netInfoResponseText", netInfoBox)[0]; | |
if (file.category == "image") { | |
netInfoBox.responsePresented = true; | |
var responseImage = netInfoBox.ownerDocument.createElement("img"); | |
responseImage.src = file.href; | |
clearNode(responseTextBox); | |
responseTextBox.appendChild(responseImage, responseTextBox) | |
} else { | |
this.setResponseText(file, netInfoBox, responseTextBox, context) | |
} | |
} else { | |
if (hasClass(tab, "netInfoCacheTab") && file.loaded && !netInfoBox.cachePresented) { | |
var responseTextBox = netInfoBox.getElementsByClassName("netInfoCacheText").item(0); | |
if (file.cacheEntry) { | |
netInfoBox.cachePresented = true; | |
this.insertHeaderRows(netInfoBox, file.cacheEntry, "Cache") | |
} | |
} else { | |
if (hasClass(tab, "netInfoHtmlTab") && file.loaded && !netInfoBox.htmlPresented) { | |
netInfoBox.htmlPresented = true; | |
var text = Utils.getResponseText(file, context); | |
var iframe = $$(".netInfoHtmlPreview", netInfoBox)[0]; | |
var reScript = /<script(.|\s)*?\/script>/gi; | |
text = text.replace(reScript, ""); | |
iframe.contentWindow.document.write(text); | |
iframe.contentWindow.document.close() | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
dispatch(NetInfoBody.fbListeners, "updateTabBody", [netInfoBox, file, context]) | |
}, | |
setResponseText: function(file, netInfoBox, responseTextBox, context) { | |
netInfoBox.responsePresented = true; | |
if (isIE) { | |
responseTextBox.style.whiteSpace = "nowrap" | |
} | |
responseTextBox[typeof responseTextBox.textContent != "undefined" ? "textContent": "innerText"] = file.responseText; | |
return; | |
var text = Utils.getResponseText(file, context); | |
var limit = Firebug.netDisplayedResponseLimit + 15; | |
var limitReached = text ? (text.length > limit) : false; | |
if (limitReached) { | |
text = text.substr(0, limit) + "..." | |
} | |
if (text) { | |
insertWrappedText(text, responseTextBox) | |
} else { | |
insertWrappedText("", responseTextBox) | |
} | |
if (limitReached) { | |
var object = { | |
text: $STR("net.responseSizeLimitMessage"), | |
onClickLink: function() { | |
var panel = context.getPanel("net", true); | |
panel.openResponseInTab(file) | |
} | |
}; | |
Firebug.NetMonitor.ResponseSizeLimit.append(object, responseTextBox) | |
} | |
netInfoBox.responsePresented = true; | |
if (FBTrace.DBG_NET) { | |
FBTrace.sysout("net.setResponseText; response text updated") | |
} | |
}, | |
insertHeaderRows: function(netInfoBox, headers, tableName, rowName) { | |
if (!headers.length) { | |
return | |
} | |
var headersTable = $$(".netInfo" + tableName + "Table", netInfoBox)[0]; | |
var tbody = getChildByClass(headersTable, "netInfo" + rowName + "Body"); | |
if (!tbody) { | |
tbody = headersTable.firstChild | |
} | |
var titleRow = getChildByClass(tbody, "netInfo" + rowName + "Title"); | |
this.headerDataTag.insertRows({ | |
headers: headers | |
}, | |
titleRow ? titleRow: tbody); | |
removeClass(titleRow, "collapsed") | |
} | |
}); | |
var NetInfoBody = Firebug.NetMonitor.NetInfoBody; | |
Firebug.NetMonitor.NetInfoHeaders = domplate(Firebug.Rep, { | |
tag: DIV({ | |
"class": "netInfoHeadersTable", | |
role: "tabpanel" | |
}, | |
DIV({ | |
"class": "netInfoHeadersGroup netInfoResponseHeadersTitle" | |
}, | |
SPAN($STR("ResponseHeaders")), SPAN({ | |
"class": "netHeadersViewSource response collapsed", | |
onclick: "$onViewSource", | |
_sourceDisplayed: false, | |
_rowName: "ResponseHeaders" | |
}, | |
$STR("net.headers.view source"))), TABLE({ | |
cellpadding: 0, | |
cellspacing: 0 | |
}, | |
TBODY({ | |
"class": "netInfoResponseHeadersBody", | |
role: "list", | |
"aria-label": $STR("ResponseHeaders") | |
})), DIV({ | |
"class": "netInfoHeadersGroup netInfoRequestHeadersTitle" | |
}, | |
SPAN($STR("RequestHeaders")), SPAN({ | |
"class": "netHeadersViewSource request collapsed", | |
onclick: "$onViewSource", | |
_sourceDisplayed: false, | |
_rowName: "RequestHeaders" | |
}, | |
$STR("net.headers.view source"))), TABLE({ | |
cellpadding: 0, | |
cellspacing: 0 | |
}, | |
TBODY({ | |
"class": "netInfoRequestHeadersBody", | |
role: "list", | |
"aria-label": $STR("RequestHeaders") | |
}))), | |
sourceTag: TR({ | |
role: "presentation" | |
}, | |
TD({ | |
colspan: 2, | |
role: "presentation" | |
}, | |
PRE({ | |
"class": "source" | |
}))), | |
onViewSource: function(event) { | |
var target = event.target; | |
var requestHeaders = (target.rowName == "RequestHeaders"); | |
var netInfoBox = getAncestorByClass(target, "netInfoBody"); | |
var file = netInfoBox.repObject; | |
if (target.sourceDisplayed) { | |
var headers = requestHeaders ? file.requestHeaders: file.responseHeaders; | |
this.insertHeaderRows(netInfoBox, headers, target.rowName); | |
target.innerHTML = $STR("net.headers.view source") | |
} else { | |
var source = requestHeaders ? file.requestHeadersText: file.responseHeadersText; | |
this.insertSource(netInfoBox, source, target.rowName); | |
target.innerHTML = $STR("net.headers.pretty print") | |
} | |
target.sourceDisplayed = !target.sourceDisplayed; | |
cancelEvent(event) | |
}, | |
insertSource: function(netInfoBox, source, rowName) { | |
var tbody = $$(".netInfo" + rowName + "Body", netInfoBox)[0]; | |
var node = this.sourceTag.replace({}, | |
tbody); | |
var sourceNode = $$(".source", node)[0]; | |
sourceNode.innerHTML = source | |
}, | |
insertHeaderRows: function(netInfoBox, headers, rowName) { | |
var headersTable = $$(".netInfoHeadersTable", netInfoBox)[0]; | |
var tbody = $$(".netInfo" + rowName + "Body", headersTable)[0]; | |
clearNode(tbody); | |
if (!headers.length) { | |
return | |
} | |
NetInfoBody.headerDataTag.insertRows({ | |
headers: headers | |
}, | |
tbody); | |
var titleRow = getChildByClass(headersTable, "netInfo" + rowName + "Title"); | |
removeClass(titleRow, "collapsed") | |
}, | |
init: function(parent) { | |
var rootNode = this.tag.append({}, | |
parent); | |
var netInfoBox = getAncestorByClass(parent, "netInfoBody"); | |
var file = netInfoBox.repObject; | |
var viewSource; | |
viewSource = $$(".request", rootNode)[0]; | |
if (file.requestHeadersText) { | |
removeClass(viewSource, "collapsed") | |
} | |
viewSource = $$(".response", rootNode)[0]; | |
if (file.responseHeadersText) { | |
removeClass(viewSource, "collapsed") | |
} | |
}, | |
renderHeaders: function(parent, headers, rowName) { | |
if (!parent.firstChild) { | |
this.init(parent) | |
} | |
this.insertHeaderRows(parent, headers, rowName) | |
} | |
}); | |
var NetInfoHeaders = Firebug.NetMonitor.NetInfoHeaders; | |
Firebug.NetMonitor.NetInfoPostData = domplate(Firebug.Rep, { | |
paramsTable: TABLE({ | |
"class": "netInfoPostParamsTable", | |
cellpadding: 0, | |
cellspacing: 0, | |
role: "presentation" | |
}, | |
TBODY({ | |
role: "list", | |
"aria-label": $STR("net.label.Parameters") | |
}, | |
TR({ | |
"class": "netInfoPostParamsTitle", | |
role: "presentation" | |
}, | |
TD({ | |
colspan: 3, | |
role: "presentation" | |
}, | |
DIV({ | |
"class": "netInfoPostParams" | |
}, | |
$STR("net.label.Parameters"), SPAN({ | |
"class": "netInfoPostContentType" | |
}, | |
"application/x-www-form-urlencoded")))))), | |
partsTable: TABLE({ | |
"class": "netInfoPostPartsTable", | |
cellpadding: 0, | |
cellspacing: 0, | |
role: "presentation" | |
}, | |
TBODY({ | |
role: "list", | |
"aria-label": $STR("net.label.Parts") | |
}, | |
TR({ | |
"class": "netInfoPostPartsTitle", | |
role: "presentation" | |
}, | |
TD({ | |
colspan: 2, | |
role: "presentation" | |
}, | |
DIV({ | |
"class": "netInfoPostParams" | |
}, | |
$STR("net.label.Parts"), SPAN({ | |
"class": "netInfoPostContentType" | |
}, | |
"multipart/form-data")))))), | |
jsonTable: TABLE({ | |
"class": "netInfoPostJSONTable", | |
cellpadding: 0, | |
cellspacing: 0, | |
role: "presentation" | |
}, | |
TBODY({ | |
role: "list", | |
"aria-label": $STR("JSON") | |
}, | |
TR({ | |
"class": "netInfoPostJSONTitle", | |
role: "presentation" | |
}, | |
TD({ | |
role: "presentation" | |
}, | |
DIV({ | |
"class": "netInfoPostParams" | |
}, | |
$STR("JSON")))), TR(TD({ | |
"class": "netInfoPostJSONBody" | |
})))), | |
xmlTable: TABLE({ | |
"class": "netInfoPostXMLTable", | |
cellpadding: 0, | |
cellspacing: 0, | |
role: "presentation" | |
}, | |
TBODY({ | |
role: "list", | |
"aria-label": $STR("xmlviewer.tab.XML") | |
}, | |
TR({ | |
"class": "netInfoPostXMLTitle", | |
role: "presentation" | |
}, | |
TD({ | |
role: "presentation" | |
}, | |
DIV({ | |
"class": "netInfoPostParams" | |
}, | |
$STR("xmlviewer.tab.XML")))), TR(TD({ | |
"class": "netInfoPostXMLBody" | |
})))), | |
sourceTable: TABLE({ | |
"class": "netInfoPostSourceTable", | |
cellpadding: 0, | |
cellspacing: 0, | |
role: "presentation" | |
}, | |
TBODY({ | |
role: "list", | |
"aria-label": $STR("net.label.Source") | |
}, | |
TR({ | |
"class": "netInfoPostSourceTitle", | |
role: "presentation" | |
}, | |
TD({ | |
colspan: 2, | |
role: "presentation" | |
}, | |
DIV({ | |
"class": "netInfoPostSource" | |
}, | |
$STR("net.label.Source")))))), | |
sourceBodyTag: TR({ | |
role: "presentation" | |
}, | |
TD({ | |
colspan: 2, | |
role: "presentation" | |
}, | |
FOR("line", "$param|getParamValueIterator", CODE({ | |
"class": "focusRow subFocusRow", | |
role: "listitem" | |
}, | |
"$line")))), | |
getParamValueIterator: function(param) { | |
return NetInfoBody.getParamValueIterator(param) | |
}, | |
render: function(context, parentNode, file) { | |
var spy = getAncestorByClass(parentNode, "spyHead"); | |
var spyObject = spy.repObject; | |
var data = spyObject.data; | |
var contentType = file.mimeType; | |
if (contentType && contentType == "application/x-www-form-urlencoded" || data && data.indexOf("=") != -1) { | |
var params = parseURLEncodedTextArray(data); | |
if (params) { | |
this.insertParameters(parentNode, params) | |
} | |
} | |
var jsonData = { | |
responseText: data | |
}; | |
if (Firebug.JSONViewerModel.isJSON(contentType, data)) { | |
this.insertJSON(parentNode, jsonData, context) | |
} | |
var postText = data; | |
if (postText) { | |
this.insertSource(parentNode, postText) | |
} | |
}, | |
insertParameters: function(parentNode, params) { | |
if (!params || !params.length) { | |
return | |
} | |
var paramTable = this.paramsTable.append({ | |
object: {} | |
}, | |
parentNode); | |
var row = $$(".netInfoPostParamsTitle", paramTable)[0]; | |
var tbody = paramTable.getElementsByTagName("tbody")[0]; | |
NetInfoBody.headerDataTag.insertRows({ | |
headers: params | |
}, | |
row) | |
}, | |
insertParts: function(parentNode, data) { | |
if (!data.params || !data.params.length) { | |
return | |
} | |
var partsTable = this.partsTable.append({ | |
object: {} | |
}, | |
parentNode); | |
var row = $$(".netInfoPostPartsTitle", paramTable)[0]; | |
NetInfoBody.headerDataTag.insertRows({ | |
headers: data.params | |
}, | |
row) | |
}, | |
insertJSON: function(parentNode, file, context) { | |
var text = file.responseText; | |
var data = parseJSONString(text); | |
if (!data) { | |
return | |
} | |
var jsonTable = this.jsonTable.append({}, | |
parentNode); | |
var jsonBody = $$(".netInfoPostJSONBody", jsonTable)[0]; | |
if (!this.toggles) { | |
this.toggles = {} | |
} | |
Firebug.DOMPanel.DirTable.tag.replace({ | |
object: data, | |
toggles: this.toggles | |
}, | |
jsonBody) | |
}, | |
insertXML: function(parentNode, file, context) { | |
var text = Utils.getPostText(file, context); | |
var jsonTable = this.xmlTable.append(null, parentNode); | |
var jsonBody = $$(".netInfoPostXMLBody", jsonTable)[0]; | |
Firebug.XMLViewerModel.insertXML(jsonBody, text) | |
}, | |
insertSource: function(parentNode, text) { | |
var sourceTable = this.sourceTable.append({ | |
object: {} | |
}, | |
parentNode); | |
var row = $$(".netInfoPostSourceTitle", sourceTable)[0]; | |
var param = { | |
value: [text] | |
}; | |
this.sourceBodyTag.insertRows({ | |
param: param | |
}, | |
row) | |
}, | |
parseMultiPartText: function(file, context) { | |
var text = Utils.getPostText(file, context); | |
if (text == undefined) { | |
return null | |
} | |
FBTrace.sysout("net.parseMultiPartText; boundary: ", text); | |
var boundary = text.match(/\s*boundary=\s*(.*)/)[1]; | |
var divider = "\r\n\r\n"; | |
var bodyStart = text.indexOf(divider); | |
var body = text.substr(bodyStart + divider.length); | |
var postData = {}; | |
postData.mimeType = "multipart/form-data"; | |
postData.params = []; | |
var parts = body.split("--" + boundary); | |
for (var i = 0; i < parts.length; i++) { | |
var part = parts[i].split(divider); | |
if (part.length != 2) { | |
continue | |
} | |
var m = part[0].match(/\s*name=\"(.*)\"(;|$)/); | |
postData.params.push({ | |
name: (m && m.length > 1) ? m[1] : "", | |
value: trim(part[1]) | |
}) | |
} | |
return postData | |
} | |
}); | |
var NetInfoPostData = Firebug.NetMonitor.NetInfoPostData; | |
var $STRP = function(a) { | |
return a | |
}; | |
Firebug.NetMonitor.NetLimit = domplate(Firebug.Rep, { | |
collapsed: true, | |
tableTag: DIV(TABLE({ | |
width: "100%", | |
cellpadding: 0, | |
cellspacing: 0 | |
}, | |
TBODY())), | |
limitTag: TR({ | |
"class": "netRow netLimitRow", | |
$collapsed: "$isCollapsed" | |
}, | |
TD({ | |
"class": "netCol netLimitCol", | |
colspan: 6 | |
}, | |
TABLE({ | |
cellpadding: 0, | |
cellspacing: 0 | |
}, | |
TBODY(TR(TD(SPAN({ | |
"class": "netLimitLabel" | |
}, | |
$STRP("plural.Limit_Exceeded", [0]))), TD({ | |
style: "width:100%" | |
}), TD(BUTTON({ | |
"class": "netLimitButton", | |
title: "$limitPrefsTitle", | |
onclick: "$onPreferences" | |
}, | |
$STR("LimitPrefs"))), TD(" ")))))), | |
isCollapsed: function() { | |
return this.collapsed | |
}, | |
onPreferences: function(event) { | |
openNewTab("about:config") | |
}, | |
updateCounter: function(row) { | |
removeClass(row, "collapsed"); | |
var limitLabel = row.getElementsByClassName("netLimitLabel").item(0); | |
limitLabel.firstChild.nodeValue = $STRP("plural.Limit_Exceeded", [row.limitInfo.totalCount]) | |
}, | |
createTable: function(parent, limitInfo) { | |
var table = this.tableTag.replace({}, | |
parent); | |
var row = this.createRow(table.firstChild.firstChild, limitInfo); | |
return [table, row] | |
}, | |
createRow: function(parent, limitInfo) { | |
var row = this.limitTag.insertRows(limitInfo, parent, this)[0]; | |
row.limitInfo = limitInfo; | |
return row | |
}, | |
observe: function(subject, topic, data) { | |
if (topic != "nsPref:changed") { | |
return | |
} | |
if (data.indexOf("net.logLimit") != -1) { | |
this.updateMaxLimit() | |
} | |
}, | |
updateMaxLimit: function() { | |
var value = Firebug.getPref(Firebug.prefDomain, "net.logLimit"); | |
maxQueueRequests = value ? value: maxQueueRequests | |
} | |
}); | |
var NetLimit = Firebug.NetMonitor.NetLimit; | |
Firebug.NetMonitor.ResponseSizeLimit = domplate(Firebug.Rep, { | |
tag: DIV({ | |
"class": "netInfoResponseSizeLimit" | |
}, | |
SPAN("$object.beforeLink"), A({ | |
"class": "objectLink", | |
onclick: "$onClickLink" | |
}, | |
"$object.linkText"), SPAN("$object.afterLink")), | |
reLink: /^(.*)<a>(.*)<\/a>(.*$)/, | |
append: function(obj, parent) { | |
var m = obj.text.match(this.reLink); | |
return this.tag.append({ | |
onClickLink: obj.onClickLink, | |
object: { | |
beforeLink: m[1], | |
linkText: m[2], | |
afterLink: m[3] | |
} | |
}, | |
parent, this) | |
} | |
}); | |
Firebug.NetMonitor.Utils = { | |
findHeader: function(headers, name) { | |
if (!headers) { | |
return null | |
} | |
name = name.toLowerCase(); | |
for (var i = 0; i < headers.length; ++i) { | |
var headerName = headers[i].name.toLowerCase(); | |
if (headerName == name) { | |
return headers[i].value | |
} | |
} | |
}, | |
formatPostText: function(text) { | |
if (text instanceof XMLDocument) { | |
return getElementXML(text.documentElement) | |
} else { | |
return text | |
} | |
}, | |
getPostText: function(file, context, noLimit) { | |
if (!file.postText) { | |
file.postText = readPostTextFromRequest(file.request, context); | |
if (!file.postText && context) { | |
file.postText = readPostTextFromPage(file.href, context) | |
} | |
} | |
if (!file.postText) { | |
return file.postText | |
} | |
var limit = Firebug.netDisplayedPostBodyLimit; | |
if (file.postText.length > limit && !noLimit) { | |
return cropString(file.postText, limit, "\n\n... " + $STR("net.postDataSizeLimitMessage") + " ...\n\n") | |
} | |
return file.postText | |
}, | |
getResponseText: function(file, context) { | |
return (typeof(file.responseText) != "undefined") ? file.responseText: context.sourceCache.loadText(file.href, file.method, file) | |
}, | |
isURLEncodedRequest: function(file, context) { | |
var text = Utils.getPostText(file, context); | |
if (text && text.toLowerCase().indexOf("content-type: application/x-www-form-urlencoded") == 0) { | |
return true | |
} | |
var headerValue = Utils.findHeader(file.requestHeaders, "content-type"); | |
if (headerValue && headerValue.indexOf("application/x-www-form-urlencoded") == 0) { | |
return true | |
} | |
return false | |
}, | |
isMultiPartRequest: function(file, context) { | |
var text = Utils.getPostText(file, context); | |
if (text && text.toLowerCase().indexOf("content-type: multipart/form-data") == 0) { | |
return true | |
} | |
return false | |
}, | |
getMimeType: function(mimeType, uri) { | |
if (!mimeType || !(mimeCategoryMap.hasOwnProperty(mimeType))) { | |
var ext = getFileExtension(uri); | |
if (!ext) { | |
return mimeType | |
} else { | |
var extMimeType = mimeExtensionMap[ext.toLowerCase()]; | |
return extMimeType ? extMimeType: mimeType | |
} | |
} else { | |
return mimeType | |
} | |
}, | |
getDateFromSeconds: function(s) { | |
var d = new Date(); | |
d.setTime(s * 1000); | |
return d | |
}, | |
getHttpHeaders: function(request, file) { | |
try { | |
var http = QI(request, Ci.nsIHttpChannel); | |
file.status = request.responseStatus; | |
file.method = http.requestMethod; | |
file.urlParams = parseURLParams(file.href); | |
file.mimeType = Utils.getMimeType(request.contentType, request.name); | |
if (!file.responseHeaders && Firebug.collectHttpHeaders) { | |
var requestHeaders = [], | |
responseHeaders = []; | |
http.visitRequestHeaders({ | |
visitHeader: function(name, value) { | |
requestHeaders.push({ | |
name: name, | |
value: value | |
}) | |
} | |
}); | |
http.visitResponseHeaders({ | |
visitHeader: function(name, value) { | |
responseHeaders.push({ | |
name: name, | |
value: value | |
}) | |
} | |
}); | |
file.requestHeaders = requestHeaders; | |
file.responseHeaders = responseHeaders | |
} | |
} catch(exc) { | |
if (FBTrace.DBG_ERRORS) { | |
FBTrace.sysout("net.getHttpHeaders FAILS " + file.href, exc) | |
} | |
} | |
}, | |
isXHR: function(request) { | |
try { | |
var callbacks = request.notificationCallbacks; | |
var xhrRequest = callbacks ? callbacks.getInterface(Ci.nsIXMLHttpRequest) : null; | |
if (FBTrace.DBG_NET) { | |
FBTrace.sysout("net.isXHR; " + (xhrRequest != null) + ", " + safeGetName(request)) | |
} | |
return (xhrRequest != null) | |
} catch(exc) {} | |
return false | |
}, | |
getFileCategory: function(file) { | |
if (file.category) { | |
if (FBTrace.DBG_NET) { | |
FBTrace.sysout("net.getFileCategory; current: " + file.category + " for: " + file.href, file) | |
} | |
return file.category | |
} | |
if (file.isXHR) { | |
if (FBTrace.DBG_NET) { | |
FBTrace.sysout("net.getFileCategory; XHR for: " + file.href, file) | |
} | |
return file.category = "xhr" | |
} | |
if (!file.mimeType) { | |
var ext = getFileExtension(file.href); | |
if (ext) { | |
file.mimeType = mimeExtensionMap[ext.toLowerCase()] | |
} | |
} | |
if (!file.mimeType) { | |
return "" | |
} | |
var mimeType = file.mimeType; | |
if (mimeType) { | |
mimeType = mimeType.split(";")[0] | |
} | |
return (file.category = mimeCategoryMap[mimeType]) | |
} | |
}; | |
var Utils = Firebug.NetMonitor.Utils; | |
Firebug.registerModule(Firebug.NetMonitor) | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
var contexts = []; | |
Firebug.Spy = extend(Firebug.Module, { | |
dispatchName: "spy", | |
initialize: function() { | |
if (Firebug.TraceModule) { | |
Firebug.TraceModule.addListener(this.TraceListener) | |
} | |
Firebug.Module.initialize.apply(this, arguments) | |
}, | |
shutdown: function() { | |
Firebug.Module.shutdown.apply(this, arguments); | |
if (Firebug.TraceModule) { | |
Firebug.TraceModule.removeListener(this.TraceListener) | |
} | |
}, | |
initContext: function(context) { | |
context.spies = []; | |
if (Firebug.showXMLHttpRequests && Firebug.Console.isAlwaysEnabled()) { | |
this.attachObserver(context, context.window) | |
} | |
if (FBTrace.DBG_SPY) { | |
FBTrace.sysout("spy.initContext " + contexts.length + " ", context.getName()) | |
} | |
}, | |
destroyContext: function(context) { | |
this.detachObserver(context, null); | |
if (FBTrace.DBG_SPY && context.spies.length) { | |
FBTrace.sysout("spy.destroyContext; ERROR There are leaking Spies (" + context.spies.length + ") " + context.getName()) | |
} | |
delete context.spies; | |
if (FBTrace.DBG_SPY) { | |
FBTrace.sysout("spy.destroyContext " + contexts.length + " ", context.getName()) | |
} | |
}, | |
watchWindow: function(context, win) { | |
if (Firebug.showXMLHttpRequests && Firebug.Console.isAlwaysEnabled()) { | |
this.attachObserver(context, win) | |
} | |
}, | |
unwatchWindow: function(context, win) { | |
try { | |
this.detachObserver(context, win) | |
} catch(ex) { | |
ERROR(ex) | |
} | |
}, | |
updateOption: function(name, value) { | |
if (name == "showXMLHttpRequests") { | |
var tach = value ? this.attachObserver: this.detachObserver; | |
for (var i = 0; i < TabWatcher.contexts.length; ++i) { | |
var context = TabWatcher.contexts[i]; | |
iterateWindows(context.window, | |
function(win) { | |
tach.apply(this, [context, win]) | |
}) | |
} | |
} | |
}, | |
skipSpy: function(win) { | |
if (!win) { | |
return true | |
} | |
var uri = safeGetWindowLocation(win); | |
if (uri && (uri.indexOf("about:") == 0 || uri.indexOf("chrome:") == 0)) { | |
return true | |
} | |
}, | |
attachObserver: function(context, win) { | |
if (Firebug.Spy.skipSpy(win)) { | |
return | |
} | |
for (var i = 0; i < contexts.length; ++i) { | |
if ((contexts[i].context == context) && (contexts[i].win == win)) { | |
return | |
} | |
} | |
if (contexts.length == 0) { | |
httpObserver.addObserver(SpyHttpObserver, "firebug-http-event", false); | |
SpyHttpActivityObserver.registerObserver() | |
} | |
contexts.push({ | |
context: context, | |
win: win | |
}); | |
if (FBTrace.DBG_SPY) { | |
FBTrace.sysout("spy.attachObserver (HTTP) " + contexts.length + " ", context.getName()) | |
} | |
}, | |
detachObserver: function(context, win) { | |
for (var i = 0; i < contexts.length; ++i) { | |
if (contexts[i].context == context) { | |
if (win && (contexts[i].win != win)) { | |
continue | |
} | |
contexts.splice(i, 1); | |
if (contexts.length == 0) { | |
httpObserver.removeObserver(SpyHttpObserver, "firebug-http-event"); | |
SpyHttpActivityObserver.unregisterObserver() | |
} | |
if (FBTrace.DBG_SPY) { | |
FBTrace.sysout("spy.detachObserver (HTTP) " + contexts.length + " ", context.getName()) | |
} | |
return | |
} | |
} | |
}, | |
getXHR: function(request) { | |
if (! (request instanceof Ci.nsIHttpChannel)) { | |
return null | |
} | |
try { | |
var callbacks = request.notificationCallbacks; | |
return (callbacks ? callbacks.getInterface(Ci.nsIXMLHttpRequest) : null) | |
} catch(exc) { | |
if (exc.name == "NS_NOINTERFACE") { | |
if (FBTrace.DBG_SPY) { | |
FBTrace.sysout("spy.getXHR; Request is not nsIXMLHttpRequest: " + safeGetRequestName(request)) | |
} | |
} | |
} | |
return null | |
} | |
}); | |
Firebug.Spy.XHR = domplate(Firebug.Rep, { | |
tag: DIV({ | |
"class": "spyHead", | |
_repObject: "$object" | |
}, | |
TABLE({ | |
"class": "spyHeadTable focusRow outerFocusRow", | |
cellpadding: 0, | |
cellspacing: 0, | |
role: "listitem", | |
"aria-expanded": "false" | |
}, | |
TBODY({ | |
role: "presentation" | |
}, | |
TR({ | |
"class": "spyRow" | |
}, | |
TD({ | |
"class": "spyTitleCol spyCol", | |
onclick: "$onToggleBody" | |
}, | |
DIV({ | |
"class": "spyTitle" | |
}, | |
"$object|getCaption"), DIV({ | |
"class": "spyFullTitle spyTitle" | |
}, | |
"$object|getFullUri")), TD({ | |
"class": "spyCol" | |
}, | |
DIV({ | |
"class": "spyStatus" | |
}, | |
"$object|getStatus")), TD({ | |
"class": "spyCol" | |
}, | |
SPAN({ | |
"class": "spyIcon" | |
})), TD({ | |
"class": "spyCol" | |
}, | |
SPAN({ | |
"class": "spyTime" | |
})), TD({ | |
"class": "spyCol" | |
}, | |
TAG(FirebugReps.SourceLink.tag, { | |
object: "$object.sourceLink" | |
})))))), | |
getCaption: function(spy) { | |
return spy.method.toUpperCase() + " " + cropString(spy.getURL(), 100) | |
}, | |
getFullUri: function(spy) { | |
return spy.method.toUpperCase() + " " + spy.getURL() | |
}, | |
getStatus: function(spy) { | |
var text = ""; | |
if (spy.statusCode) { | |
text += spy.statusCode + " " | |
} | |
if (spy.statusText) { | |
return text += spy.statusText | |
} | |
return text | |
}, | |
onToggleBody: function(event) { | |
var target = event.currentTarget || event.srcElement; | |
var logRow = getAncestorByClass(target, "logRow-spy"); | |
if (isLeftClick(event)) { | |
toggleClass(logRow, "opened"); | |
var spy = getChildByClass(logRow, "spyHead").repObject; | |
var spyHeadTable = getAncestorByClass(target, "spyHeadTable"); | |
if (hasClass(logRow, "opened")) { | |
updateHttpSpyInfo(spy, logRow); | |
if (spyHeadTable) { | |
spyHeadTable.setAttribute("aria-expanded", "true") | |
} | |
} else {} | |
} | |
}, | |
copyURL: function(spy) { | |
copyToClipboard(spy.getURL()) | |
}, | |
copyParams: function(spy) { | |
var text = spy.postText; | |
if (!text) { | |
return | |
} | |
var url = reEncodeURL(spy, text, true); | |
copyToClipboard(url) | |
}, | |
copyResponse: function(spy) { | |
copyToClipboard(spy.responseText) | |
}, | |
openInTab: function(spy) { | |
openNewTab(spy.getURL(), spy.postText) | |
}, | |
supportsObject: function(object) { | |
return false; | |
return object instanceof Firebug.Spy.XMLHttpRequestSpy | |
}, | |
browseObject: function(spy, context) { | |
var url = spy.getURL(); | |
openNewTab(url); | |
return true | |
}, | |
getRealObject: function(spy, context) { | |
return spy.xhrRequest | |
}, | |
getContextMenuItems: function(spy) { | |
var items = [{ | |
label: "CopyLocation", | |
command: bindFixed(this.copyURL, this, spy) | |
}]; | |
if (spy.postText) { | |
items.push({ | |
label: "CopyLocationParameters", | |
command: bindFixed(this.copyParams, this, spy) | |
}) | |
} | |
items.push({ | |
label: "CopyResponse", | |
command: bindFixed(this.copyResponse, this, spy) | |
}, | |
"-", { | |
label: "OpenInTab", | |
command: bindFixed(this.openInTab, this, spy) | |
}); | |
return items | |
} | |
}); | |
function updateTime(spy) { | |
var timeBox = spy.logRow.getElementsByClassName("spyTime").item(0); | |
if (spy.responseTime) { | |
timeBox.textContent = " " + formatTime(spy.responseTime) | |
} | |
} | |
function updateLogRow(spy) { | |
updateTime(spy); | |
var statusBox = spy.logRow.getElementsByClassName("spyStatus").item(0); | |
statusBox.textContent = Firebug.Spy.XHR.getStatus(spy); | |
removeClass(spy.logRow, "loading"); | |
setClass(spy.logRow, "loaded"); | |
try { | |
var errorRange = Math.floor(spy.xhrRequest.status / 100); | |
if (errorRange == 4 || errorRange == 5) { | |
setClass(spy.logRow, "error") | |
} | |
} catch(exc) {} | |
} | |
var updateHttpSpyInfo = function updateHttpSpyInfo(spy, logRow) { | |
if (!spy.logRow && logRow) { | |
spy.logRow = logRow | |
} | |
if (!spy.logRow || !hasClass(spy.logRow, "opened")) { | |
return | |
} | |
if (!spy.params) { | |
spy.params = parseURLParams(spy.href + "") | |
} | |
if (!spy.requestHeaders) { | |
spy.requestHeaders = getRequestHeaders(spy) | |
} | |
if (!spy.responseHeaders && spy.loaded) { | |
spy.responseHeaders = getResponseHeaders(spy) | |
} | |
var template = Firebug.NetMonitor.NetInfoBody; | |
var netInfoBox = getChildByClass(spy.logRow, "spyHead", "netInfoBody"); | |
if (!netInfoBox) { | |
var head = getChildByClass(spy.logRow, "spyHead"); | |
netInfoBox = template.tag.append({ | |
file: spy | |
}, | |
head); | |
dispatch(template.fbListeners, "initTabBody", [netInfoBox, spy]); | |
template.selectTabByName(netInfoBox, "Response") | |
} else { | |
template.updateInfo(netInfoBox, spy, spy.context) | |
} | |
}; | |
function getRequestHeaders(spy) { | |
var headers = []; | |
var channel = spy.xhrRequest.channel; | |
if (channel instanceof Ci.nsIHttpChannel) { | |
channel.visitRequestHeaders({ | |
visitHeader: function(name, value) { | |
headers.push({ | |
name: name, | |
value: value | |
}) | |
} | |
}) | |
} | |
return headers | |
} | |
function getResponseHeaders(spy) { | |
var headers = []; | |
try { | |
var channel = spy.xhrRequest.channel; | |
if (channel instanceof Ci.nsIHttpChannel) { | |
channel.visitResponseHeaders({ | |
visitHeader: function(name, value) { | |
headers.push({ | |
name: name, | |
value: value | |
}) | |
} | |
}) | |
} | |
} catch(exc) { | |
if (FBTrace.DBG_SPY || FBTrace.DBG_ERRORS) { | |
FBTrace.sysout("spy.getResponseHeaders; EXCEPTION " + safeGetRequestName(spy.request), exc) | |
} | |
} | |
return headers | |
} | |
Firebug.registerModule(Firebug.Spy) | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
var contentTypes = { | |
"text/javascript": 1, | |
"text/x-javascript": 1, | |
"text/json": 1, | |
"text/x-json": 1, | |
"application/json": 1, | |
"application/x-json": 1, | |
"application/javascript": 1, | |
"application/x-javascript": 1, | |
"application/json-rpc": 1 | |
}; | |
Firebug.JSONViewerModel = extend(Firebug.Module, { | |
dispatchName: "jsonViewer", | |
initialize: function() { | |
Firebug.NetMonitor.NetInfoBody.addListener(this); | |
this.toggles = {} | |
}, | |
shutdown: function() { | |
Firebug.NetMonitor.NetInfoBody.removeListener(this) | |
}, | |
initTabBody: function(infoBox, file) { | |
if (FBTrace.DBG_JSONVIEWER) { | |
FBTrace.sysout("jsonviewer.initTabBody", infoBox) | |
} | |
dispatch(this.fbListeners, "onParseJSON", [file]); | |
if (!file.jsonObject) { | |
if (this.isJSON(file.mimeType, file.responseText)) { | |
file.jsonObject = this.parseJSON(file) | |
} | |
} | |
if (file.jsonObject && hasProperties(file.jsonObject)) { | |
Firebug.NetMonitor.NetInfoBody.appendTab(infoBox, "JSON", $STR("JSON")); | |
if (FBTrace.DBG_JSONVIEWER) { | |
FBTrace.sysout("jsonviewer.initTabBody; JSON object available " + (typeof(file.jsonObject) != "undefined"), file.jsonObject) | |
} | |
} | |
}, | |
isJSON: function(contentType, data) { | |
var responseText = data ? trim(data) : null; | |
if (responseText && responseText.indexOf("{") == 0) { | |
return true | |
} | |
if (!contentType) { | |
return false | |
} | |
contentType = contentType.split(";")[0]; | |
contentType = trim(contentType); | |
return contentTypes[contentType] | |
}, | |
updateTabBody: function(infoBox, file, context) { | |
var tab = infoBox.selectedTab; | |
var tabBody = $$(".netInfoJSONText", infoBox)[0]; | |
if (!hasClass(tab, "netInfoJSONTab") || tabBody.updated) { | |
return | |
} | |
tabBody.updated = true; | |
if (file.jsonObject) { | |
Firebug.DOMPanel.DirTable.tag.replace({ | |
object: file.jsonObject, | |
toggles: this.toggles | |
}, | |
tabBody) | |
} | |
}, | |
parseJSON: function(file) { | |
var jsonString = new String(file.responseText); | |
return parseJSONString(jsonString) | |
} | |
}); | |
Firebug.registerModule(Firebug.JSONViewerModel) | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
var xmlContentTypes = ["text/xml", "application/xml", "application/xhtml+xml", "application/rss+xml", "application/atom+xml", , "application/vnd.mozilla.maybe.feed", "application/rdf+xml", "application/vnd.mozilla.xul+xml"]; | |
Firebug.XMLViewerModel = extend(Firebug.Module, { | |
dispatchName: "xmlViewer", | |
initialize: function() { | |
Firebug.Module.initialize.apply(this, arguments); | |
Firebug.NetMonitor.NetInfoBody.addListener(this) | |
}, | |
shutdown: function() { | |
Firebug.Module.shutdown.apply(this, arguments); | |
Firebug.NetMonitor.NetInfoBody.removeListener(this) | |
}, | |
initTabBody: function(infoBox, file) { | |
if (FBTrace.DBG_XMLVIEWER) { | |
FBTrace.sysout("xmlviewer.initTabBody", infoBox) | |
} | |
if (this.isXML(file.mimeType, file.responseText)) { | |
Firebug.NetMonitor.NetInfoBody.appendTab(infoBox, "XML", $STR("XML")); | |
if (FBTrace.DBG_XMLVIEWER) { | |
FBTrace.sysout("xmlviewer.initTabBody; XML response available") | |
} | |
} | |
}, | |
isXML: function(contentType) { | |
if (!contentType) { | |
return false | |
} | |
for (var i = 0; i < xmlContentTypes.length; i++) { | |
if (contentType.indexOf(xmlContentTypes[i]) == 0) { | |
return true | |
} | |
} | |
return false | |
}, | |
updateTabBody: function(infoBox, file, context) { | |
var tab = infoBox.selectedTab; | |
var tabBody = $$(".netInfoXMLText", infoBox)[0]; | |
if (!hasClass(tab, "netInfoXMLTab") || tabBody.updated) { | |
return | |
} | |
tabBody.updated = true; | |
this.insertXML(tabBody, Firebug.NetMonitor.Utils.getResponseText(file, context)) | |
}, | |
insertXML: function(parentNode, text) { | |
var xmlText = text.replace(/^\s*<?.+?>\s*/, ""); | |
var div = parentNode.ownerDocument.createElement("div"); | |
div.innerHTML = xmlText; | |
var root = div.getElementsByTagName("*")[0]; | |
if (FBTrace.DBG_XMLVIEWER) { | |
FBTrace.sysout("xmlviewer.updateTabBody; XML response parsed", doc) | |
} | |
var html = []; | |
Firebug.Reps.appendNode(root, html); | |
parentNode.innerHTML = html.join("") | |
} | |
}); | |
Firebug.XMLViewerModel.ParseError = domplate(Firebug.Rep, { | |
tag: DIV({ | |
"class": "xmlInfoError" | |
}, | |
DIV({ | |
"class": "xmlInfoErrorMsg" | |
}, | |
"$error.message"), PRE({ | |
"class": "xmlInfoErrorSource" | |
}, | |
"$error|getSource")), | |
getSource: function(error) { | |
var parts = error.source.split("\n"); | |
if (parts.length != 2) { | |
return error.source | |
} | |
var limit = 50; | |
var column = parts[1].length; | |
if (column >= limit) { | |
parts[0] = "..." + parts[0].substr(column - limit); | |
parts[1] = "..." + parts[1].substr(column - limit) | |
} | |
if (parts[0].length > 80) { | |
parts[0] = parts[0].substr(0, 80) + "..." | |
} | |
return parts.join("\n") | |
} | |
}); | |
Firebug.registerModule(Firebug.XMLViewerModel) | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
var consoleQueue = []; | |
var lastHighlightedObject; | |
var FirebugContext = Env.browser; | |
var maxQueueRequests = 500; | |
Firebug.ConsoleBase = { | |
log: function(object, context, className, rep, noThrottle, sourceLink) { | |
return this.logRow(appendObject, object, context, className, rep, sourceLink, noThrottle) | |
}, | |
logFormatted: function(objects, context, className, noThrottle, sourceLink) { | |
return this.logRow(appendFormatted, objects, context, className, null, sourceLink, noThrottle) | |
}, | |
openGroup: function(objects, context, className, rep, noThrottle, sourceLink, noPush) { | |
return this.logRow(appendOpenGroup, objects, context, className, rep, sourceLink, noThrottle) | |
}, | |
closeGroup: function(context, noThrottle) { | |
return this.logRow(appendCloseGroup, null, context, null, null, null, noThrottle, true) | |
}, | |
logRow: function(appender, objects, context, className, rep, sourceLink, noThrottle, noRow) { | |
noThrottle = true; | |
if (!context) { | |
context = FirebugContext | |
} | |
if (FBTrace.DBG_ERRORS && !context) { | |
FBTrace.sysout("Console.logRow has no context, skipping objects", objects) | |
} | |
if (!context) { | |
return | |
} | |
if (noThrottle || !context) { | |
var panel = this.getPanel(context); | |
if (panel) { | |
var row = panel.append(appender, objects, className, rep, sourceLink, noRow); | |
var container = panel.panelNode; | |
return row | |
} else { | |
consoleQueue.push([appender, objects, context, className, rep, sourceLink, noThrottle, noRow]) | |
} | |
} else { | |
if (!context.throttle) { | |
return | |
} | |
var args = [appender, objects, context, className, rep, sourceLink, true, noRow]; | |
context.throttle(this.logRow, this, args) | |
} | |
}, | |
appendFormatted: function(args, row, context) { | |
if (!context) { | |
context = FirebugContext | |
} | |
var panel = this.getPanel(context); | |
panel.appendFormatted(args, row) | |
}, | |
clear: function(context) { | |
if (!context) { | |
context = Firebug.context | |
} | |
var panel = this.getPanel(context, true); | |
if (panel) { | |
panel.clear() | |
} | |
}, | |
getPanel: function(context, noCreate) { | |
return Firebug.chrome ? Firebug.chrome.getPanel("Console") : null | |
} | |
}; | |
var ActivableConsole = extend(Firebug.ConsoleBase, { | |
isAlwaysEnabled: function() { | |
return true | |
} | |
}); | |
Firebug.Console = Firebug.Console = extend(ActivableConsole, { | |
dispatchName: "console", | |
error: function() { | |
Firebug.Console.logFormatted(arguments, Firebug.browser, "error") | |
}, | |
flush: function() { | |
dispatch(this.fbListeners, "flush", []); | |
for (var i = 0, | |
length = consoleQueue.length; i < length; i++) { | |
var args = consoleQueue[i]; | |
this.logRow.apply(this, args) | |
} | |
}, | |
showPanel: function(browser, panel) {}, | |
getFirebugConsoleElement: function(context, win) { | |
var element = win.document.getElementById("_firebugConsole"); | |
if (!element) { | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("getFirebugConsoleElement forcing element") | |
} | |
var elementForcer = "(function(){var r=null; try { r = window._getFirebugConsoleElement();}catch(exc){r=exc;} return r;})();"; | |
if (context.stopped) { | |
Firebug.Console.injector.evaluateConsoleScript(context) | |
} else { | |
var r = Firebug.CommandLine.evaluateInWebPage(elementForcer, context, win) | |
} | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("getFirebugConsoleElement forcing element result " + r, r) | |
} | |
var element = win.document.getElementById("_firebugConsole"); | |
if (!element) { | |
if (FBTrace.DBG_ERRORS) { | |
FBTrace.sysout("console.getFirebugConsoleElement: no _firebugConsole in win:", win) | |
} | |
Firebug.Console.logFormatted(["Firebug cannot find _firebugConsole element", r, win], context, "error", true) | |
} | |
} | |
return element | |
}, | |
isReadyElsePreparing: function(context, win) { | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("console.isReadyElsePreparing, win is " + (win ? "an argument: ": "null, context.window: ") + (win ? win.location: context.window.location), (win ? win: context.window)) | |
} | |
if (win) { | |
return this.injector.attachIfNeeded(context, win) | |
} else { | |
var attached = true; | |
for (var i = 0; i < context.windows.length; i++) { | |
attached = attached && this.injector.attachIfNeeded(context, context.windows[i]) | |
} | |
if (context.windows.indexOf(context.window) == -1) { | |
FBTrace.sysout("isReadyElsePreparing ***************** context.window not in context.windows") | |
} | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("console.isReadyElsePreparing attached to " + context.windows.length + " and returns " + attached) | |
} | |
return attached | |
} | |
}, | |
initialize: function() { | |
this.panelName = "console" | |
}, | |
enable: function() { | |
if (Firebug.Console.isAlwaysEnabled()) { | |
this.watchForErrors() | |
} | |
}, | |
disable: function() { | |
if (Firebug.Console.isAlwaysEnabled()) { | |
this.unwatchForErrors() | |
} | |
}, | |
initContext: function(context, persistedState) { | |
Firebug.ActivableModule.initContext.apply(this, arguments); | |
context.consoleReloadWarning = true | |
}, | |
loadedContext: function(context) { | |
for (var url in context.sourceFileMap) { | |
return | |
} | |
this.clearReloadWarning(context) | |
}, | |
clearReloadWarning: function(context) { | |
if (context.consoleReloadWarning) { | |
var panel = context.getPanel(this.panelName); | |
panel.clearReloadWarning(); | |
delete context.consoleReloadWarning | |
} | |
}, | |
togglePersist: function(context) { | |
var panel = context.getPanel(this.panelName); | |
panel.persistContent = panel.persistContent ? false: true; | |
Firebug.chrome.setGlobalAttribute("cmd_togglePersistConsole", "checked", panel.persistContent) | |
}, | |
showContext: function(browser, context) { | |
Firebug.chrome.setGlobalAttribute("cmd_clearConsole", "disabled", !context); | |
Firebug.ActivableModule.showContext.apply(this, arguments) | |
}, | |
destroyContext: function(context, persistedState) { | |
Firebug.Console.injector.detachConsole(context, context.window) | |
}, | |
onPanelEnable: function(panelName) { | |
if (panelName != this.panelName) { | |
return | |
} | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("console.onPanelEnable**************") | |
} | |
this.watchForErrors(); | |
Firebug.Debugger.addDependentModule(this) | |
}, | |
onPanelDisable: function(panelName) { | |
if (panelName != this.panelName) { | |
return | |
} | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("console.onPanelDisable**************") | |
} | |
Firebug.Debugger.removeDependentModule(this); | |
this.unwatchForErrors(); | |
this.clear() | |
}, | |
onSuspendFirebug: function() { | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("console.onSuspendFirebug\n") | |
} | |
if (Firebug.Console.isAlwaysEnabled()) { | |
this.unwatchForErrors() | |
} | |
}, | |
onResumeFirebug: function() { | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("console.onResumeFirebug\n") | |
} | |
if (Firebug.Console.isAlwaysEnabled()) { | |
this.watchForErrors() | |
} | |
}, | |
watchForErrors: function() { | |
Firebug.Errors.checkEnabled(); | |
$("fbStatusIcon").setAttribute("console", "on") | |
}, | |
unwatchForErrors: function() { | |
Firebug.Errors.checkEnabled(); | |
$("fbStatusIcon").removeAttribute("console") | |
}, | |
onMonitorScript: function(context, frame) { | |
Firebug.Console.log(frame, context) | |
}, | |
onFunctionCall: function(context, frame, depth, calling) { | |
if (calling) { | |
Firebug.Console.openGroup([frame, "depth:" + depth], context) | |
} else { | |
Firebug.Console.closeGroup(context) | |
} | |
}, | |
logRow: function(appender, objects, context, className, rep, sourceLink, noThrottle, noRow) { | |
if (!context) { | |
context = FirebugContext | |
} | |
if (FBTrace.DBG_WINDOWS && !context) { | |
FBTrace.sysout("Console.logRow: no context \n") | |
} | |
if (this.isAlwaysEnabled()) { | |
return Firebug.ConsoleBase.logRow.apply(this, arguments) | |
} | |
} | |
}); | |
Firebug.ConsoleListener = { | |
log: function(context, object, className, sourceLink) {}, | |
logFormatted: function(context, objects, className, sourceLink) {} | |
}; | |
Firebug.ConsolePanel = function() {}; | |
Firebug.ConsolePanel.prototype = extend(Firebug.Panel, { | |
wasScrolledToBottom: false, | |
messageCount: 0, | |
lastLogTime: 0, | |
groups: null, | |
limit: null, | |
append: function(appender, objects, className, rep, sourceLink, noRow) { | |
var container = this.getTopContainer(); | |
if (noRow) { | |
appender.apply(this, [objects]) | |
} else { | |
var row = this.createRow("logRow", className); | |
appender.apply(this, [objects, row, rep]); | |
if (sourceLink) { | |
FirebugReps.SourceLink.tag.append({ | |
object: sourceLink | |
}, | |
row) | |
} | |
container.appendChild(row); | |
this.filterLogRow(row, this.wasScrolledToBottom); | |
if (this.wasScrolledToBottom) { | |
scrollToBottom(this.panelNode) | |
} | |
return row | |
} | |
}, | |
clear: function() { | |
if (this.panelNode) { | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("ConsolePanel.clear") | |
} | |
clearNode(this.panelNode); | |
this.insertLogLimit(this.context) | |
} | |
}, | |
insertLogLimit: function() { | |
var row = this.createRow("limitRow"); | |
var limitInfo = { | |
totalCount: 0, | |
limitPrefsTitle: $STRF("LimitPrefsTitle", [Firebug.prefDomain + ".console.logLimit"]) | |
}; | |
return; | |
var netLimitRep = Firebug.NetMonitor.NetLimit; | |
var nodes = netLimitRep.createTable(row, limitInfo); | |
this.limit = nodes[1]; | |
var container = this.panelNode; | |
container.insertBefore(nodes[0], container.firstChild) | |
}, | |
insertReloadWarning: function() { | |
this.warningRow = this.append(appendObject, $STR("message.Reload to activate window console"), "info") | |
}, | |
clearReloadWarning: function() { | |
if (this.warningRow) { | |
this.warningRow.parentNode.removeChild(this.warningRow); | |
delete this.warningRow | |
} | |
}, | |
appendObject: function(object, row, rep) { | |
if (!rep) { | |
rep = Firebug.getRep(object) | |
} | |
return rep.tag.append({ | |
object: object | |
}, | |
row) | |
}, | |
appendFormatted: function(objects, row, rep) { | |
if (!objects || !objects.length) { | |
return | |
} | |
function logText(text, row) { | |
var node = row.ownerDocument.createTextNode(text); | |
row.appendChild(node) | |
} | |
var format = objects[0]; | |
var objIndex = 0; | |
if (typeof(format) != "string") { | |
format = ""; | |
objIndex = -1 | |
} else { | |
if (objects.length === 1) { | |
if (format.length < 1) { | |
logText("(an empty string)", row); | |
return | |
} | |
} | |
} | |
var parts = parseFormat(format); | |
var trialIndex = objIndex; | |
for (var i = 0; i < parts.length; i++) { | |
var part = parts[i]; | |
if (part && typeof(part) == "object") { | |
if (++trialIndex > objects.length) { | |
format = ""; | |
objIndex = -1; | |
parts.length = 0; | |
break | |
} | |
} | |
} | |
for (var i = 0; i < parts.length; ++i) { | |
var part = parts[i]; | |
if (part && typeof(part) == "object") { | |
var object = objects[++objIndex]; | |
if (typeof(object) != "undefined") { | |
this.appendObject(object, row, part.rep) | |
} else { | |
this.appendObject(part.type, row, FirebugReps.Text) | |
} | |
} else { | |
FirebugReps.Text.tag.append({ | |
object: part | |
}, | |
row) | |
} | |
} | |
for (var i = objIndex + 1; i < objects.length; ++i) { | |
logText(" ", row); | |
var object = objects[i]; | |
if (typeof(object) == "string") { | |
FirebugReps.Text.tag.append({ | |
object: object | |
}, | |
row) | |
} else { | |
this.appendObject(object, row) | |
} | |
} | |
}, | |
appendOpenGroup: function(objects, row, rep) { | |
if (!this.groups) { | |
this.groups = [] | |
} | |
setClass(row, "logGroup"); | |
setClass(row, "opened"); | |
var innerRow = this.createRow("logRow"); | |
setClass(innerRow, "logGroupLabel"); | |
if (rep) { | |
rep.tag.replace({ | |
objects: objects | |
}, | |
innerRow) | |
} else { | |
this.appendFormatted(objects, innerRow, rep) | |
} | |
row.appendChild(innerRow); | |
var groupBody = this.createRow("logGroupBody"); | |
row.appendChild(groupBody); | |
groupBody.setAttribute("role", "group"); | |
this.groups.push(groupBody); | |
addEvent(innerRow, "mousedown", | |
function(event) { | |
if (isLeftClick(event)) { | |
var target = event.target || event.srcElement; | |
target = getAncestorByClass(target, "logGroupLabel"); | |
var groupRow = target.parentNode; | |
if (hasClass(groupRow, "opened")) { | |
removeClass(groupRow, "opened"); | |
target.setAttribute("aria-expanded", "false") | |
} else { | |
setClass(groupRow, "opened"); | |
target.setAttribute("aria-expanded", "true") | |
} | |
} | |
}) | |
}, | |
appendCloseGroup: function(object, row, rep) { | |
if (this.groups) { | |
this.groups.pop() | |
} | |
}, | |
onMouseMove: function(event) { | |
if (!Firebug.Inspector) { | |
return | |
} | |
var target = event.srcElement || event.target; | |
var object = getAncestorByClass(target, "objectLink-element"); | |
object = object ? object.repObject: null; | |
if (object && instanceOf(object, "Element") && object.nodeType == 1) { | |
if (object != lastHighlightedObject) { | |
Firebug.Inspector.drawBoxModel(object); | |
object = lastHighlightedObject | |
} | |
} else { | |
Firebug.Inspector.hideBoxModel() | |
} | |
}, | |
onMouseDown: function(event) { | |
var target = event.srcElement || event.target; | |
var object = getAncestorByClass(target, "objectLink"); | |
var repObject = object ? object.repObject: null; | |
if (!repObject) { | |
return | |
} | |
if (hasClass(object, "objectLink-object")) { | |
Firebug.chrome.selectPanel("DOM"); | |
Firebug.chrome.getPanel("DOM").select(repObject, true) | |
} else { | |
if (hasClass(object, "objectLink-element")) { | |
Firebug.chrome.selectPanel("HTML"); | |
Firebug.chrome.getPanel("HTML").select(repObject, true) | |
} | |
} | |
}, | |
name: "Console", | |
title: "Console", | |
options: { | |
hasCommandLine: true, | |
hasToolButtons: true, | |
isPreRendered: true | |
}, | |
create: function() { | |
Firebug.Panel.create.apply(this, arguments); | |
this.context = Firebug.browser.window; | |
this.document = Firebug.chrome.document; | |
this.onMouseMove = bind(this.onMouseMove, this); | |
this.onMouseDown = bind(this.onMouseDown, this); | |
this.clearButton = new Button({ | |
element: $("fbConsole_btClear"), | |
owner: Firebug.Console, | |
onClick: Firebug.Console.clear | |
}) | |
}, | |
initialize: function() { | |
Firebug.Panel.initialize.apply(this, arguments); | |
if (!this.persistedContent && Firebug.Console.isAlwaysEnabled()) { | |
this.insertLogLimit(this.context); | |
this.updateMaxLimit(); | |
if (this.context.consoleReloadWarning) { | |
this.insertReloadWarning() | |
} | |
} | |
addEvent(this.panelNode, "mouseover", this.onMouseMove); | |
addEvent(this.panelNode, "mousedown", this.onMouseDown); | |
this.clearButton.initialize() | |
}, | |
initializeNode: function() { | |
if (FBTrace.DBG_CONSOLE) { | |
this.onScroller = bind(this.onScroll, this); | |
addEvent(this.panelNode, "scroll", this.onScroller) | |
} | |
this.onResizer = bind(this.onResize, this); | |
this.resizeEventTarget = Firebug.chrome.$("fbContentBox"); | |
addEvent(this.resizeEventTarget, "resize", this.onResizer) | |
}, | |
destroyNode: function() { | |
if (this.onScroller) { | |
removeEvent(this.panelNode, "scroll", this.onScroller) | |
} | |
}, | |
shutdown: function() { | |
this.clearButton.shutdown(); | |
removeEvent(this.panelNode, "mousemove", this.onMouseMove); | |
removeEvent(this.panelNode, "mousedown", this.onMouseDown); | |
this.destroyNode(); | |
Firebug.Panel.shutdown.apply(this, arguments) | |
}, | |
ishow: function(state) { | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("Console.panel show; " + this.context.getName(), state) | |
} | |
var enabled = Firebug.Console.isAlwaysEnabled(); | |
if (enabled) { | |
Firebug.Console.disabledPanelPage.hide(this); | |
this.showCommandLine(true); | |
this.showToolbarButtons("fbConsoleButtons", true); | |
Firebug.chrome.setGlobalAttribute("cmd_togglePersistConsole", "checked", this.persistContent); | |
if (state && state.wasScrolledToBottom) { | |
this.wasScrolledToBottom = state.wasScrolledToBottom; | |
delete state.wasScrolledToBottom | |
} | |
if (this.wasScrolledToBottom) { | |
scrollToBottom(this.panelNode) | |
} | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("console.show ------------------ wasScrolledToBottom: " + this.wasScrolledToBottom + ", " + this.context.getName()) | |
} | |
} else { | |
this.hide(state); | |
Firebug.Console.disabledPanelPage.show(this) | |
} | |
}, | |
ihide: function(state) { | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("Console.panel hide; " + this.context.getName(), state) | |
} | |
this.showToolbarButtons("fbConsoleButtons", false); | |
this.showCommandLine(false); | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("console.hide ------------------ wasScrolledToBottom: " + this.wasScrolledToBottom + ", " + this.context.getName()) | |
} | |
}, | |
destroy: function(state) { | |
if (this.panelNode.offsetHeight) { | |
this.wasScrolledToBottom = isScrolledToBottom(this.panelNode) | |
} | |
if (state) { | |
state.wasScrolledToBottom = this.wasScrolledToBottom | |
} | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("console.destroy ------------------ wasScrolledToBottom: " + this.wasScrolledToBottom + ", " + this.context.getName()) | |
} | |
}, | |
shouldBreakOnNext: function() { | |
return Firebug.getPref(Firebug.servicePrefDomain, "breakOnErrors") | |
}, | |
getBreakOnNextTooltip: function(enabled) { | |
return (enabled ? $STR("console.Disable Break On All Errors") : $STR("console.Break On All Errors")) | |
}, | |
enablePanel: function(module) { | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("console.ConsolePanel.enablePanel; " + this.context.getName()) | |
} | |
Firebug.ActivablePanel.enablePanel.apply(this, arguments); | |
this.showCommandLine(true); | |
if (this.wasScrolledToBottom) { | |
scrollToBottom(this.panelNode) | |
} | |
}, | |
disablePanel: function(module) { | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("console.ConsolePanel.disablePanel; " + this.context.getName()) | |
} | |
Firebug.ActivablePanel.disablePanel.apply(this, arguments); | |
this.showCommandLine(false) | |
}, | |
getOptionsMenuItems: function() { | |
return [optionMenu("ShowJavaScriptErrors", "showJSErrors"), optionMenu("ShowJavaScriptWarnings", "showJSWarnings"), optionMenu("ShowCSSErrors", "showCSSErrors"), optionMenu("ShowXMLErrors", "showXMLErrors"), optionMenu("ShowXMLHttpRequests", "showXMLHttpRequests"), optionMenu("ShowChromeErrors", "showChromeErrors"), optionMenu("ShowChromeMessages", "showChromeMessages"), optionMenu("ShowExternalErrors", "showExternalErrors"), optionMenu("ShowNetworkErrors", "showNetworkErrors"), this.getShowStackTraceMenuItem(), this.getStrictOptionMenuItem(), "-", optionMenu("LargeCommandLine", "largeCommandLine")] | |
}, | |
getShowStackTraceMenuItem: function() { | |
var menuItem = serviceOptionMenu("ShowStackTrace", "showStackTrace"); | |
if (FirebugContext && !Firebug.Debugger.isAlwaysEnabled()) { | |
menuItem.disabled = true | |
} | |
return menuItem | |
}, | |
getStrictOptionMenuItem: function() { | |
var strictDomain = "javascript.options"; | |
var strictName = "strict"; | |
var strictValue = prefs.getBoolPref(strictDomain + "." + strictName); | |
return { | |
label: "JavascriptOptionsStrict", | |
type: "checkbox", | |
checked: strictValue, | |
command: bindFixed(Firebug.setPref, Firebug, strictDomain, strictName, !strictValue) | |
} | |
}, | |
getBreakOnMenuItems: function() { | |
return [] | |
}, | |
search: function(text) { | |
if (!text) { | |
return | |
} | |
if (this.matchSet) { | |
for (var i in this.matchSet) { | |
removeClass(this.matchSet[i], "matched") | |
} | |
} | |
this.matchSet = []; | |
function findRow(node) { | |
return getAncestorByClass(node, "logRow") | |
} | |
var search = new TextSearch(this.panelNode, findRow); | |
var logRow = search.find(text); | |
if (!logRow) { | |
dispatch([Firebug.A11yModel], "onConsoleSearchMatchFound", [this, text, []]); | |
return false | |
} | |
for (; logRow; logRow = search.findNext()) { | |
setClass(logRow, "matched"); | |
this.matchSet.push(logRow) | |
} | |
dispatch([Firebug.A11yModel], "onConsoleSearchMatchFound", [this, text, this.matchSet]); | |
return true | |
}, | |
breakOnNext: function(breaking) { | |
Firebug.setPref(Firebug.servicePrefDomain, "breakOnErrors", breaking) | |
}, | |
createRow: function(rowName, className) { | |
var elt = this.document.createElement("div"); | |
elt.className = rowName + (className ? " " + rowName + "-" + className: ""); | |
return elt | |
}, | |
getTopContainer: function() { | |
if (this.groups && this.groups.length) { | |
return this.groups[this.groups.length - 1] | |
} else { | |
return this.panelNode | |
} | |
}, | |
filterLogRow: function(logRow, scrolledToBottom) { | |
if (this.searchText) { | |
setClass(logRow, "matching"); | |
setClass(logRow, "matched"); | |
setTimeout(bindFixed(function() { | |
if (this.searchFilter(this.searchText, logRow)) { | |
this.matchSet.push(logRow) | |
} else { | |
removeClass(logRow, "matched") | |
} | |
removeClass(logRow, "matching"); | |
if (scrolledToBottom) { | |
scrollToBottom(this.panelNode) | |
} | |
}, | |
this), 100) | |
} | |
}, | |
searchFilter: function(text, logRow) { | |
var count = this.panelNode.childNodes.length; | |
var searchRange = this.document.createRange(); | |
searchRange.setStart(this.panelNode, 0); | |
searchRange.setEnd(this.panelNode, count); | |
var startPt = this.document.createRange(); | |
startPt.setStartBefore(logRow); | |
var endPt = this.document.createRange(); | |
endPt.setStartAfter(logRow); | |
return finder.Find(text, searchRange, startPt, endPt) != null | |
}, | |
observe: function(subject, topic, data) { | |
if (topic != "nsPref:changed") { | |
return | |
} | |
var prefDomain = "Firebug.extension."; | |
var prefName = data.substr(prefDomain.length); | |
if (prefName == "console.logLimit") { | |
this.updateMaxLimit() | |
} | |
}, | |
updateMaxLimit: function() { | |
var value = 1000; | |
maxQueueRequests = value ? value: maxQueueRequests | |
}, | |
showCommandLine: function(shouldShow) { | |
return; | |
if (shouldShow) { | |
collapse(Firebug.chrome.$("fbCommandBox"), false); | |
Firebug.CommandLine.setMultiLine(Firebug.largeCommandLine, Firebug.chrome) | |
} else { | |
Firebug.CommandLine.setMultiLine(false, Firebug.chrome, Firebug.largeCommandLine); | |
collapse(Firebug.chrome.$("fbCommandBox"), true) | |
} | |
}, | |
onScroll: function(event) { | |
this.wasScrolledToBottom = FBL.isScrolledToBottom(this.panelNode); | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("console.onScroll ------------------ wasScrolledToBottom: " + this.wasScrolledToBottom + ", wasScrolledToBottom: " + this.context.getName(), event) | |
} | |
}, | |
onResize: function(event) { | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("console.onResize ------------------ wasScrolledToBottom: " + this.wasScrolledToBottom + ", offsetHeight: " + this.panelNode.offsetHeight + ", scrollTop: " + this.panelNode.scrollTop + ", scrollHeight: " + this.panelNode.scrollHeight + ", " + this.context.getName(), event) | |
} | |
if (this.wasScrolledToBottom) { | |
scrollToBottom(this.panelNode) | |
} | |
} | |
}); | |
function parseFormat(format) { | |
var parts = []; | |
if (format.length <= 0) { | |
return parts | |
} | |
var reg = /((^%|.%)(\d+)?(\.)([a-zA-Z]))|((^%|.%)([a-zA-Z]))/; | |
for (var m = reg.exec(format); m; m = reg.exec(format)) { | |
if (m[0].substr(0, 2) == "%%") { | |
parts.push(format.substr(0, m.index)); | |
parts.push(m[0].substr(1)) | |
} else { | |
var type = m[8] ? m[8] : m[5]; | |
var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0); | |
var rep = null; | |
switch (type) { | |
case "s": | |
rep = FirebugReps.Text; | |
break; | |
case "f": | |
case "i": | |
case "d": | |
rep = FirebugReps.Number; | |
break; | |
case "o": | |
rep = null; | |
break | |
} | |
parts.push(format.substr(0, m[0][0] == "%" ? m.index: m.index + 1)); | |
parts.push({ | |
rep: rep, | |
precision: precision, | |
type: ("%" + type) | |
}) | |
} | |
format = format.substr(m.index + m[0].length) | |
} | |
parts.push(format); | |
return parts | |
} | |
var appendObject = Firebug.ConsolePanel.prototype.appendObject; | |
var appendFormatted = Firebug.ConsolePanel.prototype.appendFormatted; | |
var appendOpenGroup = Firebug.ConsolePanel.prototype.appendOpenGroup; | |
var appendCloseGroup = Firebug.ConsolePanel.prototype.appendCloseGroup; | |
Firebug.registerModule(Firebug.Console); | |
Firebug.registerPanel(Firebug.ConsolePanel) | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
var frameCounters = {}; | |
var traceRecursion = 0; | |
Firebug.Console.injector = { | |
install: function(context) { | |
var win = context.window; | |
var consoleHandler = new FirebugConsoleHandler(context, win); | |
var properties = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupCollapsed", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd", "clear", "open", "close"]; | |
var Handler = function(name) { | |
var c = consoleHandler; | |
var f = consoleHandler[name]; | |
return function() { | |
return f.apply(c, arguments) | |
} | |
}; | |
var installer = function(c) { | |
for (var i = 0, | |
l = properties.length; i < l; i++) { | |
var name = properties[i]; | |
c[name] = new Handler(name); | |
c.firebuglite = Firebug.version | |
} | |
}; | |
var sandbox; | |
if (win.console) { | |
if (Env.Options.overrideConsole) { | |
sandbox = new win.Function("arguments.callee.install(window.console={})") | |
} else { | |
return | |
} | |
} else { | |
try { | |
sandbox = new win.Function("arguments.callee.install(window.console={})") | |
} catch(E) { | |
sandbox = new win.Function("arguments.callee.install(window.firebug={})") | |
} | |
} | |
sandbox.install = installer; | |
sandbox() | |
}, | |
isAttached: function(context, win) { | |
if (win.wrappedJSObject) { | |
var attached = (win.wrappedJSObject._getFirebugConsoleElement ? true: false); | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("Console.isAttached:" + attached + " to win.wrappedJSObject " + safeGetWindowLocation(win.wrappedJSObject)) | |
} | |
return attached | |
} else { | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("Console.isAttached? to win " + win.location + " fnc:" + win._getFirebugConsoleElement) | |
} | |
return (win._getFirebugConsoleElement ? true: false) | |
} | |
}, | |
attachIfNeeded: function(context, win) { | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("Console.attachIfNeeded has win " + (win ? ((win.wrappedJSObject ? "YES": "NO") + " wrappedJSObject") : "null")) | |
} | |
if (this.isAttached(context, win)) { | |
return true | |
} | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("Console.attachIfNeeded found isAttached false ") | |
} | |
this.attachConsoleInjector(context, win); | |
this.addConsoleListener(context, win); | |
Firebug.Console.clearReloadWarning(context); | |
var attached = this.isAttached(context, win); | |
if (attached) { | |
dispatch(Firebug.Console.fbListeners, "onConsoleInjected", [context, win]) | |
} | |
return attached | |
}, | |
attachConsoleInjector: function(context, win) { | |
var consoleInjection = this.getConsoleInjectionScript(); | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("attachConsoleInjector evaluating in " + win.location, consoleInjection) | |
} | |
Firebug.CommandLine.evaluateInWebPage(consoleInjection, context, win); | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("attachConsoleInjector evaluation completed for " + win.location) | |
} | |
}, | |
getConsoleInjectionScript: function() { | |
if (!this.consoleInjectionScript) { | |
var script = ""; | |
script += "window.__defineGetter__('console', function() {\n"; | |
script += " return (window._firebug ? window._firebug : window.loadFirebugConsole()); })\n\n"; | |
script += "window.loadFirebugConsole = function() {\n"; | |
script += "window._firebug = new _FirebugConsole();"; | |
if (FBTrace.DBG_CONSOLE) { | |
script += " window.dump('loadFirebugConsole '+window.location+'\\n');\n" | |
} | |
script += " return window._firebug };\n"; | |
var theFirebugConsoleScript = getResource("chrome://firebug/content/consoleInjected.js"); | |
script += theFirebugConsoleScript; | |
this.consoleInjectionScript = script | |
} | |
return this.consoleInjectionScript | |
}, | |
forceConsoleCompilationInPage: function(context, win) { | |
if (!win) { | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("no win in forceConsoleCompilationInPage!") | |
} | |
return | |
} | |
var consoleForcer = "window.loadFirebugConsole();"; | |
if (context.stopped) { | |
Firebug.Console.injector.evaluateConsoleScript(context) | |
} else { | |
Firebug.CommandLine.evaluateInWebPage(consoleForcer, context, win) | |
} | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("forceConsoleCompilationInPage " + win.location, consoleForcer) | |
} | |
}, | |
evaluateConsoleScript: function(context) { | |
var scriptSource = this.getConsoleInjectionScript(); | |
Firebug.Debugger.evaluate(scriptSource, context) | |
}, | |
addConsoleListener: function(context, win) { | |
if (!context.activeConsoleHandlers) { | |
context.activeConsoleHandlers = [] | |
} else { | |
for (var i = 0; i < context.activeConsoleHandlers.length; i++) { | |
if (context.activeConsoleHandlers[i].window == win) { | |
context.activeConsoleHandlers[i].detach(); | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("consoleInjector addConsoleListener removed handler(" + context.activeConsoleHandlers[i].handler_name + ") from _firebugConsole in : " + win.location + "\n") | |
} | |
context.activeConsoleHandlers.splice(i, 1) | |
} | |
} | |
} | |
var element = Firebug.Console.getFirebugConsoleElement(context, win); | |
if (element) { | |
element.setAttribute("FirebugVersion", Firebug.version) | |
} else { | |
return false | |
} | |
var handler = new FirebugConsoleHandler(context, win); | |
handler.attachTo(element); | |
context.activeConsoleHandlers.push(handler); | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("consoleInjector addConsoleListener attached handler(" + handler.handler_name + ") to _firebugConsole in : " + win.location + "\n") | |
} | |
return true | |
}, | |
detachConsole: function(context, win) { | |
if (win && win.document) { | |
var element = win.document.getElementById("_firebugConsole"); | |
if (element) { | |
element.parentNode.removeChild(element) | |
} | |
} | |
} | |
}; | |
var total_handlers = 0; | |
var FirebugConsoleHandler = function FirebugConsoleHandler(context, win) { | |
this.window = win; | |
this.attachTo = function(element) { | |
this.element = element; | |
this.boundHandler = bind(this.handleEvent, this); | |
this.element.addEventListener("firebugAppendConsole", this.boundHandler, true) | |
}; | |
this.detach = function() { | |
this.element.removeEventListener("firebugAppendConsole", this.boundHandler, true) | |
}; | |
this.handler_name = ++total_handlers; | |
this.handleEvent = function(event) { | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("FirebugConsoleHandler(" + this.handler_name + ") " + event.target.getAttribute("methodName") + ", event", event) | |
} | |
if (!Firebug.CommandLine.CommandHandler.handle(event, this, win)) { | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("FirebugConsoleHandler", this) | |
} | |
var methodName = event.target.getAttribute("methodName"); | |
Firebug.Console.log($STRF("console.MethodNotSupported", [methodName])) | |
} | |
}; | |
this.firebuglite = Firebug.version; | |
this.init = function() { | |
var consoleElement = win.document.getElementById("_firebugConsole"); | |
consoleElement.setAttribute("FirebugVersion", Firebug.version) | |
}; | |
this.log = function() { | |
logFormatted(arguments, "log") | |
}; | |
this.debug = function() { | |
logFormatted(arguments, "debug", true) | |
}; | |
this.info = function() { | |
logFormatted(arguments, "info", true) | |
}; | |
this.warn = function() { | |
logFormatted(arguments, "warn", true) | |
}; | |
this.error = function() { | |
logFormatted(arguments, "error", true) | |
}; | |
this.exception = function() { | |
logAssert("error", arguments) | |
}; | |
this.assert = function(x) { | |
if (!x) { | |
var rest = []; | |
for (var i = 1; i < arguments.length; i++) { | |
rest.push(arguments[i]) | |
} | |
logAssert("assert", rest) | |
} | |
}; | |
this.dir = function(o) { | |
Firebug.Console.log(o, context, "dir", Firebug.DOMPanel.DirTable) | |
}; | |
this.dirxml = function(o) { | |
if (instanceOf(o, "Window")) { | |
o = o.document.documentElement | |
} else { | |
if (instanceOf(o, "Document")) { | |
o = o.documentElement | |
} | |
} | |
Firebug.Console.log(o, context, "dirxml", Firebug.HTMLPanel.SoloElement) | |
}; | |
this.group = function() { | |
var sourceLink = null; | |
Firebug.Console.openGroup(arguments, null, "group", null, false, sourceLink) | |
}; | |
this.groupEnd = function() { | |
Firebug.Console.closeGroup(context) | |
}; | |
this.groupCollapsed = function() { | |
var sourceLink = getStackLink(); | |
var row = Firebug.Console.openGroup(arguments, null, "group", null, true, sourceLink); | |
removeClass(row, "opened") | |
}; | |
this.profile = function(title) { | |
logFormatted(["console.profile() not supported."], "warn", true) | |
}; | |
this.profileEnd = function() { | |
logFormatted(["console.profile() not supported."], "warn", true) | |
}; | |
this.count = function(key) { | |
var frameId = "0"; | |
if (frameId) { | |
if (!frameCounters) { | |
frameCounters = {} | |
} | |
if (key != undefined) { | |
frameId += key | |
} | |
var frameCounter = frameCounters[frameId]; | |
if (!frameCounter) { | |
var logRow = logFormatted(["0"], null, true, true); | |
frameCounter = { | |
logRow: logRow, | |
count: 1 | |
}; | |
frameCounters[frameId] = frameCounter | |
} else {++frameCounter.count | |
} | |
var label = key == undefined ? frameCounter.count: key + " " + frameCounter.count; | |
frameCounter.logRow.firstChild.firstChild.nodeValue = label | |
} | |
}; | |
this.trace = function() { | |
var getFuncName = function getFuncName(f) { | |
if (f.getName instanceof Function) { | |
return f.getName() | |
} | |
if (f.name) { | |
return f.name | |
} | |
var name = f.toString().match(/function\s*([_$\w\d]*)/)[1]; | |
return name || "anonymous" | |
}; | |
var wasVisited = function(fn) { | |
for (var i = 0, | |
l = frames.length; i < l; i++) { | |
if (frames[i].fn == fn) { | |
return true | |
} | |
} | |
return false | |
}; | |
traceRecursion++; | |
if (traceRecursion > 1) { | |
traceRecursion--; | |
return | |
} | |
var frames = []; | |
for (var fn = arguments.callee.caller.caller; fn; fn = fn.caller) { | |
if (wasVisited(fn)) { | |
break | |
} | |
var args = []; | |
for (var i = 0, | |
l = fn.arguments.length; i < l; ++i) { | |
args.push({ | |
value: fn.arguments[i] | |
}) | |
} | |
frames.push({ | |
fn: fn, | |
name: getFuncName(fn), | |
args: args | |
}) | |
} | |
try { (0)() | |
} catch(e) { | |
var result = e; | |
var stack = result.stack || result.stacktrace || ""; | |
stack = stack.replace(/\n\r|\r\n/g, "\n"); | |
var items = stack.split(/[\n\r]/); | |
if (FBL.isSafari) { | |
var reChromeStackItem = /^\s+at\s+(.*)((?:http|https|ftp|file):\/\/.*)$/; | |
var reChromeStackItemName = /\s*\($/; | |
var reChromeStackItemValue = /^(.+)\:(\d+\:\d+)\)?$/; | |
var framePos = 0; | |
for (var i = 4, | |
length = items.length; i < length; i++, framePos++) { | |
var frame = frames[framePos]; | |
var item = items[i]; | |
var match = item.match(reChromeStackItem); | |
if (match) { | |
var name = match[1]; | |
if (name) { | |
name = name.replace(reChromeStackItemName, ""); | |
frame.name = name | |
} | |
var value = match[2].match(reChromeStackItemValue); | |
if (value) { | |
frame.href = value[1]; | |
frame.lineNo = value[2] | |
} | |
} | |
} | |
} else { | |
if (FBL.isFirefox) { | |
var reFirefoxStackItem = /^(.*)@(.*)$/; | |
var reFirefoxStackItemValue = /^(.+)\:(\d+)$/; | |
var framePos = 0; | |
for (var i = 2, | |
length = items.length; i < length; i++, framePos++) { | |
var frame = frames[framePos] || {}; | |
var item = items[i]; | |
var match = item.match(reFirefoxStackItem); | |
if (match) { | |
var name = match[1]; | |
var value = match[2].match(reFirefoxStackItemValue); | |
if (value) { | |
frame.href = value[1]; | |
frame.lineNo = value[2] | |
} | |
} | |
} | |
} | |
} | |
} | |
Firebug.Console.log({ | |
frames: frames | |
}, | |
context, "stackTrace", FirebugReps.StackTrace); | |
traceRecursion-- | |
}; | |
this.trace_ok = function() { | |
var getFuncName = function getFuncName(f) { | |
if (f.getName instanceof Function) { | |
return f.getName() | |
} | |
if (f.name) { | |
return f.name | |
} | |
var name = f.toString().match(/function\s*([_$\w\d]*)/)[1]; | |
return name || "anonymous" | |
}; | |
var wasVisited = function(fn) { | |
for (var i = 0, | |
l = frames.length; i < l; i++) { | |
if (frames[i].fn == fn) { | |
return true | |
} | |
} | |
return false | |
}; | |
var frames = []; | |
for (var fn = arguments.callee.caller; fn; fn = fn.caller) { | |
if (wasVisited(fn)) { | |
break | |
} | |
var args = []; | |
for (var i = 0, | |
l = fn.arguments.length; i < l; ++i) { | |
args.push({ | |
value: fn.arguments[i] | |
}) | |
} | |
frames.push({ | |
fn: fn, | |
name: getFuncName(fn), | |
args: args | |
}) | |
} | |
Firebug.Console.log({ | |
frames: frames | |
}, | |
context, "stackTrace", FirebugReps.StackTrace) | |
}; | |
this.clear = function() { | |
Firebug.Console.clear(context) | |
}; | |
this.time = function(name, reset) { | |
if (!name) { | |
return | |
} | |
var time = new Date().getTime(); | |
if (!this.timeCounters) { | |
this.timeCounters = {} | |
} | |
var key = "KEY" + name.toString(); | |
if (!reset && this.timeCounters[key]) { | |
return | |
} | |
this.timeCounters[key] = time | |
}; | |
this.timeEnd = function(name) { | |
var time = new Date().getTime(); | |
if (!this.timeCounters) { | |
return | |
} | |
var key = "KEY" + name.toString(); | |
var timeCounter = this.timeCounters[key]; | |
if (timeCounter) { | |
var diff = time - timeCounter; | |
var label = name + ": " + diff + "ms"; | |
this.info(label); | |
delete this.timeCounters[key] | |
} | |
return diff | |
}; | |
this.evaluated = function(result, context) { | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("consoleInjector.FirebugConsoleHandler evalutated default called", result) | |
} | |
Firebug.Console.log(result, context) | |
}; | |
this.evaluateError = function(result, context) { | |
Firebug.Console.log(result, context, "errorMessage") | |
}; | |
function logFormatted(args, className, linkToSource, noThrottle) { | |
var sourceLink = linkToSource ? getStackLink() : null; | |
return Firebug.Console.logFormatted(args, context, className, noThrottle, sourceLink) | |
} | |
function logAssert(category, args) { | |
Firebug.Errors.increaseCount(context); | |
if (!args || !args.length || args.length == 0) { | |
var msg = [FBL.$STR("Assertion")] | |
} else { | |
var msg = args[0] | |
} | |
if (Firebug.errorStackTrace) { | |
var trace = Firebug.errorStackTrace; | |
delete Firebug.errorStackTrace; | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("logAssert trace from errorStackTrace", trace) | |
} | |
} else { | |
if (msg.stack) { | |
var trace = parseToStackTrace(msg.stack); | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("logAssert trace from msg.stack", trace) | |
} | |
} else { | |
var trace = getJSDUserStack(); | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("logAssert trace from getJSDUserStack", trace) | |
} | |
} | |
} | |
var errorObject = new FBL.ErrorMessage(msg, (msg.fileName ? msg.fileName: win.location), (msg.lineNumber ? msg.lineNumber: 0), "", category, context, trace); | |
if (trace && trace.frames && trace.frames[0]) { | |
errorObject.correctWithStackTrace(trace) | |
} | |
errorObject.resetSource(); | |
var objects = errorObject; | |
if (args.length > 1) { | |
objects = [errorObject]; | |
for (var i = 1; i < args.length; i++) { | |
objects.push(args[i]) | |
} | |
} | |
var row = Firebug.Console.log(objects, context, "errorMessage", null, true); | |
row.scrollIntoView() | |
} | |
function getComponentsStackDump() { | |
var frame = Components.stack; | |
var userURL = win.location.href.toString(); | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("consoleInjector.getComponentsStackDump initial stack for userURL " + userURL, frame) | |
} | |
while (frame && FBL.isSystemURL(frame.filename)) { | |
frame = frame.caller | |
} | |
if (frame) { | |
frame = frame.caller | |
} | |
if (frame) { | |
frame = frame.caller | |
} | |
if (FBTrace.DBG_CONSOLE) { | |
FBTrace.sysout("consoleInjector.getComponentsStackDump final stack for userURL " + userURL, frame) | |
} | |
return frame | |
} | |
function getStackLink() { | |
return | |
} | |
function getJSDUserStack() { | |
var trace = FBL.getCurrentStackTrace(context); | |
var frames = trace ? trace.frames: null; | |
if (frames && (frames.length > 0)) { | |
var oldest = frames.length - 1; | |
for (var i = 0; i < frames.length; i++) { | |
if (frames[oldest - i].href.indexOf("chrome:") == 0) { | |
break | |
} | |
var fn = frames[oldest - i].fn + ""; | |
if (fn && (fn.indexOf("_firebugEvalEvent") != -1)) { | |
break | |
} | |
} | |
FBTrace.sysout("consoleInjector getJSDUserStack: " + frames.length + " oldest: " + oldest + " i: " + i + " i - oldest + 2: " + (i - oldest + 2), trace); | |
trace.frames = trace.frames.slice(2 - i); | |
return trace | |
} else { | |
return "Firebug failed to get stack trace with any frames" | |
} | |
} | |
}; | |
FBL.registerConsole = function() { | |
var win = Env.browser.window; | |
Firebug.Console.injector.install(win) | |
}; | |
registerConsole() | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
var commandPrefix = ">>>"; | |
var reOpenBracket = /[\[\(\{]/; | |
var reCloseBracket = /[\]\)\}]/; | |
var commandHistory = []; | |
var commandPointer = -1; | |
var isAutoCompleting = null; | |
var autoCompletePrefix = null; | |
var autoCompleteExpr = null; | |
var autoCompleteBuffer = null; | |
var autoCompletePosition = null; | |
var fbCommandLine = null; | |
var fbLargeCommandLine = null; | |
var fbLargeCommandButtons = null; | |
var _completion = { | |
window: ["console"], | |
document: ["getElementById", "getElementsByTagName"] | |
}; | |
var _stack = function(command) { | |
Firebug.context.persistedState.commandHistory.push(command); | |
Firebug.context.persistedState.commandPointer = Firebug.context.persistedState.commandHistory.length | |
}; | |
Firebug.CommandLine = extend(Firebug.Module, { | |
element: null, | |
isMultiLine: false, | |
isActive: false, | |
initialize: function(doc) { | |
this.clear = bind(this.clear, this); | |
this.enter = bind(this.enter, this); | |
this.onError = bind(this.onError, this); | |
this.onKeyDown = bind(this.onKeyDown, this); | |
this.onMultiLineKeyDown = bind(this.onMultiLineKeyDown, this); | |
addEvent(Firebug.browser.window, "error", this.onError); | |
addEvent(Firebug.chrome.window, "error", this.onError) | |
}, | |
shutdown: function(doc) { | |
this.deactivate(); | |
removeEvent(Firebug.browser.window, "error", this.onError); | |
removeEvent(Firebug.chrome.window, "error", this.onError) | |
}, | |
activate: function(multiLine, hideToggleIcon, onRun) { | |
defineCommandLineAPI(); | |
Firebug.context.persistedState.commandHistory = Firebug.context.persistedState.commandHistory || []; | |
Firebug.context.persistedState.commandPointer = Firebug.context.persistedState.commandPointer || -1; | |
if (this.isActive) { | |
if (this.isMultiLine == multiLine) { | |
return | |
} | |
this.deactivate() | |
} | |
fbCommandLine = $("fbCommandLine"); | |
fbLargeCommandLine = $("fbLargeCommandLine"); | |
fbLargeCommandButtons = $("fbLargeCommandButtons"); | |
if (multiLine) { | |
onRun = onRun || this.enter; | |
this.isMultiLine = true; | |
this.element = fbLargeCommandLine; | |
addEvent(this.element, "keydown", this.onMultiLineKeyDown); | |
addEvent($("fbSmallCommandLineIcon"), "click", Firebug.chrome.hideLargeCommandLine); | |
this.runButton = new Button({ | |
element: $("fbCommand_btRun"), | |
owner: Firebug.CommandLine, | |
onClick: onRun | |
}); | |
this.runButton.initialize(); | |
this.clearButton = new Button({ | |
element: $("fbCommand_btClear"), | |
owner: Firebug.CommandLine, | |
onClick: this.clear | |
}); | |
this.clearButton.initialize() | |
} else { | |
this.isMultiLine = false; | |
this.element = fbCommandLine; | |
if (!fbCommandLine) { | |
return | |
} | |
addEvent(this.element, "keydown", this.onKeyDown) | |
} | |
if (isOpera) { | |
fixOperaTabKey(this.element) | |
} | |
if (this.lastValue) { | |
this.element.value = this.lastValue | |
} | |
this.isActive = true | |
}, | |
deactivate: function() { | |
if (!this.isActive) { | |
return | |
} | |
this.isActive = false; | |
this.lastValue = this.element.value; | |
if (this.isMultiLine) { | |
removeEvent(this.element, "keydown", this.onMultiLineKeyDown); | |
removeEvent($("fbSmallCommandLineIcon"), "click", Firebug.chrome.hideLargeCommandLine); | |
this.runButton.destroy(); | |
this.clearButton.destroy() | |
} else { | |
removeEvent(this.element, "keydown", this.onKeyDown) | |
} | |
this.element = null; | |
delete this.element; | |
fbCommandLine = null; | |
fbLargeCommandLine = null; | |
fbLargeCommandButtons = null | |
}, | |
focus: function() { | |
this.element.focus() | |
}, | |
blur: function() { | |
this.element.blur() | |
}, | |
clear: function() { | |
this.element.value = "" | |
}, | |
evaluate: function(expr) { | |
var api = "Firebug.CommandLine.API"; | |
var result = Firebug.context.evaluate(expr, "window", api, Firebug.Console.error); | |
return result | |
}, | |
enter: function() { | |
var command = this.element.value; | |
if (!command) { | |
return | |
} | |
_stack(command); | |
Firebug.Console.log(commandPrefix + " " + stripNewLines(command), Firebug.browser, "command", FirebugReps.Text); | |
var result = this.evaluate(command); | |
Firebug.Console.log(result) | |
}, | |
prevCommand: function() { | |
if (Firebug.context.persistedState.commandPointer > 0 && Firebug.context.persistedState.commandHistory.length > 0) { | |
this.element.value = Firebug.context.persistedState.commandHistory[--Firebug.context.persistedState.commandPointer] | |
} | |
}, | |
nextCommand: function() { | |
var element = this.element; | |
var limit = Firebug.context.persistedState.commandHistory.length - 1; | |
var i = Firebug.context.persistedState.commandPointer; | |
if (i < limit) { | |
element.value = Firebug.context.persistedState.commandHistory[++Firebug.context.persistedState.commandPointer] | |
} else { | |
if (i == limit) {++Firebug.context.persistedState.commandPointer; | |
element.value = "" | |
} | |
} | |
}, | |
autocomplete: function(reverse) { | |
var element = this.element; | |
var command = element.value; | |
var offset = getExpressionOffset(command); | |
var valBegin = offset ? command.substr(0, offset) : ""; | |
var val = command.substr(offset); | |
var buffer, obj, objName, commandBegin, result, prefix; | |
if (!isAutoCompleting) { | |
var reObj = /(.*[^_$\w\d\.])?((?:[_$\w][_$\w\d]*\.)*)([_$\w][_$\w\d]*)?$/; | |
var r = reObj.exec(val); | |
if (r[1] || r[2] || r[3]) { | |
commandBegin = r[1] || ""; | |
objName = r[2] || ""; | |
prefix = r[3] || "" | |
} else { | |
if (val == "") { | |
commandBegin = objName = prefix = "" | |
} else { | |
return | |
} | |
} | |
isAutoCompleting = true; | |
if (objName == "") { | |
obj = window | |
} else { | |
objName = objName.replace(/\.$/, ""); | |
var n = objName.split("."); | |
var target = window, | |
o; | |
for (var i = 0, | |
ni; ni = n[i]; i++) { | |
if (o = target[ni]) { | |
target = o | |
} else { | |
target = null; | |
break | |
} | |
} | |
obj = target | |
} | |
if (obj) { | |
autoCompletePrefix = prefix; | |
autoCompleteExpr = valBegin + commandBegin + (objName ? objName + ".": ""); | |
autoCompletePosition = -1; | |
buffer = autoCompleteBuffer = isIE ? _completion[objName || "window"] || [] : []; | |
for (var p in obj) { | |
buffer.push(p) | |
} | |
} | |
} else { | |
buffer = autoCompleteBuffer | |
} | |
if (buffer) { | |
prefix = autoCompletePrefix; | |
var diff = reverse ? -1 : 1; | |
for (var i = autoCompletePosition + diff, | |
l = buffer.length, | |
bi; i >= 0 && i < l; i += diff) { | |
bi = buffer[i]; | |
if (bi.indexOf(prefix) == 0) { | |
autoCompletePosition = i; | |
result = bi; | |
break | |
} | |
} | |
} | |
if (result) { | |
element.value = autoCompleteExpr + result | |
} | |
}, | |
setMultiLine: function(multiLine) { | |
if (multiLine == this.isMultiLine) { | |
return | |
} | |
this.activate(multiLine) | |
}, | |
onError: function(msg, href, lineNo) { | |
href = href || ""; | |
var lastSlash = href.lastIndexOf("/"); | |
var fileName = lastSlash == -1 ? href: href.substr(lastSlash + 1); | |
var html = ['<span class="errorMessage">', msg, "</span>", '<div class="objectBox-sourceLink">', fileName, " (line ", lineNo, ")</div>"] | |
}, | |
onKeyDown: function(e) { | |
e = e || event; | |
var code = e.keyCode; | |
if (code != 9 && code != 16 && code != 17 && code != 18) { | |
isAutoCompleting = false | |
} | |
if (code == 13) { | |
this.enter(); | |
this.clear() | |
} else { | |
if (code == 27) { | |
setTimeout(this.clear, 0) | |
} else { | |
if (code == 38) { | |
this.prevCommand() | |
} else { | |
if (code == 40) { | |
this.nextCommand() | |
} else { | |
if (code == 9) { | |
this.autocomplete(e.shiftKey) | |
} else { | |
return | |
} | |
} | |
} | |
} | |
} | |
cancelEvent(e, true); | |
return false | |
}, | |
onMultiLineKeyDown: function(e) { | |
e = e || event; | |
var code = e.keyCode; | |
if (code == 13 && e.ctrlKey) { | |
this.enter() | |
} | |
} | |
}); | |
Firebug.registerModule(Firebug.CommandLine); | |
function getExpressionOffset(command) { | |
var bracketCount = 0; | |
var start = command.length - 1; | |
for (; start >= 0; --start) { | |
var c = command[start]; | |
if ((c == "," || c == ";" || c == " ") && !bracketCount) { | |
break | |
} | |
if (reOpenBracket.test(c)) { | |
if (bracketCount) {--bracketCount | |
} else { | |
break | |
} | |
} else { | |
if (reCloseBracket.test(c)) {++bracketCount | |
} | |
} | |
} | |
return start + 1 | |
} | |
var CommandLineAPI = { | |
$: function(id) { | |
return Firebug.browser.document.getElementById(id) | |
}, | |
$$: function(selector, context) { | |
context = context || Firebug.browser.document; | |
return Firebug.Selector ? Firebug.Selector(selector, context) : Firebug.Console.error("Firebug.Selector module not loaded.") | |
}, | |
$0: null, | |
$1: null, | |
dir: function(o) { | |
Firebug.Console.log(o, Firebug.context, "dir", Firebug.DOMPanel.DirTable) | |
}, | |
dirxml: function(o) { | |
if (instanceOf(o, "Window")) { | |
o = o.document.documentElement | |
} else { | |
if (instanceOf(o, "Document")) { | |
o = o.documentElement | |
} | |
} | |
Firebug.Console.log(o, Firebug.context, "dirxml", Firebug.HTMLPanel.SoloElement) | |
} | |
}; | |
var defineCommandLineAPI = function defineCommandLineAPI() { | |
Firebug.CommandLine.API = {}; | |
for (var m in CommandLineAPI) { | |
if (!Env.browser.window[m]) { | |
Firebug.CommandLine.API[m] = CommandLineAPI[m] | |
} | |
} | |
var stack = FirebugChrome.htmlSelectionStack; | |
if (stack) { | |
Firebug.CommandLine.API.$0 = stack[0]; | |
Firebug.CommandLine.API.$1 = stack[1] | |
} | |
} | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
var ElementCache = Firebug.Lite.Cache.Element; | |
var cacheID = Firebug.Lite.Cache.ID; | |
var ignoreHTMLProps = { | |
sizcache: 1, | |
sizset: 1 | |
}; | |
if (Firebug.ignoreFirebugElements) { | |
ignoreHTMLProps[cacheID] = 1 | |
} | |
Firebug.HTML = extend(Firebug.Module, { | |
appendTreeNode: function(nodeArray, html) { | |
var reTrim = /^\s+|\s+$/g; | |
if (!nodeArray.length) { | |
nodeArray = [nodeArray] | |
} | |
for (var n = 0, | |
node; node = nodeArray[n]; n++) { | |
if (node.nodeType == 1) { | |
if (Firebug.ignoreFirebugElements && node.firebugIgnore) { | |
continue | |
} | |
var uid = ElementCache(node); | |
var child = node.childNodes; | |
var childLength = child.length; | |
var nodeName = node.nodeName.toLowerCase(); | |
var nodeVisible = isVisible(node); | |
var hasSingleTextChild = childLength == 1 && node.firstChild.nodeType == 3 && nodeName != "script" && nodeName != "style"; | |
var nodeControl = !hasSingleTextChild && childLength > 0 ? ('<div class="nodeControl"></div>') : ""; | |
if (isIE && nodeControl) { | |
html.push(nodeControl) | |
} | |
if (typeof uid != "undefined") { | |
html.push('<div class="objectBox-element" ', 'id="', uid, '">', !isIE && nodeControl ? nodeControl: "", "<span ", cacheID, '="', uid, '" class="nodeBox', nodeVisible ? "": " nodeHidden", '"><<span class="nodeTag">', nodeName, "</span>") | |
} else { | |
html.push('<div class="objectBox-element"><span class="nodeBox', nodeVisible ? "": " nodeHidden", '"><<span class="nodeTag">', nodeName, "</span>") | |
} | |
for (var i = 0; i < node.attributes.length; ++i) { | |
var attr = node.attributes[i]; | |
if (!attr.specified || isIE && (browserVersion - 0 < 9) && typeof attr.nodeValue != "string" || Firebug.ignoreFirebugElements && ignoreHTMLProps.hasOwnProperty(attr.nodeName)) { | |
continue | |
} | |
var name = attr.nodeName.toLowerCase(); | |
var value = name == "style" ? formatStyles(node.style.cssText) : attr.nodeValue; | |
html.push(' <span class="nodeName">', name, '</span>="<span class="nodeValue">', escapeHTML(value), "</span>"") | |
} | |
if (hasSingleTextChild) { | |
var value = child[0].nodeValue.replace(reTrim, ""); | |
if (value) { | |
html.push('><span class="nodeText">', escapeHTML(value), '</span></<span class="nodeTag">', nodeName, "</span>></span></div>") | |
} else { | |
html.push("/></span></div>") | |
} | |
} else { | |
if (childLength > 0) { | |
html.push("></span></div>") | |
} else { | |
html.push("/></span></div>") | |
} | |
} | |
} else { | |
if (node.nodeType == 3) { | |
if (node.parentNode && (node.parentNode.nodeName.toLowerCase() == "script" || node.parentNode.nodeName.toLowerCase() == "style")) { | |
var value = node.nodeValue.replace(reTrim, ""); | |
if (isIE) { | |
var src = value + "\n" | |
} else { | |
var src = "\n" + value + "\n" | |
} | |
var match = src.match(/\n/g); | |
var num = match ? match.length: 0; | |
var s = [], | |
sl = 0; | |
for (var c = 1; c < num; c++) { | |
s[sl++] = '<div line="' + c + '">' + c + "</div>" | |
} | |
html.push('<div class="lineNo">', s.join(""), '</div><pre class="sourceCode">', escapeHTML(src), "</pre>") | |
} else { | |
var value = node.nodeValue.replace(reTrim, ""); | |
if (value) { | |
html.push('<div class="nodeText">', escapeHTML(value), "</div>") | |
} | |
} | |
} | |
} | |
} | |
}, | |
appendTreeChildren: function(treeNode) { | |
var doc = Firebug.chrome.document; | |
var uid = treeNode.id; | |
var parentNode = ElementCache.get(uid); | |
if (parentNode.childNodes.length == 0) { | |
return | |
} | |
var treeNext = treeNode.nextSibling; | |
var treeParent = treeNode.parentNode; | |
var control = isIE ? treeNode.previousSibling: treeNode.firstChild; | |
control.className = "nodeControl nodeMaximized"; | |
var html = []; | |
var children = doc.createElement("div"); | |
children.className = "nodeChildren"; | |
this.appendTreeNode(parentNode.childNodes, html); | |
children.innerHTML = html.join(""); | |
treeParent.insertBefore(children, treeNext); | |
var closeElement = doc.createElement("div"); | |
closeElement.className = "objectBox-element"; | |
closeElement.innerHTML = '</<span class="nodeTag">' + parentNode.nodeName.toLowerCase() + "></span>"; | |
treeParent.insertBefore(closeElement, treeNext) | |
}, | |
removeTreeChildren: function(treeNode) { | |
var children = treeNode.nextSibling; | |
var closeTag = children.nextSibling; | |
var control = isIE ? treeNode.previousSibling: treeNode.firstChild; | |
control.className = "nodeControl"; | |
children.parentNode.removeChild(children); | |
closeTag.parentNode.removeChild(closeTag) | |
}, | |
isTreeNodeVisible: function(id) { | |
return $(id) | |
}, | |
select: function(el) { | |
var id = el && ElementCache(el); | |
if (id) { | |
this.selectTreeNode(id) | |
} | |
}, | |
selectTreeNode: function(id) { | |
id = "" + id; | |
var node, stack = []; | |
while (id && !this.isTreeNodeVisible(id)) { | |
stack.push(id); | |
var node = ElementCache.get(id).parentNode; | |
if (node) { | |
id = ElementCache(node) | |
} else { | |
break | |
} | |
} | |
stack.push(id); | |
while (stack.length > 0) { | |
id = stack.pop(); | |
node = $(id); | |
if (stack.length > 0 && ElementCache.get(id).childNodes.length > 0) { | |
this.appendTreeChildren(node) | |
} | |
} | |
selectElement(node); | |
if (fbPanel1) { | |
fbPanel1.scrollTop = Math.round(node.offsetTop - fbPanel1.clientHeight / 2) | |
} | |
} | |
}); | |
Firebug.registerModule(Firebug.HTML); | |
function HTMLPanel() {} | |
HTMLPanel.prototype = extend(Firebug.Panel, { | |
name: "HTML", | |
title: "HTML", | |
options: { | |
hasSidePanel: true, | |
isPreRendered: !Firebug.flexChromeEnabled, | |
innerHTMLSync: true | |
}, | |
create: function() { | |
Firebug.Panel.create.apply(this, arguments); | |
this.panelNode.style.padding = "4px 3px 1px 15px"; | |
this.panelNode.style.minWidth = "500px"; | |
if (Env.Options.enablePersistent || Firebug.chrome.type != "popup") { | |
this.createUI() | |
} | |
if (this.sidePanelBar && !this.sidePanelBar.selectedPanel) { | |
this.sidePanelBar.selectPanel("css") | |
} | |
}, | |
destroy: function() { | |
selectedElement = null; | |
fbPanel1 = null; | |
selectedSidePanelTS = null; | |
selectedSidePanelTimer = null; | |
Firebug.Panel.destroy.apply(this, arguments) | |
}, | |
createUI: function() { | |
var rootNode = Firebug.browser.document.documentElement; | |
var html = []; | |
Firebug.HTML.appendTreeNode(rootNode, html); | |
this.panelNode.innerHTML = html.join("") | |
}, | |
initialize: function() { | |
Firebug.Panel.initialize.apply(this, arguments); | |
addEvent(this.panelNode, "click", Firebug.HTML.onTreeClick); | |
fbPanel1 = $("fbPanel1"); | |
if (!selectedElement) { | |
Firebug.context.persistedState.selectedHTMLElementId = Firebug.context.persistedState.selectedHTMLElementId && ElementCache.get(Firebug.context.persistedState.selectedHTMLElementId) ? Firebug.context.persistedState.selectedHTMLElementId: ElementCache(Firebug.browser.document.body); | |
Firebug.HTML.selectTreeNode(Firebug.context.persistedState.selectedHTMLElementId) | |
} | |
addEvent(fbPanel1, "mousemove", Firebug.HTML.onListMouseMove); | |
addEvent($("fbContent"), "mouseout", Firebug.HTML.onListMouseMove); | |
addEvent(Firebug.chrome.node, "mouseout", Firebug.HTML.onListMouseMove) | |
}, | |
shutdown: function() { | |
removeEvent(fbPanel1, "mousemove", Firebug.HTML.onListMouseMove); | |
removeEvent($("fbContent"), "mouseout", Firebug.HTML.onListMouseMove); | |
removeEvent(Firebug.chrome.node, "mouseout", Firebug.HTML.onListMouseMove); | |
removeEvent(this.panelNode, "click", Firebug.HTML.onTreeClick); | |
fbPanel1 = null; | |
Firebug.Panel.shutdown.apply(this, arguments) | |
}, | |
reattach: function() { | |
if (Firebug.context.persistedState.selectedHTMLElementId) { | |
Firebug.HTML.selectTreeNode(Firebug.context.persistedState.selectedHTMLElementId) | |
} | |
}, | |
updateSelection: function(object) { | |
var id = ElementCache(object); | |
if (id) { | |
Firebug.HTML.selectTreeNode(id) | |
} | |
} | |
}); | |
Firebug.registerPanel(HTMLPanel); | |
var formatStyles = function(styles) { | |
return isIE ? styles.replace(/([^\s]+)\s*:/g, | |
function(m, g) { | |
return g.toLowerCase() + ":" | |
}) : styles | |
}; | |
var selectedElement = null; | |
var fbPanel1 = null; | |
var selectedSidePanelTS, selectedSidePanelTimer; | |
var selectElement = function selectElement(e) { | |
if (e != selectedElement) { | |
if (selectedElement) { | |
selectedElement.className = "objectBox-element" | |
} | |
e.className = e.className + " selectedElement"; | |
if (FBL.isFirefox) { | |
e.style.MozBorderRadius = "2px" | |
} else { | |
if (FBL.isSafari) { | |
e.style.WebkitBorderRadius = "2px" | |
} | |
} | |
e.style.borderRadius = "2px"; | |
selectedElement = e; | |
Firebug.context.persistedState.selectedHTMLElementId = e.id; | |
var target = ElementCache.get(e.id); | |
var sidePanelBar = Firebug.chrome.getPanel("HTML").sidePanelBar; | |
var selectedSidePanel = sidePanelBar ? sidePanelBar.selectedPanel: null; | |
var stack = FirebugChrome.htmlSelectionStack; | |
stack.unshift(target); | |
if (stack.length > 2) { | |
stack.pop() | |
} | |
var lazySelect = function() { | |
selectedSidePanelTS = new Date().getTime(); | |
if (selectedSidePanel) { | |
selectedSidePanel.select(target, true) | |
} | |
}; | |
if (selectedSidePanelTimer) { | |
clearTimeout(selectedSidePanelTimer); | |
selectedSidePanelTimer = null | |
} | |
if (new Date().getTime() - selectedSidePanelTS > 100) { | |
setTimeout(lazySelect, 0) | |
} else { | |
selectedSidePanelTimer = setTimeout(lazySelect, 150) | |
} | |
} | |
}; | |
Firebug.HTML.onTreeClick = function(e) { | |
e = e || event; | |
var targ; | |
if (e.target) { | |
targ = e.target | |
} else { | |
if (e.srcElement) { | |
targ = e.srcElement | |
} | |
} | |
if (targ.nodeType == 3) { | |
targ = targ.parentNode | |
} | |
if (targ.className.indexOf("nodeControl") != -1 || targ.className == "nodeTag") { | |
if (targ.className == "nodeTag") { | |
var control = isIE ? (targ.parentNode.previousSibling || targ) : (targ.parentNode.previousSibling || targ); | |
selectElement(targ.parentNode.parentNode); | |
if (control.className.indexOf("nodeControl") == -1) { | |
return | |
} | |
} else { | |
control = targ | |
} | |
FBL.cancelEvent(e); | |
var treeNode = isIE ? control.nextSibling: control.parentNode; | |
if (control.className.indexOf(" nodeMaximized") != -1) { | |
FBL.Firebug.HTML.removeTreeChildren(treeNode) | |
} else { | |
FBL.Firebug.HTML.appendTreeChildren(treeNode) | |
} | |
} else { | |
if (targ.className == "nodeValue" || targ.className == "nodeName") {} | |
} | |
}; | |
function onListMouseOut(e) { | |
e = e || event || window; | |
var targ; | |
if (e.target) { | |
targ = e.target | |
} else { | |
if (e.srcElement) { | |
targ = e.srcElement | |
} | |
} | |
if (targ.nodeType == 3) { | |
targ = targ.parentNode | |
} | |
if (hasClass(targ, "fbPanel")) { | |
FBL.Firebug.Inspector.hideBoxModel(); | |
hoverElement = null | |
} | |
} | |
var hoverElement = null; | |
var hoverElementTS = 0; | |
Firebug.HTML.onListMouseMove = function onListMouseMove(e) { | |
try { | |
e = e || event || window; | |
var targ; | |
if (e.target) { | |
targ = e.target | |
} else { | |
if (e.srcElement) { | |
targ = e.srcElement | |
} | |
} | |
if (targ.nodeType == 3) { | |
targ = targ.parentNode | |
} | |
var found = false; | |
while (targ && !found) { | |
if (!/\snodeBox\s|\sobjectBox-selector\s/.test(" " + targ.className + " ")) { | |
targ = targ.parentNode | |
} else { | |
found = true | |
} | |
} | |
if (!targ) { | |
FBL.Firebug.Inspector.hideBoxModel(); | |
hoverElement = null; | |
return | |
} | |
if (typeof targ.attributes[cacheID] == "undefined") { | |
return | |
} | |
var uid = targ.attributes[cacheID]; | |
if (!uid) { | |
return | |
} | |
var el = ElementCache.get(uid.value); | |
var nodeName = el.nodeName.toLowerCase(); | |
if (FBL.isIE && " meta title script link ".indexOf(" " + nodeName + " ") != -1) { | |
return | |
} | |
if (!/\snodeBox\s|\sobjectBox-selector\s/.test(" " + targ.className + " ")) { | |
return | |
} | |
if (el.id == "FirebugUI" || " html head body br script link iframe ".indexOf(" " + nodeName + " ") != -1) { | |
FBL.Firebug.Inspector.hideBoxModel(); | |
hoverElement = null; | |
return | |
} | |
if ((new Date().getTime() - hoverElementTS > 40) && hoverElement != el) { | |
hoverElementTS = new Date().getTime(); | |
hoverElement = el; | |
FBL.Firebug.Inspector.drawBoxModel(el) | |
} | |
} catch(E) {} | |
}; | |
Firebug.Reps = { | |
appendText: function(object, html) { | |
html.push(escapeHTML(objectToString(object))) | |
}, | |
appendNull: function(object, html) { | |
html.push('<span class="objectBox-null">', escapeHTML(objectToString(object)), "</span>") | |
}, | |
appendString: function(object, html) { | |
html.push('<span class="objectBox-string">"', escapeHTML(objectToString(object)), ""</span>") | |
}, | |
appendInteger: function(object, html) { | |
html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), "</span>") | |
}, | |
appendFloat: function(object, html) { | |
html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), "</span>") | |
}, | |
appendFunction: function(object, html) { | |
var reName = /function ?(.*?)\(/; | |
var m = reName.exec(objectToString(object)); | |
var name = m && m[1] ? m[1] : "function"; | |
html.push('<span class="objectBox-function">', escapeHTML(name), "()</span>") | |
}, | |
appendObject: function(object, html) { | |
try { | |
if (object == undefined) { | |
this.appendNull("undefined", html) | |
} else { | |
if (object == null) { | |
this.appendNull("null", html) | |
} else { | |
if (typeof object == "string") { | |
this.appendString(object, html) | |
} else { | |
if (typeof object == "number") { | |
this.appendInteger(object, html) | |
} else { | |
if (typeof object == "boolean") { | |
this.appendInteger(object, html) | |
} else { | |
if (typeof object == "function") { | |
this.appendFunction(object, html) | |
} else { | |
if (object.nodeType == 1) { | |
this.appendSelector(object, html) | |
} else { | |
if (typeof object == "object") { | |
if (typeof object.length != "undefined") { | |
this.appendArray(object, html) | |
} else { | |
this.appendObjectFormatted(object, html) | |
} | |
} else { | |
this.appendText(object, html) | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} catch(exc) {} | |
}, | |
appendObjectFormatted: function(object, html) { | |
var text = objectToString(object); | |
var reObject = /\[object (.*?)\]/; | |
var m = reObject.exec(text); | |
html.push('<span class="objectBox-object">', m ? m[1] : text, "</span>") | |
}, | |
appendSelector: function(object, html) { | |
var uid = ElementCache(object); | |
var uidString = uid ? [cacheID, '="', uid, '"'].join("") : ""; | |
html.push('<span class="objectBox-selector"', uidString, ">"); | |
html.push('<span class="selectorTag">', escapeHTML(object.nodeName.toLowerCase()), "</span>"); | |
if (object.id) { | |
html.push('<span class="selectorId">#', escapeHTML(object.id), "</span>") | |
} | |
if (object.className) { | |
html.push('<span class="selectorClass">.', escapeHTML(object.className), "</span>") | |
} | |
html.push("</span>") | |
}, | |
appendNode: function(node, html) { | |
if (node.nodeType == 1) { | |
var uid = ElementCache(node); | |
var uidString = uid ? [cacheID, '="', uid, '"'].join("") : ""; | |
html.push('<div class="objectBox-element"', uidString, '">', "<span ", cacheID, '="', uid, '" class="nodeBox">', '<<span class="nodeTag">', node.nodeName.toLowerCase(), "</span>"); | |
for (var i = 0; i < node.attributes.length; ++i) { | |
var attr = node.attributes[i]; | |
if (!attr.specified || attr.nodeName == cacheID) { | |
continue | |
} | |
var name = attr.nodeName.toLowerCase(); | |
var value = name == "style" ? node.style.cssText: attr.nodeValue; | |
html.push(' <span class="nodeName">', name, '</span>="<span class="nodeValue">', escapeHTML(value), "</span>"") | |
} | |
if (node.firstChild) { | |
html.push('></div><div class="nodeChildren">'); | |
for (var child = node.firstChild; child; child = child.nextSibling) { | |
this.appendNode(child, html) | |
} | |
html.push('</div><div class="objectBox-element"></<span class="nodeTag">', node.nodeName.toLowerCase(), "></span></span></div>") | |
} else { | |
html.push("/></span></div>") | |
} | |
} else { | |
if (node.nodeType == 3) { | |
var value = trim(node.nodeValue); | |
if (value) { | |
html.push('<div class="nodeText">', escapeHTML(value), "</div>") | |
} | |
} | |
} | |
}, | |
appendArray: function(object, html) { | |
html.push('<span class="objectBox-array"><b>[</b> '); | |
for (var i = 0, | |
l = object.length, | |
obj; i < l; ++i) { | |
this.appendObject(object[i], html); | |
if (i < l - 1) { | |
html.push(", ") | |
} | |
} | |
html.push(" <b>]</b></span>") | |
} | |
} | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
var maxWidth = 100, | |
maxHeight = 80; | |
var infoTipMargin = 10; | |
var infoTipWindowPadding = 25; | |
Firebug.InfoTip = extend(Firebug.Module, { | |
dispatchName: "infoTip", | |
tags: domplate({ | |
infoTipTag: DIV({ | |
"class": "infoTip" | |
}), | |
colorTag: DIV({ | |
style: "background: $rgbValue; width: 100px; height: 40px" | |
}, | |
" "), | |
imgTag: DIV({ | |
"class": "infoTipImageBox infoTipLoading" | |
}, | |
IMG({ | |
"class": "infoTipImage", | |
src: "$urlValue", | |
repeat: "$repeat", | |
onload: "$onLoadImage" | |
}), IMG({ | |
"class": "infoTipBgImage", | |
collapsed: true, | |
src: "blank.gif" | |
}), DIV({ | |
"class": "infoTipCaption" | |
})), | |
onLoadImage: function(event) { | |
var img = event.currentTarget || event.srcElement; | |
var innerBox = img.parentNode; | |
var caption = getElementByClass(innerBox, "infoTipCaption"); | |
var bgImg = getElementByClass(innerBox, "infoTipBgImage"); | |
if (!bgImg) { | |
return | |
} | |
if (isIE) { | |
removeClass(innerBox, "infoTipLoading") | |
} | |
var updateInfoTip = function() { | |
var w = img.naturalWidth || img.width || 10, | |
h = img.naturalHeight || img.height || 10; | |
var repeat = img.getAttribute("repeat"); | |
if (repeat == "repeat-x" || (w == 1 && h > 1)) { | |
collapse(img, true); | |
collapse(bgImg, false); | |
bgImg.style.background = "url(" + img.src + ") repeat-x"; | |
bgImg.style.width = maxWidth + "px"; | |
if (h > maxHeight) { | |
bgImg.style.height = maxHeight + "px" | |
} else { | |
bgImg.style.height = h + "px" | |
} | |
} else { | |
if (repeat == "repeat-y" || (h == 1 && w > 1)) { | |
collapse(img, true); | |
collapse(bgImg, false); | |
bgImg.style.background = "url(" + img.src + ") repeat-y"; | |
bgImg.style.height = maxHeight + "px"; | |
if (w > maxWidth) { | |
bgImg.style.width = maxWidth + "px" | |
} else { | |
bgImg.style.width = w + "px" | |
} | |
} else { | |
if (repeat == "repeat" || (w == 1 && h == 1)) { | |
collapse(img, true); | |
collapse(bgImg, false); | |
bgImg.style.background = "url(" + img.src + ") repeat"; | |
bgImg.style.width = maxWidth + "px"; | |
bgImg.style.height = maxHeight + "px" | |
} else { | |
if (w > maxWidth || h > maxHeight) { | |
if (w > h) { | |
img.style.width = maxWidth + "px"; | |
img.style.height = Math.round((h / w) * maxWidth) + "px" | |
} else { | |
img.style.width = Math.round((w / h) * maxHeight) + "px"; | |
img.style.height = maxHeight + "px" | |
} | |
} | |
} | |
} | |
} | |
caption.innerHTML = $STRF(w + " x " + h) | |
}; | |
if (isIE) { | |
setTimeout(updateInfoTip, 0) | |
} else { | |
updateInfoTip(); | |
removeClass(innerBox, "infoTipLoading") | |
} | |
} | |
}), | |
initializeBrowser: function(browser) { | |
browser.onInfoTipMouseOut = bind(this.onMouseOut, this, browser); | |
browser.onInfoTipMouseMove = bind(this.onMouseMove, this, browser); | |
var doc = browser.document; | |
if (!doc) { | |
return | |
} | |
addEvent(doc, "mouseover", browser.onInfoTipMouseMove); | |
addEvent(doc, "mouseout", browser.onInfoTipMouseOut); | |
addEvent(doc, "mousemove", browser.onInfoTipMouseMove); | |
return browser.infoTip = this.tags.infoTipTag.append({}, | |
getBody(doc)) | |
}, | |
uninitializeBrowser: function(browser) { | |
if (browser.infoTip) { | |
var doc = browser.document; | |
removeEvent(doc, "mouseover", browser.onInfoTipMouseMove); | |
removeEvent(doc, "mouseout", browser.onInfoTipMouseOut); | |
removeEvent(doc, "mousemove", browser.onInfoTipMouseMove); | |
browser.infoTip.parentNode.removeChild(browser.infoTip); | |
delete browser.infoTip; | |
delete browser.onInfoTipMouseMove | |
} | |
}, | |
showInfoTip: function(infoTip, panel, target, x, y, rangeParent, rangeOffset) { | |
if (!Firebug.showInfoTips) { | |
return | |
} | |
var scrollParent = getOverflowParent(target); | |
var scrollX = x + (scrollParent ? scrollParent.scrollLeft: 0); | |
if (panel.showInfoTip(infoTip, target, scrollX, y, rangeParent, rangeOffset)) { | |
var htmlElt = infoTip.ownerDocument.documentElement; | |
var panelWidth = htmlElt.clientWidth; | |
var panelHeight = htmlElt.clientHeight; | |
if (x + infoTip.offsetWidth + infoTipMargin > panelWidth) { | |
infoTip.style.left = Math.max(0, panelWidth - (infoTip.offsetWidth + infoTipMargin)) + "px"; | |
infoTip.style.right = "auto" | |
} else { | |
infoTip.style.left = (x + infoTipMargin) + "px"; | |
infoTip.style.right = "auto" | |
} | |
if (y + infoTip.offsetHeight + infoTipMargin > panelHeight) { | |
infoTip.style.top = Math.max(0, panelHeight - (infoTip.offsetHeight + infoTipMargin)) + "px"; | |
infoTip.style.bottom = "auto" | |
} else { | |
infoTip.style.top = (y + infoTipMargin) + "px"; | |
infoTip.style.bottom = "auto" | |
} | |
if (FBTrace.DBG_INFOTIP) { | |
FBTrace.sysout("infotip.showInfoTip; top: " + infoTip.style.top + ", left: " + infoTip.style.left + ", bottom: " + infoTip.style.bottom + ", right:" + infoTip.style.right + ", offsetHeight: " + infoTip.offsetHeight + ", offsetWidth: " + infoTip.offsetWidth + ", x: " + x + ", panelWidth: " + panelWidth + ", y: " + y + ", panelHeight: " + panelHeight) | |
} | |
infoTip.setAttribute("active", "true") | |
} else { | |
this.hideInfoTip(infoTip) | |
} | |
}, | |
hideInfoTip: function(infoTip) { | |
if (infoTip) { | |
infoTip.removeAttribute("active") | |
} | |
}, | |
onMouseOut: function(event, browser) { | |
if (!event.relatedTarget) { | |
this.hideInfoTip(browser.infoTip) | |
} | |
}, | |
onMouseMove: function(event, browser) { | |
if (getAncestorByClass(event.target, "infoTip")) { | |
return | |
} | |
if (browser.currentPanel) { | |
var x = event.clientX, | |
y = event.clientY, | |
target = event.target || event.srcElement; | |
this.showInfoTip(browser.infoTip, browser.currentPanel, target, x, y, event.rangeParent, event.rangeOffset) | |
} else { | |
this.hideInfoTip(browser.infoTip) | |
} | |
}, | |
populateColorInfoTip: function(infoTip, color) { | |
this.tags.colorTag.replace({ | |
rgbValue: color | |
}, | |
infoTip); | |
return true | |
}, | |
populateImageInfoTip: function(infoTip, url, repeat) { | |
if (!repeat) { | |
repeat = "no-repeat" | |
} | |
this.tags.imgTag.replace({ | |
urlValue: url, | |
repeat: repeat | |
}, | |
infoTip); | |
return true | |
}, | |
disable: function() {}, | |
showPanel: function(browser, panel) { | |
if (panel) { | |
var infoTip = panel.panelBrowser.infoTip; | |
if (!infoTip) { | |
infoTip = this.initializeBrowser(panel.panelBrowser) | |
} | |
this.hideInfoTip(infoTip) | |
} | |
}, | |
showSidePanel: function(browser, panel) { | |
this.showPanel(browser, panel) | |
} | |
}); | |
Firebug.registerModule(Firebug.InfoTip) | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
var CssParser = null; | |
CssParser = (function() { | |
function rule(start, body_start, end) { | |
return { | |
start: start || 0, | |
body_start: body_start || 0, | |
end: end || 0, | |
line: -1, | |
selector: null, | |
parent: null, | |
children: [], | |
addChild: function(start, body_start, end) { | |
var r = rule(start, body_start, end); | |
r.parent = this; | |
this.children.push(r); | |
return r | |
}, | |
lastChild: function() { | |
return this.children[this.children.length - 1] | |
} | |
} | |
} | |
function removeAll(str, re) { | |
var m; | |
while (m = str.match(re)) { | |
str = str.substring(m[0].length) | |
} | |
return str | |
} | |
function trim(str) { | |
return str.replace(/^\s+|\s+$/g, "") | |
} | |
function normalizeSelector(selector) { | |
selector = selector.replace(/[\n\r]/g, " "); | |
selector = trim(selector); | |
selector = selector.replace(/\s*,\s*/g, ","); | |
return selector | |
} | |
function preprocessRules(text, rule_node) { | |
for (var i = 0, | |
il = rule_node.children.length; i < il; i++) { | |
var r = rule_node.children[i], | |
rule_start = text.substring(r.start, r.body_start), | |
cur_len = rule_start.length; | |
rule_start = rule_start.replace(/[\n\r]/g, " "); | |
rule_start = removeAll(rule_start, /^\s*\/\*.*?\*\/[\s\t]*/); | |
rule_start = rule_start.replace(/^[\s\t]+/, ""); | |
r.start += (cur_len - rule_start.length); | |
r.selector = normalizeSelector(rule_start) | |
} | |
return rule_node | |
} | |
function saveLineIndexes(text) { | |
var result = [0], | |
i = 0, | |
il = text.length, | |
ch, | |
ch2; | |
while (i < il) { | |
ch = text.charAt(i); | |
if (ch == "\n" || ch == "\r") { | |
if (ch == "\r" && i < il - 1 && text.charAt(i + 1) == "\n") { | |
i++ | |
} | |
result.push(i + 1) | |
} | |
i++ | |
} | |
return result | |
} | |
function saveLineNumbers(text, rule_node, line_indexes, startLine) { | |
preprocessRules(text, rule_node); | |
startLine = startLine || 0; | |
if (!line_indexes) { | |
var line_indexes = saveLineIndexes(text) | |
} | |
for (var i = 0, | |
il = rule_node.children.length; i < il; i++) { | |
var r = rule_node.children[i]; | |
r.line = line_indexes.length + startLine; | |
for (var j = 0, | |
jl = line_indexes.length - 1; j < jl; j++) { | |
var line_ix = line_indexes[j]; | |
if (r.start >= line_indexes[j] && r.start < line_indexes[j + 1]) { | |
r.line = j + 1 + startLine; | |
break | |
} | |
} | |
saveLineNumbers(text, r, line_indexes) | |
} | |
return rule_node | |
} | |
return { | |
read: function(text, startLine) { | |
var rule_start = [], | |
rule_body_start = [], | |
rules = [], | |
in_comment = 0, | |
root = rule(), | |
cur_parent = root, | |
last_rule = null, | |
stack = [], | |
ch, | |
ch2; | |
stack.last = function() { | |
return this[this.length - 1] | |
}; | |
function hasStr(pos, substr) { | |
return text.substr(pos, substr.length) == substr | |
} | |
for (var i = 0, | |
il = text.length; i < il; i++) { | |
ch = text.charAt(i); | |
ch2 = i < il - 1 ? text.charAt(i + 1) : ""; | |
if (!rule_start.length) { | |
rule_start.push(i) | |
} | |
switch (ch) { | |
case "@": | |
if (!in_comment) { | |
if (hasStr(i, "@import")) { | |
var m = text.substr(i).match(/^@import\s*url\((['"])?.+?\1?\)\;?/); | |
if (m) { | |
cur_parent.addChild(i, i + 7, i + m[0].length); | |
i += m[0].length; | |
rule_start.pop() | |
} | |
break | |
} | |
} | |
case "/": | |
if (!in_comment && ch2 == "*") { | |
in_comment++ | |
} | |
break; | |
case "*": | |
if (ch2 == "/") { | |
in_comment-- | |
} | |
break; | |
case "{": | |
if (!in_comment) { | |
rule_body_start.push(i); | |
cur_parent = cur_parent.addChild(rule_start.pop()); | |
stack.push(cur_parent) | |
} | |
break; | |
case "}": | |
if (!in_comment) { | |
var last_rule = stack.pop(); | |
rule_start.pop(); | |
last_rule.body_start = rule_body_start.pop(); | |
last_rule.end = i; | |
cur_parent = last_rule.parent || root | |
} | |
break | |
} | |
} | |
return saveLineNumbers(text, root, null, startLine) | |
}, | |
normalizeSelector: normalizeSelector, | |
findBySelector: function(rule_node, selector, source) { | |
var selector = normalizeSelector(selector), | |
result = []; | |
if (rule_node) { | |
for (var i = 0, | |
il = rule_node.children.length; i < il; i++) { | |
var r = rule_node.children[i]; | |
if (r.selector == selector) { | |
result.push(r) | |
} | |
} | |
} | |
if (result.length) { | |
return result | |
} else { | |
return null | |
} | |
} | |
} | |
})(); | |
FBL.CssParser = CssParser | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
var CssAnalyzer = {}; | |
var CSSRuleMap = {}; | |
var ElementCSSRulesMap = {}; | |
var internalStyleSheetIndex = -1; | |
var reSelectorTag = /(^|\s)(?:\w+)/g; | |
var reSelectorClass = /\.[\w\d_-]+/g; | |
var reSelectorId = /#[\w\d_-]+/g; | |
var globalCSSRuleIndex; | |
var processAllStyleSheetsTimeout = null; | |
var externalStyleSheetURLs = []; | |
var ElementCache = Firebug.Lite.Cache.Element; | |
var StyleSheetCache = Firebug.Lite.Cache.StyleSheet; | |
CssAnalyzer.externalStyleSheetWarning = domplate(Firebug.Rep, { | |
tag: DIV({ | |
"class": "warning focusRow", | |
style: "font-weight:normal;", | |
role: "listitem" | |
}, | |
SPAN("$object|STR"), A({ | |
href: "$href", | |
target: "_blank" | |
}, | |
"$link|STR")) | |
}); | |
CssAnalyzer.processAllStyleSheets = function(doc, styleSheetIterator) { | |
try { | |
processAllStyleSheets(doc, styleSheetIterator) | |
} catch(e) { | |
FBTrace.sysout("CssAnalyzer.processAllStyleSheets fails: ", e) | |
} | |
}; | |
CssAnalyzer.getElementCSSRules = function(element) { | |
try { | |
return getElementCSSRules(element) | |
} catch(e) { | |
FBTrace.sysout("CssAnalyzer.getElementCSSRules fails: ", e) | |
} | |
}; | |
CssAnalyzer.getRuleData = function(ruleId) { | |
return CSSRuleMap[ruleId] | |
}; | |
CssAnalyzer.getRuleLine = function() {}; | |
CssAnalyzer.hasExternalStyleSheet = function() { | |
return externalStyleSheetURLs.length > 0 | |
}; | |
CssAnalyzer.parseStyleSheet = function(href) { | |
var sourceData = extractSourceData(href); | |
var parsedObj = CssParser.read(sourceData.source, sourceData.startLine); | |
var parsedRules = parsedObj.children; | |
for (var i = 0; i < parsedRules.length;) { | |
if (parsedRules[i].selector.indexOf("@") != -1) { | |
parsedRules.splice(i, 1) | |
} else { | |
i++ | |
} | |
} | |
return parsedRules | |
}; | |
var processAllStyleSheets = function(doc, styleSheetIterator) { | |
styleSheetIterator = styleSheetIterator || processStyleSheet; | |
globalCSSRuleIndex = -1; | |
var styleSheets = doc.styleSheets; | |
var importedStyleSheets = []; | |
if (FBTrace.DBG_CSS) { | |
var start = new Date().getTime() | |
} | |
for (var i = 0, | |
length = styleSheets.length; i < length; i++) { | |
try { | |
var styleSheet = styleSheets[i]; | |
if ("firebugIgnore" in styleSheet) { | |
continue | |
} | |
var rules = isIE ? styleSheet.rules: styleSheet.cssRules; | |
rules.length | |
} catch(e) { | |
externalStyleSheetURLs.push(styleSheet.href); | |
styleSheet.restricted = true; | |
var ssid = StyleSheetCache(styleSheet) | |
} | |
styleSheetIterator(doc, styleSheet); | |
var importedStyleSheet, importedRules; | |
if (isIE) { | |
var imports = styleSheet.imports; | |
for (var j = 0, | |
importsLength = imports.length; j < importsLength; j++) { | |
try { | |
importedStyleSheet = imports[j]; | |
importedRules = importedStyleSheet.rules; | |
importedRules.length | |
} catch(e) { | |
externalStyleSheetURLs.push(styleSheet.href); | |
importedStyleSheet.restricted = true; | |
var ssid = StyleSheetCache(importedStyleSheet) | |
} | |
styleSheetIterator(doc, importedStyleSheet) | |
} | |
} else { | |
if (rules) { | |
for (var j = 0, | |
rulesLength = rules.length; j < rulesLength; j++) { | |
try { | |
var rule = rules[j]; | |
importedStyleSheet = rule.styleSheet; | |
if (importedStyleSheet) { | |
importedRules = importedStyleSheet.cssRules; | |
importedRules.length | |
} else { | |
break | |
} | |
} catch(e) { | |
externalStyleSheetURLs.push(styleSheet.href); | |
importedStyleSheet.restricted = true; | |
var ssid = StyleSheetCache(importedStyleSheet) | |
} | |
styleSheetIterator(doc, importedStyleSheet) | |
} | |
} | |
} | |
} | |
if (FBTrace.DBG_CSS) { | |
FBTrace.sysout("FBL.processAllStyleSheets", "all stylesheet rules processed in " + (new Date().getTime() - start) + "ms") | |
} | |
}; | |
var processStyleSheet = function(doc, styleSheet) { | |
if (styleSheet.restricted) { | |
return | |
} | |
var rules = isIE ? styleSheet.rules: styleSheet.cssRules; | |
var ssid = StyleSheetCache(styleSheet); | |
var href = styleSheet.href; | |
var shouldParseCSS = typeof CssParser != "undefined" && !Firebug.disableResourceFetching; | |
if (shouldParseCSS) { | |
try { | |
var parsedRules = CssAnalyzer.parseStyleSheet(href) | |
} catch(e) { | |
if (FBTrace.DBG_ERRORS) { | |
FBTrace.sysout("processStyleSheet FAILS", e.message || e) | |
} | |
shouldParseCSS = false | |
} finally { | |
var parsedRulesIndex = 0; | |
var dontSupportGroupedRules = isIE && browserVersion < 9; | |
var group = []; | |
var groupItem | |
} | |
} | |
for (var i = 0, | |
length = rules.length; i < length; i++) { | |
var rid = ssid + ":" + i; | |
var rule = rules[i]; | |
var selector = rule.selectorText || ""; | |
var lineNo = null; | |
if (!selector || selector.indexOf("@") != -1) { | |
continue | |
} | |
if (isIE) { | |
selector = selector.replace(reSelectorTag, | |
function(s) { | |
return s.toLowerCase() | |
}) | |
} | |
if (shouldParseCSS) { | |
var parsedRule = parsedRules[parsedRulesIndex]; | |
var parsedSelector = parsedRule.selector; | |
if (dontSupportGroupedRules && parsedSelector.indexOf(",") != -1 && group.length == 0) { | |
group = parsedSelector.split(",") | |
} | |
if (dontSupportGroupedRules && group.length > 0) { | |
groupItem = group.shift(); | |
if (CssParser.normalizeSelector(selector) == groupItem) { | |
lineNo = parsedRule.line | |
} | |
if (group.length == 0) { | |
parsedRulesIndex++ | |
} | |
} else { | |
if (CssParser.normalizeSelector(selector) == parsedRule.selector) { | |
lineNo = parsedRule.line; | |
parsedRulesIndex++ | |
} | |
} | |
} | |
CSSRuleMap[rid] = { | |
styleSheetId: ssid, | |
styleSheetIndex: i, | |
order: ++globalCSSRuleIndex, | |
specificity: selector && selector.indexOf(",") == -1 ? getCSSRuleSpecificity(selector) : 0, | |
rule: rule, | |
lineNo: lineNo, | |
selector: selector, | |
cssText: rule.style ? rule.style.cssText: rule.cssText ? rule.cssText: "" | |
}; | |
var elements = Firebug.Selector(selector, doc); | |
for (var j = 0, | |
elementsLength = elements.length; j < elementsLength; j++) { | |
var element = elements[j]; | |
var eid = ElementCache(element); | |
if (!ElementCSSRulesMap[eid]) { | |
ElementCSSRulesMap[eid] = [] | |
} | |
ElementCSSRulesMap[eid].push(rid) | |
} | |
} | |
}; | |
var loadExternalStylesheet = function(doc, styleSheetIterator, styleSheet) { | |
var url = styleSheet.href; | |
styleSheet.firebugIgnore = true; | |
var source = Firebug.Lite.Proxy.load(url); | |
source = source.replace(/url\(([^\)]+)\)/g, | |
function(a, name) { | |
var hasDomain = /\w+:\/\/./.test(name); | |
if (!hasDomain) { | |
name = name.replace(/^(["'])(.+)\1$/, "$2"); | |
var first = name.charAt(0); | |
if (first == "/") { | |
var m = /^([^:]+:\/{1,3}[^\/]+)/.exec(url); | |
return m ? "url(" + m[1] + name + ")": "url(" + name + ")" | |
} else { | |
var path = url.replace(/[^\/]+\.[\w\d]+(\?.+|#.+)?$/g, ""); | |
path = path + name; | |
var reBack = /[^\/]+\/\.\.\//; | |
while (reBack.test(path)) { | |
path = path.replace(reBack, "") | |
} | |
return "url(" + path + ")" | |
} | |
} | |
return a | |
}); | |
var oldStyle = styleSheet.ownerNode; | |
if (!oldStyle) { | |
return | |
} | |
if (!oldStyle.parentNode) { | |
return | |
} | |
var style = createGlobalElement("style"); | |
style.setAttribute("charset", "utf-8"); | |
style.setAttribute("type", "text/css"); | |
style.innerHTML = source; | |
oldStyle.parentNode.insertBefore(style, oldStyle.nextSibling); | |
oldStyle.parentNode.removeChild(oldStyle); | |
doc.styleSheets[doc.styleSheets.length - 1].externalURL = url; | |
console.log(url, "call " + externalStyleSheetURLs.length, source); | |
externalStyleSheetURLs.pop(); | |
if (processAllStyleSheetsTimeout) { | |
clearTimeout(processAllStyleSheetsTimeout) | |
} | |
processAllStyleSheetsTimeout = setTimeout(function() { | |
console.log("processing"); | |
FBL.processAllStyleSheets(doc, styleSheetIterator); | |
processAllStyleSheetsTimeout = null | |
}, | |
200) | |
}; | |
var getElementCSSRules = function(element) { | |
var eid = ElementCache(element); | |
var rules = ElementCSSRulesMap[eid]; | |
if (!rules) { | |
return | |
} | |
var arr = [element]; | |
var Selector = Firebug.Selector; | |
var ruleId, rule; | |
for (var i = 0, | |
length = rules.length; i < length; i++) { | |
ruleId = rules[i]; | |
rule = CSSRuleMap[ruleId]; | |
if (rule.selector.indexOf(",") != -1) { | |
var selectors = rule.selector.split(","); | |
var maxSpecificity = -1; | |
var sel, spec, mostSpecificSelector; | |
for (var j, len = selectors.length; j < len; j++) { | |
sel = selectors[j]; | |
if (Selector.matches(sel, arr).length == 1) { | |
spec = getCSSRuleSpecificity(sel); | |
if (spec > maxSpecificity) { | |
maxSpecificity = spec; | |
mostSpecificSelector = sel | |
} | |
} | |
} | |
rule.specificity = maxSpecificity | |
} | |
} | |
rules.sort(sortElementRules); | |
return rules | |
}; | |
var sortElementRules = function(a, b) { | |
var ruleA = CSSRuleMap[a]; | |
var ruleB = CSSRuleMap[b]; | |
var specificityA = ruleA.specificity; | |
var specificityB = ruleB.specificity; | |
if (specificityA > specificityB) { | |
return 1 | |
} else { | |
if (specificityA < specificityB) { | |
return - 1 | |
} else { | |
return ruleA.order > ruleB.order ? 1 : -1 | |
} | |
} | |
}; | |
var solveRulesTied = function(a, b) { | |
var ruleA = CSSRuleMap[a]; | |
var ruleB = CSSRuleMap[b]; | |
if (ruleA.specificity == ruleB.specificity) { | |
return ruleA.order > ruleB.order ? 1 : -1 | |
} | |
return null | |
}; | |
var getCSSRuleSpecificity = function(selector) { | |
var match = selector.match(reSelectorTag); | |
var tagCount = match ? match.length: 0; | |
match = selector.match(reSelectorClass); | |
var classCount = match ? match.length: 0; | |
match = selector.match(reSelectorId); | |
var idCount = match ? match.length: 0; | |
return tagCount + 10 * classCount + 100 * idCount | |
}; | |
var extractSourceData = function(href) { | |
var sourceData = { | |
source: null, | |
startLine: 0 | |
}; | |
if (href) { | |
sourceData.source = Firebug.Lite.Proxy.load(href) | |
} else { | |
var index = 0; | |
var ssIndex = ++internalStyleSheetIndex; | |
var reStyleTag = /\<\s*style.*\>/gi; | |
var reEndStyleTag = /\<\/\s*style.*\>/gi; | |
var source = Firebug.Lite.Proxy.load(Env.browser.location.href); | |
source = source.replace(/\n\r|\r\n/g, "\n"); | |
var startLine = 0; | |
do { | |
var matchStyleTag = source.match(reStyleTag); | |
var i0 = source.indexOf(matchStyleTag[0]) + matchStyleTag[0].length; | |
for (var i = 0; i < i0; i++) { | |
if (source.charAt(i) == "\n") { | |
startLine++ | |
} | |
} | |
source = source.substr(i0); | |
index++ | |
} while ( index <= ssIndex ); | |
var matchEndStyleTag = source.match(reEndStyleTag); | |
var i1 = source.indexOf(matchEndStyleTag[0]); | |
var extractedSource = source.substr(0, i1); | |
sourceData.source = extractedSource; | |
sourceData.startLine = startLine | |
} | |
return sourceData | |
}; | |
FBL.CssAnalyzer = CssAnalyzer | |
} | |
}); (function() { | |
this.getElementXPath = function(element) { | |
try { | |
if (element && element.id) { | |
return '//*[@id="' + element.id + '"]' | |
} else { | |
return this.getElementTreeXPath(element) | |
} | |
} catch(E) {} | |
}; | |
this.getElementTreeXPath = function(element) { | |
var paths = []; | |
for (; element && element.nodeType == 1; element = element.parentNode) { | |
var index = 0; | |
var nodeName = element.nodeName; | |
for (var sibling = element.previousSibling; sibling; sibling = sibling.previousSibling) { | |
if (sibling.nodeType != 1) { | |
continue | |
} | |
if (sibling.nodeName == nodeName) {++index | |
} | |
} | |
var tagName = element.nodeName.toLowerCase(); | |
var pathIndex = (index ? "[" + (index + 1) + "]": ""); | |
paths.splice(0, 0, tagName + pathIndex) | |
} | |
return paths.length ? "/" + paths.join("/") : null | |
}; | |
this.getElementsByXPath = function(doc, xpath) { | |
var nodes = []; | |
try { | |
var result = doc.evaluate(xpath, doc, null, XPathResult.ANY_TYPE, null); | |
for (var item = result.iterateNext(); item; item = result.iterateNext()) { | |
nodes.push(item) | |
} | |
} catch(exc) {} | |
return nodes | |
}; | |
this.getRuleMatchingElements = function(rule, doc) { | |
var css = rule.selectorText; | |
var xpath = this.cssToXPath(css); | |
return this.getElementsByXPath(doc, xpath) | |
} | |
}).call(FBL); | |
FBL.ns(function() { | |
with(FBL) { | |
var toCamelCase = function toCamelCase(s) { | |
return s.replace(reSelectorCase, toCamelCaseReplaceFn) | |
}; | |
var toSelectorCase = function toSelectorCase(s) { | |
return s.replace(reCamelCase, "-$1").toLowerCase() | |
}; | |
var reCamelCase = /([A-Z])/g; | |
var reSelectorCase = /\-(.)/g; | |
var toCamelCaseReplaceFn = function toCamelCaseReplaceFn(m, g) { | |
return g.toUpperCase() | |
}; | |
var ElementCache = Firebug.Lite.Cache.Element; | |
var StyleSheetCache = Firebug.Lite.Cache.StyleSheet; | |
Firebug.SourceBoxPanel = Firebug.Panel; | |
var reSelectorTag = /(^|\s)(?:\w+)/g; | |
var domUtils = null; | |
var textContent = isIE ? "innerText": "textContent"; | |
var CSSDomplateBase = { | |
isEditable: function(rule) { | |
return ! rule.isSystemSheet | |
}, | |
isSelectorEditable: function(rule) { | |
return rule.isSelectorEditable && this.isEditable(rule) | |
} | |
}; | |
var CSSPropTag = domplate(CSSDomplateBase, { | |
tag: DIV({ | |
"class": "cssProp focusRow", | |
$disabledStyle: "$prop.disabled", | |
$editGroup: "$rule|isEditable", | |
$cssOverridden: "$prop.overridden", | |
role: "option" | |
}, | |
A({ | |
"class": "cssPropDisable" | |
}, | |
" "), SPAN({ | |
"class": "cssPropName", | |
$editable: "$rule|isEditable" | |
}, | |
"$prop.name"), SPAN({ | |
"class": "cssColon" | |
}, | |
":"), SPAN({ | |
"class": "cssPropValue", | |
$editable: "$rule|isEditable" | |
}, | |
"$prop.value$prop.important"), SPAN({ | |
"class": "cssSemi" | |
}, | |
";")) | |
}); | |
var CSSRuleTag = TAG("$rule.tag", { | |
rule: "$rule" | |
}); | |
var CSSImportRuleTag = domplate({ | |
tag: DIV({ | |
"class": "cssRule insertInto focusRow importRule", | |
_repObject: "$rule.rule" | |
}, | |
"@import "", A({ | |
"class": "objectLink", | |
_repObject: "$rule.rule.styleSheet" | |
}, | |
"$rule.rule.href"), "";") | |
}); | |
var CSSStyleRuleTag = domplate(CSSDomplateBase, { | |
tag: DIV({ | |
"class": "cssRule insertInto", | |
$cssEditableRule: "$rule|isEditable", | |
$editGroup: "$rule|isSelectorEditable", | |
_repObject: "$rule.rule", | |
ruleId: "$rule.id", | |
role: "presentation" | |
}, | |
DIV({ | |
"class": "cssHead focusRow", | |
role: "listitem" | |
}, | |
SPAN({ | |
"class": "cssSelector", | |
$editable: "$rule|isSelectorEditable" | |
}, | |
"$rule.selector"), " {"), DIV({ | |
role: "group" | |
}, | |
DIV({ | |
"class": "cssPropertyListBox", | |
role: "listbox" | |
}, | |
FOR("prop", "$rule.props", TAG(CSSPropTag.tag, { | |
rule: "$rule", | |
prop: "$prop" | |
})))), DIV({ | |
"class": "editable insertBefore", | |
role: "presentation" | |
}, | |
"}")) | |
}); | |
var reSplitCSS = /(url\("?[^"\)]+?"?\))|(rgb\(.*?\))|(#[\dA-Fa-f]+)|(-?\d+(\.\d+)?(%|[a-z]{1,2})?)|([^,\s]+)|"(.*?)"/; | |
var reURL = /url\("?([^"\)]+)?"?\)/; | |
var reRepeat = /no-repeat|repeat-x|repeat-y|repeat/; | |
var sothinkInstalled = false; | |
var styleGroups = { | |
text: ["font-family", "font-size", "font-weight", "font-style", "color", "text-transform", "text-decoration", "letter-spacing", "word-spacing", "line-height", "text-align", "vertical-align", "direction", "column-count", "column-gap", "column-width"], | |
background: ["background-color", "background-image", "background-repeat", "background-position", "background-attachment", "opacity"], | |
box: ["width", "height", "top", "right", "bottom", "left", "margin-top", "margin-right", "margin-bottom", "margin-left", "padding-top", "padding-right", "padding-bottom", "padding-left", "border-top-width", "border-right-width", "border-bottom-width", "border-left-width", "border-top-color", "border-right-color", "border-bottom-color", "border-left-color", "border-top-style", "border-right-style", "border-bottom-style", "border-left-style", "-moz-border-top-radius", "-moz-border-right-radius", "-moz-border-bottom-radius", "-moz-border-left-radius", "outline-top-width", "outline-right-width", "outline-bottom-width", "outline-left-width", "outline-top-color", "outline-right-color", "outline-bottom-color", "outline-left-color", "outline-top-style", "outline-right-style", "outline-bottom-style", "outline-left-style"], | |
layout: ["position", "display", "visibility", "z-index", "overflow-x", "overflow-y", "overflow-clip", "white-space", "clip", "float", "clear", "-moz-box-sizing"], | |
other: ["cursor", "list-style-image", "list-style-position", "list-style-type", "marker-offset", "user-focus", "user-select", "user-modify", "user-input"] | |
}; | |
var styleGroupTitles = { | |
text: "Text", | |
background: "Background", | |
box: "Box Model", | |
layout: "Layout", | |
other: "Other" | |
}; | |
Firebug.CSSModule = extend(Firebug.Module, { | |
freeEdit: function(styleSheet, value) { | |
if (!styleSheet.editStyleSheet) { | |
var ownerNode = getStyleSheetOwnerNode(styleSheet); | |
styleSheet.disabled = true; | |
var url = CCSV("@mozilla.org/network/standard-url;1", Components.interfaces.nsIURL); | |
url.spec = styleSheet.href; | |
var editStyleSheet = ownerNode.ownerDocument.createElementNS("http://www.w3.org/1999/xhtml", "style"); | |
unwrapObject(editStyleSheet).firebugIgnore = true; | |
editStyleSheet.setAttribute("type", "text/css"); | |
editStyleSheet.setAttributeNS("http://www.w3.org/XML/1998/namespace", "base", url.directory); | |
if (ownerNode.hasAttribute("media")) { | |
editStyleSheet.setAttribute("media", ownerNode.getAttribute("media")) | |
} | |
ownerNode.parentNode.insertBefore(editStyleSheet, ownerNode.nextSibling); | |
styleSheet.editStyleSheet = editStyleSheet | |
} | |
styleSheet.editStyleSheet.innerHTML = value; | |
if (FBTrace.DBG_CSS) { | |
FBTrace.sysout("css.saveEdit styleSheet.href:" + styleSheet.href + " got innerHTML:" + value + "\n") | |
} | |
dispatch(this.fbListeners, "onCSSFreeEdit", [styleSheet, value]) | |
}, | |
insertRule: function(styleSheet, cssText, ruleIndex) { | |
if (FBTrace.DBG_CSS) { | |
FBTrace.sysout("Insert: " + ruleIndex + " " + cssText) | |
} | |
var insertIndex = styleSheet.insertRule(cssText, ruleIndex); | |
dispatch(this.fbListeners, "onCSSInsertRule", [styleSheet, cssText, ruleIndex]); | |
return insertIndex | |
}, | |
deleteRule: function(styleSheet, ruleIndex) { | |
if (FBTrace.DBG_CSS) { | |
FBTrace.sysout("deleteRule: " + ruleIndex + " " + styleSheet.cssRules.length, styleSheet.cssRules) | |
} | |
dispatch(this.fbListeners, "onCSSDeleteRule", [styleSheet, ruleIndex]); | |
styleSheet.deleteRule(ruleIndex) | |
}, | |
setProperty: function(rule, propName, propValue, propPriority) { | |
var style = rule.style || rule; | |
var baseText = style.cssText; | |
if (style.getPropertyValue) { | |
var prevValue = style.getPropertyValue(propName); | |
var prevPriority = style.getPropertyPriority(propName); | |
style.removeProperty(propName); | |
style.setProperty(propName, propValue, propPriority) | |
} else { | |
style[toCamelCase(propName)] = propValue | |
} | |
if (propName) { | |
dispatch(this.fbListeners, "onCSSSetProperty", [style, propName, propValue, propPriority, prevValue, prevPriority, rule, baseText]) | |
} | |
}, | |
removeProperty: function(rule, propName, parent) { | |
var style = rule.style || rule; | |
var baseText = style.cssText; | |
if (style.getPropertyValue) { | |
var prevValue = style.getPropertyValue(propName); | |
var prevPriority = style.getPropertyPriority(propName); | |
style.removeProperty(propName) | |
} else { | |
style[toCamelCase(propName)] = "" | |
} | |
if (propName) { | |
dispatch(this.fbListeners, "onCSSRemoveProperty", [style, propName, prevValue, prevPriority, rule, baseText]) | |
} | |
} | |
}); | |
Firebug.CSSStyleSheetPanel = function() {}; | |
Firebug.CSSStyleSheetPanel.prototype = extend(Firebug.SourceBoxPanel, { | |
template: domplate({ | |
tag: DIV({ | |
"class": "cssSheet insertInto a11yCSSView" | |
}, | |
FOR("rule", "$rules", CSSRuleTag), DIV({ | |
"class": "cssSheet editable insertBefore" | |
}, | |
"")) | |
}), | |
refresh: function() { | |
if (this.location) { | |
this.updateLocation(this.location) | |
} else { | |
if (this.selection) { | |
this.updateSelection(this.selection) | |
} | |
} | |
}, | |
toggleEditing: function() { | |
if (!this.stylesheetEditor) { | |
this.stylesheetEditor = new StyleSheetEditor(this.document) | |
} | |
if (this.editing) { | |
Firebug.Editor.stopEditing() | |
} else { | |
if (!this.location) { | |
return | |
} | |
var styleSheet = this.location.editStyleSheet ? this.location.editStyleSheet.sheet: this.location; | |
var css = getStyleSheetCSS(styleSheet, this.context); | |
this.stylesheetEditor.styleSheet = this.location; | |
Firebug.Editor.startEditing(this.panelNode, css, this.stylesheetEditor) | |
} | |
}, | |
getStylesheetURL: function(rule) { | |
if (this.location.href) { | |
return this.location.href | |
} else { | |
return this.context.window.location.href | |
} | |
}, | |
getRuleByLine: function(styleSheet, line) { | |
if (!domUtils) { | |
return null | |
} | |
var cssRules = styleSheet.cssRules; | |
for (var i = 0; i < cssRules.length; ++i) { | |
var rule = cssRules[i]; | |
if (rule instanceof CSSStyleRule) { | |
var ruleLine = domUtils.getRuleLine(rule); | |
if (ruleLine >= line) { | |
return rule | |
} | |
} | |
} | |
}, | |
highlightRule: function(rule) { | |
var ruleElement = Firebug.getElementByRepObject(this.panelNode.firstChild, rule); | |
if (ruleElement) { | |
scrollIntoCenterView(ruleElement, this.panelNode); | |
setClassTimed(ruleElement, "jumpHighlight", this.context) | |
} | |
}, | |
getStyleSheetRules: function(context, styleSheet) { | |
var isSystemSheet = isSystemStyleSheet(styleSheet); | |
function appendRules(cssRules) { | |
for (var i = 0; i < cssRules.length; ++i) { | |
var rule = cssRules[i]; | |
if (instanceOf(rule, "CSSStyleRule")) { | |
var props = this.getRuleProperties(context, rule); | |
var line = null; | |
var selector = rule.selectorText; | |
if (isIE) { | |
selector = selector.replace(reSelectorTag, | |
function(s) { | |
return s.toLowerCase() | |
}) | |
} | |
var ruleId = rule.selectorText + "/" + line; | |
rules.push({ | |
tag: CSSStyleRuleTag.tag, | |
rule: rule, | |
id: ruleId, | |
selector: selector, | |
props: props, | |
isSystemSheet: isSystemSheet, | |
isSelectorEditable: true | |
}) | |
} else { | |
if (instanceOf(rule, "CSSImportRule")) { | |
rules.push({ | |
tag: CSSImportRuleTag.tag, | |
rule: rule | |
}) | |
} else { | |
if (instanceOf(rule, "CSSMediaRule")) { | |
appendRules.apply(this, [rule.cssRules]) | |
} else { | |
if (FBTrace.DBG_ERRORS || FBTrace.DBG_CSS) { | |
FBTrace.sysout("css getStyleSheetRules failed to classify a rule ", rule) | |
} | |
} | |
} | |
} | |
} | |
} | |
var rules = []; | |
appendRules.apply(this, [styleSheet.cssRules || styleSheet.rules]); | |
return rules | |
}, | |
parseCSSProps: function(style, inheritMode) { | |
var props = []; | |
if (Firebug.expandShorthandProps) { | |
var count = style.length - 1, | |
index = style.length; | |
while (index--) { | |
var propName = style.item(count - index); | |
this.addProperty(propName, style.getPropertyValue(propName), !!style.getPropertyPriority(propName), false, inheritMode, props) | |
} | |
} else { | |
var lines = style.cssText.match(/(?:[^;\(]*(?:\([^\)]*?\))?[^;\(]*)*;?/g); | |
var propRE = /\s*([^:\s]*)\s*:\s*(.*?)\s*(! important)?;?$/; | |
var line, i = 0; | |
var m; | |
while (line = lines[i++]) { | |
m = propRE.exec(line); | |
if (!m) { | |
continue | |
} | |
if (m[2]) { | |
this.addProperty(m[1], m[2], !!m[3], false, inheritMode, props) | |
} | |
} | |
} | |
return props | |
}, | |
getRuleProperties: function(context, rule, inheritMode) { | |
var props = this.parseCSSProps(rule.style, inheritMode); | |
var line; | |
var ruleId = rule.selectorText + "/" + line; | |
this.addOldProperties(context, ruleId, inheritMode, props); | |
sortProperties(props); | |
return props | |
}, | |
addOldProperties: function(context, ruleId, inheritMode, props) { | |
if (context.selectorMap && context.selectorMap.hasOwnProperty(ruleId)) { | |
var moreProps = context.selectorMap[ruleId]; | |
for (var i = 0; i < moreProps.length; ++i) { | |
var prop = moreProps[i]; | |
this.addProperty(prop.name, prop.value, prop.important, true, inheritMode, props) | |
} | |
} | |
}, | |
addProperty: function(name, value, important, disabled, inheritMode, props) { | |
name = name.toLowerCase(); | |
if (inheritMode && !inheritedStyleNames[name]) { | |
return | |
} | |
name = this.translateName(name, value); | |
if (name) { | |
value = stripUnits(rgbToHex(value)); | |
important = important ? " !important": ""; | |
var prop = { | |
name: name, | |
value: value, | |
important: important, | |
disabled: disabled | |
}; | |
props.push(prop) | |
} | |
}, | |
translateName: function(name, value) { | |
if ((value == "-moz-initial" && (name == "-moz-background-clip" || name == "-moz-background-origin" || name == "-moz-background-inline-policy")) || (value == "physical" && (name == "margin-left-ltr-source" || name == "margin-left-rtl-source" || name == "margin-right-ltr-source" || name == "margin-right-rtl-source")) || (value == "physical" && (name == "padding-left-ltr-source" || name == "padding-left-rtl-source" || name == "padding-right-ltr-source" || name == "padding-right-rtl-source"))) { | |
return null | |
} | |
if (name == "margin-left-value") { | |
return "margin-left" | |
} else { | |
if (name == "margin-right-value") { | |
return "margin-right" | |
} else { | |
if (name == "margin-top-value") { | |
return "margin-top" | |
} else { | |
if (name == "margin-bottom-value") { | |
return "margin-bottom" | |
} else { | |
if (name == "padding-left-value") { | |
return "padding-left" | |
} else { | |
if (name == "padding-right-value") { | |
return "padding-right" | |
} else { | |
if (name == "padding-top-value") { | |
return "padding-top" | |
} else { | |
if (name == "padding-bottom-value") { | |
return "padding-bottom" | |
} else { | |
return name | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
}, | |
editElementStyle: function() { | |
var rulesBox = $$(".cssElementRuleContainer", this.panelNode)[0]; | |
var styleRuleBox = rulesBox && Firebug.getElementByRepObject(rulesBox, this.selection); | |
if (!styleRuleBox) { | |
var rule = { | |
rule: this.selection, | |
inherited: false, | |
selector: "element.style", | |
props: [] | |
}; | |
if (!rulesBox) { | |
styleRuleBox = this.template.cascadedTag.replace({ | |
rules: [rule], | |
inherited: [], | |
inheritLabel: "Inherited from" | |
}, | |
this.panelNode); | |
styleRuleBox = $$(".cssElementRuleContainer", styleRuleBox)[0] | |
} else { | |
styleRuleBox = this.template.ruleTag.insertBefore({ | |
rule: rule | |
}, | |
rulesBox) | |
} | |
styleRuleBox = $$(".insertInto", styleRuleBox)[0] | |
} | |
Firebug.Editor.insertRowForObject(styleRuleBox) | |
}, | |
insertPropertyRow: function(row) { | |
Firebug.Editor.insertRowForObject(row) | |
}, | |
insertRule: function(row) { | |
var location = getAncestorByClass(row, "cssRule"); | |
if (!location) { | |
location = getChildByClass(this.panelNode, "cssSheet"); | |
Firebug.Editor.insertRowForObject(location) | |
} else { | |
Firebug.Editor.insertRow(location, "before") | |
} | |
}, | |
editPropertyRow: function(row) { | |
var propValueBox = getChildByClass(row, "cssPropValue"); | |
Firebug.Editor.startEditing(propValueBox) | |
}, | |
deletePropertyRow: function(row) { | |
var rule = Firebug.getRepObject(row); | |
var propName = getChildByClass(row, "cssPropName")[textContent]; | |
Firebug.CSSModule.removeProperty(rule, propName); | |
var ruleId = Firebug.getRepNode(row).getAttribute("ruleId"); | |
if (this.context.selectorMap && this.context.selectorMap.hasOwnProperty(ruleId)) { | |
var map = this.context.selectorMap[ruleId]; | |
for (var i = 0; i < map.length; ++i) { | |
if (map[i].name == propName) { | |
map.splice(i, 1); | |
break | |
} | |
} | |
} | |
if (this.name == "stylesheet") { | |
dispatch([Firebug.A11yModel], "onInlineEditorClose", [this, row.firstChild, true]) | |
} | |
row.parentNode.removeChild(row); | |
this.markChange(this.name == "stylesheet") | |
}, | |
disablePropertyRow: function(row) { | |
toggleClass(row, "disabledStyle"); | |
var rule = Firebug.getRepObject(row); | |
var propName = getChildByClass(row, "cssPropName")[textContent]; | |
if (!this.context.selectorMap) { | |
this.context.selectorMap = {} | |
} | |
var ruleId = Firebug.getRepNode(row).getAttribute("ruleId"); | |
if (! (this.context.selectorMap.hasOwnProperty(ruleId))) { | |
this.context.selectorMap[ruleId] = [] | |
} | |
var map = this.context.selectorMap[ruleId]; | |
var propValue = getChildByClass(row, "cssPropValue")[textContent]; | |
var parsedValue = parsePriority(propValue); | |
if (hasClass(row, "disabledStyle")) { | |
Firebug.CSSModule.removeProperty(rule, propName); | |
map.push({ | |
name: propName, | |
value: parsedValue.value, | |
important: parsedValue.priority | |
}) | |
} else { | |
Firebug.CSSModule.setProperty(rule, propName, parsedValue.value, parsedValue.priority); | |
var index = findPropByName(map, propName); | |
map.splice(index, 1) | |
} | |
this.markChange(this.name == "stylesheet") | |
}, | |
onMouseDown: function(event) { | |
var offset = event.clientX - this.panelNode.parentNode.offsetLeft; | |
if (!isLeftClick(event) || offset > 20) { | |
return | |
} | |
var target = event.target || event.srcElement; | |
if (hasClass(target, "textEditor")) { | |
return | |
} | |
var row = getAncestorByClass(target, "cssProp"); | |
if (row && hasClass(row, "editGroup")) { | |
this.disablePropertyRow(row); | |
cancelEvent(event) | |
} | |
}, | |
onDoubleClick: function(event) { | |
var offset = event.clientX - this.panelNode.parentNode.offsetLeft; | |
if (!isLeftClick(event) || offset <= 20) { | |
return | |
} | |
var target = event.target || event.srcElement; | |
if (hasClass(target, "textEditorInner")) { | |
return | |
} | |
var row = getAncestorByClass(target, "cssRule"); | |
if (row && !getAncestorByClass(target, "cssPropName") && !getAncestorByClass(target, "cssPropValue")) { | |
this.insertPropertyRow(row); | |
cancelEvent(event) | |
} | |
}, | |
name: "stylesheet", | |
title: "CSS", | |
parentPanel: null, | |
searchable: true, | |
dependents: ["css", "stylesheet", "dom", "domSide", "layout"], | |
options: { | |
hasToolButtons: true | |
}, | |
create: function() { | |
Firebug.Panel.create.apply(this, arguments); | |
this.onMouseDown = bind(this.onMouseDown, this); | |
this.onDoubleClick = bind(this.onDoubleClick, this); | |
if (this.name == "stylesheet") { | |
this.onChangeSelect = bind(this.onChangeSelect, this); | |
var doc = Firebug.browser.document; | |
var selectNode = this.selectNode = createElement("select"); | |
CssAnalyzer.processAllStyleSheets(doc, | |
function(doc, styleSheet) { | |
var key = StyleSheetCache.key(styleSheet); | |
var fileName = getFileName(styleSheet.href) || getFileName(doc.location.href); | |
var option = createElement("option", { | |
value: key | |
}); | |
option.appendChild(Firebug.chrome.document.createTextNode(fileName)); | |
selectNode.appendChild(option) | |
}); | |
this.toolButtonsNode.appendChild(selectNode) | |
} | |
}, | |
onChangeSelect: function(event) { | |
event = event || window.event; | |
var target = event.srcElement || event.currentTarget; | |
var key = target.value; | |
var styleSheet = StyleSheetCache.get(key); | |
this.updateLocation(styleSheet) | |
}, | |
initialize: function() { | |
Firebug.Panel.initialize.apply(this, arguments); | |
this.context = Firebug.chrome; | |
this.document = Firebug.chrome.document; | |
this.initializeNode(); | |
if (this.name == "stylesheet") { | |
var styleSheets = Firebug.browser.document.styleSheets; | |
if (styleSheets.length > 0) { | |
addEvent(this.selectNode, "change", this.onChangeSelect); | |
this.updateLocation(styleSheets[0]) | |
} | |
} | |
}, | |
shutdown: function() { | |
Firebug.Editor.stopEditing(); | |
if (this.name == "stylesheet") { | |
removeEvent(this.selectNode, "change", this.onChangeSelect) | |
} | |
this.destroyNode(); | |
Firebug.Panel.shutdown.apply(this, arguments) | |
}, | |
destroy: function(state) { | |
Firebug.Panel.destroy.apply(this, arguments) | |
}, | |
initializeNode: function(oldPanelNode) { | |
addEvent(this.panelNode, "mousedown", this.onMouseDown); | |
addEvent(this.panelNode, "dblclick", this.onDoubleClick) | |
}, | |
destroyNode: function() { | |
removeEvent(this.panelNode, "mousedown", this.onMouseDown); | |
removeEvent(this.panelNode, "dblclick", this.onDoubleClick) | |
}, | |
ishow: function(state) { | |
Firebug.Inspector.stopInspecting(true); | |
this.showToolbarButtons("fbCSSButtons", true); | |
if (this.context.loaded && !this.location) { | |
restoreObjects(this, state); | |
if (!this.location) { | |
this.location = this.getDefaultLocation() | |
} | |
if (state && state.scrollTop) { | |
this.panelNode.scrollTop = state.scrollTop | |
} | |
} | |
}, | |
ihide: function() { | |
this.showToolbarButtons("fbCSSButtons", false); | |
this.lastScrollTop = this.panelNode.scrollTop | |
}, | |
supportsObject: function(object) { | |
if (object instanceof CSSStyleSheet) { | |
return 1 | |
} else { | |
if (object instanceof CSSStyleRule) { | |
return 2 | |
} else { | |
if (object instanceof CSSStyleDeclaration) { | |
return 2 | |
} else { | |
if (object instanceof SourceLink && object.type == "css" && reCSS.test(object.href)) { | |
return 2 | |
} else { | |
return 0 | |
} | |
} | |
} | |
} | |
}, | |
updateLocation: function(styleSheet) { | |
if (!styleSheet) { | |
return | |
} | |
if (styleSheet.editStyleSheet) { | |
styleSheet = styleSheet.editStyleSheet.sheet | |
} | |
if (styleSheet.restricted) { | |
FirebugReps.Warning.tag.replace({ | |
object: "AccessRestricted" | |
}, | |
this.panelNode); | |
CssAnalyzer.externalStyleSheetWarning.tag.append({ | |
object: "The stylesheet could not be loaded due to access restrictions. ", | |
link: "more...", | |
href: "http://getfirebug.com/wiki/index.php/Firebug_Lite_FAQ#I_keep_seeing_.22Access_to_restricted_URI_denied.22" | |
}, | |
this.panelNode); | |
return | |
} | |
var rules = this.getStyleSheetRules(this.context, styleSheet); | |
var result; | |
if (rules.length) { | |
result = this.template.tag.replace({ | |
rules: rules | |
}, | |
this.panelNode) | |
} else { | |
result = FirebugReps.Warning.tag.replace({ | |
object: "EmptyStyleSheet" | |
}, | |
this.panelNode) | |
} | |
}, | |
updateSelection: function(object) { | |
this.selection = null; | |
if (object instanceof CSSStyleDeclaration) { | |
object = object.parentRule | |
} | |
if (object instanceof CSSStyleRule) { | |
this.navigate(object.parentStyleSheet); | |
this.highlightRule(object) | |
} else { | |
if (object instanceof CSSStyleSheet) { | |
this.navigate(object) | |
} else { | |
if (object instanceof SourceLink) { | |
try { | |
var sourceLink = object; | |
var sourceFile = getSourceFileByHref(sourceLink.href, this.context); | |
if (sourceFile) { | |
clearNode(this.panelNode); | |
this.showSourceFile(sourceFile); | |
var lineNo = object.line; | |
if (lineNo) { | |
this.scrollToLine(lineNo, this.jumpHighlightFactory(lineNo, this.context)) | |
} | |
} else { | |
var stylesheet = getStyleSheetByHref(sourceLink.href, this.context); | |
if (stylesheet) { | |
this.navigate(stylesheet) | |
} else { | |
if (FBTrace.DBG_CSS) { | |
FBTrace.sysout("css.updateSelection no sourceFile for " + sourceLink.href, sourceLink) | |
} | |
} | |
} | |
} catch(exc) { | |
if (FBTrace.DBG_CSS) { | |
FBTrace.sysout("css.upDateSelection FAILS " + exc, exc) | |
} | |
} | |
} | |
} | |
} | |
}, | |
updateOption: function(name, value) { | |
if (name == "expandShorthandProps") { | |
this.refresh() | |
} | |
}, | |
getLocationList: function() { | |
var styleSheets = getAllStyleSheets(this.context); | |
return styleSheets | |
}, | |
getOptionsMenuItems: function() { | |
return [{ | |
label: "Expand Shorthand Properties", | |
type: "checkbox", | |
checked: Firebug.expandShorthandProps, | |
command: bindFixed(Firebug.togglePref, Firebug, "expandShorthandProps") | |
}, | |
"-", { | |
label: "Refresh", | |
command: bind(this.refresh, this) | |
}] | |
}, | |
getContextMenuItems: function(style, target) { | |
var items = []; | |
if (this.infoTipType == "color") { | |
items.push({ | |
label: "CopyColor", | |
command: bindFixed(copyToClipboard, FBL, this.infoTipObject) | |
}) | |
} else { | |
if (this.infoTipType == "image") { | |
items.push({ | |
label: "CopyImageLocation", | |
command: bindFixed(copyToClipboard, FBL, this.infoTipObject) | |
}, | |
{ | |
label: "OpenImageInNewTab", | |
command: bindFixed(openNewTab, FBL, this.infoTipObject) | |
}) | |
} | |
} | |
if (isElement(this.selection)) { | |
items.push({ | |
label: "EditStyle", | |
command: bindFixed(this.editElementStyle, this) | |
}) | |
} else { | |
if (!isSystemStyleSheet(this.selection)) { | |
items.push({ | |
label: "NewRule", | |
command: bindFixed(this.insertRule, this, target) | |
}) | |
} | |
} | |
var cssRule = getAncestorByClass(target, "cssRule"); | |
if (cssRule && hasClass(cssRule, "cssEditableRule")) { | |
items.push("-", { | |
label: "NewProp", | |
command: bindFixed(this.insertPropertyRow, this, target) | |
}); | |
var propRow = getAncestorByClass(target, "cssProp"); | |
if (propRow) { | |
var propName = getChildByClass(propRow, "cssPropName")[textContent]; | |
var isDisabled = hasClass(propRow, "disabledStyle"); | |
items.push({ | |
label: $STRF("EditProp", [propName]), | |
nol10n: true, | |
command: bindFixed(this.editPropertyRow, this, propRow) | |
}, | |
{ | |
label: $STRF("DeleteProp", [propName]), | |
nol10n: true, | |
command: bindFixed(this.deletePropertyRow, this, propRow) | |
}, | |
{ | |
label: $STRF("DisableProp", [propName]), | |
nol10n: true, | |
type: "checkbox", | |
checked: isDisabled, | |
command: bindFixed(this.disablePropertyRow, this, propRow) | |
}) | |
} | |
} | |
items.push("-", { | |
label: "Refresh", | |
command: bind(this.refresh, this) | |
}); | |
return items | |
}, | |
browseObject: function(object) { | |
if (this.infoTipType == "image") { | |
openNewTab(this.infoTipObject); | |
return true | |
} | |
}, | |
showInfoTip: function(infoTip, target, x, y) { | |
var propValue = getAncestorByClass(target, "cssPropValue"); | |
if (propValue) { | |
var offset = getClientOffset(propValue); | |
var offsetX = x - offset.x; | |
var text = propValue[textContent]; | |
var charWidth = propValue.offsetWidth / text.length; | |
var charOffset = Math.floor(offsetX / charWidth); | |
var cssValue = parseCSSValue(text, charOffset); | |
if (cssValue) { | |
if (cssValue.value == this.infoTipValue) { | |
return true | |
} | |
this.infoTipValue = cssValue.value; | |
if (cssValue.type == "rgb" || (!cssValue.type && isColorKeyword(cssValue.value))) { | |
this.infoTipType = "color"; | |
this.infoTipObject = cssValue.value; | |
return Firebug.InfoTip.populateColorInfoTip(infoTip, cssValue.value) | |
} else { | |
if (cssValue.type == "url") { | |
var propNameNode = getElementByClass(target.parentNode, "cssPropName"); | |
if (propNameNode && isImageRule(propNameNode[textContent])) { | |
var rule = Firebug.getRepObject(target); | |
var baseURL = this.getStylesheetURL(rule); | |
var relURL = parseURLValue(cssValue.value); | |
var absURL = isDataURL(relURL) ? relURL: absoluteURL(relURL, baseURL); | |
var repeat = parseRepeatValue(text); | |
this.infoTipType = "image"; | |
this.infoTipObject = absURL; | |
return Firebug.InfoTip.populateImageInfoTip(infoTip, absURL, repeat) | |
} | |
} | |
} | |
} | |
} | |
delete this.infoTipType; | |
delete this.infoTipValue; | |
delete this.infoTipObject | |
}, | |
getEditor: function(target, value) { | |
if (target == this.panelNode || hasClass(target, "cssSelector") || hasClass(target, "cssRule") || hasClass(target, "cssSheet")) { | |
if (!this.ruleEditor) { | |
this.ruleEditor = new CSSRuleEditor(this.document) | |
} | |
return this.ruleEditor | |
} else { | |
if (!this.editor) { | |
this.editor = new CSSEditor(this.document) | |
} | |
return this.editor | |
} | |
}, | |
getDefaultLocation: function() { | |
try { | |
var styleSheets = this.context.window.document.styleSheets; | |
if (styleSheets.length) { | |
var sheet = styleSheets[0]; | |
return (Firebug.filterSystemURLs && isSystemURL(getURLForStyleSheet(sheet))) ? null: sheet | |
} | |
} catch(exc) { | |
if (FBTrace.DBG_LOCATIONS) { | |
FBTrace.sysout("css.getDefaultLocation FAILS " + exc, exc) | |
} | |
} | |
}, | |
getObjectDescription: function(styleSheet) { | |
var url = getURLForStyleSheet(styleSheet); | |
var instance = getInstanceForStyleSheet(styleSheet); | |
var baseDescription = splitURLBase(url); | |
if (instance) { | |
baseDescription.name = baseDescription.name + " #" + (instance + 1) | |
} | |
return baseDescription | |
}, | |
search: function(text, reverse) { | |
var curDoc = this.searchCurrentDoc(!Firebug.searchGlobal, text, reverse); | |
if (!curDoc && Firebug.searchGlobal) { | |
return this.searchOtherDocs(text, reverse) | |
} | |
return curDoc | |
}, | |
searchOtherDocs: function(text, reverse) { | |
var scanRE = Firebug.Search.getTestingRegex(text); | |
function scanDoc(styleSheet) { | |
for (var i = 0; i < styleSheet.cssRules.length; i++) { | |
if (scanRE.test(styleSheet.cssRules[i].cssText)) { | |
return true | |
} | |
} | |
} | |
if (this.navigateToNextDocument(scanDoc, reverse)) { | |
return this.searchCurrentDoc(true, text, reverse) | |
} | |
}, | |
searchCurrentDoc: function(wrapSearch, text, reverse) { | |
if (!text) { | |
delete this.currentSearch; | |
return false | |
} | |
var row; | |
if (this.currentSearch && text == this.currentSearch.text) { | |
row = this.currentSearch.findNext(wrapSearch, false, reverse, Firebug.Search.isCaseSensitive(text)) | |
} else { | |
if (this.editing) { | |
this.currentSearch = new TextSearch(this.stylesheetEditor.box); | |
row = this.currentSearch.find(text, reverse, Firebug.Search.isCaseSensitive(text)); | |
if (row) { | |
var sel = this.document.defaultView.getSelection(); | |
sel.removeAllRanges(); | |
sel.addRange(this.currentSearch.range); | |
scrollSelectionIntoView(this); | |
return true | |
} else { | |
return false | |
} | |
} else { | |
function findRow(node) { | |
return node.nodeType == 1 ? node: node.parentNode | |
} | |
this.currentSearch = new TextSearch(this.panelNode, findRow); | |
row = this.currentSearch.find(text, reverse, Firebug.Search.isCaseSensitive(text)) | |
} | |
} | |
if (row) { | |
this.document.defaultView.getSelection().selectAllChildren(row); | |
scrollIntoCenterView(row, this.panelNode); | |
dispatch([Firebug.A11yModel], "onCSSSearchMatchFound", [this, text, row]); | |
return true | |
} else { | |
dispatch([Firebug.A11yModel], "onCSSSearchMatchFound", [this, text, null]); | |
return false | |
} | |
}, | |
getSearchOptionsMenuItems: function() { | |
return [Firebug.Search.searchOptionMenu("search.Case_Sensitive", "searchCaseSensitive"), Firebug.Search.searchOptionMenu("search.Multiple_Files", "searchGlobal")] | |
} | |
}); | |
function CSSElementPanel() {} | |
CSSElementPanel.prototype = extend(Firebug.CSSStyleSheetPanel.prototype, { | |
template: domplate({ | |
cascadedTag: DIV({ | |
"class": "a11yCSSView", | |
role: "presentation" | |
}, | |
DIV({ | |
role: "list", | |
"aria-label": $STR("aria.labels.style rules") | |
}, | |
FOR("rule", "$rules", TAG("$ruleTag", { | |
rule: "$rule" | |
}))), DIV({ | |
role: "list", | |
"aria-label": $STR("aria.labels.inherited style rules") | |
}, | |
FOR("section", "$inherited", H1({ | |
"class": "cssInheritHeader groupHeader focusRow", | |
role: "listitem" | |
}, | |
SPAN({ | |
"class": "cssInheritLabel" | |
}, | |
"$inheritLabel"), TAG(FirebugReps.Element.shortTag, { | |
object: "$section.element" | |
})), DIV({ | |
role: "group" | |
}, | |
FOR("rule", "$section.rules", TAG("$ruleTag", { | |
rule: "$rule" | |
})))))), | |
ruleTag: isIE ? DIV({ | |
"class": "cssElementRuleContainer" | |
}, | |
TAG(FirebugReps.SourceLink.tag, { | |
object: "$rule.sourceLink" | |
}), TAG(CSSStyleRuleTag.tag, { | |
rule: "$rule" | |
})) : DIV({ | |
"class": "cssElementRuleContainer" | |
}, | |
TAG(CSSStyleRuleTag.tag, { | |
rule: "$rule" | |
}), TAG(FirebugReps.SourceLink.tag, { | |
object: "$rule.sourceLink" | |
})) | |
}), | |
updateCascadeView: function(element) { | |
var rules = [], | |
sections = [], | |
usedProps = {}; | |
this.getInheritedRules(element, sections, usedProps); | |
this.getElementRules(element, rules, usedProps); | |
if (rules.length || sections.length) { | |
var inheritLabel = "Inherited from"; | |
var result = this.template.cascadedTag.replace({ | |
rules: rules, | |
inherited: sections, | |
inheritLabel: inheritLabel | |
}, | |
this.panelNode) | |
} else { | |
var result = FirebugReps.Warning.tag.replace({ | |
object: "EmptyElementCSS" | |
}, | |
this.panelNode) | |
} | |
if (CssAnalyzer.hasExternalStyleSheet()) { | |
CssAnalyzer.externalStyleSheetWarning.tag.append({ | |
object: "The results here may be inaccurate because some stylesheets could not be loaded due to access restrictions. ", | |
link: "more...", | |
href: "http://getfirebug.com/wiki/index.php/Firebug_Lite_FAQ#I_keep_seeing_.22This_element_has_no_style_rules.22" | |
}, | |
this.panelNode) | |
} | |
}, | |
getStylesheetURL: function(rule) { | |
if (rule && rule.parentStyleSheet && rule.parentStyleSheet.href) { | |
return rule.parentStyleSheet.href | |
} else { | |
return this.selection.ownerDocument.location.href | |
} | |
}, | |
getInheritedRules: function(element, sections, usedProps) { | |
var parent = element.parentNode; | |
if (parent && parent.nodeType == 1) { | |
this.getInheritedRules(parent, sections, usedProps); | |
var rules = []; | |
this.getElementRules(parent, rules, usedProps, true); | |
if (rules.length) { | |
sections.splice(0, 0, { | |
element: parent, | |
rules: rules | |
}) | |
} | |
} | |
}, | |
getElementRules: function(element, rules, usedProps, inheritMode) { | |
var inspectedRules, displayedRules = {}; | |
inspectedRules = CssAnalyzer.getElementCSSRules(element); | |
if (inspectedRules) { | |
for (var i = 0, | |
length = inspectedRules.length; i < length; ++i) { | |
var ruleId = inspectedRules[i]; | |
var ruleData = CssAnalyzer.getRuleData(ruleId); | |
var rule = ruleData.rule; | |
var ssid = ruleData.styleSheetId; | |
var parentStyleSheet = StyleSheetCache.get(ssid); | |
var href = parentStyleSheet.externalURL ? parentStyleSheet.externalURL: parentStyleSheet.href; | |
var instance = null; | |
var isSystemSheet = false; | |
if (!Firebug.showUserAgentCSS && isSystemSheet) { | |
continue | |
} | |
if (!href) { | |
href = element.ownerDocument.location.href | |
} | |
var props = this.getRuleProperties(this.context, rule, inheritMode); | |
if (inheritMode && !props.length) { | |
continue | |
} | |
var line = ruleData.lineNo; | |
var ruleId = rule.selectorText + "/" + line; | |
var sourceLink = new SourceLink(href, line, "css", rule, instance); | |
this.markOverridenProps(props, usedProps, inheritMode); | |
rules.splice(0, 0, { | |
rule: rule, | |
id: ruleId, | |
selector: ruleData.selector, | |
sourceLink: sourceLink, | |
props: props, | |
inherited: inheritMode, | |
isSystemSheet: isSystemSheet | |
}) | |
} | |
} | |
if (element.style) { | |
this.getStyleProperties(element, rules, usedProps, inheritMode) | |
} | |
if (FBTrace.DBG_CSS) { | |
FBTrace.sysout("getElementRules " + rules.length + " rules for " + getElementXPath(element), rules) | |
} | |
}, | |
markOverridenProps: function(props, usedProps, inheritMode) { | |
for (var i = 0; i < props.length; ++i) { | |
var prop = props[i]; | |
if (usedProps.hasOwnProperty(prop.name)) { | |
var deadProps = usedProps[prop.name]; | |
for (var j = 0; j < deadProps.length; ++j) { | |
var deadProp = deadProps[j]; | |
if (!deadProp.disabled && !deadProp.wasInherited && deadProp.important && !prop.important) { | |
prop.overridden = true | |
} else { | |
if (!prop.disabled) { | |
deadProp.overridden = true | |
} | |
} | |
} | |
} else { | |
usedProps[prop.name] = [] | |
} | |
prop.wasInherited = inheritMode ? true: false; | |
usedProps[prop.name].push(prop) | |
} | |
}, | |
getStyleProperties: function(element, rules, usedProps, inheritMode) { | |
var props = this.parseCSSProps(element.style, inheritMode); | |
this.addOldProperties(this.context, getElementXPath(element), inheritMode, props); | |
sortProperties(props); | |
this.markOverridenProps(props, usedProps, inheritMode); | |
if (props.length) { | |
rules.splice(0, 0, { | |
rule: element, | |
id: getElementXPath(element), | |
selector: "element.style", | |
props: props, | |
inherited: inheritMode | |
}) | |
} | |
}, | |
name: "css", | |
title: "Style", | |
parentPanel: "HTML", | |
order: 0, | |
initialize: function() { | |
this.context = Firebug.chrome; | |
this.document = Firebug.chrome.document; | |
Firebug.CSSStyleSheetPanel.prototype.initialize.apply(this, arguments); | |
var selection = ElementCache.get(Firebug.context.persistedState.selectedHTMLElementId); | |
if (selection) { | |
this.select(selection, true) | |
} | |
}, | |
ishow: function(state) {}, | |
watchWindow: function(win) { | |
if (domUtils) { | |
var doc = win.document | |
} | |
}, | |
unwatchWindow: function(win) { | |
var doc = win.document; | |
if (isAncestor(this.stateChangeEl, doc)) { | |
this.removeStateChangeHandlers() | |
} | |
}, | |
supportsObject: function(object) { | |
return object instanceof Element ? 1 : 0 | |
}, | |
updateView: function(element) { | |
this.updateCascadeView(element); | |
if (domUtils) { | |
this.contentState = safeGetContentState(element); | |
this.addStateChangeHandlers(element) | |
} | |
}, | |
updateSelection: function(element) { | |
if (!instanceOf(element, "Element")) { | |
return | |
} | |
if (sothinkInstalled) { | |
FirebugReps.Warning.tag.replace({ | |
object: "SothinkWarning" | |
}, | |
this.panelNode); | |
return | |
} | |
if (!element) { | |
return | |
} | |
this.updateView(element) | |
}, | |
updateOption: function(name, value) { | |
if (name == "showUserAgentCSS" || name == "expandShorthandProps") { | |
this.refresh() | |
} | |
}, | |
getOptionsMenuItems: function() { | |
var ret = [{ | |
label: "Show User Agent CSS", | |
type: "checkbox", | |
checked: Firebug.showUserAgentCSS, | |
command: bindFixed(Firebug.togglePref, Firebug, "showUserAgentCSS") | |
}, | |
{ | |
label: "Expand Shorthand Properties", | |
type: "checkbox", | |
checked: Firebug.expandShorthandProps, | |
command: bindFixed(Firebug.togglePref, Firebug, "expandShorthandProps") | |
}]; | |
if (domUtils && this.selection) { | |
var state = safeGetContentState(this.selection); | |
ret.push("-"); | |
ret.push({ | |
label: ":active", | |
type: "checkbox", | |
checked: state & STATE_ACTIVE, | |
command: bindFixed(this.updateContentState, this, STATE_ACTIVE, state & STATE_ACTIVE) | |
}); | |
ret.push({ | |
label: ":hover", | |
type: "checkbox", | |
checked: state & STATE_HOVER, | |
command: bindFixed(this.updateContentState, this, STATE_HOVER, state & STATE_HOVER) | |
}) | |
} | |
return ret | |
}, | |
updateContentState: function(state, remove) { | |
domUtils.setContentState(remove ? this.selection.ownerDocument.documentElement: this.selection, state); | |
this.refresh() | |
}, | |
addStateChangeHandlers: function(el) { | |
this.removeStateChangeHandlers(); | |
this.stateChangeEl = el | |
}, | |
removeStateChangeHandlers: function() { | |
var sel = this.stateChangeEl; | |
if (sel) {} | |
}, | |
contentStateCheck: function(state) { | |
if (!state || this.contentState & state) { | |
var timeoutRunner = bindFixed(function() { | |
var newState = safeGetContentState(this.selection); | |
if (newState != this.contentState) { | |
this.context.invalidatePanels(this.name) | |
} | |
}, | |
this); | |
setTimeout(timeoutRunner, 0) | |
} | |
} | |
}); | |
function safeGetContentState(selection) { | |
try { | |
return domUtils.getContentState(selection) | |
} catch(e) { | |
if (FBTrace.DBG_ERRORS) { | |
FBTrace.sysout("css.safeGetContentState; EXCEPTION", e) | |
} | |
} | |
} | |
function CSSComputedElementPanel() {} | |
CSSComputedElementPanel.prototype = extend(CSSElementPanel.prototype, { | |
template: domplate({ | |
computedTag: DIV({ | |
"class": "a11yCSSView", | |
role: "list", | |
"aria-label": $STR("aria.labels.computed styles") | |
}, | |
FOR("group", "$groups", H1({ | |
"class": "cssInheritHeader groupHeader focusRow", | |
role: "listitem" | |
}, | |
SPAN({ | |
"class": "cssInheritLabel" | |
}, | |
"$group.title")), TABLE({ | |
width: "100%", | |
role: "group" | |
}, | |
TBODY({ | |
role: "presentation" | |
}, | |
FOR("prop", "$group.props", TR({ | |
"class": "focusRow computedStyleRow", | |
role: "listitem" | |
}, | |
TD({ | |
"class": "stylePropName", | |
role: "presentation" | |
}, | |
"$prop.name"), TD({ | |
"class": "stylePropValue", | |
role: "presentation" | |
}, | |
"$prop.value"))))))) | |
}), | |
updateComputedView: function(element) { | |
var win = isIE ? element.ownerDocument.parentWindow: element.ownerDocument.defaultView; | |
var style = isIE ? element.currentStyle: win.getComputedStyle(element, ""); | |
var groups = []; | |
for (var groupName in styleGroups) { | |
var title = styleGroupTitles[groupName]; | |
var group = { | |
title: title, | |
props: [] | |
}; | |
groups.push(group); | |
var props = styleGroups[groupName]; | |
for (var i = 0; i < props.length; ++i) { | |
var propName = props[i]; | |
var propValue = style.getPropertyValue ? style.getPropertyValue(propName) : "" + style[toCamelCase(propName)]; | |
if (propValue === undefined || propValue === null) { | |
continue | |
} | |
propValue = stripUnits(rgbToHex(propValue)); | |
if (propValue) { | |
group.props.push({ | |
name: propName, | |
value: propValue | |
}) | |
} | |
} | |
} | |
var result = this.template.computedTag.replace({ | |
groups: groups | |
}, | |
this.panelNode) | |
}, | |
name: "computed", | |
title: "Computed", | |
parentPanel: "HTML", | |
order: 1, | |
updateView: function(element) { | |
this.updateComputedView(element) | |
}, | |
getOptionsMenuItems: function() { | |
return [{ | |
label: "Refresh", | |
command: bind(this.refresh, this) | |
}] | |
} | |
}); | |
function CSSEditor(doc) { | |
this.initializeInline(doc) | |
} | |
CSSEditor.prototype = domplate(Firebug.InlineEditor.prototype, { | |
insertNewRow: function(target, insertWhere) { | |
var rule = Firebug.getRepObject(target); | |
var emptyProp = { | |
name: "", | |
value: "", | |
important: "" | |
}; | |
if (insertWhere == "before") { | |
return CSSPropTag.tag.insertBefore({ | |
prop: emptyProp, | |
rule: rule | |
}, | |
target) | |
} else { | |
return CSSPropTag.tag.insertAfter({ | |
prop: emptyProp, | |
rule: rule | |
}, | |
target) | |
} | |
}, | |
saveEdit: function(target, value, previousValue) { | |
if (!value) { | |
return | |
} | |
target.innerHTML = escapeForCss(value); | |
var row = getAncestorByClass(target, "cssProp"); | |
if (hasClass(row, "disabledStyle")) { | |
toggleClass(row, "disabledStyle") | |
} | |
var rule = Firebug.getRepObject(target); | |
if (hasClass(target, "cssPropName")) { | |
if (value && previousValue != value) { | |
var propValue = getChildByClass(row, "cssPropValue")[textContent]; | |
var parsedValue = parsePriority(propValue); | |
if (propValue && propValue != "undefined") { | |
if (FBTrace.DBG_CSS) { | |
FBTrace.sysout("CSSEditor.saveEdit : " + previousValue + "->" + value + " = " + propValue + "\n") | |
} | |
if (previousValue) { | |
Firebug.CSSModule.removeProperty(rule, previousValue) | |
} | |
Firebug.CSSModule.setProperty(rule, value, parsedValue.value, parsedValue.priority) | |
} | |
} else { | |
if (!value) { | |
Firebug.CSSModule.removeProperty(rule, previousValue) | |
} | |
} | |
} else { | |
if (getAncestorByClass(target, "cssPropValue")) { | |
var propName = getChildByClass(row, "cssPropName")[textContent]; | |
var propValue = getChildByClass(row, "cssPropValue")[textContent]; | |
if (FBTrace.DBG_CSS) { | |
FBTrace.sysout("CSSEditor.saveEdit propName=propValue: " + propName + " = " + propValue + "\n") | |
} | |
if (value && value != "null") { | |
var parsedValue = parsePriority(value); | |
Firebug.CSSModule.setProperty(rule, propName, parsedValue.value, parsedValue.priority) | |
} else { | |
if (previousValue && previousValue != "null") { | |
Firebug.CSSModule.removeProperty(rule, propName) | |
} | |
} | |
} | |
} | |
this.panel.markChange(this.panel.name == "stylesheet") | |
}, | |
advanceToNext: function(target, charCode) { | |
if (charCode == 58 && hasClass(target, "cssPropName")) { | |
return true | |
} | |
}, | |
getAutoCompleteRange: function(value, offset) { | |
if (hasClass(this.target, "cssPropName")) { | |
return { | |
start: 0, | |
end: value.length - 1 | |
} | |
} else { | |
return parseCSSValue(value, offset) | |
} | |
}, | |
getAutoCompleteList: function(preExpr, expr, postExpr) { | |
if (hasClass(this.target, "cssPropName")) { | |
return getCSSPropertyNames() | |
} else { | |
var row = getAncestorByClass(this.target, "cssProp"); | |
var propName = getChildByClass(row, "cssPropName")[textContent]; | |
return getCSSKeywordsByProperty(propName) | |
} | |
} | |
}); | |
function CSSRuleEditor(doc) { | |
this.initializeInline(doc); | |
this.completeAsYouType = false | |
} | |
CSSRuleEditor.uniquifier = 0; | |
CSSRuleEditor.prototype = domplate(Firebug.InlineEditor.prototype, { | |
insertNewRow: function(target, insertWhere) { | |
var emptyRule = { | |
selector: "", | |
id: "", | |
props: [], | |
isSelectorEditable: true | |
}; | |
if (insertWhere == "before") { | |
return CSSStyleRuleTag.tag.insertBefore({ | |
rule: emptyRule | |
}, | |
target) | |
} else { | |
return CSSStyleRuleTag.tag.insertAfter({ | |
rule: emptyRule | |
}, | |
target) | |
} | |
}, | |
saveEdit: function(target, value, previousValue) { | |
if (FBTrace.DBG_CSS) { | |
FBTrace.sysout("CSSRuleEditor.saveEdit: '" + value + "' '" + previousValue + "'", target) | |
} | |
target.innerHTML = escapeForCss(value); | |
if (value === previousValue) { | |
return | |
} | |
var row = getAncestorByClass(target, "cssRule"); | |
var styleSheet = this.panel.location; | |
styleSheet = styleSheet.editStyleSheet ? styleSheet.editStyleSheet.sheet: styleSheet; | |
var cssRules = styleSheet.cssRules; | |
var rule = Firebug.getRepObject(target), | |
oldRule = rule; | |
var ruleIndex = cssRules.length; | |
if (rule || Firebug.getRepObject(row.nextSibling)) { | |
var searchRule = rule || Firebug.getRepObject(row.nextSibling); | |
for (ruleIndex = 0; ruleIndex < cssRules.length && searchRule != cssRules[ruleIndex]; ruleIndex++) {} | |
} | |
if (oldRule) { | |
Firebug.CSSModule.deleteRule(styleSheet, ruleIndex) | |
} | |
if (value) { | |
var cssText = [value, "{"]; | |
var props = row.getElementsByClassName("cssProp"); | |
for (var i = 0; i < props.length; i++) { | |
var propEl = props[i]; | |
if (!hasClass(propEl, "disabledStyle")) { | |
cssText.push(getChildByClass(propEl, "cssPropName")[textContent]); | |
cssText.push(":"); | |
cssText.push(getChildByClass(propEl, "cssPropValue")[textContent]); | |
cssText.push(";") | |
} | |
} | |
cssText.push("}"); | |
cssText = cssText.join(""); | |
try { | |
var insertLoc = Firebug.CSSModule.insertRule(styleSheet, cssText, ruleIndex); | |
rule = cssRules[insertLoc]; | |
ruleIndex++ | |
} catch(err) { | |
if (FBTrace.DBG_CSS || FBTrace.DBG_ERRORS) { | |
FBTrace.sysout("CSS Insert Error: " + err, err) | |
} | |
target.innerHTML = escapeForCss(previousValue); | |
row.repObject = undefined; | |
return | |
} | |
} else { | |
rule = undefined | |
} | |
row.repObject = rule; | |
if (!oldRule) { | |
var ruleId = "new/" + value + "/" + (++CSSRuleEditor.uniquifier); | |
row.setAttribute("ruleId", ruleId) | |
} | |
this.panel.markChange(this.panel.name == "stylesheet") | |
} | |
}); | |
function StyleSheetEditor(doc) { | |
this.box = this.tag.replace({}, | |
doc, this); | |
this.input = this.box.firstChild | |
} | |
StyleSheetEditor.prototype = domplate(Firebug.BaseEditor, { | |
multiLine: true, | |
tag: DIV(TEXTAREA({ | |
"class": "styleSheetEditor fullPanelEditor", | |
oninput: "$onInput" | |
})), | |
getValue: function() { | |
return this.input.value | |
}, | |
setValue: function(value) { | |
return this.input.value = value | |
}, | |
show: function(target, panel, value, textSize, targetSize) { | |
this.target = target; | |
this.panel = panel; | |
this.panel.panelNode.appendChild(this.box); | |
this.input.value = value; | |
this.input.focus(); | |
var command = Firebug.chrome.$("cmd_toggleCSSEditing"); | |
command.setAttribute("checked", true) | |
}, | |
hide: function() { | |
var command = Firebug.chrome.$("cmd_toggleCSSEditing"); | |
command.setAttribute("checked", false); | |
if (this.box.parentNode == this.panel.panelNode) { | |
this.panel.panelNode.removeChild(this.box) | |
} | |
delete this.target; | |
delete this.panel; | |
delete this.styleSheet | |
}, | |
saveEdit: function(target, value, previousValue) { | |
Firebug.CSSModule.freeEdit(this.styleSheet, value) | |
}, | |
endEditing: function() { | |
this.panel.refresh(); | |
return true | |
}, | |
onInput: function() { | |
Firebug.Editor.update() | |
}, | |
scrollToLine: function(line, offset) { | |
this.startMeasuring(this.input); | |
var lineHeight = this.measureText().height; | |
this.stopMeasuring(); | |
this.input.scrollTop = (line * lineHeight) + offset | |
} | |
}); | |
var rgbToHex = function rgbToHex(value) { | |
return value.replace(/\brgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)/gi, rgbToHexReplacer) | |
}; | |
var rgbToHexReplacer = function(_, r, g, b) { | |
return "#" + ((1 << 24) + (r << 16) + (g << 8) + (b << 0)).toString(16).substr( - 6).toUpperCase() | |
}; | |
var stripUnits = function stripUnits(value) { | |
return value.replace(/(url\(.*?\)|[^0]\S*\s*)|0(%|em|ex|px|in|cm|mm|pt|pc)(\s|$)/gi, stripUnitsReplacer) | |
}; | |
var stripUnitsReplacer = function(_, skip, remove, whitespace) { | |
return skip || ("0" + whitespace) | |
}; | |
function parsePriority(value) { | |
var rePriority = /(.*?)\s*(!important)?$/; | |
var m = rePriority.exec(value); | |
var propValue = m ? m[1] : ""; | |
var priority = m && m[2] ? "important": ""; | |
return { | |
value: propValue, | |
priority: priority | |
} | |
} | |
function parseURLValue(value) { | |
var m = reURL.exec(value); | |
return m ? m[1] : "" | |
} | |
function parseRepeatValue(value) { | |
var m = reRepeat.exec(value); | |
return m ? m[0] : "" | |
} | |
function parseCSSValue(value, offset) { | |
var start = 0; | |
var m; | |
while (1) { | |
m = reSplitCSS.exec(value); | |
if (m && m.index + m[0].length < offset) { | |
value = value.substr(m.index + m[0].length); | |
start += m.index + m[0].length; | |
offset -= m.index + m[0].length | |
} else { | |
break | |
} | |
} | |
if (m) { | |
var type; | |
if (m[1]) { | |
type = "url" | |
} else { | |
if (m[2] || m[3]) { | |
type = "rgb" | |
} else { | |
if (m[4]) { | |
type = "int" | |
} | |
} | |
} | |
return { | |
value: m[0], | |
start: start + m.index, | |
end: start + m.index + (m[0].length - 1), | |
type: type | |
} | |
} | |
} | |
function findPropByName(props, name) { | |
for (var i = 0; i < props.length; ++i) { | |
if (props[i].name == name) { | |
return i | |
} | |
} | |
} | |
function sortProperties(props) { | |
props.sort(function(a, b) { | |
return a.name > b.name ? 1 : -1 | |
}) | |
} | |
function getTopmostRuleLine(panelNode) { | |
for (var child = panelNode.firstChild; child; child = child.nextSibling) { | |
if (child.offsetTop + child.offsetHeight > panelNode.scrollTop) { | |
var rule = child.repObject; | |
if (rule) { | |
return { | |
line: domUtils.getRuleLine(rule), | |
offset: panelNode.scrollTop - child.offsetTop | |
} | |
} | |
} | |
} | |
return 0 | |
} | |
function getStyleSheetCSS(sheet, context) { | |
if (sheet.ownerNode instanceof HTMLStyleElement) { | |
return sheet.ownerNode.innerHTML | |
} else { | |
return context.sourceCache.load(sheet.href).join("") | |
} | |
} | |
function getStyleSheetOwnerNode(sheet) { | |
for (; sheet && !sheet.ownerNode; sheet = sheet.parentStyleSheet) {} | |
return sheet.ownerNode | |
} | |
function scrollSelectionIntoView(panel) { | |
var selCon = getSelectionController(panel); | |
selCon.scrollSelectionIntoView(nsISelectionController.SELECTION_NORMAL, nsISelectionController.SELECTION_FOCUS_REGION, true) | |
} | |
function getSelectionController(panel) { | |
var browser = Firebug.chrome.getPanelBrowser(panel); | |
return browser.docShell.QueryInterface(nsIInterfaceRequestor).getInterface(nsISelectionDisplay).QueryInterface(nsISelectionController) | |
} | |
Firebug.registerModule(Firebug.CSSModule); | |
Firebug.registerPanel(Firebug.CSSStyleSheetPanel); | |
Firebug.registerPanel(CSSElementPanel); | |
Firebug.registerPanel(CSSComputedElementPanel) | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
Firebug.Script = extend(Firebug.Module, { | |
getPanel: function() { | |
return Firebug.chrome ? Firebug.chrome.getPanel("Script") : null | |
}, | |
selectSourceCode: function(index) { | |
this.getPanel().selectSourceCode(index) | |
} | |
}); | |
Firebug.registerModule(Firebug.Script); | |
function ScriptPanel() {} | |
ScriptPanel.prototype = extend(Firebug.Panel, { | |
name: "Script", | |
title: "Script", | |
selectIndex: 0, | |
sourceIndex: -1, | |
options: { | |
hasToolButtons: true | |
}, | |
create: function() { | |
Firebug.Panel.create.apply(this, arguments); | |
this.onChangeSelect = bind(this.onChangeSelect, this); | |
var doc = Firebug.browser.document; | |
var scripts = doc.getElementsByTagName("script"); | |
var selectNode = this.selectNode = createElement("select"); | |
for (var i = 0, | |
script; script = scripts[i]; i++) { | |
if (Firebug.ignoreFirebugElements && script.getAttribute("firebugIgnore")) { | |
continue | |
} | |
var fileName = getFileName(script.src) || getFileName(doc.location.href); | |
var option = createElement("option", { | |
value: i | |
}); | |
option.appendChild(Firebug.chrome.document.createTextNode(fileName)); | |
selectNode.appendChild(option) | |
} | |
this.toolButtonsNode.appendChild(selectNode) | |
}, | |
initialize: function() { | |
this.selectSourceCode(this.selectIndex); | |
Firebug.Panel.initialize.apply(this, arguments); | |
addEvent(this.selectNode, "change", this.onChangeSelect) | |
}, | |
shutdown: function() { | |
removeEvent(this.selectNode, "change", this.onChangeSelect); | |
Firebug.Panel.shutdown.apply(this, arguments) | |
}, | |
detach: function(oldChrome, newChrome) { | |
Firebug.Panel.detach.apply(this, arguments); | |
var oldPanel = oldChrome.getPanel("Script"); | |
var index = oldPanel.selectIndex; | |
this.selectNode.selectedIndex = index; | |
this.selectIndex = index; | |
this.sourceIndex = -1 | |
}, | |
onChangeSelect: function(event) { | |
var select = this.selectNode; | |
this.selectIndex = select.selectedIndex; | |
var option = select.options[select.selectedIndex]; | |
if (!option) { | |
return | |
} | |
var selectedSourceIndex = parseInt(option.value); | |
this.renderSourceCode(selectedSourceIndex) | |
}, | |
selectSourceCode: function(index) { | |
var select = this.selectNode; | |
select.selectedIndex = index; | |
var option = select.options[index]; | |
if (!option) { | |
return | |
} | |
var selectedSourceIndex = parseInt(option.value); | |
this.renderSourceCode(selectedSourceIndex) | |
}, | |
renderSourceCode: function(index) { | |
if (this.sourceIndex != index) { | |
var renderProcess = function renderProcess(src) { | |
var html = [], | |
hl = 0; | |
src = isIE && !isExternal ? src + "\n": "\n" + src; | |
src = src.replace(/\n\r|\r\n/g, "\n"); | |
var match = src.match(/[\n]/g); | |
var lines = match ? match.length: 0; | |
html[hl++] = '<div><div class="sourceBox" style="left:'; | |
html[hl++] = 35 + 7 * (lines + "").length; | |
html[hl++] = 'px;"><pre class="sourceCode">'; | |
html[hl++] = escapeHTML(src); | |
html[hl++] = '</pre></div><div class="lineNo">'; | |
for (var l = 1, | |
lines; l <= lines; l++) { | |
html[hl++] = '<div line="'; | |
html[hl++] = l; | |
html[hl++] = '">'; | |
html[hl++] = l; | |
html[hl++] = "</div>" | |
} | |
html[hl++] = "</div></div>"; | |
updatePanel(html) | |
}; | |
var updatePanel = function(html) { | |
self.panelNode.innerHTML = html.join(""); | |
setTimeout(function() { | |
self.synchronizeUI() | |
}, | |
0) | |
}; | |
var onFailure = function() { | |
FirebugReps.Warning.tag.replace({ | |
object: "AccessRestricted" | |
}, | |
self.panelNode) | |
}; | |
var self = this; | |
var doc = Firebug.browser.document; | |
var script = doc.getElementsByTagName("script")[index]; | |
var url = getScriptURL(script); | |
var isExternal = url && url != doc.location.href; | |
try { | |
if (Firebug.disableResourceFetching) { | |
renderProcess(Firebug.Lite.Proxy.fetchResourceDisabledMessage) | |
} else { | |
if (isExternal) { | |
Ajax.request({ | |
url: url, | |
onSuccess: renderProcess, | |
onFailure: onFailure | |
}) | |
} else { | |
var src = script.innerHTML; | |
renderProcess(src) | |
} | |
} | |
} catch(e) { | |
onFailure() | |
} | |
this.sourceIndex = index | |
} | |
} | |
}); | |
Firebug.registerPanel(ScriptPanel); | |
var getScriptURL = function getScriptURL(script) { | |
var reFile = /([^\/\?#]+)(#.+)?$/; | |
var rePath = /^(.*\/)/; | |
var reProtocol = /^\w+:\/\//; | |
var path = null; | |
var doc = Firebug.browser.document; | |
var file = reFile.exec(script.src); | |
if (file) { | |
var fileName = file[1]; | |
var fileOptions = file[2]; | |
if (reProtocol.test(script.src)) { | |
path = rePath.exec(script.src)[1] | |
} else { | |
var r = rePath.exec(script.src); | |
var src = r ? r[1] : script.src; | |
var backDir = /^((?:\.\.\/)+)(.*)/.exec(src); | |
var reLastDir = /^(.*\/)[^\/]+\/$/; | |
path = rePath.exec(doc.location.href)[1]; | |
if (backDir) { | |
var j = backDir[1].length / 3; | |
var p; | |
while (j-->0) { | |
path = reLastDir.exec(path)[1] | |
} | |
path += backDir[2] | |
} else { | |
if (src.indexOf("/") != -1) { | |
if (/^\.\/./.test(src)) { | |
path += src.substring(2) | |
} else { | |
if (/^\/./.test(src)) { | |
var domain = /^(\w+:\/\/[^\/]+)/.exec(path); | |
path = domain[1] + src | |
} else { | |
path += src | |
} | |
} | |
} | |
} | |
} | |
} | |
var m = path && path.match(/([^\/]+)\/$/) || null; | |
if (path && m) { | |
return path + fileName | |
} | |
}; | |
var getFileName = function getFileName(path) { | |
if (!path) { | |
return "" | |
} | |
var match = path && path.match(/[^\/]+(\?.*)?(#.*)?$/); | |
return match && match[0] || path | |
} | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
var ElementCache = Firebug.Lite.Cache.Element; | |
var insertSliceSize = 18; | |
var insertInterval = 40; | |
var ignoreVars = { | |
__firebug__: 1, | |
"eval": 1, | |
java: 1, | |
sun: 1, | |
Packages: 1, | |
JavaArray: 1, | |
JavaMember: 1, | |
JavaObject: 1, | |
JavaClass: 1, | |
JavaPackage: 1, | |
_firebug: 1, | |
_FirebugConsole: 1, | |
_FirebugCommandLine: 1 | |
}; | |
if (Firebug.ignoreFirebugElements) { | |
ignoreVars[Firebug.Lite.Cache.ID] = 1 | |
} | |
var memberPanelRep = isIE6 ? { | |
"class": "memberLabel $member.type\\Label", | |
href: "javacript:void(0)" | |
}: { | |
"class": "memberLabel $member.type\\Label" | |
}; | |
var RowTag = TR({ | |
"class": "memberRow $member.open $member.type\\Row", | |
$hasChildren: "$member.hasChildren", | |
role: "presentation", | |
level: "$member.level" | |
}, | |
TD({ | |
"class": "memberLabelCell", | |
style: "padding-left: $member.indent\\px", | |
role: "presentation" | |
}, | |
A(memberPanelRep, SPAN({}, | |
"$member.name"))), TD({ | |
"class": "memberValueCell", | |
role: "presentation" | |
}, | |
TAG("$member.tag", { | |
object: "$member.value" | |
}))); | |
var WatchRowTag = TR({ | |
"class": "watchNewRow", | |
level: 0 | |
}, | |
TD({ | |
"class": "watchEditCell", | |
colspan: 2 | |
}, | |
DIV({ | |
"class": "watchEditBox a11yFocusNoTab", | |
role: "button", | |
tabindex: "0", | |
"aria-label": $STR("press enter to add new watch expression") | |
}, | |
$STR("NewWatch")))); | |
var SizerRow = TR({ | |
role: "presentation" | |
}, | |
TD({ | |
width: "30%" | |
}), TD({ | |
width: "70%" | |
})); | |
var domTableClass = isIElt8 ? "domTable domTableIE": "domTable"; | |
var DirTablePlate = domplate(Firebug.Rep, { | |
tag: TABLE({ | |
"class": domTableClass, | |
cellpadding: 0, | |
cellspacing: 0, | |
onclick: "$onClick", | |
role: "tree" | |
}, | |
TBODY({ | |
role: "presentation" | |
}, | |
SizerRow, FOR("member", "$object|memberIterator", RowTag))), | |
watchTag: TABLE({ | |
"class": domTableClass, | |
cellpadding: 0, | |
cellspacing: 0, | |
_toggles: "$toggles", | |
_domPanel: "$domPanel", | |
onclick: "$onClick", | |
role: "tree" | |
}, | |
TBODY({ | |
role: "presentation" | |
}, | |
SizerRow, WatchRowTag)), | |
tableTag: TABLE({ | |
"class": domTableClass, | |
cellpadding: 0, | |
cellspacing: 0, | |
_toggles: "$toggles", | |
_domPanel: "$domPanel", | |
onclick: "$onClick", | |
role: "tree" | |
}, | |
TBODY({ | |
role: "presentation" | |
}, | |
SizerRow)), | |
rowTag: FOR("member", "$members", RowTag), | |
memberIterator: function(object, level) { | |
return getMembers(object, level) | |
}, | |
onClick: function(event) { | |
if (!isLeftClick(event)) { | |
return | |
} | |
var target = event.target || event.srcElement; | |
var row = getAncestorByClass(target, "memberRow"); | |
var label = getAncestorByClass(target, "memberLabel"); | |
if (label && hasClass(row, "hasChildren")) { | |
var row = label.parentNode.parentNode; | |
this.toggleRow(row) | |
} else { | |
var object = Firebug.getRepObject(target); | |
if (typeof(object) == "function") { | |
Firebug.chrome.select(object, "script"); | |
cancelEvent(event) | |
} else { | |
if (event.detail == 2 && !object) { | |
var panel = row.parentNode.parentNode.domPanel; | |
if (panel) { | |
var rowValue = panel.getRowPropertyValue(row); | |
if (typeof(rowValue) == "boolean") { | |
panel.setPropertyValue(row, !rowValue) | |
} else { | |
panel.editProperty(row) | |
} | |
cancelEvent(event) | |
} | |
} | |
} | |
} | |
return false | |
}, | |
toggleRow: function(row) { | |
var level = parseInt(row.getAttribute("level")); | |
var toggles = row.parentNode.parentNode.toggles; | |
if (hasClass(row, "opened")) { | |
removeClass(row, "opened"); | |
if (toggles) { | |
var path = getPath(row); | |
for (var i = 0; i < path.length; ++i) { | |
if (i == path.length - 1) { | |
delete toggles[path[i]] | |
} else { | |
toggles = toggles[path[i]] | |
} | |
} | |
} | |
var rowTag = this.rowTag; | |
var tbody = row.parentNode; | |
setTimeout(function() { | |
for (var firstRow = row.nextSibling; firstRow; firstRow = row.nextSibling) { | |
if (parseInt(firstRow.getAttribute("level")) <= level) { | |
break | |
} | |
tbody.removeChild(firstRow) | |
} | |
}, | |
row.insertTimeout ? row.insertTimeout: 0) | |
} else { | |
setClass(row, "opened"); | |
if (toggles) { | |
var path = getPath(row); | |
for (var i = 0; i < path.length; ++i) { | |
var name = path[i]; | |
if (toggles.hasOwnProperty(name)) { | |
toggles = toggles[name] | |
} else { | |
toggles = toggles[name] = {} | |
} | |
} | |
} | |
var value = row.lastChild.firstChild.repObject; | |
var members = getMembers(value, level + 1); | |
var rowTag = this.rowTag; | |
var lastRow = row; | |
var delay = 0; | |
while (members.length) { | |
with({ | |
slice: members.splice(0, insertSliceSize), | |
isLast: !members.length | |
}) { | |
setTimeout(function() { | |
if (lastRow.parentNode) { | |
var result = rowTag.insertRows({ | |
members: slice | |
}, | |
lastRow); | |
lastRow = result[1] | |
} | |
if (isLast) { | |
row.removeAttribute("insertTimeout") | |
} | |
}, | |
delay) | |
} | |
delay += insertInterval | |
} | |
row.insertTimeout = delay | |
} | |
} | |
}); | |
Firebug.DOMBasePanel = function() {}; | |
Firebug.DOMBasePanel.prototype = extend(Firebug.Panel, { | |
tag: DirTablePlate.tableTag, | |
getRealObject: function(object) { | |
if (!object) { | |
return object | |
} | |
if (object.wrappedJSObject) { | |
return object.wrappedJSObject | |
} | |
return object | |
}, | |
rebuild: function(update, scrollTop) { | |
var members = getMembers(this.selection); | |
expandMembers(members, this.toggles, 0, 0); | |
this.showMembers(members, update, scrollTop); | |
if (!this.parentPanel) { | |
updateStatusBar(this) | |
} | |
}, | |
showMembers: function(members, update, scrollTop) { | |
if (this.timeouts) { | |
for (var i = 0; i < this.timeouts.length; ++i) { | |
this.context.clearTimeout(this.timeouts[i]) | |
} | |
delete this.timeouts | |
} | |
if (!members.length) { | |
return this.showEmptyMembers() | |
} | |
var panelNode = this.panelNode; | |
var priorScrollTop = scrollTop == undefined ? panelNode.scrollTop: scrollTop; | |
var offscreen = update && panelNode.firstChild; | |
var dest = offscreen ? panelNode.ownerDocument: panelNode; | |
var table = this.tag.replace({ | |
domPanel: this, | |
toggles: this.toggles | |
}, | |
dest); | |
var tbody = table.lastChild; | |
var rowTag = DirTablePlate.rowTag; | |
var panel = this; | |
var result; | |
var timeouts = []; | |
var delay = 0; | |
var renderStart = new Date().getTime(); | |
while (members.length) { | |
with({ | |
slice: members.splice(0, insertSliceSize), | |
isLast: !members.length | |
}) { | |
timeouts.push(this.context.setTimeout(function() { | |
if (!tbody.lastChild) { | |
return | |
} | |
result = rowTag.insertRows({ | |
members: slice | |
}, | |
tbody.lastChild); | |
if ((panelNode.scrollHeight + panelNode.offsetHeight) >= priorScrollTop) { | |
panelNode.scrollTop = priorScrollTop | |
} | |
}, | |
delay)); | |
delay += insertInterval | |
} | |
} | |
if (offscreen) { | |
timeouts.push(this.context.setTimeout(function() { | |
if (panelNode.firstChild) { | |
panelNode.replaceChild(table, panelNode.firstChild) | |
} else { | |
panelNode.appendChild(table) | |
} | |
panelNode.scrollTop = priorScrollTop | |
}, | |
delay)) | |
} else { | |
timeouts.push(this.context.setTimeout(function() { | |
panelNode.scrollTop = scrollTop == undefined ? 0 : scrollTop | |
}, | |
delay)) | |
} | |
this.timeouts = timeouts | |
}, | |
showEmptyMembers: function() { | |
FirebugReps.Warning.tag.replace({ | |
object: "NoMembersWarning" | |
}, | |
this.panelNode) | |
}, | |
findPathObject: function(object) { | |
var pathIndex = -1; | |
for (var i = 0; i < this.objectPath.length; ++i) { | |
if (this.getPathObject(i) === object) { | |
return i | |
} | |
} | |
return - 1 | |
}, | |
getPathObject: function(index) { | |
var object = this.objectPath[index]; | |
if (object instanceof Property) { | |
return object.getObject() | |
} else { | |
return object | |
} | |
}, | |
getRowObject: function(row) { | |
var object = getRowOwnerObject(row); | |
return object ? object: this.selection | |
}, | |
getRowPropertyValue: function(row) { | |
var object = this.getRowObject(row); | |
object = this.getRealObject(object); | |
if (object) { | |
var propName = getRowName(row); | |
if (object instanceof jsdIStackFrame) { | |
return Firebug.Debugger.evaluate(propName, this.context) | |
} else { | |
return object[propName] | |
} | |
} | |
}, | |
onMouseMove: function(event) { | |
var target = event.srcElement || event.target; | |
var object = getAncestorByClass(target, "objectLink-element"); | |
object = object ? object.repObject: null; | |
if (object && instanceOf(object, "Element") && object.nodeType == 1) { | |
if (object != lastHighlightedObject) { | |
Firebug.Inspector.drawBoxModel(object); | |
object = lastHighlightedObject | |
} | |
} else { | |
Firebug.Inspector.hideBoxModel() | |
} | |
}, | |
create: function() { | |
this.context = Firebug.browser; | |
this.objectPath = []; | |
this.propertyPath = []; | |
this.viewPath = []; | |
this.pathIndex = -1; | |
this.toggles = {}; | |
Firebug.Panel.create.apply(this, arguments); | |
this.panelNode.style.padding = "0 1px" | |
}, | |
initialize: function() { | |
Firebug.Panel.initialize.apply(this, arguments); | |
addEvent(this.panelNode, "mousemove", this.onMouseMove) | |
}, | |
shutdown: function() { | |
removeEvent(this.panelNode, "mousemove", this.onMouseMove); | |
Firebug.Panel.shutdown.apply(this, arguments) | |
}, | |
ishow: function(state) { | |
if (this.context.loaded && !this.selection) { | |
if (!state) { | |
this.select(null); | |
return | |
} | |
if (state.viewPath) { | |
this.viewPath = state.viewPath | |
} | |
if (state.propertyPath) { | |
this.propertyPath = state.propertyPath | |
} | |
var defaultObject = this.getDefaultSelection(this.context); | |
var selectObject = defaultObject; | |
if (state.firstSelection) { | |
var restored = state.firstSelection(this.context); | |
if (restored) { | |
selectObject = restored; | |
this.objectPath = [defaultObject, restored] | |
} else { | |
this.objectPath = [defaultObject] | |
} | |
} else { | |
this.objectPath = [defaultObject] | |
} | |
if (this.propertyPath.length > 1) { | |
for (var i = 1; i < this.propertyPath.length; ++i) { | |
var name = this.propertyPath[i]; | |
if (!name) { | |
continue | |
} | |
var object = selectObject; | |
try { | |
selectObject = object[name] | |
} catch(exc) { | |
selectObject = null | |
} | |
if (selectObject) { | |
this.objectPath.push(new Property(object, name)) | |
} else { | |
this.viewPath.splice(i); | |
this.propertyPath.splice(i); | |
this.objectPath.splice(i); | |
selectObject = this.getPathObject(this.objectPath.length - 1); | |
break | |
} | |
} | |
} | |
var selection = state.pathIndex <= this.objectPath.length - 1 ? this.getPathObject(state.pathIndex) : this.getPathObject(this.objectPath.length - 1); | |
this.select(selection) | |
} | |
}, | |
supportsObject: function(object) { | |
if (object == null) { | |
return 1000 | |
} | |
if (typeof(object) == "undefined") { | |
return 1000 | |
} else { | |
if (object instanceof SourceLink) { | |
return 0 | |
} else { | |
return 1 | |
} | |
} | |
}, | |
refresh: function() { | |
this.rebuild(true) | |
}, | |
updateSelection: function(object) { | |
var previousIndex = this.pathIndex; | |
var previousView = previousIndex == -1 ? null: this.viewPath[previousIndex]; | |
var newPath = this.pathToAppend; | |
delete this.pathToAppend; | |
var pathIndex = this.findPathObject(object); | |
if (newPath || pathIndex == -1) { | |
this.toggles = {}; | |
if (newPath) { | |
if (previousView) { | |
if (this.panelNode.scrollTop) { | |
previousView.scrollTop = this.panelNode.scrollTop | |
} | |
var start = previousIndex + 1, | |
length = this.objectPath.length - start; | |
this.objectPath.splice(start, length); | |
this.propertyPath.splice(start, length); | |
this.viewPath.splice(start, length) | |
} | |
var value = this.getPathObject(previousIndex); | |
if (!value) { | |
if (FBTrace.DBG_ERRORS) { | |
FBTrace.sysout("dom.updateSelection no pathObject for " + previousIndex + "\n") | |
} | |
return | |
} | |
for (var i = 0, | |
length = newPath.length; i < length; ++i) { | |
var name = newPath[i]; | |
var object = value; | |
try { | |
value = value[name] | |
} catch(exc) { | |
if (FBTrace.DBG_ERRORS) { | |
FBTrace.sysout("dom.updateSelection FAILS at path_i=" + i + " for name:" + name + "\n") | |
} | |
return | |
}++this.pathIndex; | |
this.objectPath.push(new Property(object, name)); | |
this.propertyPath.push(name); | |
this.viewPath.push({ | |
toggles: this.toggles, | |
scrollTop: 0 | |
}) | |
} | |
} else { | |
this.toggles = {}; | |
var win = Firebug.browser.window; | |
if (object === win) { | |
this.pathIndex = 0; | |
this.objectPath = [win]; | |
this.propertyPath = [null]; | |
this.viewPath = [{ | |
toggles: this.toggles, | |
scrollTop: 0 | |
}] | |
} else { | |
this.pathIndex = 1; | |
this.objectPath = [win, object]; | |
this.propertyPath = [null, null]; | |
this.viewPath = [{ | |
toggles: {}, | |
scrollTop: 0 | |
}, | |
{ | |
toggles: this.toggles, | |
scrollTop: 0 | |
}] | |
} | |
} | |
this.panelNode.scrollTop = 0; | |
this.rebuild() | |
} else { | |
this.pathIndex = pathIndex; | |
var view = this.viewPath[pathIndex]; | |
this.toggles = view.toggles; | |
if (previousView && this.panelNode.scrollTop) { | |
previousView.scrollTop = this.panelNode.scrollTop | |
} | |
this.rebuild(false, view.scrollTop) | |
} | |
}, | |
getObjectPath: function(object) { | |
return this.objectPath | |
}, | |
getDefaultSelection: function() { | |
return Firebug.browser.window | |
} | |
}); | |
var updateStatusBar = function(panel) { | |
var path = panel.propertyPath; | |
var index = panel.pathIndex; | |
var r = []; | |
for (var i = 0, | |
l = path.length; i < l; i++) { | |
r.push(i == index ? '<a class="fbHover fbButton fbBtnSelected" ': '<a class="fbHover fbButton" '); | |
r.push("pathIndex="); | |
r.push(i); | |
if (isIE6) { | |
r.push(' href="javascript:void(0)"') | |
} | |
r.push(">"); | |
r.push(i == 0 ? "window": path[i] || "Object"); | |
r.push("</a>"); | |
if (i < l - 1) { | |
r.push('<span class="fbStatusSeparator">></span>') | |
} | |
} | |
panel.statusBarNode.innerHTML = r.join("") | |
}; | |
var DOMMainPanel = Firebug.DOMPanel = function() {}; | |
Firebug.DOMPanel.DirTable = DirTablePlate; | |
DOMMainPanel.prototype = extend(Firebug.DOMBasePanel.prototype, { | |
onClickStatusBar: function(event) { | |
var target = event.srcElement || event.target; | |
var element = getAncestorByClass(target, "fbHover"); | |
if (element) { | |
var pathIndex = element.getAttribute("pathIndex"); | |
if (pathIndex) { | |
this.select(this.getPathObject(pathIndex)) | |
} | |
} | |
}, | |
selectRow: function(row, target) { | |
if (!target) { | |
target = row.lastChild.firstChild | |
} | |
if (!target || !target.repObject) { | |
return | |
} | |
this.pathToAppend = getPath(row); | |
var valueBox = row.lastChild.firstChild; | |
if (hasClass(valueBox, "objectBox-array")) { | |
var arrayIndex = FirebugReps.Arr.getItemIndex(target); | |
this.pathToAppend.push(arrayIndex) | |
} | |
this.select(target.repObject, true) | |
}, | |
onClick: function(event) { | |
var target = event.srcElement || event.target; | |
var repNode = Firebug.getRepNode(target); | |
if (repNode) { | |
var row = getAncestorByClass(target, "memberRow"); | |
if (row) { | |
this.selectRow(row, repNode); | |
cancelEvent(event) | |
} | |
} | |
}, | |
name: "DOM", | |
title: "DOM", | |
searchable: true, | |
statusSeparator: ">", | |
options: { | |
hasToolButtons: true, | |
hasStatusBar: true | |
}, | |
create: function() { | |
Firebug.DOMBasePanel.prototype.create.apply(this, arguments); | |
this.onClick = bind(this.onClick, this); | |
this.onClickStatusBar = bind(this.onClickStatusBar, this); | |
this.panelNode.style.padding = "0 1px" | |
}, | |
initialize: function(oldPanelNode) { | |
Firebug.DOMBasePanel.prototype.initialize.apply(this, arguments); | |
addEvent(this.panelNode, "click", this.onClick); | |
this.ishow(); | |
addEvent(this.statusBarNode, "click", this.onClickStatusBar) | |
}, | |
shutdown: function() { | |
removeEvent(this.panelNode, "click", this.onClick); | |
Firebug.DOMBasePanel.prototype.shutdown.apply(this, arguments) | |
} | |
}); | |
Firebug.registerPanel(DOMMainPanel); | |
var getMembers = function getMembers(object, level) { | |
if (!level) { | |
level = 0 | |
} | |
var ordinals = [], | |
userProps = [], | |
userClasses = [], | |
userFuncs = [], | |
domProps = [], | |
domFuncs = [], | |
domConstants = []; | |
try { | |
var domMembers = getDOMMembers(object); | |
if (object.wrappedJSObject) { | |
var insecureObject = object.wrappedJSObject | |
} else { | |
var insecureObject = object | |
} | |
if (isIE && isFunction(object)) { | |
addMember("user", userProps, "prototype", object.prototype, level) | |
} | |
for (var name in insecureObject) { | |
if (ignoreVars[name] == 1) { | |
continue | |
} | |
var val; | |
try { | |
val = insecureObject[name] | |
} catch(exc) { | |
if (FBTrace.DBG_ERRORS && FBTrace.DBG_DOM) { | |
FBTrace.sysout("dom.getMembers cannot access " + name, exc) | |
} | |
} | |
var ordinal = parseInt(name); | |
if (ordinal || ordinal == 0) { | |
addMember("ordinal", ordinals, name, val, level) | |
} else { | |
if (isFunction(val)) { | |
if (isClassFunction(val) && !(name in domMembers)) { | |
addMember("userClass", userClasses, name, val, level) | |
} else { | |
if (name in domMembers) { | |
addMember("domFunction", domFuncs, name, val, level, domMembers[name]) | |
} else { | |
addMember("userFunction", userFuncs, name, val, level) | |
} | |
} | |
} else { | |
var prefix = ""; | |
if (name in domMembers && !(name in domConstantMap)) { | |
addMember("dom", domProps, (prefix + name), val, level, domMembers[name]) | |
} else { | |
if (name in domConstantMap) { | |
addMember("dom", domConstants, (prefix + name), val, level) | |
} else { | |
addMember("user", userProps, (prefix + name), val, level) | |
} | |
} | |
} | |
} | |
} | |
} catch(exc) { | |
throw exc; | |
if (FBTrace.DBG_ERRORS && FBTrace.DBG_DOM) { | |
FBTrace.sysout("dom.getMembers FAILS: ", exc) | |
} | |
} | |
function sortName(a, b) { | |
return a.name > b.name ? 1 : -1 | |
} | |
function sortOrder(a, b) { | |
return a.order > b.order ? 1 : -1 | |
} | |
var members = []; | |
members.push.apply(members, ordinals); | |
Firebug.showUserProps = true; | |
Firebug.showUserFuncs = true; | |
Firebug.showDOMProps = true; | |
Firebug.showDOMFuncs = true; | |
Firebug.showDOMConstants = true; | |
if (Firebug.showUserProps) { | |
userProps.sort(sortName); | |
members.push.apply(members, userProps) | |
} | |
if (Firebug.showUserFuncs) { | |
userClasses.sort(sortName); | |
members.push.apply(members, userClasses); | |
userFuncs.sort(sortName); | |
members.push.apply(members, userFuncs) | |
} | |
if (Firebug.showDOMProps) { | |
domProps.sort(sortName); | |
members.push.apply(members, domProps) | |
} | |
if (Firebug.showDOMFuncs) { | |
domFuncs.sort(sortName); | |
members.push.apply(members, domFuncs) | |
} | |
if (Firebug.showDOMConstants) { | |
members.push.apply(members, domConstants) | |
} | |
return members | |
}; | |
function expandMembers(members, toggles, offset, level) { | |
var expanded = 0; | |
for (var i = offset; i < members.length; ++i) { | |
var member = members[i]; | |
if (member.level > level) { | |
break | |
} | |
if (toggles.hasOwnProperty(member.name)) { | |
member.open = "opened"; | |
var newMembers = getMembers(member.value, level + 1); | |
var args = [i + 1, 0]; | |
args.push.apply(args, newMembers); | |
members.splice.apply(members, args); | |
expanded += newMembers.length; | |
i += newMembers.length + expandMembers(members, toggles[member.name], i + 1, level + 1) | |
} | |
} | |
return expanded | |
} | |
function isClassFunction(fn) { | |
try { | |
for (var name in fn.prototype) { | |
return true | |
} | |
} catch(exc) {} | |
return false | |
} | |
FBL.ErrorCopy = function(message) { | |
this.message = message | |
}; | |
var addMember = function addMember(type, props, name, value, level, order) { | |
var rep = Firebug.getRep(value); | |
var tag = rep.shortTag ? rep.shortTag: rep.tag; | |
var ErrorCopy = function() {}; | |
var valueType = typeof(value); | |
var hasChildren = hasProperties(value) && !(value instanceof ErrorCopy) && (isFunction(value) || (valueType == "object" && value != null) || (valueType == "string" && value.length > Firebug.stringCropLength)); | |
props.push({ | |
name: name, | |
value: value, | |
type: type, | |
rowClass: "memberRow-" + type, | |
open: "", | |
order: order, | |
level: level, | |
indent: level * 16, | |
hasChildren: hasChildren, | |
tag: tag | |
}) | |
}; | |
var getWatchRowIndex = function getWatchRowIndex(row) { | |
var index = -1; | |
for (; row && hasClass(row, "watchRow"); row = row.previousSibling) {++index | |
} | |
return index | |
}; | |
var getRowName = function getRowName(row) { | |
var node = row.firstChild; | |
return node.textContent ? node.textContent: node.innerText | |
}; | |
var getRowValue = function getRowValue(row) { | |
return row.lastChild.firstChild.repObject | |
}; | |
var getRowOwnerObject = function getRowOwnerObject(row) { | |
var parentRow = getParentRow(row); | |
if (parentRow) { | |
return getRowValue(parentRow) | |
} | |
}; | |
var getParentRow = function getParentRow(row) { | |
var level = parseInt(row.getAttribute("level")) - 1; | |
for (row = row.previousSibling; row; row = row.previousSibling) { | |
if (parseInt(row.getAttribute("level")) == level) { | |
return row | |
} | |
} | |
}; | |
var getPath = function getPath(row) { | |
var name = getRowName(row); | |
var path = [name]; | |
var level = parseInt(row.getAttribute("level")) - 1; | |
for (row = row.previousSibling; row; row = row.previousSibling) { | |
if (parseInt(row.getAttribute("level")) == level) { | |
var name = getRowName(row); | |
path.splice(0, 0, name); --level | |
} | |
} | |
return path | |
}; | |
Firebug.DOM = extend(Firebug.Module, { | |
getPanel: function() { | |
return Firebug.chrome ? Firebug.chrome.getPanel("DOM") : null | |
} | |
}); | |
Firebug.registerModule(Firebug.DOM); | |
var lastHighlightedObject; | |
function DOMSidePanel() {} | |
DOMSidePanel.prototype = extend(Firebug.DOMBasePanel.prototype, { | |
selectRow: function(row, target) { | |
if (!target) { | |
target = row.lastChild.firstChild | |
} | |
if (!target || !target.repObject) { | |
return | |
} | |
this.pathToAppend = getPath(row); | |
var valueBox = row.lastChild.firstChild; | |
if (hasClass(valueBox, "objectBox-array")) { | |
var arrayIndex = FirebugReps.Arr.getItemIndex(target); | |
this.pathToAppend.push(arrayIndex) | |
} | |
var object = target.repObject; | |
if (instanceOf(object, "Element")) { | |
Firebug.HTML.selectTreeNode(ElementCache(object)) | |
} else { | |
Firebug.chrome.selectPanel("DOM"); | |
Firebug.chrome.getPanel("DOM").select(object, true) | |
} | |
}, | |
onClick: function(event) { | |
var target = event.srcElement || event.target; | |
var repNode = Firebug.getRepNode(target); | |
if (repNode) { | |
var row = getAncestorByClass(target, "memberRow"); | |
if (row) { | |
this.selectRow(row, repNode); | |
cancelEvent(event) | |
} | |
} | |
}, | |
name: "DOMSidePanel", | |
parentPanel: "HTML", | |
title: "DOM", | |
options: { | |
hasToolButtons: true | |
}, | |
isInitialized: false, | |
create: function() { | |
Firebug.DOMBasePanel.prototype.create.apply(this, arguments); | |
this.onClick = bind(this.onClick, this) | |
}, | |
initialize: function() { | |
Firebug.DOMBasePanel.prototype.initialize.apply(this, arguments); | |
addEvent(this.panelNode, "click", this.onClick); | |
var selection = ElementCache.get(Firebug.context.persistedState.selectedHTMLElementId); | |
if (selection) { | |
this.select(selection, true) | |
} | |
}, | |
shutdown: function() { | |
removeEvent(this.panelNode, "click", this.onClick); | |
Firebug.DOMBasePanel.prototype.shutdown.apply(this, arguments) | |
}, | |
reattach: function(oldChrome) { | |
this.toggles = oldChrome.getPanel("DOMSidePanel").toggles | |
} | |
}); | |
Firebug.registerPanel(DOMSidePanel) | |
} | |
}); | |
FBL.FBTrace = {}; (function() { | |
var traceOptions = { | |
DBG_TIMESTAMP: 1, | |
DBG_INITIALIZE: 1, | |
DBG_CHROME: 1, | |
DBG_ERRORS: 1, | |
DBG_DISPATCH: 1, | |
DBG_CSS: 1 | |
}; | |
this.module = null; | |
this.initialize = function() { | |
if (!this.messageQueue) { | |
this.messageQueue = [] | |
} | |
for (var name in traceOptions) { | |
this[name] = traceOptions[name] | |
} | |
}; | |
this.sysout = function() { | |
return this.logFormatted(arguments, "") | |
}; | |
this.dumpProperties = function(title, object) { | |
return this.logFormatted("dumpProperties() not supported.", "warning") | |
}; | |
this.dumpStack = function() { | |
return this.logFormatted("dumpStack() not supported.", "warning") | |
}; | |
this.flush = function(module) { | |
this.module = module; | |
var queue = this.messageQueue; | |
this.messageQueue = []; | |
for (var i = 0; i < queue.length; ++i) { | |
this.writeMessage(queue[i][0], queue[i][1], queue[i][2]) | |
} | |
}; | |
this.getPanel = function() { | |
return this.module ? this.module.getPanel() : null | |
}; | |
this.logFormatted = function(objects, className) { | |
var html = this.DBG_TIMESTAMP ? [getTimestamp(), " | "] : []; | |
var length = objects.length; | |
for (var i = 0; i < length; ++i) { | |
appendText(" ", html); | |
var object = objects[i]; | |
if (i == 0) { | |
html.push("<b>"); | |
appendText(object, html); | |
html.push("</b>") | |
} else { | |
appendText(object, html) | |
} | |
} | |
return this.logRow(html, className) | |
}; | |
this.logRow = function(message, className) { | |
var panel = this.getPanel(); | |
if (panel && panel.panelNode) { | |
this.writeMessage(message, className) | |
} else { | |
this.messageQueue.push([message, className]) | |
} | |
return this.LOG_COMMAND | |
}; | |
this.writeMessage = function(message, className) { | |
var container = this.getPanel().containerNode; | |
var isScrolledToBottom = container.scrollTop + container.offsetHeight >= container.scrollHeight; | |
this.writeRow.call(this, message, className); | |
if (isScrolledToBottom) { | |
container.scrollTop = container.scrollHeight - container.offsetHeight | |
} | |
}; | |
this.appendRow = function(row) { | |
var container = this.getPanel().panelNode; | |
container.appendChild(row) | |
}; | |
this.writeRow = function(message, className) { | |
var row = this.getPanel().panelNode.ownerDocument.createElement("div"); | |
row.className = "logRow" + (className ? " logRow-" + className: ""); | |
row.innerHTML = message.join(""); | |
this.appendRow(row) | |
}; | |
function appendText(object, html) { | |
html.push(escapeHTML(objectToString(object))) | |
} | |
function getTimestamp() { | |
var now = new Date(); | |
var ms = "" + (now.getMilliseconds() / 1000).toFixed(3); | |
ms = ms.substr(2); | |
return now.toLocaleTimeString() + "." + ms | |
} | |
var HTMLtoEntity = { | |
"<": "<", | |
">": ">", | |
"&": "&", | |
"'": "'", | |
'"': """ | |
}; | |
function replaceChars(ch) { | |
return HTMLtoEntity[ch] | |
} | |
function escapeHTML(value) { | |
return (value + "").replace(/[<>&"']/g, replaceChars) | |
} | |
function objectToString(object) { | |
try { | |
return object + "" | |
} catch(exc) { | |
return null | |
} | |
} | |
}).apply(FBL.FBTrace); | |
FBL.ns(function() { | |
with(FBL) { | |
if (!Env.Options.enableTrace) { | |
return | |
} | |
Firebug.Trace = extend(Firebug.Module, { | |
getPanel: function() { | |
return Firebug.chrome ? Firebug.chrome.getPanel("Trace") : null | |
}, | |
clear: function() { | |
this.getPanel().panelNode.innerHTML = "" | |
} | |
}); | |
Firebug.registerModule(Firebug.Trace); | |
function TracePanel() {} | |
TracePanel.prototype = extend(Firebug.Panel, { | |
name: "Trace", | |
title: "Trace", | |
options: { | |
hasToolButtons: true, | |
innerHTMLSync: true | |
}, | |
create: function() { | |
Firebug.Panel.create.apply(this, arguments); | |
this.clearButton = new Button({ | |
caption: "Clear", | |
title: "Clear FBTrace logs", | |
owner: Firebug.Trace, | |
onClick: Firebug.Trace.clear | |
}) | |
}, | |
initialize: function() { | |
Firebug.Panel.initialize.apply(this, arguments); | |
this.clearButton.initialize() | |
}, | |
shutdown: function() { | |
this.clearButton.shutdown(); | |
Firebug.Panel.shutdown.apply(this, arguments) | |
} | |
}); | |
Firebug.registerPanel(TracePanel) | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
var modules = []; | |
var panelTypes = []; | |
var panelTypeMap = {}; | |
var parentPanelMap = {}; | |
var registerModule = Firebug.registerModule; | |
var registerPanel = Firebug.registerPanel; | |
append(Firebug, { | |
extend: function(fn) { | |
if (Firebug.chrome && Firebug.chrome.addPanel) { | |
var namespace = ns(fn); | |
fn.call(namespace, FBL) | |
} else { | |
setTimeout(function() { | |
Firebug.extend(fn) | |
}, | |
100) | |
} | |
}, | |
registerModule: function() { | |
registerModule.apply(Firebug, arguments); | |
modules.push.apply(modules, arguments); | |
dispatch(modules, "initialize", []); | |
if (FBTrace.DBG_INITIALIZE) { | |
FBTrace.sysout("Firebug.registerModule") | |
} | |
}, | |
registerPanel: function() { | |
registerPanel.apply(Firebug, arguments); | |
panelTypes.push.apply(panelTypes, arguments); | |
for (var i = 0, | |
panelType; panelType = arguments[i]; ++i) { | |
if (panelType.prototype.name == "Dev") { | |
continue | |
} | |
panelTypeMap[panelType.prototype.name] = arguments[i]; | |
var parentPanelName = panelType.prototype.parentPanel; | |
if (parentPanelName) { | |
parentPanelMap[parentPanelName] = 1 | |
} else { | |
var panelName = panelType.prototype.name; | |
var chrome = Firebug.chrome; | |
chrome.addPanel(panelName); | |
var onTabClick = function onTabClick() { | |
chrome.selectPanel(panelName); | |
return false | |
}; | |
chrome.addController([chrome.panelMap[panelName].tabNode, "mousedown", onTabClick]) | |
} | |
} | |
if (FBTrace.DBG_INITIALIZE) { | |
for (var i = 0; i < arguments.length; ++i) { | |
FBTrace.sysout("Firebug.registerPanel", arguments[i].prototype.name) | |
} | |
} | |
} | |
}) | |
} | |
}); | |
FBL.ns(function() { | |
with(FBL) { | |
FirebugChrome.Skin = { | |
CSS: '.obscured{left:-999999px !important;}.collapsed{display:none;}[collapsed="true"]{display:none;}#fbCSS{padding:0 !important;}.cssPropDisable{float:left;display:block;width:2em;cursor:default;}.infoTip{z-index:2147483647;position:fixed;padding:2px 3px;border:1px solid #CBE087;background:LightYellow;font-family:Monaco,monospace;color:#000000;display:none;white-space:nowrap;pointer-events:none;}.infoTip[active="true"]{display:block;}.infoTipLoading{width:16px;height:16px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/loading_16.gif) no-repeat;}.infoTipImageBox{font-size:11px;min-width:100px;text-align:center;}.infoTipCaption{font-size:11px;font:Monaco,monospace;}.infoTipLoading > .infoTipImage,.infoTipLoading > .infoTipCaption{display:none;}h1.groupHeader{padding:2px 4px;margin:0 0 4px 0;border-top:1px solid #CCCCCC;border-bottom:1px solid #CCCCCC;background:#eee url(https://getfirebug.com/releases/lite/latest/skin/xp/group.gif) repeat-x;font-size:11px;font-weight:bold;_position:relative;}.inlineEditor,.fixedWidthEditor{z-index:2147483647;position:absolute;display:none;}.inlineEditor{margin-left:-6px;margin-top:-3px;}.textEditorInner,.fixedWidthEditor{margin:0 0 0 0 !important;padding:0;border:none !important;font:inherit;text-decoration:inherit;background-color:#FFFFFF;}.fixedWidthEditor{border-top:1px solid #888888 !important;border-bottom:1px solid #888888 !important;}.textEditorInner{position:relative;top:-7px;left:-5px;outline:none;resize:none;}.textEditorInner1{padding-left:11px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorBorders.png) repeat-y;_background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorBorders.gif) repeat-y;_overflow:hidden;}.textEditorInner2{position:relative;padding-right:2px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorBorders.png) repeat-y 100% 0;_background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorBorders.gif) repeat-y 100% 0;_position:fixed;}.textEditorTop1{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorCorners.png) no-repeat 100% 0;margin-left:11px;height:10px;_background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorCorners.gif) no-repeat 100% 0;_overflow:hidden;}.textEditorTop2{position:relative;left:-11px;width:11px;height:10px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorCorners.png) no-repeat;_background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorCorners.gif) no-repeat;}.textEditorBottom1{position:relative;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorCorners.png) no-repeat 100% 100%;margin-left:11px;height:12px;_background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorCorners.gif) no-repeat 100% 100%;}.textEditorBottom2{position:relative;left:-11px;width:11px;height:12px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorCorners.png) no-repeat 0 100%;_background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorCorners.gif) no-repeat 0 100%;}.panelNode-css{overflow-x:hidden;}.cssSheet > .insertBefore{height:1.5em;}.cssRule{position:relative;margin:0;padding:1em 0 0 6px;font-family:Monaco,monospace;color:#000000;}.cssRule:first-child{padding-top:6px;}.cssElementRuleContainer{position:relative;}.cssHead{padding-right:150px;}.cssProp{}.cssPropName{color:DarkGreen;}.cssPropValue{margin-left:8px;color:DarkBlue;}.cssOverridden span{text-decoration:line-through;}.cssInheritedRule{}.cssInheritLabel{margin-right:0.5em;font-weight:bold;}.cssRule .objectLink-sourceLink{top:0;}.cssProp.editGroup:hover{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/disable.png) no-repeat 2px 1px;_background:url(https://getfirebug.com/releases/lite/latest/skin/xp/disable.gif) no-repeat 2px 1px;}.cssProp.editGroup.editing{background:none;}.cssProp.disabledStyle{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/disableHover.png) no-repeat 2px 1px;_background:url(https://getfirebug.com/releases/lite/latest/skin/xp/disableHover.gif) no-repeat 2px 1px;opacity:1;color:#CCCCCC;}.disabledStyle .cssPropName,.disabledStyle .cssPropValue{color:#CCCCCC;}.cssPropValue.editing + .cssSemi,.inlineExpander + .cssSemi{display:none;}.cssPropValue.editing{white-space:nowrap;}.stylePropName{font-weight:bold;padding:0 4px 4px 4px;width:50%;}.stylePropValue{width:50%;}.panelNode-net{overflow-x:hidden;}.netTable{width:100%;}.hideCategory-undefined .category-undefined,.hideCategory-html .category-html,.hideCategory-css .category-css,.hideCategory-js .category-js,.hideCategory-image .category-image,.hideCategory-xhr .category-xhr,.hideCategory-flash .category-flash,.hideCategory-txt .category-txt,.hideCategory-bin .category-bin{display:none;}.netHeadRow{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/group.gif) repeat-x #FFFFFF;}.netHeadCol{border-bottom:1px solid #CCCCCC;padding:2px 4px 2px 18px;font-weight:bold;}.netHeadLabel{white-space:nowrap;overflow:hidden;}.netHeaderRow{height:16px;}.netHeaderCell{cursor:pointer;-moz-user-select:none;border-bottom:1px solid #9C9C9C;padding:0 !important;font-weight:bold;background:#BBBBBB url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/tableHeader.gif) repeat-x;white-space:nowrap;}.netHeaderRow > .netHeaderCell:first-child > .netHeaderCellBox{padding:2px 14px 2px 18px;}.netHeaderCellBox{padding:2px 14px 2px 10px;border-left:1px solid #D9D9D9;border-right:1px solid #9C9C9C;}.netHeaderCell:hover:active{background:#959595 url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/tableHeaderActive.gif) repeat-x;}.netHeaderSorted{background:#7D93B2 url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/tableHeaderSorted.gif) repeat-x;}.netHeaderSorted > .netHeaderCellBox{border-right-color:#6B7C93;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/arrowDown.png) no-repeat right;}.netHeaderSorted.sortedAscending > .netHeaderCellBox{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/arrowUp.png);}.netHeaderSorted:hover:active{background:#536B90 url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/tableHeaderSortedActive.gif) repeat-x;}.panelNode-net .netRowHeader{display:block;}.netRowHeader{cursor:pointer;display:none;height:15px;margin-right:0 !important;}.netRow .netRowHeader{background-position:5px 1px;}.netRow[breakpoint="true"] .netRowHeader{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/breakpoint.png);}.netRow[breakpoint="true"][disabledBreakpoint="true"] .netRowHeader{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/breakpointDisabled.png);}.netRow.category-xhr:hover .netRowHeader{background-color:#F6F6F6;}#netBreakpointBar{max-width:38px;}#netHrefCol > .netHeaderCellBox{border-left:0px;}.netRow .netRowHeader{width:3px;}.netInfoRow .netRowHeader{display:table-cell;}.netTable[hiddenCols~=netHrefCol] TD[id="netHrefCol"],.netTable[hiddenCols~=netHrefCol] TD.netHrefCol,.netTable[hiddenCols~=netStatusCol] TD[id="netStatusCol"],.netTable[hiddenCols~=netStatusCol] TD.netStatusCol,.netTable[hiddenCols~=netDomainCol] TD[id="netDomainCol"],.netTable[hiddenCols~=netDomainCol] TD.netDomainCol,.netTable[hiddenCols~=netSizeCol] TD[id="netSizeCol"],.netTable[hiddenCols~=netSizeCol] TD.netSizeCol,.netTable[hiddenCols~=netTimeCol] TD[id="netTimeCol"],.netTable[hiddenCols~=netTimeCol] TD.netTimeCol{display:none;}.netRow{background:LightYellow;}.netRow.loaded{background:#FFFFFF;}.netRow.loaded:hover{background:#EFEFEF;}.netCol{padding:0;vertical-align:top;border-bottom:1px solid #EFEFEF;white-space:nowrap;height:17px;}.netLabel{width:100%;}.netStatusCol{padding-left:10px;color:rgb(128,128,128);}.responseError > .netStatusCol{color:red;}.netDomainCol{padding-left:5px;}.netSizeCol{text-align:right;padding-right:10px;}.netHrefLabel{-moz-box-sizing:padding-box;overflow:hidden;z-index:10;position:absolute;padding-left:18px;padding-top:1px;max-width:15%;font-weight:bold;}.netFullHrefLabel{display:none;-moz-user-select:none;padding-right:10px;padding-bottom:3px;max-width:100%;background:#FFFFFF;z-index:200;}.netHrefCol:hover > .netFullHrefLabel{display:block;}.netRow.loaded:hover .netCol > .netFullHrefLabel{background-color:#EFEFEF;}.useA11y .a11yShowFullLabel{display:block;background-image:none !important;border:1px solid #CBE087;background-color:LightYellow;font-family:Monaco,monospace;color:#000000;font-size:10px;z-index:2147483647;}.netSizeLabel{padding-left:6px;}.netStatusLabel,.netDomainLabel,.netSizeLabel,.netBar{padding:1px 0 2px 0 !important;}.responseError{color:red;}.hasHeaders .netHrefLabel:hover{cursor:pointer;color:blue;text-decoration:underline;}.netLoadingIcon{position:absolute;border:0;margin-left:14px;width:16px;height:16px;background:transparent no-repeat 0 0;background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/loading_16.gif);display:inline-block;}.loaded .netLoadingIcon{display:none;}.netBar,.netSummaryBar{position:relative;border-right:50px solid transparent;}.netResolvingBar{position:absolute;left:0;top:0;bottom:0;background:#FFFFFF url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/netBarResolving.gif) repeat-x;z-index:60;}.netConnectingBar{position:absolute;left:0;top:0;bottom:0;background:#FFFFFF url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/netBarConnecting.gif) repeat-x;z-index:50;}.netBlockingBar{position:absolute;left:0;top:0;bottom:0;background:#FFFFFF url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/netBarWaiting.gif) repeat-x;z-index:40;}.netSendingBar{position:absolute;left:0;top:0;bottom:0;background:#FFFFFF url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/netBarSending.gif) repeat-x;z-index:30;}.netWaitingBar{position:absolute;left:0;top:0;bottom:0;background:#FFFFFF url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/netBarResponded.gif) repeat-x;z-index:20;min-width:1px;}.netReceivingBar{position:absolute;left:0;top:0;bottom:0;background:#38D63B url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/netBarLoading.gif) repeat-x;z-index:10;}.netWindowLoadBar,.netContentLoadBar{position:absolute;left:0;top:0;bottom:0;width:1px;background-color:red;z-index:70;opacity:0.5;display:none;margin-bottom:-1px;}.netContentLoadBar{background-color:Blue;}.netTimeLabel{-moz-box-sizing:padding-box;position:absolute;top:1px;left:100%;padding-left:6px;color:#444444;min-width:16px;}.loaded .netReceivingBar,.loaded.netReceivingBar{background:#B6B6B6 url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/netBarLoaded.gif) repeat-x;border-color:#B6B6B6;}.fromCache .netReceivingBar,.fromCache.netReceivingBar{background:#D6D6D6 url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/netBarCached.gif) repeat-x;border-color:#D6D6D6;}.netSummaryRow .netTimeLabel,.loaded .netTimeLabel{background:transparent;}.timeInfoTip{width:150px; height:40px}.timeInfoTipBar,.timeInfoTipEventBar{position:relative;display:block;margin:0;opacity:1;height:15px;width:4px;}.timeInfoTipEventBar{width:1px !important;}.timeInfoTipCell.startTime{padding-right:8px;}.timeInfoTipCell.elapsedTime{text-align:right;padding-right:8px;}.sizeInfoLabelCol{font-weight:bold;padding-right:10px;font-family:Lucida Grande,Tahoma,sans-serif;font-size:11px;}.sizeInfoSizeCol{font-weight:bold;}.sizeInfoDetailCol{color:gray;text-align:right;}.sizeInfoDescCol{font-style:italic;}.netSummaryRow .netReceivingBar{background:#BBBBBB;border:none;}.netSummaryLabel{color:#222222;}.netSummaryRow{background:#BBBBBB !important;font-weight:bold;}.netSummaryRow .netBar{border-right-color:#BBBBBB;}.netSummaryRow > .netCol{border-top:1px solid #999999;border-bottom:2px solid;-moz-border-bottom-colors:#EFEFEF #999999;padding-top:1px;padding-bottom:2px;}.netSummaryRow > .netHrefCol:hover{background:transparent !important;}.netCountLabel{padding-left:18px;}.netTotalSizeCol{text-align:right;padding-right:10px;}.netTotalTimeCol{text-align:right;}.netCacheSizeLabel{position:absolute;z-index:1000;left:0;top:0;}.netLimitRow{background:rgb(255,255,225) !important;font-weight:normal;color:black;font-weight:normal;}.netLimitLabel{padding-left:18px;}.netLimitRow > .netCol{border-bottom:2px solid;-moz-border-bottom-colors:#EFEFEF #999999;vertical-align:middle !important;padding-top:2px;padding-bottom:2px;}.netLimitButton{font-size:11px;padding-top:1px;padding-bottom:1px;}.netInfoCol{border-top:1px solid #EEEEEE;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/group.gif) repeat-x #FFFFFF;}.netInfoBody{margin:10px 0 4px 10px;}.netInfoTabs{position:relative;padding-left:17px;}.netInfoTab{position:relative;top:-3px;margin-top:10px;padding:4px 6px;border:1px solid transparent;border-bottom:none;_border:none;font-weight:bold;color:#565656;cursor:pointer;}.netInfoTabSelected{cursor:default !important;border:1px solid #D7D7D7 !important;border-bottom:none !important;-moz-border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;background-color:#FFFFFF;}.logRow-netInfo.error .netInfoTitle{color:red;}.logRow-netInfo.loading .netInfoResponseText{font-style:italic;color:#888888;}.loading .netInfoResponseHeadersTitle{display:none;}.netInfoResponseSizeLimit{font-family:Lucida Grande,Tahoma,sans-serif;padding-top:10px;font-size:11px;}.netInfoText{display:none;margin:0;border:1px solid #D7D7D7;border-right:none;padding:8px;background-color:#FFFFFF;font-family:Monaco,monospace;white-space:pre-wrap;}.netInfoTextSelected{display:block;}.netInfoParamName{padding-right:10px;font-family:Lucida Grande,Tahoma,sans-serif;font-weight:bold;vertical-align:top;text-align:right;white-space:nowrap;}.netInfoPostText .netInfoParamName{width:1px;}.netInfoParamValue{width:100%;}.netInfoHeadersText,.netInfoPostText,.netInfoPutText{padding-top:0;}.netInfoHeadersGroup,.netInfoPostParams,.netInfoPostSource{margin-bottom:4px;border-bottom:1px solid #D7D7D7;padding-top:8px;padding-bottom:2px;font-family:Lucida Grande,Tahoma,sans-serif;font-weight:bold;color:#565656;}.netInfoPostParamsTable,.netInfoPostPartsTable,.netInfoPostJSONTable,.netInfoPostXMLTable,.netInfoPostSourceTable{margin-bottom:10px;width:100%;}.netInfoPostContentType{color:#bdbdbd;padding-left:50px;font-weight:normal;}.netInfoHtmlPreview{border:0;width:100%;height:100%;}.netHeadersViewSource{color:#bdbdbd;margin-left:200px;font-weight:normal;}.netHeadersViewSource:hover{color:blue;cursor:pointer;}.netActivationRow,.netPageSeparatorRow{background:rgb(229,229,229) !important;font-weight:normal;color:black;}.netActivationLabel{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/infoIcon.png) no-repeat 3px 2px;padding-left:22px;}.netPageSeparatorRow{height:5px !important;}.netPageSeparatorLabel{padding-left:22px;height:5px !important;}.netPageRow{background-color:rgb(255,255,255);}.netPageRow:hover{background:#EFEFEF;}.netPageLabel{padding:1px 0 2px 18px !important;font-weight:bold;}.netActivationRow > .netCol{border-bottom:2px solid;-moz-border-bottom-colors:#EFEFEF #999999;padding-top:2px;padding-bottom:3px;}.twisty,.logRow-errorMessage > .hasTwisty > .errorTitle,.logRow-log > .objectBox-array.hasTwisty,.logRow-spy .spyHead .spyTitle,.logGroup > .logRow,.memberRow.hasChildren > .memberLabelCell > .memberLabel,.hasHeaders .netHrefLabel,.netPageRow > .netCol > .netPageTitle{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/tree_open.gif);background-repeat:no-repeat;background-position:2px 2px;min-height:12px;}.logRow-errorMessage > .hasTwisty.opened > .errorTitle,.logRow-log > .objectBox-array.hasTwisty.opened,.logRow-spy.opened .spyHead .spyTitle,.logGroup.opened > .logRow,.memberRow.hasChildren.opened > .memberLabelCell > .memberLabel,.nodeBox.highlightOpen > .nodeLabel > .twisty,.nodeBox.open > .nodeLabel > .twisty,.netRow.opened > .netCol > .netHrefLabel,.netPageRow.opened > .netCol > .netPageTitle{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/tree_close.gif);}.twisty{background-position:4px 4px;}* html .logRow-spy .spyHead .spyTitle,* html .logGroup .logGroupLabel,* html .hasChildren .memberLabelCell .memberLabel,* html .hasHeaders .netHrefLabel{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/tree_open.gif);background-repeat:no-repeat;background-position:2px 2px;}* html .opened .spyHead .spyTitle,* html .opened .logGroupLabel,* html .opened .memberLabelCell .memberLabel{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/tree_close.gif);background-repeat:no-repeat;background-position:2px 2px;}.panelNode-console{overflow-x:hidden;}.objectLink{text-decoration:none;}.objectLink:hover{cursor:pointer;text-decoration:underline;}.logRow{position:relative;margin:0;border-bottom:1px solid #D7D7D7;padding:2px 4px 1px 6px;background-color:#FFFFFF;overflow:hidden !important;}.useA11y .logRow:focus{border-bottom:1px solid #000000 !important;outline:none !important;background-color:#FFFFAD !important;}.useA11y .logRow:focus a.objectLink-sourceLink{background-color:#FFFFAD;}.useA11y .a11yFocus:focus,.useA11y .objectBox:focus{outline:2px solid #FF9933;background-color:#FFFFAD;}.useA11y .objectBox-null:focus,.useA11y .objectBox-undefined:focus{background-color:#888888 !important;}.useA11y .logGroup.opened > .logRow{border-bottom:1px solid #ffffff;}.logGroup{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/group.gif) repeat-x #FFFFFF;padding:0 !important;border:none !important;}.logGroupBody{display:none;margin-left:16px;border-left:1px solid #D7D7D7;border-top:1px solid #D7D7D7;background:#FFFFFF;}.logGroup > .logRow{background-color:transparent !important;font-weight:bold;}.logGroup.opened > .logRow{border-bottom:none;}.logGroup.opened > .logGroupBody{display:block;}.logRow-command > .objectBox-text{font-family:Monaco,monospace;color:#0000FF;white-space:pre-wrap;}.logRow-info,.logRow-warn,.logRow-error,.logRow-assert,.logRow-warningMessage,.logRow-errorMessage{padding-left:22px;background-repeat:no-repeat;background-position:4px 2px;}.logRow-assert,.logRow-warningMessage,.logRow-errorMessage{padding-top:0;padding-bottom:0;}.logRow-info,.logRow-info .objectLink-sourceLink{background-color:#FFFFFF;}.logRow-warn,.logRow-warningMessage,.logRow-warn .objectLink-sourceLink,.logRow-warningMessage .objectLink-sourceLink{background-color:cyan;}.logRow-error,.logRow-assert,.logRow-errorMessage,.logRow-error .objectLink-sourceLink,.logRow-errorMessage .objectLink-sourceLink{background-color:LightYellow;}.logRow-error,.logRow-assert,.logRow-errorMessage{color:#FF0000;}.logRow-info{}.logRow-warn,.logRow-warningMessage{}.logRow-error,.logRow-assert,.logRow-errorMessage{}.objectBox-string,.objectBox-text,.objectBox-number,.objectLink-element,.objectLink-textNode,.objectLink-function,.objectBox-stackTrace,.objectLink-profile{font-family:Monaco,monospace;}.objectBox-string,.objectBox-text,.objectLink-textNode{white-space:pre-wrap;}.objectBox-number,.objectLink-styleRule,.objectLink-element,.objectLink-textNode{color:#000088;}.objectBox-string{color:#FF0000;}.objectLink-function,.objectBox-stackTrace,.objectLink-profile{color:DarkGreen;}.objectBox-null,.objectBox-undefined{padding:0 2px;border:1px solid #666666;background-color:#888888;color:#FFFFFF;}.objectBox-exception{padding:0 2px 0 18px;color:red;}.objectLink-sourceLink{position:absolute;right:4px;top:2px;padding-left:8px;font-family:Lucida Grande,sans-serif;font-weight:bold;color:#0000FF;}.errorTitle{margin-top:0px;margin-bottom:1px;padding-top:2px;padding-bottom:2px;}.errorTrace{margin-left:17px;}.errorSourceBox{margin:2px 0;}.errorSource-none{display:none;}.errorSource-syntax > .errorBreak{visibility:hidden;}.errorSource{cursor:pointer;font-family:Monaco,monospace;color:DarkGreen;}.errorSource:hover{text-decoration:underline;}.errorBreak{cursor:pointer;display:none;margin:0 6px 0 0;width:13px;height:14px;vertical-align:bottom;opacity:0.1;}.hasBreakSwitch .errorBreak{display:inline;}.breakForError .errorBreak{opacity:1;}.assertDescription{margin:0;}.logRow-profile > .logRow > .objectBox-text{font-family:Lucida Grande,Tahoma,sans-serif;color:#000000;}.logRow-profile > .logRow > .objectBox-text:last-child{color:#555555;font-style:italic;}.logRow-profile.opened > .logRow{padding-bottom:4px;}.profilerRunning > .logRow{padding-left:22px !important;}.profileSizer{width:100%;overflow-x:auto;overflow-y:scroll;}.profileTable{border-bottom:1px solid #D7D7D7;padding:0 0 4px 0;}.profileTable tr[odd="1"]{background-color:#F5F5F5;vertical-align:middle;}.profileTable a{vertical-align:middle;}.profileTable td{padding:1px 4px 0 4px;}.headerCell{cursor:pointer;-moz-user-select:none;border-bottom:1px solid #9C9C9C;padding:0 !important;font-weight:bold;}.headerCellBox{padding:2px 4px;border-left:1px solid #D9D9D9;border-right:1px solid #9C9C9C;}.headerCell:hover:active{}.headerSorted{}.headerSorted > .headerCellBox{border-right-color:#6B7C93;}.headerSorted.sortedAscending > .headerCellBox{}.headerSorted:hover:active{}.linkCell{text-align:right;}.linkCell > .objectLink-sourceLink{position:static;}.logRow-stackTrace{padding-top:0;background:#f8f8f8;}.logRow-stackTrace > .objectBox-stackFrame{position:relative;padding-top:2px;}.objectLink-object{font-family:Lucida Grande,sans-serif;font-weight:bold;color:DarkGreen;white-space:pre-wrap;}.objectProp-object{color:DarkGreen;}.objectProps{color:#000;font-weight:normal;}.objectPropName{color:#777;}.objectProps .objectProp-string{color:#f55;}.objectProps .objectProp-number{color:#55a;}.objectProps .objectProp-object{color:#585;}.selectorTag,.selectorId,.selectorClass{font-family:Monaco,monospace;font-weight:normal;}.selectorTag{color:#0000FF;}.selectorId{color:DarkBlue;}.selectorClass{color:red;}.selectorHidden > .selectorTag{color:#5F82D9;}.selectorHidden > .selectorId{color:#888888;}.selectorHidden > .selectorClass{color:#D86060;}.selectorValue{font-family:Lucida Grande,sans-serif;font-style:italic;color:#555555;}.panelNode.searching .logRow{display:none;}.logRow.matched{display:block !important;}.logRow.matching{position:absolute;left:-1000px;top:-1000px;max-width:0;max-height:0;overflow:hidden;}.objectLeftBrace,.objectRightBrace,.objectEqual,.objectComma,.arrayLeftBracket,.arrayRightBracket,.arrayComma{font-family:Monaco,monospace;}.objectLeftBrace,.objectRightBrace,.arrayLeftBracket,.arrayRightBracket{font-weight:bold;}.objectLeftBrace,.arrayLeftBracket{margin-right:4px;}.objectRightBrace,.arrayRightBracket{margin-left:4px;}.logRow-dir{padding:0;}.logRow-errorMessage .hasTwisty .errorTitle,.logRow-spy .spyHead .spyTitle,.logGroup .logRow{cursor:pointer;padding-left:18px;background-repeat:no-repeat;background-position:3px 3px;}.logRow-errorMessage > .hasTwisty > .errorTitle{background-position:2px 3px;}.logRow-errorMessage > .hasTwisty > .errorTitle:hover,.logRow-spy .spyHead .spyTitle:hover,.logGroup > .logRow:hover{text-decoration:underline;}.logRow-spy{padding:0 !important;}.logRow-spy,.logRow-spy .objectLink-sourceLink{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/group.gif) repeat-x #FFFFFF;padding-right:4px;right:0;}.logRow-spy.opened{padding-bottom:4px;border-bottom:none;}.spyTitle{color:#000000;font-weight:bold;-moz-box-sizing:padding-box;overflow:hidden;z-index:100;padding-left:18px;}.spyCol{padding:0;white-space:nowrap;height:16px;}.spyTitleCol:hover > .objectLink-sourceLink,.spyTitleCol:hover > .spyTime,.spyTitleCol:hover > .spyStatus,.spyTitleCol:hover > .spyTitle{display:none;}.spyFullTitle{display:none;-moz-user-select:none;max-width:100%;background-color:Transparent;}.spyTitleCol:hover > .spyFullTitle{display:block;}.spyStatus{padding-left:10px;color:rgb(128,128,128);}.spyTime{margin-left:4px;margin-right:4px;color:rgb(128,128,128);}.spyIcon{margin-right:4px;margin-left:4px;width:16px;height:16px;vertical-align:middle;background:transparent no-repeat 0 0;display:none;}.loading .spyHead .spyRow .spyIcon{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/loading_16.gif);display:block;}.logRow-spy.loaded:not(.error) .spyHead .spyRow .spyIcon{width:0;margin:0;}.logRow-spy.error .spyHead .spyRow .spyIcon{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/errorIcon-sm.png);display:block;background-position:2px 2px;}.logRow-spy .spyHead .netInfoBody{display:none;}.logRow-spy.opened .spyHead .netInfoBody{margin-top:10px;display:block;}.logRow-spy.error .spyTitle,.logRow-spy.error .spyStatus,.logRow-spy.error .spyTime{color:red;}.logRow-spy.loading .spyResponseText{font-style:italic;color:#888888;}.caption{font-family:Lucida Grande,Tahoma,sans-serif;font-weight:bold;color:#444444;}.warning{padding:10px;font-family:Lucida Grande,Tahoma,sans-serif;font-weight:bold;color:#888888;}.panelNode-dom{overflow-x:hidden !important;}.domTable{font-size:1em;width:100%;table-layout:fixed;background:#fff;}.domTableIE{width:auto;}.memberLabelCell{padding:2px 0 2px 0;vertical-align:top;}.memberValueCell{padding:1px 0 1px 5px;display:block;overflow:hidden;}.memberLabel{display:block;cursor:default;-moz-user-select:none;overflow:hidden;padding-left:18px;background-color:#FFFFFF;text-decoration:none;}.memberRow.hasChildren .memberLabelCell .memberLabel:hover{cursor:pointer;color:blue;text-decoration:underline;}.userLabel{color:#000000;font-weight:bold;}.userClassLabel{color:#E90000;font-weight:bold;}.userFunctionLabel{color:#025E2A;font-weight:bold;}.domLabel{color:#000000;}.domFunctionLabel{color:#025E2A;}.ordinalLabel{color:SlateBlue;font-weight:bold;}.scopesRow{padding:2px 18px;background-color:LightYellow;border-bottom:5px solid #BEBEBE;color:#666666;}.scopesLabel{background-color:LightYellow;}.watchEditCell{padding:2px 18px;background-color:LightYellow;border-bottom:1px solid #BEBEBE;color:#666666;}.editor-watchNewRow,.editor-memberRow{font-family:Monaco,monospace !important;}.editor-memberRow{padding:1px 0 !important;}.editor-watchRow{padding-bottom:0 !important;}.watchRow > .memberLabelCell{font-family:Monaco,monospace;padding-top:1px;padding-bottom:1px;}.watchRow > .memberLabelCell > .memberLabel{background-color:transparent;}.watchRow > .memberValueCell{padding-top:2px;padding-bottom:2px;}.watchRow > .memberLabelCell,.watchRow > .memberValueCell{background-color:#F5F5F5;border-bottom:1px solid #BEBEBE;}.watchToolbox{z-index:2147483647;position:absolute;right:0;padding:1px 2px;}#fbConsole{overflow-x:hidden !important;}#fbCSS{font:1em Monaco,monospace;padding:0 7px;}#fbstylesheetButtons select,#fbScriptButtons select{font:11px Lucida Grande,Tahoma,sans-serif;margin-top:1px;padding-left:3px;background:#fafafa;border:1px inset #fff;width:220px;outline:none;}.Selector{margin-top:10px}.CSSItem{margin-left:4%}.CSSText{padding-left:20px;}.CSSProperty{color:#005500;}.CSSValue{padding-left:5px; color:#000088;}#fbHTMLStatusBar{display:inline;}.fbToolbarButtons{display:none;}.fbStatusSeparator{display:block;float:left;padding-top:4px;}#fbStatusBarBox{display:none;}#fbToolbarContent{display:block;position:absolute;_position:absolute;top:0;padding-top:4px;height:23px;clip:rect(0,2048px,27px,0);}.fbTabMenuTarget{display:none !important;float:left;width:10px;height:10px;margin-top:6px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuTarget.png);}.fbTabMenuTarget:hover{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuTargetHover.png);}.fbShadow{float:left;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/shadowAlpha.png) no-repeat bottom right !important;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/shadow2.gif) no-repeat bottom right;margin:10px 0 0 10px !important;margin:10px 0 0 5px;}.fbShadowContent{display:block;position:relative;background-color:#fff;border:1px solid #a9a9a9;top:-6px;left:-6px;}.fbMenu{display:none;position:absolute;font-size:11px;line-height:13px;z-index:2147483647;}.fbMenuContent{padding:2px;}.fbMenuSeparator{display:block;position:relative;padding:1px 18px 0;text-decoration:none;color:#000;cursor:default;background:#ACA899;margin:4px 0;}.fbMenuOption{display:block;position:relative;padding:2px 18px;text-decoration:none;color:#000;cursor:default;}.fbMenuOption:hover{color:#fff;background:#316AC5;}.fbMenuGroup{background:transparent url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuPin.png) no-repeat right 0;}.fbMenuGroup:hover{background:#316AC5 url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuPin.png) no-repeat right -17px;}.fbMenuGroupSelected{color:#fff;background:#316AC5 url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuPin.png) no-repeat right -17px;}.fbMenuChecked{background:transparent url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuCheckbox.png) no-repeat 4px 0;}.fbMenuChecked:hover{background:#316AC5 url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuCheckbox.png) no-repeat 4px -17px;}.fbMenuRadioSelected{background:transparent url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuRadio.png) no-repeat 4px 0;}.fbMenuRadioSelected:hover{background:#316AC5 url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuRadio.png) no-repeat 4px -17px;}.fbMenuShortcut{padding-right:85px;}.fbMenuShortcutKey{position:absolute;right:0;top:2px;width:77px;}#fbFirebugMenu{top:22px;left:0;}.fbMenuDisabled{color:#ACA899 !important;}#fbFirebugSettingsMenu{left:245px;top:99px;}#fbConsoleMenu{top:42px;left:48px;}.fbIconButton{display:block;}.fbIconButton{display:block;}.fbIconButton{display:block;float:left;height:20px;width:20px;color:#000;margin-right:2px;text-decoration:none;cursor:default;}.fbIconButton:hover{position:relative;top:-1px;left:-1px;margin-right:0;_margin-right:1px;color:#333;border:1px solid #fff;border-bottom:1px solid #bbb;border-right:1px solid #bbb;}.fbIconPressed{position:relative;margin-right:0;_margin-right:1px;top:0 !important;left:0 !important;height:19px;color:#333 !important;border:1px solid #bbb !important;border-bottom:1px solid #cfcfcf !important;border-right:1px solid #ddd !important;}#fbErrorPopup{position:absolute;right:0;bottom:0;height:19px;width:75px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) #f1f2ee 0 0;z-index:999;}#fbErrorPopupContent{position:absolute;right:0;top:1px;height:18px;width:75px;_width:74px;border-left:1px solid #aca899;}#fbErrorIndicator{position:absolute;top:2px;right:5px;}.fbBtnInspectActive{background:#aaa;color:#fff !important;}.fbBody{margin:0;padding:0;overflow:hidden;font-family:Lucida Grande,Tahoma,sans-serif;font-size:11px;background:#fff;}.clear{clear:both;}#fbMiniChrome{display:none;right:0;height:27px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) #f1f2ee 0 0;margin-left:1px;}#fbMiniContent{display:block;position:relative;left:-1px;right:0;top:1px;height:25px;border-left:1px solid #aca899;}#fbToolbarSearch{float:right;border:1px solid #ccc;margin:0 5px 0 0;background:#fff url(https://getfirebug.com/releases/lite/latest/skin/xp/search.png) no-repeat 4px 2px !important;background:#fff url(https://getfirebug.com/releases/lite/latest/skin/xp/search.gif) no-repeat 4px 2px;padding-left:20px;font-size:11px;}#fbToolbarErrors{float:right;margin:1px 4px 0 0;font-size:11px;}#fbLeftToolbarErrors{float:left;margin:7px 0px 0 5px;font-size:11px;}.fbErrors{padding-left:20px;height:14px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/errorIcon.png) no-repeat !important;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/errorIcon.gif) no-repeat;color:#f00;font-weight:bold;}#fbMiniErrors{display:inline;display:none;float:right;margin:5px 2px 0 5px;}#fbMiniIcon{float:right;margin:3px 4px 0;height:20px;width:20px;float:right;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) 0 -135px;cursor:pointer;}#fbChrome{font-family:Lucida Grande,Tahoma,sans-serif;font-size:11px;position:absolute;_position:static;top:0;left:0;height:100%;width:100%;border-collapse:collapse;border-spacing:0;background:#fff;overflow:hidden;}#fbChrome > tbody > tr > td{padding:0;}#fbTop{height:49px;}#fbToolbar{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) #f1f2ee 0 0;height:27px;font-size:11px;line-height:13px;}#fbPanelBarBox{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) #dbd9c9 0 -27px;height:22px;}#fbContent{height:100%;vertical-align:top;}#fbBottom{height:18px;background:#fff;}#fbToolbarIcon{float:left;padding:0 5px 0;}#fbToolbarIcon a{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) 0 -135px;}#fbToolbarButtons{padding:0 2px 0 5px;}#fbToolbarButtons{padding:0 2px 0 5px;}.fbButton{text-decoration:none;display:block;float:left;color:#000;padding:4px 6px 4px 7px;cursor:default;}.fbButton:hover{color:#333;background:#f5f5ef url(https://getfirebug.com/releases/lite/latest/skin/xp/buttonBg.png);padding:3px 5px 3px 6px;border:1px solid #fff;border-bottom:1px solid #bbb;border-right:1px solid #bbb;}.fbBtnPressed{background:#e3e3db url(https://getfirebug.com/releases/lite/latest/skin/xp/buttonBgHover.png) !important;padding:3px 4px 2px 6px !important;margin:1px 0 0 1px !important;border:1px solid #ACA899 !important;border-color:#ACA899 #ECEBE3 #ECEBE3 #ACA899 !important;}#fbStatusBarBox{top:4px;cursor:default;}.fbToolbarSeparator{overflow:hidden;border:1px solid;border-color:transparent #fff transparent #777;_border-color:#eee #fff #eee #777;height:7px;margin:6px 3px;float:left;}.fbBtnSelected{font-weight:bold;}.fbStatusBar{color:#aca899;}.fbStatusBar a{text-decoration:none;color:black;}.fbStatusBar a:hover{color:blue;cursor:pointer;}#fbWindowButtons{position:absolute;white-space:nowrap;right:0;top:0;height:17px;width:48px;padding:5px;z-index:6;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) #f1f2ee 0 0;}#fbPanelBar1{width:1024px; z-index:8;left:0;white-space:nowrap;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) #dbd9c9 0 -27px;position:absolute;left:4px;}#fbPanelBar2Box{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) #dbd9c9 0 -27px;position:absolute;height:22px;width:300px; z-index:9;right:0;}#fbPanelBar2{position:absolute;width:290px; height:22px;padding-left:4px;}.fbPanel{display:none;}#fbPanelBox1,#fbPanelBox2{max-height:inherit;height:100%;font-size:1em;}#fbPanelBox2{background:#fff;}#fbPanelBox2{width:300px;background:#fff;}#fbPanel2{margin-left:6px;background:#fff;}#fbLargeCommandLine{display:none;position:absolute;z-index:9;top:27px;right:0;width:294px;height:201px;border-width:0;margin:0;padding:2px 0 0 2px;resize:none;outline:none;font-size:11px;overflow:auto;border-top:1px solid #B9B7AF;_right:-1px;_border-left:1px solid #fff;}#fbLargeCommandButtons{display:none;background:#ECE9D8;bottom:0;right:0;width:294px;height:21px;padding-top:1px;position:fixed;border-top:1px solid #ACA899;z-index:9;}#fbSmallCommandLineIcon{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/down.png) no-repeat;position:absolute;right:2px;bottom:3px;z-index:99;}#fbSmallCommandLineIcon:hover{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/downHover.png) no-repeat;}.hide{overflow:hidden !important;position:fixed !important;display:none !important;visibility:hidden !important;}#fbCommand{height:18px;}#fbCommandBox{position:fixed;_position:absolute;width:100%;height:18px;bottom:0;overflow:hidden;z-index:9;background:#fff;border:0;border-top:1px solid #ccc;}#fbCommandIcon{position:absolute;color:#00f;top:2px;left:6px;display:inline;font:11px Monaco,monospace;z-index:10;}#fbCommandLine{position:absolute;width:100%;top:0;left:0;border:0;margin:0;padding:2px 0 2px 32px;font:11px Monaco,monospace;z-index:9;outline:none;}#fbLargeCommandLineIcon{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/up.png) no-repeat;position:absolute;right:1px;bottom:1px;z-index:10;}#fbLargeCommandLineIcon:hover{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/upHover.png) no-repeat;}div.fbFitHeight{overflow:auto;position:relative;}.fbSmallButton{overflow:hidden;width:16px;height:16px;display:block;text-decoration:none;cursor:default;}#fbWindowButtons .fbSmallButton{float:right;}#fbWindow_btClose{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/min.png);}#fbWindow_btClose:hover{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/minHover.png);}#fbWindow_btDetach{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/detach.png);}#fbWindow_btDetach:hover{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/detachHover.png);}#fbWindow_btDeactivate{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/off.png);}#fbWindow_btDeactivate:hover{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/offHover.png);}.fbTab{text-decoration:none;display:none;float:left;width:auto;float:left;c |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment