From 0253e03fb581dab463b0de2dfd9a90275e4e69f5 Mon Sep 17 00:00:00 2001 From: Ken ISHIMOTO Date: Mon, 23 Jul 2012 19:55:18 +0200 Subject: [PATCH] New ERFirebug Framework This Framework use Firebug Lite. * It work's Offline * It work's on iOS & IE Usage : only write in the Component HTML Part : --- Frameworks/Misc/ERFirebug/.classpath | 15 + Frameworks/Misc/ERFirebug/.project | 23 + .../org.eclipse.core.resources.prefs | 2 + .../Misc/ERFirebug/Components/ERFirebug.api | 6 + .../ERFirebug.wo/ERFirebug.html | 4 + .../ERFirebug.wo/ERFirebug.wod | 13 + .../ERFirebug.wo/ERFirebug.woo | 4 + .../Misc/ERFirebug/Resources/Properties | 3 + .../er/firebug/components/ERFirebug.java | 40 + .../ERFirebug/Sources/er/firebug/package.html | 92 + .../content/firebug-lite-dev.js | 832 ++ .../content/firebug-lite.js | 8257 +++++++++++++++++ .../content/firebug/console.js | 1193 +++ .../content/firebug/consoleInjector.js | 841 ++ .../WebServerResources/content/firebug/css.js | 2491 +++++ .../content/firebug/debugger.js | 4138 +++++++++ .../WebServerResources/content/firebug/dom.js | 1692 ++++ .../content/firebug/domplate.js | 1147 +++ .../content/firebug/editor.js | 1395 +++ .../content/firebug/highlighter.css | 117 + .../content/firebug/infotip.js | 369 + .../content/firebug/insideOutBox.js | 561 ++ .../content/firebug/jsonViewer.js | 127 + .../content/firebug/lib/htmlLib.js | 753 ++ .../WebServerResources/content/firebug/net.js | 1311 +++ .../content/firebug/reps.js | 1934 ++++ .../content/firebug/sourceBox.js | 1070 +++ .../content/firebug/sourceCache.js | 372 + .../content/firebug/sourceFile.js | 804 ++ .../WebServerResources/content/firebug/spy.js | 763 ++ .../content/firebug/tabContext.js | 543 ++ .../content/firebug/tabWatcher.js | 1030 ++ .../content/firebug/xmlViewer.js | 205 + .../content/firediff-original/cssEvents.js | 386 + .../content/firediff-original/cssModel.js | 280 + .../content/firediff-original/diff.js | 271 + .../content/firediff-original/diffModule.js | 392 + .../content/firediff-original/diffMonitor.js | 365 + .../content/firediff-original/domEvents.js | 446 + .../content/firediff-original/domplate.js | 654 ++ .../content/firediff-original/events.js | 392 + .../content/firediff-original/firediff.xul | 52 + .../content/firediff-original/pages.js | 404 + .../content/firediff-original/path.js | 295 + .../content/firediff-original/search.js | 452 + .../firediff-original/versionCompat.js | 310 + .../firediff/content/firediff/cssEvents.js | 392 + .../firediff/content/firediff/cssModel.js | 280 + .../content/firediff/content/firediff/diff.js | 271 + .../firediff/content/firediff/diffModule.js | 396 + .../firediff/content/firediff/diffMonitor.js | 378 + .../firediff/content/firediff/domEvents.js | 446 + .../firediff/content/firediff/domplate.js | 654 ++ .../firediff/content/firediff/events.js | 392 + .../firediff/content/firediff/firediff.xul | 52 + .../firediff/content/firediff/pages.js | 411 + .../content/firediff/content/firediff/path.js | 295 + .../firediff/content/firediff/search.js | 452 + .../content/firediff/versionCompat.js | 310 + .../content/firediff/license.txt | 31 + .../firediff/skin/classic/firediff.css | 154 + .../content/firerainbow/chrome.manifest | 5 + .../firerainbow/chrome/content/codemirror.js | 1451 +++ .../chrome/content/codemirror/LICENSE | 23 + .../chrome/content/codemirror/parsecss.js | 161 + .../content/codemirror/parsehtmlmixed.js | 93 + .../content/codemirror/parsejavascript.js | 359 + .../chrome/content/codemirror/parsexml.js | 291 + .../chrome/content/codemirror/stringstream.js | 145 + .../chrome/content/codemirror/tokenize.js | 57 + .../content/codemirror/tokenizejavascript.js | 174 + .../chrome/content/codemirror/util.js | 130 + .../chrome/content/firerainbow-original.js | 685 ++ .../firerainbow/chrome/content/firerainbow.js | 746 ++ .../chrome/content/firerainbow.xul | 9 + .../firerainbow/chrome/content/import.xul | 16 + .../firerainbow/chrome/content/worker.js | 63 + .../firerainbow/chrome/skin/import.css | 15 + .../firerainbow/chrome/skin/rainbow.css | 369 + .../firerainbow/chrome/skin/rainbow.png | Bin 0 -> 1997 bytes .../defaults/preferences/firerainbow.js | 6 + .../content/firerainbow/install.rdf | 31 + .../content/firerainbow/license.txt | 30 + .../content/firerainbow/rakefile | 156 + .../content/firerainbow/readme.md | 11 + .../content/firerainbow/support/example.html | 30 + .../firerainbow/support/screenshot.png | Bin 0 -> 139810 bytes .../content/firerainbow/themes/active4d.css | 50 + .../firerainbow/themes/all_hallows_eve.css | 36 + .../content/firerainbow/themes/amy.css | 46 + .../content/firerainbow/themes/blackboard.css | 36 + .../firerainbow/themes/brilliance_black.css | 70 + .../firerainbow/themes/brilliance_dull.css | 79 + .../content/firerainbow/themes/cobalt.css | 68 + .../content/firerainbow/themes/codemirror.css | 29 + .../content/firerainbow/themes/cowtown.css | 44 + .../content/firerainbow/themes/dawn.css | 37 + .../content/firerainbow/themes/eclipse.css | 29 + .../content/firerainbow/themes/eiffel.css | 57 + .../firerainbow/themes/espresso_libre.css | 67 + .../content/firerainbow/themes/idle.css | 32 + .../content/firerainbow/themes/iplastic.css | 60 + .../content/firerainbow/themes/ir_black.css | 91 + .../content/firerainbow/themes/lazy.css | 36 + .../firerainbow/themes/mac_classic.css | 68 + .../firerainbow/themes/magicwb_amiga.css | 46 + .../firerainbow/themes/pastels_on_dark.css | 96 + .../content/firerainbow/themes/rainbow.css | 116 + .../firerainbow/themes/slush_poppies.css | 32 + .../content/firerainbow/themes/spacecadet.css | 28 + .../content/firerainbow/themes/sunburst.css | 80 + .../content/firerainbow/themes/twilight.css | 80 + .../firerainbow/themes/zenburnesque.css | 32 + .../content/firerainbow/utils/Rakefile | 222 + .../WebServerResources/content/lite/boot.js | 3 + .../WebServerResources/content/lite/chrome.js | 2367 +++++ .../content/lite/chromeSkin.js | 13 + .../content/lite/commandLine.js | 554 ++ .../content/lite/context.js | 647 ++ .../content/lite/css/cssAnalyzer.js | 623 ++ .../content/lite/css/cssParser.js | 312 + .../content/lite/eventDelegator.js | 676 ++ .../content/lite/example/helloWorld.js | 24 + .../content/lite/example/pluginSample.js | 62 + .../content/lite/firebug.js | 1360 +++ .../WebServerResources/content/lite/gui.js | 976 ++ .../WebServerResources/content/lite/html.js | 801 ++ .../WebServerResources/content/lite/i18n.js | 126 + .../content/lite/inspector.js | 516 + .../WebServerResources/content/lite/lib.js | 6100 ++++++++++++ .../content/lite/lib/cache.js | 203 + .../WebServerResources/content/lite/lite.js | 11 + .../content/lite/lite/browser.js | 27 + .../content/lite/lite/cache.js | 180 + .../content/lite/lite/proxy.js | 134 + .../content/lite/lite/script.js | 31 + .../content/lite/lite/style.js | 11 + .../WebServerResources/content/lite/plugin.js | 95 + .../WebServerResources/content/lite/script.js | 301 + .../content/lite/selector.js | 1031 ++ .../content/lite/store/json.js | 493 + .../content/lite/store/package.json | 40 + .../content/lite/store/store.js | 142 + .../content/lite/temp/chrome2.js | 1747 ++++ .../content/lite/temp/html2.js | 1906 ++++ .../content/lite/temp/html3.js | 2200 +++++ .../content/lite/temp/inspector2.js | 825 ++ .../WebServerResources/content/lite/trace.js | 180 + .../content/lite/tracePanel.js | 72 + .../WebServerResources/content/lite/xhr.js | 543 ++ .../WebServerResources/plugin/proxy/proxy.php | 258 + .../WebServerResources/skin/light/blank.gif | Bin 0 -> 43 bytes .../skin/light/buttonBg.png | Bin 0 -> 167 bytes .../skin/light/buttonBgHover.png | Bin 0 -> 171 bytes .../WebServerResources/skin/light/close.png | Bin 0 -> 3490 bytes .../skin/light/closeHover.png | Bin 0 -> 3480 bytes .../WebServerResources/skin/light/detach.png | Bin 0 -> 3466 bytes .../skin/light/detachHover.png | Bin 0 -> 3473 bytes .../WebServerResources/skin/light/disable.gif | Bin 0 -> 340 bytes .../WebServerResources/skin/light/disable.png | Bin 0 -> 543 bytes .../skin/light/disableHover.gif | Bin 0 -> 344 bytes .../skin/light/disableHover.png | Bin 0 -> 512 bytes .../WebServerResources/skin/light/down.png | Bin 0 -> 637 bytes .../skin/light/downActive.png | Bin 0 -> 543 bytes .../skin/light/downHover.png | Bin 0 -> 526 bytes .../skin/light/errorIcon-sm.png | Bin 0 -> 447 bytes .../skin/light/errorIcon.gif | Bin 0 -> 365 bytes .../skin/light/errorIcon.png | Bin 0 -> 457 bytes .../WebServerResources/skin/light/firebug.css | 3063 ++++++ .../skin/light/firebug.html | 213 + .../WebServerResources/skin/light/firebug.png | Bin 0 -> 1037 bytes .../WebServerResources/skin/light/group.gif | Bin 0 -> 158 bytes .../skin/light/infoIcon.gif | Bin 0 -> 359 bytes .../skin/light/infoIcon.png | Bin 0 -> 524 bytes .../skin/light/loading_16.gif | Bin 0 -> 1553 bytes .../WebServerResources/skin/light/min.png | Bin 0 -> 552 bytes .../skin/light/minHover.png | Bin 0 -> 485 bytes .../WebServerResources/skin/light/off.png | Bin 0 -> 742 bytes .../skin/light/offHover.png | Bin 0 -> 680 bytes .../skin/light/pixel_transparent.gif | Bin 0 -> 43 bytes .../skin/light/roundCorner.svg | 6 + .../WebServerResources/skin/light/search.gif | Bin 0 -> 550 bytes .../WebServerResources/skin/light/search.png | Bin 0 -> 685 bytes .../WebServerResources/skin/light/shadow.gif | Bin 0 -> 4364 bytes .../WebServerResources/skin/light/shadow2.gif | Bin 0 -> 3093 bytes .../skin/light/shadowAlpha.png | Bin 0 -> 3403 bytes .../WebServerResources/skin/light/sprite.png | Bin 0 -> 7464 bytes .../skin/light/tabHoverLeft.png | Bin 0 -> 432 bytes .../skin/light/tabHoverMid.png | Bin 0 -> 239 bytes .../skin/light/tabHoverRight.png | Bin 0 -> 432 bytes .../WebServerResources/skin/light/tabLeft.png | Bin 0 -> 440 bytes .../skin/light/tabMenuCheckbox.png | Bin 0 -> 220 bytes .../skin/light/tabMenuPin.png | Bin 0 -> 207 bytes .../skin/light/tabMenuRadio.png | Bin 0 -> 192 bytes .../skin/light/tabMenuTarget.png | Bin 0 -> 142 bytes .../skin/light/tabMenuTargetHover.png | Bin 0 -> 148 bytes .../WebServerResources/skin/light/tabMid.png | Bin 0 -> 236 bytes .../skin/light/tabRight.png | Bin 0 -> 433 bytes .../skin/light/textEditorBorders.gif | Bin 0 -> 117 bytes .../skin/light/textEditorBorders.png | Bin 0 -> 3144 bytes .../skin/light/textEditorCorners.gif | Bin 0 -> 1821 bytes .../skin/light/textEditorCorners.png | Bin 0 -> 3960 bytes .../skin/light/titlebarMid.png | Bin 0 -> 171 bytes .../skin/light/toolbarMid.png | Bin 0 -> 256 bytes .../skin/light/tree_close.gif | Bin 0 -> 300 bytes .../skin/light/tree_open.gif | Bin 0 -> 202 bytes .../skin/light/twistyClosed.png | Bin 0 -> 334 bytes .../skin/light/twistyOpen.png | Bin 0 -> 309 bytes .../WebServerResources/skin/light/up.png | Bin 0 -> 619 bytes .../skin/light/upActive.png | Bin 0 -> 551 bytes .../WebServerResources/skin/light/upHover.png | Bin 0 -> 526 bytes .../skin/light/warningIcon.gif | Bin 0 -> 357 bytes .../skin/light/warningIcon.png | Bin 0 -> 516 bytes .../WebServerResources/skin/xp/blank.gif | Bin 0 -> 43 bytes .../WebServerResources/skin/xp/buttonBg.png | Bin 0 -> 167 bytes .../skin/xp/buttonBgHover.png | Bin 0 -> 171 bytes .../WebServerResources/skin/xp/debugger.css | 331 + .../WebServerResources/skin/xp/detach.png | Bin 0 -> 655 bytes .../skin/xp/detachHover.png | Bin 0 -> 586 bytes .../WebServerResources/skin/xp/disable.gif | Bin 0 -> 340 bytes .../WebServerResources/skin/xp/disable.png | Bin 0 -> 543 bytes .../skin/xp/disableHover.gif | Bin 0 -> 344 bytes .../skin/xp/disableHover.png | Bin 0 -> 512 bytes .../WebServerResources/skin/xp/down.png | Bin 0 -> 637 bytes .../WebServerResources/skin/xp/downActive.png | Bin 0 -> 543 bytes .../WebServerResources/skin/xp/downHover.png | Bin 0 -> 526 bytes .../skin/xp/errorIcon-sm.png | Bin 0 -> 447 bytes .../WebServerResources/skin/xp/errorIcon.gif | Bin 0 -> 365 bytes .../WebServerResources/skin/xp/errorIcon.png | Bin 0 -> 457 bytes .../skin/xp/firebug-1.3a2.css | 817 ++ .../skin/xp/firebug.IE6.css | 20 + .../WebServerResources/skin/xp/firebug.css | 3147 +++++++ .../WebServerResources/skin/xp/firebug.html | 215 + .../WebServerResources/skin/xp/firebug.png | Bin 0 -> 1167 bytes .../WebServerResources/skin/xp/group.gif | Bin 0 -> 158 bytes .../WebServerResources/skin/xp/html.css | 272 + .../WebServerResources/skin/xp/infoIcon.gif | Bin 0 -> 359 bytes .../WebServerResources/skin/xp/infoIcon.png | Bin 0 -> 524 bytes .../WebServerResources/skin/xp/loading_16.gif | Bin 0 -> 1553 bytes .../WebServerResources/skin/xp/min.png | Bin 0 -> 552 bytes .../WebServerResources/skin/xp/minHover.png | Bin 0 -> 485 bytes .../WebServerResources/skin/xp/off.png | Bin 0 -> 742 bytes .../WebServerResources/skin/xp/offHover.png | Bin 0 -> 680 bytes .../skin/xp/pixel_transparent.gif | Bin 0 -> 43 bytes .../skin/xp/roundCorner.svg | 6 + .../WebServerResources/skin/xp/search.gif | Bin 0 -> 550 bytes .../WebServerResources/skin/xp/search.png | Bin 0 -> 685 bytes .../WebServerResources/skin/xp/shadow.gif | Bin 0 -> 4364 bytes .../WebServerResources/skin/xp/shadow2.gif | Bin 0 -> 3093 bytes .../skin/xp/shadowAlpha.png | Bin 0 -> 3403 bytes .../WebServerResources/skin/xp/sprite.png | Bin 0 -> 40027 bytes .../skin/xp/tabHoverLeft.png | Bin 0 -> 438 bytes .../skin/xp/tabHoverMid.png | Bin 0 -> 261 bytes .../skin/xp/tabHoverRight.png | Bin 0 -> 436 bytes .../WebServerResources/skin/xp/tabLeft.png | Bin 0 -> 449 bytes .../skin/xp/tabMenuCheckbox.png | Bin 0 -> 220 bytes .../WebServerResources/skin/xp/tabMenuPin.png | Bin 0 -> 207 bytes .../skin/xp/tabMenuRadio.png | Bin 0 -> 192 bytes .../skin/xp/tabMenuTarget.png | Bin 0 -> 142 bytes .../skin/xp/tabMenuTargetHover.png | Bin 0 -> 148 bytes .../WebServerResources/skin/xp/tabMid.png | Bin 0 -> 262 bytes .../WebServerResources/skin/xp/tabRight.png | Bin 0 -> 448 bytes .../skin/xp/textEditorBorders.gif | Bin 0 -> 117 bytes .../skin/xp/textEditorBorders.png | Bin 0 -> 3144 bytes .../skin/xp/textEditorCorners.gif | Bin 0 -> 1821 bytes .../skin/xp/textEditorCorners.png | Bin 0 -> 3960 bytes .../skin/xp/titlebarMid.png | Bin 0 -> 273 bytes .../WebServerResources/skin/xp/toolbarMid.png | Bin 0 -> 242 bytes .../WebServerResources/skin/xp/tree_close.gif | Bin 0 -> 300 bytes .../WebServerResources/skin/xp/tree_open.gif | Bin 0 -> 202 bytes .../skin/xp/twistyClosed.png | Bin 0 -> 334 bytes .../WebServerResources/skin/xp/twistyOpen.png | Bin 0 -> 309 bytes .../WebServerResources/skin/xp/up.png | Bin 0 -> 619 bytes .../WebServerResources/skin/xp/upActive.png | Bin 0 -> 551 bytes .../WebServerResources/skin/xp/upHover.png | Bin 0 -> 526 bytes .../skin/xp/warningIcon.gif | Bin 0 -> 357 bytes .../skin/xp/warningIcon.png | Bin 0 -> 516 bytes Frameworks/Misc/ERFirebug/build.properties | 17 + .../woproject/classes.exclude.patternset | 1 + .../woproject/classes.include.patternset | 2 + .../woproject/resources.exclude.patternset | 3 + .../woproject/resources.include.patternset | 3 + .../woproject/wsresources.exclude.patternset | 3 + .../woproject/wsresources.include.patternset | 1 + 284 files changed, 82193 insertions(+) create mode 100644 Frameworks/Misc/ERFirebug/.classpath create mode 100644 Frameworks/Misc/ERFirebug/.project create mode 100644 Frameworks/Misc/ERFirebug/.settings/org.eclipse.core.resources.prefs create mode 100644 Frameworks/Misc/ERFirebug/Components/ERFirebug.api create mode 100644 Frameworks/Misc/ERFirebug/Components/Nonlocalized.lproj/ERFirebug.wo/ERFirebug.html create mode 100644 Frameworks/Misc/ERFirebug/Components/Nonlocalized.lproj/ERFirebug.wo/ERFirebug.wod create mode 100644 Frameworks/Misc/ERFirebug/Components/Nonlocalized.lproj/ERFirebug.wo/ERFirebug.woo create mode 100644 Frameworks/Misc/ERFirebug/Resources/Properties create mode 100644 Frameworks/Misc/ERFirebug/Sources/er/firebug/components/ERFirebug.java create mode 100644 Frameworks/Misc/ERFirebug/Sources/er/firebug/package.html create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firebug-lite-dev.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firebug-lite.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firebug/console.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firebug/consoleInjector.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firebug/css.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firebug/debugger.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firebug/dom.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firebug/domplate.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firebug/editor.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firebug/highlighter.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firebug/infotip.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firebug/insideOutBox.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firebug/jsonViewer.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firebug/lib/htmlLib.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firebug/net.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firebug/reps.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firebug/sourceBox.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firebug/sourceCache.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firebug/sourceFile.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firebug/spy.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firebug/tabContext.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firebug/tabWatcher.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firebug/xmlViewer.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff-original/cssEvents.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff-original/cssModel.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff-original/diff.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff-original/diffModule.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff-original/diffMonitor.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff-original/domEvents.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff-original/domplate.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff-original/events.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff-original/firediff.xul create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff-original/pages.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff-original/path.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff-original/search.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff-original/versionCompat.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff/cssEvents.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff/cssModel.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff/diff.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff/diffModule.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff/diffMonitor.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff/domEvents.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff/domplate.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff/events.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff/firediff.xul create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff/pages.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff/path.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff/search.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/content/firediff/versionCompat.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/license.txt create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firediff/skin/classic/firediff.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/chrome.manifest create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/chrome/content/codemirror.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/chrome/content/codemirror/LICENSE create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/chrome/content/codemirror/parsecss.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/chrome/content/codemirror/parsehtmlmixed.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/chrome/content/codemirror/parsejavascript.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/chrome/content/codemirror/parsexml.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/chrome/content/codemirror/stringstream.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/chrome/content/codemirror/tokenize.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/chrome/content/codemirror/tokenizejavascript.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/chrome/content/codemirror/util.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/chrome/content/firerainbow-original.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/chrome/content/firerainbow.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/chrome/content/firerainbow.xul create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/chrome/content/import.xul create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/chrome/content/worker.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/chrome/skin/import.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/chrome/skin/rainbow.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/chrome/skin/rainbow.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/defaults/preferences/firerainbow.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/install.rdf create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/license.txt create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/rakefile create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/readme.md create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/support/example.html create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/support/screenshot.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/active4d.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/all_hallows_eve.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/amy.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/blackboard.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/brilliance_black.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/brilliance_dull.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/cobalt.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/codemirror.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/cowtown.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/dawn.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/eclipse.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/eiffel.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/espresso_libre.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/idle.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/iplastic.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/ir_black.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/lazy.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/mac_classic.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/magicwb_amiga.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/pastels_on_dark.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/rainbow.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/slush_poppies.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/spacecadet.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/sunburst.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/twilight.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/zenburnesque.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/utils/Rakefile create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/boot.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/chrome.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/chromeSkin.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/commandLine.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/context.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/css/cssAnalyzer.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/css/cssParser.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/eventDelegator.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/example/helloWorld.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/example/pluginSample.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/firebug.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/gui.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/html.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/i18n.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/inspector.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lib.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lib/cache.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lite.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lite/browser.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lite/cache.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lite/proxy.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lite/script.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lite/style.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/plugin.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/script.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/selector.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/store/json.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/store/package.json create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/store/store.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/temp/chrome2.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/temp/html2.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/temp/html3.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/temp/inspector2.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/trace.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/tracePanel.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/content/lite/xhr.js create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/plugin/proxy/proxy.php create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/blank.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/buttonBg.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/buttonBgHover.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/close.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/closeHover.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/detach.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/detachHover.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/disable.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/disable.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/disableHover.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/disableHover.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/down.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/downActive.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/downHover.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/errorIcon-sm.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/errorIcon.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/errorIcon.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/firebug.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/firebug.html create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/firebug.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/group.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/infoIcon.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/infoIcon.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/loading_16.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/min.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/minHover.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/off.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/offHover.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/pixel_transparent.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/roundCorner.svg create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/search.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/search.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/shadow.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/shadow2.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/shadowAlpha.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/sprite.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tabHoverLeft.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tabHoverMid.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tabHoverRight.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tabLeft.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tabMenuCheckbox.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tabMenuPin.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tabMenuRadio.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tabMenuTarget.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tabMenuTargetHover.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tabMid.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tabRight.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/textEditorBorders.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/textEditorBorders.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/textEditorCorners.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/textEditorCorners.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/titlebarMid.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/toolbarMid.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tree_close.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tree_open.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/twistyClosed.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/twistyOpen.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/up.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/upActive.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/upHover.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/warningIcon.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/light/warningIcon.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/blank.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/buttonBg.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/buttonBgHover.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/debugger.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/detach.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/detachHover.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/disable.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/disable.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/disableHover.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/disableHover.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/down.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/downActive.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/downHover.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/errorIcon-sm.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/errorIcon.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/errorIcon.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/firebug-1.3a2.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/firebug.IE6.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/firebug.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/firebug.html create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/firebug.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/group.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/html.css create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/infoIcon.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/infoIcon.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/loading_16.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/min.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/minHover.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/off.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/offHover.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/pixel_transparent.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/roundCorner.svg create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/search.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/search.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/shadow.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/shadow2.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/shadowAlpha.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/sprite.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabHoverLeft.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabHoverMid.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabHoverRight.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabLeft.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabMenuCheckbox.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabMenuPin.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabMenuRadio.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabMenuTarget.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabMenuTargetHover.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabMid.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabRight.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/textEditorBorders.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/textEditorBorders.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/textEditorCorners.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/textEditorCorners.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/titlebarMid.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/toolbarMid.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tree_close.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tree_open.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/twistyClosed.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/twistyOpen.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/up.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/upActive.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/upHover.png create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/warningIcon.gif create mode 100644 Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/warningIcon.png create mode 100644 Frameworks/Misc/ERFirebug/build.properties create mode 100644 Frameworks/Misc/ERFirebug/woproject/classes.exclude.patternset create mode 100644 Frameworks/Misc/ERFirebug/woproject/classes.include.patternset create mode 100644 Frameworks/Misc/ERFirebug/woproject/resources.exclude.patternset create mode 100644 Frameworks/Misc/ERFirebug/woproject/resources.include.patternset create mode 100644 Frameworks/Misc/ERFirebug/woproject/wsresources.exclude.patternset create mode 100644 Frameworks/Misc/ERFirebug/woproject/wsresources.include.patternset diff --git a/Frameworks/Misc/ERFirebug/.classpath b/Frameworks/Misc/ERFirebug/.classpath new file mode 100644 index 00000000000..559db7a6826 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/.classpath @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/Frameworks/Misc/ERFirebug/.project b/Frameworks/Misc/ERFirebug/.project new file mode 100644 index 00000000000..dc567364d0d --- /dev/null +++ b/Frameworks/Misc/ERFirebug/.project @@ -0,0 +1,23 @@ + + + ERFirebug + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.objectstyle.wolips.incrementalbuilder + + + + + + org.eclipse.jdt.core.javanature + org.objectstyle.wolips.incrementalframeworknature + + diff --git a/Frameworks/Misc/ERFirebug/.settings/org.eclipse.core.resources.prefs b/Frameworks/Misc/ERFirebug/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 00000000000..a6a0fefecb6 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding//Components=UTF-8 diff --git a/Frameworks/Misc/ERFirebug/Components/ERFirebug.api b/Frameworks/Misc/ERFirebug/Components/ERFirebug.api new file mode 100644 index 00000000000..b6983e17163 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/Components/ERFirebug.api @@ -0,0 +1,6 @@ + + + + + + diff --git a/Frameworks/Misc/ERFirebug/Components/Nonlocalized.lproj/ERFirebug.wo/ERFirebug.html b/Frameworks/Misc/ERFirebug/Components/Nonlocalized.lproj/ERFirebug.wo/ERFirebug.html new file mode 100644 index 00000000000..37f2727a705 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/Components/Nonlocalized.lproj/ERFirebug.wo/ERFirebug.html @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/Components/Nonlocalized.lproj/ERFirebug.wo/ERFirebug.wod b/Frameworks/Misc/ERFirebug/Components/Nonlocalized.lproj/ERFirebug.wo/ERFirebug.wod new file mode 100644 index 00000000000..2d90089b090 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/Components/Nonlocalized.lproj/ERFirebug.wo/ERFirebug.wod @@ -0,0 +1,13 @@ +UseFirebug : WOConditional { + condition = useFirebug; +} + +JS : ERXJavaScript { //FIXME : It works only if this get called. Little Strange but for now it works + framework = "ERFirebug"; + filename = "content/firebug-lite-dev.js"; +} + +JS2 : ERXJavaScript { + framework = "ERFirebug"; + filename = "content/firebug-lite.js"; +} \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/Components/Nonlocalized.lproj/ERFirebug.wo/ERFirebug.woo b/Frameworks/Misc/ERFirebug/Components/Nonlocalized.lproj/ERFirebug.wo/ERFirebug.woo new file mode 100644 index 00000000000..a076a051a7e --- /dev/null +++ b/Frameworks/Misc/ERFirebug/Components/Nonlocalized.lproj/ERFirebug.wo/ERFirebug.woo @@ -0,0 +1,4 @@ +{ + "WebObjects Release" = "WebObjects 5.0"; + encoding = "UTF-8"; +} \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/Resources/Properties b/Frameworks/Misc/ERFirebug/Resources/Properties new file mode 100644 index 00000000000..7e73cdca6cb --- /dev/null +++ b/Frameworks/Misc/ERFirebug/Resources/Properties @@ -0,0 +1,3 @@ +## Properies Info +er.extensions.load.Properties.framework.ERFirebug=load +er.extensions.ERFirebug.hasLocalization=false diff --git a/Frameworks/Misc/ERFirebug/Sources/er/firebug/components/ERFirebug.java b/Frameworks/Misc/ERFirebug/Sources/er/firebug/components/ERFirebug.java new file mode 100644 index 00000000000..18868898ebc --- /dev/null +++ b/Frameworks/Misc/ERFirebug/Sources/er/firebug/components/ERFirebug.java @@ -0,0 +1,40 @@ +package er.firebug.components; + +import com.webobjects.appserver.WOContext; + +import er.extensions.components.ERXStatelessComponent; + +/** + * Firebug lite WebObjects Framework + * + * http://getfirebug.com/lite.html + * + * @author ishimoto + */ +@SuppressWarnings("serial") +public class ERFirebug extends ERXStatelessComponent { + + public static String VERSION = "1.4"; + + //******************************************************************** + // Constructor + //******************************************************************** + + public ERFirebug(WOContext context) { + super(context); + } + + @Override + public boolean synchronizesVariablesWithBindings() { + return false; + } + + //******************************************************************** + // Bindings + //******************************************************************** + + public boolean useFirebug() { + return booleanValueForBinding("useFirebug", true); + } + +} \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/Sources/er/firebug/package.html b/Frameworks/Misc/ERFirebug/Sources/er/firebug/package.html new file mode 100644 index 00000000000..72da9f9ff73 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/Sources/er/firebug/package.html @@ -0,0 +1,92 @@ +Firebug adds a global variable named "console" to all web pages loaded in Firefox. This object contains many methods that allow you to write to the Firebug console to expose information that is flowing through your scripts. + +console.log(object[, object, ...]) + +Writes a message to the console. You may pass as many arguments as you'd like, and they will be joined together in a space-delimited line. +The first argument to log may be a string containing printf-like string substitution patterns. For example: + +console.log("The %s jumped over %d tall buildings", animal, count); + +The example above can be re-written without string substitution to achieve the same result: + +console.log("The", animal, "jumped over", count, "tall buildings"); + +These two techniques can be combined. If you use string substitution but provide more arguments than there are substitution patterns, the remaining arguments will be appended in a space-delimited line, like so: + +console.log("I am %s and I have:", myName, thing1, thing2, thing3); + +If objects are logged, they will be written not as static text, but as interactive hyperlinks that can be clicked to inspect the object in Firebug's HTML, CSS, Script, or DOM tabs. You may also use the %o pattern to substitute a hyperlink in a string. +Here is the complete set of patterns that you may use for string substitution: + + +String Substitution Patterns +%s String +%d, %i Integer (numeric formatting is not yet supported) +%f Floating point number (numeric formatting is not yet supported) +%o Object hyperlink + + +console.debug(object[, object, ...]) + + Writes a message to the console, including a hyperlink to the line where it was called. + +console.info(object[, object, ...]) + + Writes a message to the console with the visual "info" icon and color coding and a hyperlink to the line where it was called. + +console.warn(object[, object, ...]) + + Writes a message to the console with the visual "warning" icon and color coding and a hyperlink to the line where it was called. + +console.error(object[, object, ...]) + + Writes a message to the console with the visual "error" icon and color coding and a hyperlink to the line where it was called. + +console.assert(expression[, object, ...]) + + Tests that an expression is true. If not, it will write a message to the console and throw an exception. + +console.dir(object) + + Prints an interactive listing of all properties of the object. This looks identical to the view that you would see in the DOM tab. + +console.dirxml(node) + + Prints the XML source tree of an HTML or XML element. This looks identical to the view that you would see in the HTML tab. You can click on any node to inspect it in the HTML tab. + +console.trace() + + Prints an interactive stack trace of JavaScript execution at the point where it is called. + The stack trace details the functions on the stack, as well as the values that were passed as arguments to each function. You can click each function to take you to its source in the Script tab, and click each argument value to inspect it in the DOM or HTML tabs. + +console.group(object[, object, ...]) + + Writes a message to the console and opens a nested block to indent all future messages sent to the console. Call console.groupEnd() to close the block. + +console.groupCollapsed(object[, object, ...]) + + Like console.group(), but the block is initially collapsed. + +console.groupEnd() + + Closes the most recently opened block created by a call to console.group() or console.groupEnd() + +console.time(name) + + Creates a new timer under the given name. Call console.timeEnd(name) with the same name to stop the timer and print the time elapsed.. + +console.timeEnd(name) + + Stops a timer created by a call to console.time(name) and writes the time elapsed. + +console.profile([title]) + + Turns on the JavaScript profiler. The optional argument title would contain the text to be printed in the header of the profile report. + +console.profileEnd() + + Turns off the JavaScript profiler and prints its report. + +console.count([title]) + + Writes the number of times that the line of code where count was called was executed. The optional argument title will print a message in addition to the number of the count. diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firebug-lite-dev.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/firebug-lite-dev.js new file mode 100644 index 00000000000..afdb1ea68c4 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firebug-lite-dev.js @@ -0,0 +1,832 @@ +/* See license.txt for terms of usage */ + +(function(){ +// ************************************************************************************************ + +// TODO: plugin problem with Dev panel +// TODO: Dev panel doesn't work in persistent mode +// TODO: XHR listener breaks Firebug in Chrome when in persistent mode + +// Firebug Lite is already running in persistent mode so we just quit +// TODO: better detection +if (window.Firebug) + return; + +// ************************************************************************************************ + +var bookmarkletMode = true; + +var bookmarkletSkinURL = "https://getfirebug.com/releases/lite/latest/skin/xp/"; // stable +//var bookmarkletSkinURL = "https://getfirebug.com/releases/lite/beta/skin/xp/"; // beta +//var bookmarkletSkinURL = "http://fbug.googlecode.com/svn/lite/branches/firebug1.3/skin/xp/"; // developer +//var bookmarkletSkinURL = "chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/"; // chrome extension +//var bookmarkletSkinURL = "chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/"; // chrome beta extension + +// ************************************************************************************************ + +//window.FBL = {}; // force exposure in IE global namespace +window.FBDev = +{ + // ******************************************************************************************** + modules: + [ + // **************************************************************************************** + // Application Core + + "lite/lib.js", + "lite/i18n.js", + "lite/firebug.js", + + "lite/gui.js", + "lite/context.js", + "lite/chrome.js", + "lite/chromeSkin.js", + + // firebug1.4 experimental + //"lite/temp/chrome2.js", + //"firebug/tabContext.js", + //"firebug/tabWatcher.js", + + + // **************************************************************************************** + // Lite Core + + "lite/lite.js", + "lite/lite/cache.js", + "lite/lite/proxy.js", + "lite/lite/style.js", + "lite/lite/script.js", // experimental + "lite/lite/browser.js", // experimental + + "lite/store/json.js", + "lite/store/store.js", + + // **************************************************************************************** + // Firebug Classes + + "lite/selector.js", + "lite/inspector.js", + + "firebug/domplate.js", + "firebug/reps.js", + "firebug/editor.js", + + // **************************************************************************************** + // XHR Watcher + + "lite/xhr.js", + "firebug/net.js", + "firebug/spy.js", + + "firebug/jsonViewer.js", + "firebug/xmlViewer.js", + + // **************************************************************************************** + // Console / CommandLine core + + "firebug/console.js", + "firebug/consoleInjector.js", + + "lite/commandLine.js", + + // **************************************************************************************** + // Simple HTML Panel + + "lite/html.js", + + // **************************************************************************************** + // Advanced HTML Panel (experimental) + + //"firebug/insideOutBox.js", // HTML experimental + //"firebug/lib/htmlLib.js", // HTML experimental + //"lite/temp/html3.js", // HTML experimental + //"lite/temp/html2.js", // HTML experimental + + "firebug/infotip.js", + + // **************************************************************************************** + // CSS Panel + + "lite/css/cssParser.js", + "lite/css/cssAnalyzer.js", + "firebug/css.js", + + // **************************************************************************************** + // Simple Script Panel + + "lite/script.js", + + // **************************************************************************************** + // Script Panel + + //"firebug/sourceCache.js", // experimental + //"firebug/sourceFile.js", // experimental + //"firebug/sourceBox.js", // experimental + //"firebug/debugger.js", // experimental + + //"lite/eventDelegator.js", // experimental + + "firebug/dom.js", + + // **************************************************************************************** + // Trace Module/Panel + + "lite/trace.js", + "lite/tracePanel.js", + + // **************************************************************************************** + // Firediff + + /* + "firediff/content/firediff/versionCompat.js", + "firediff/content/firediff/diff.js", + "firediff/content/firediff/path.js", + "firediff/content/firediff/cssModel.js", + "firediff/content/firediff/events.js", + "firediff/content/firediff/domEvents.js", + "firediff/content/firediff/cssEvents.js", + "firediff/content/firediff/domplate.js", + "firediff/content/firediff/search.js", + "firediff/content/firediff/pages.js", + "firediff/content/firediff/diffModule.js", + "firediff/content/firediff/diffMonitor.js", + */ + + // **************************************************************************************** + // FireRainbow + + /* + "firerainbow/chrome/content/codemirror.js", + "firerainbow/chrome/content/firerainbow.js", + */ + + // **************************************************************************************** + // Example Plugin + + //"lite/example/helloWorld.js", + + // **************************************************************************************** + // Plugin Interface + + "lite/plugin.js", // must be the last module loaded + + // **************************************************************************************** + // Bootstrap + "lite/boot.js" + ], + // ******************************************************************************************** + + loadChromeApplication: function(chrome) + { + loadModules(chrome.document); return; + + FBDev.buildSource(function(source){ + var doc = chrome.document; + var script = doc.createElement("script"); + doc.getElementsByTagName("head")[0].appendChild(script); + script.text = source; + }); + }, + + panelBuild: function() { + var panel = this.getPanel(); + panel.updateOutput("Building Source..."); + + setTimeout(function(){ + FBDev.buildFullSource(function(source){ + panel.updateOutput(source); + }); + },0); + }, + + panelBuildSkin: function() + { + var panel = this.getPanel(); + panel.updateOutput("Building Source..."); + + setTimeout(function(){ + FBDev.buildSkin(function(source){ + panel.updateOutput(source); + }); + },0); + }, + + build: function() { + var out = document.createElement("textarea"); + + FBDev.buildFullSource(function(source){ + out.style.cssText = "position: absolute; top: 0; left: 0; width: 100%; height: 100%;"; + //out.appendChild(document.createTextNode(source)); + + out.value = source; + document.body.appendChild(out); + }); + }, + + buildFullSource: function(callback) + { + var useClosure = true; + var source = []; + + // remove the boot.js from the list of modules to be included + // because it will be generated bellow + var modules = FBDev.modules.slice(0,FBDev.modules.length-1); + var last = modules.length-1; + + if (useClosure) + source.push("(function(){\n\n"); + + var htmlUrl = skinURL + "firebug.html", + cssUrl = skinURL + "firebug.css", + html, + css, + injected; + + FBL.Ajax.request({ + url: htmlUrl, + onComplete:function(r) + { + html = FBDev.compressHTML(r); + } + }); + + FBL.Ajax.request({ + url: cssUrl, + onComplete:function(r) + { + css = FBDev.compressCSS(r); + injected = + "\n\nFBL.ns(function() { with (FBL) {\n" + + "// ************************************************************************************************\n\n" + + "FirebugChrome.Skin = \n" + + "{\n" + + " CSS: '" + css + "',\n" + + " HTML: '" + html + "'\n" + + "};\n\n" + + "// ************************************************************************************************\n" + + "}});\n\n" + + "// ************************************************************************************************\n" + + + // this is the bootstrap.js file + "FBL.initialize();\n" + + + "// ************************************************************************************************\n"; + } + }); + + for (var i=0, module; module=modules[i]; i++) + { + var moduleURL = sourceURL + module; + + if (module.indexOf("chromeSkin") != -1) continue; + + FBL.Ajax.request({ + url: moduleURL, + i: i, + onComplete: function(r,o) + { + source.push(r); + + if (o.i == last) + { + //alert("ok") + source.push(injected); + + if (useClosure) + source.push("\n})();"); + + callback(source.join("")); + } + else + source.push("\n\n"); + } + }); + } + }, + + buildSource: function(callback) + { + var useClosure = true; + var source = []; + var last = FBDev.modules.length-1; + + if (useClosure) + source.push("(function(){\n\n"); + + for (var i=0, module; module=FBDev.modules[i]; i++) + { + var moduleURL = sourceURL + module; + + FBL.Ajax.request({url: moduleURL, i: i, onComplete: function(r,o) + { + source.push(r); + + if (o.i == last) + { + if (useClosure) + source.push("\n})();"); + + callback(source.join("")); + } + else + source.push("\n\n"); + } + }); + } + }, + + buildSkin: function(callback) + { + var htmlUrl = skinURL + "firebug.html", + cssUrl = skinURL + "firebug.css", + html, + css, + injected; + + FBL.Ajax.request({ + url: htmlUrl, + onComplete:function(r) + { + html = FBDev.compressHTML(r); + } + }); + + FBL.Ajax.request({ + url: cssUrl, + onComplete:function(r) + { + css = FBDev.compressCSS(r); + injected = + "/* See license.txt for terms of usage */\n\n" + + "FBL.ns(function() { with (FBL) {\n" + + "// ************************************************************************************************\n\n" + + "FirebugChrome.Skin = \n" + + "{\n" + + " HTML: '" + html + "',\n" + + " CSS: '" + css + "'\n" + + "};\n\n" + + "// ************************************************************************************************\n" + + "}});"; + + callback(injected); + } + }); + }, + + compressSkinHTML: function() + { + var url = skinURL + "firebug.html"; + + var out = document.createElement("textarea"); + + FBL.Ajax.request({url: url, onComplete:function(r) + { + var result = FBDev.compressHTML(r); + + out.style.cssText = "position: absolute; top: 0; left: 0; width: 100%; height: 100%;"; + out.appendChild(document.createTextNode(result)); + document.body.appendChild(out); + } + }); + }, + + compressSkinCSS: function() + { + var url = skinURL + "firebug.css"; + + var out = document.createElement("textarea"); + + FBL.Ajax.request({url: url, onComplete:function(r) + { + var result = FBDev.compressCSS(r); + + out.style.cssText = "position: absolute; top: 0; left: 0; width: 100%; height: 100%;"; + out.appendChild(document.createTextNode(result)); + document.body.appendChild(out); + } + }); + + }, + + compressHTML: function(html) + { + var reHTMLComment = /()/g; + + return html.replace(/^[\s\S]*<\s*body.*>\s*|\s*<\s*\/body.*>[\s\S]*$/gm, ""). + replace(reHTMLComment, ""). + replace(/\s\s/gm, ""). + replace(/\s+/gm, ">"). + replace(/>\s+/gm, ">"). + replace(/\s+\/>/gm, "/>"); + }, + + compressCSS: function(css) + { + var reComment = /(\/\/.*)\n/g; + var reMultiComment = /(\/\*([^\*]|\*(?!\/))*\*\/)/g; + + return css.replace(reComment, ""). + replace(reMultiComment, ""). + replace(/url\(/gi, "url("+publishedURL). + replace(/\s\s/gm, ""). + replace(/\s+\{/gm, "{"). + replace(/\{\s+/gm, "{"). + replace(/\s+\}/gm, "}"). + replace(/\}\s+/gm, "}"). + replace(/\s+\:/gm, ":"). + replace(/\:\s+/gm, ":"). + replace(/,\s+/gm, ","); + }, + + getPanel: function() + { + return Firebug.chrome.getPanel("Dev"); + } +}; + +// ************************************************************************************************ + +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; + + // Firebug Lite 1.3.0 bookmarklet identification + var script = doc.getElementById("FirebugLite"); + + var scriptSrc; + + // If the script was loaded via bookmarklet, we already have the script tag + 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; + } + } + // otherwise we must search for the correct script tag + 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"); + + else if (file = reFirebugFile.exec(si.src)) + scriptSrc = si.src; + + else + continue; + + script = si; + break; + } + } + } + + // mark the script tag to be ignored by Firebug Lite + if (script) + script.firebugIgnore = true; + + if (file) + { + var fileName = file[1]; + var fileOptions = file[2]; + + // absolute path + if (reProtocol.test(scriptSrc)) { + path = rePath.exec(scriptSrc)[1]; + + } + // relative path + else + { + var r = rePath.exec(scriptSrc); + var src = r ? r[1] : scriptSrc; + var backDir = /^((?:\.\.\/)+)(.*)/.exec(src); + var reLastDir = /^(.*\/)[^\/]+\/$/; + path = rePath.exec(location.href)[1]; + + // "../some/path" + 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) + { + // "./some/path" + if(/^\.\/./.test(src)) + { + path += src.substring(2); + } + // "/some/path" + else if(/^\/./.test(src)) + { + var domain = /^(\w+:\/\/[^\/]+)/.exec(path); + path = domain[1] + src; + } + // "some/path" + else + { + path += src; + } + } + } + } + + var m = path.match(/([^\/]+)\/$/); + + if (path && m) + { + sourceURL = path; + baseURL = path.substr(0, path.length - m[1].length - 1); + skinURL = baseURL + "skin/xp/"; + fullURL = path + fileName; + } + else + { + throw "Firebug error: Library path not found"; + } +}; + +// ************************************************************************************************ + +function loadModules(doc) { + + findLocation(); + + publishedURL = bookmarkletMode ? bookmarkletSkinURL : skinURL; + + var sufix = isApplicationContext ? "#app" : ""; + + // FF4 will also load it asynchronously + var useDocWrite = true; + //var useDocWrite = isIE || isSafari; + + var moduleURL, script; + var scriptTags = []; + + /* + if (top != window) + { + var xhr = getXHRObject(); + var html = ""; + for (var i=0, module; module=FBDev.modules[i]; i++) + { + var moduleURL = sourceURL + module + sufix; + + xhr.open("get", moduleURL, false); + xhr.send(); + html = xhr.responseText; + + script = doc.createElement("script"); + script.text = html; + doc.getElementsByTagName("head")[0].appendChild(script); + } + return; + } + /**/ + + // new module loader + + var length = FBDev.modules.length; + var loadModule = function(index){ + if (index == length) return; + + var module = FBDev.modules[index]; + var moduleURL = sourceURL + module + sufix; + var script = doc.createElement("script"); + script.src = moduleURL; + + script.onload = function() { + if ( !script.onloadDone ) { + script.onloadDone = true; + loadModule(index+1); + } + }; + script.onreadystatechange = function() { + if ( ( "loaded" === script.readyState || "complete" === script.readyState ) && !script.onloadDone ) { + script.onloadDone = true; + loadModule(index+1); + } + }; + + doc.getElementsByTagName("head")[0].appendChild(script); + }; + loadModule(0); + /**/ + + /* + for (var i=0, module; module=FBDev.modules[i]; i++) + { + var moduleURL = sourceURL + module + sufix; + + if(useDocWrite) + { + scriptTags.push(" + + + +
+ +

I'll tell you a secret ...

+
+ + diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/support/screenshot.png b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/support/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..79dfa3757be32d84eb847c1fdd3ccde7ea51c6d7 GIT binary patch literal 139810 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š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%0A-}xS}zutbvi6e(WT7 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 Q7{EV8SrwTQsW-m=0|^8^v;Y7A literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/active4d.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/active4d.css new file mode 100644 index 00000000000..802bd1740e6 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/active4d.css @@ -0,0 +1,50 @@ +/* Active4D, converted from TextMate theme (Active4D.tmTheme) */ + +.panelNode-script { + font-size: 11px; + background-color: #FFFFFF; + font-family: Monaco, Courier New; + color: #000000; +} + +.sourceRow.hovered { + background-color: #000000; +} + +.sourceRow[exeLine="true"] { + background-color: #BAD6FD; +} + +.js-string { + color: #666666; +} + +.js-atom { + color: #A8017E; +} + +.js-variable { + color: #A535AE; +} + +.js-variable { + font-weight: bold; + color: #0053FF; +} + +.js-keyword { + font-weight: bold; + color: #006699; +} + +.xml-tagname { + color: #7A7A7A; +} + +.xml-tagname { + color: #016CFF; +} + +.xml-attname { + color: #963DFF; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/all_hallows_eve.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/all_hallows_eve.css new file mode 100644 index 00000000000..41374242303 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/all_hallows_eve.css @@ -0,0 +1,36 @@ +/* All Hallows Eve by David Heinemeier Hansson, converted from TextMate theme (All Hallows Eve.tmTheme) */ + +.panelNode-script { + font-size: 11px; + background-color: #000000; + font-family: Monaco, Courier New; + color: #FFFFFF; +} + +.sourceRow.hovered { + background-color: #333300; +} + +.sourceRow[exeLine="true"] { + background-color: #73597E; +} + +.js-comment, .xml-comment, .css-comment { + color: #9933CC; +} + +.js-atom { + color: #3387CC; +} + +.js-keyword { + color: #CC7833; +} + +.js-string { + color: #66CC33; +} + +.js-regexp { + color: #CCCC33; +} \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/amy.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/amy.css new file mode 100644 index 00000000000..0083ee16dad --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/amy.css @@ -0,0 +1,46 @@ +/* Amy by William D. Neumann, converted from TextMate theme (Amy.tmTheme) */ + +.panelNode-script { + font-size: 11px; + background-color: #200020; + font-family: Monaco, Courier New; + color: #D0D0FF; +} + +.sourceRow.hovered { + background-color: #800000; +} + +.sourceRow[exeLine="true"] { + background-color: #800000; +} + +.js-string { + color: #999999; +} + +.js-variable { + color: #707090; +} + +.js-atom { + color: #7090B0; +} + +.js-variabledef { + color: #008080; +} + +.js-keyword { + color: #A080FF; +} + +.xml-tagname { + color: #009090; +} + +.panelNode-script { + font-size: 11px; + background-color: #200020; + font-family: Monaco, Courier New; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/blackboard.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/blackboard.css new file mode 100644 index 00000000000..0ae20cd972a --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/blackboard.css @@ -0,0 +1,36 @@ +/* Blackboard by Domenico Carbotta, converted from TextMate theme (Blackboard.tmTheme) */ + +.panelNode-script { + font-size: 11px; + background-color: #0C1021; + font-family: Monaco, Courier New; + color: #F8F8F8; +} + +.sourceRow.hovered { + background-color: #FFFFFF; +} + +.sourceRow[exeLine="true"] { + background-color: #253B76; +} + +.js-comment, .xml-comment, .css-comment { + color: #AEAEAE; +} + +.js-atom { + color: #D8FA3C; +} + +.js-keyword { + color: #FBDE2D; +} + +.js-string { + color: #61CE3C; +} + +.xml-tagname { + color: #7F90AA; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/brilliance_black.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/brilliance_black.css new file mode 100644 index 00000000000..a58f9d2c5d3 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/brilliance_black.css @@ -0,0 +1,70 @@ +/* Brilliance Black by Thomas Aylott, converted from TextMate theme (Brilliance Black.tmTheme) */ + +.panelNode-script { + font-size: 11px; + background-color: #0D0D0D; + font-family: Monaco, Courier New; + color: #EEEEEE; +} + +.sourceRow.hovered { + background-color: #000080; +} + +.sourceRow[exeLine="true"] { + background-color: #0010B4; +} + +.js-regexp { + background-color: #438000; + color: #FFF800; +} + +.js-atom { + color: #C6FF00; +} + +.js-variable { + color: #07FF00; +} + +.js-variabledef { + color: #31A6FF; +} + +.xml-tagname { + color: #333333; +} + +.xml-tagname { + color: #FFFFFF; +} + +.xml-attname { + color: #FFFFFF; +} + +.xml-attname { + color: #4F00FF; +} + +.xml-attname { + color: #7900FF; +} + +.xml-attname { + color: #F800FF; +} + +.xml-attname { + color: #FF0086; +} + +.xml-attname { + font-weight: bold; + color: #FF7900; +} + +.xml-attname { + color: #C25A00; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/brilliance_dull.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/brilliance_dull.css new file mode 100644 index 00000000000..e7a6f09449c --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/brilliance_dull.css @@ -0,0 +1,79 @@ +/* Brilliance Dull by Thomas Aylott, converted from TextMate theme (Brilliance Dull.tmTheme) */ + +.panelNode-script { + font-size: 11px; + background-color: #050505; + font-family: Monaco, Courier New; + color: #CDCDCD; +} + +.sourceRow.hovered { + background-color: #000080; +} + +.sourceRow[exeLine="true"] { + background-color: #2E2EE6; +} + +.js-regexp { + background-color: #438000; + color: #A6A458; +} + +.js-atom { + color: #95A658; +} + +.js-variable { + color: #59A559; +} + +.js-variabledef { + color: #5E6B6B; +} + +.js-variabledef { + color: #5780A6; +} + +.js-keyword { + color: #A459A5; +} + +.xml-tagname { + color: #333333; +} + +.xml-attname { + background-color: #800004; + color: #A7595A; +} + +.xml-tagname { + color: #FFFFFF; +} + +.xml-attname { + color: #FFFFFF; +} + +.xml-attname { + color: #7C58A5; +} + +.xml-attname { + color: #A459A5; +} + +.xml-attname { + color: #A75980; +} + +.xml-attname { + font-weight: bold; + color: #A77D58; +} + +.js-comment, .xml-comment, .css-comment { + color: #333333; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/cobalt.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/cobalt.css new file mode 100644 index 00000000000..8fc604d07d6 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/cobalt.css @@ -0,0 +1,68 @@ +/* Cobalt by Jacob Rus, converted from TextMate theme (Cobalt.tmTheme) */ + +.panelNode-script { + font-size: 11px; + background-color: #002240; + font-family: Monaco, Courier New; + color: #FFFFFF; +} + +.sourceRow.hovered { + background-color: #000000; +} + +.sourceRow[exeLine="true"] { + background-color: #B36539; +} + +.js-atom { + color: #FF628C; +} + +.js-keyword { + color: #FF9D00; +} + +.js-comment, .xml-comment, .css-comment { + color: #0088FF; +} + +.js-variable { + color: #CCCCCC; +} + +.js-variabledef { + color: #FF80E1; +} + +.js-regexp { + color: #80FFC2; +} + +.xml-tagname { + color: #9EFFFF; +} + +.css-identifier { + color: #9EFFFF; +} + +.xml-attname { + color: #FFB454; +} + +.xml-attname { + color: #5FE461; +} + +.css-colorcode { + color: #9DF39F; +} + +.css-value { + color: #F6F080; +} + +.css-at { + color: #F6AA11; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/codemirror.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/codemirror.css new file mode 100644 index 00000000000..0e056d94f1d --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/codemirror.css @@ -0,0 +1,29 @@ +.panelNode-script { + font-family: Courier New; + font-size: 9pt; + overflow: hidden; +} +.js-keyword { + color: #770088; +} +.js-atom { + color: #228811; +} +.js-variable { + color: black; +} +.js-variabledef { + color: #0000FF; +} +.js-localvariable { + color: #004499; +} +.js-property { + color: black; +} +.js-comment { + color: #AA7700; +} +.js-string { + color: #AA2222; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/cowtown.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/cowtown.css new file mode 100644 index 00000000000..b51f9ee2d5e --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/cowtown.css @@ -0,0 +1,44 @@ +/* cowtown by psylux */ +.panelNode-script { + background:#3F2B18 none repeat scroll 0 0; + color:#7C4B00; + font-family:consolas,Monospaced,Courier New; + font-size:12px; + overflow:hidden; +} +.js-keyword { + color:#FF9D00; +} +.js-atom { + color:#FFFF33; +} +.js-variable { + color:#B0B9F2; +} +.js-variabledef { + color:#FFFFFF; +} +.js-localvariable { + color:#DDD87B; +} +.js-property { + color:#44FFFF; +} +.js-comment { + color:#9A4690; +} +.js-string { + color:#7EDC0F; +} +.js-regexp { + color:#FFA1AC; +} +.js-punctuation { + color:#E1EFFF; +} +.js-operator { + color:#FF6633; +} +.js-whitespace { + color:#EEFFEE; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/dawn.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/dawn.css new file mode 100644 index 00000000000..b697721bdc4 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/dawn.css @@ -0,0 +1,37 @@ +/* Dawn by David Powers, converted from TextMate theme (Dawn.tmTheme) */ + +.panelNode-script { + font-size: 11px; + background-color: #F9F9F9; + font-family: Monaco, Courier New; + color: #080808; +} + +.sourceRow.hovered { + background-color: #2463B4; +} + +.sourceRow[exeLine="true"] { + background-color: #275FFF; +} + +.js-comment, .xml-comment, .css-comment { + color: #5A525F; +} + +.js-atom { + font-weight: bold; + color: #811F24; +} + +.js-keyword { + color: #794938; +} + +.js-variable { + color: #234A97; +} + +.js-regexp { + color: #CF5628; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/eclipse.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/eclipse.css new file mode 100644 index 00000000000..8875ac0704a --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/eclipse.css @@ -0,0 +1,29 @@ +.panelNode-script { + font-family: Courier New; + font-size: 9pt; + overflow: hidden; +} +.js-keyword { + color: #7F0055; +} +.js-atom { + color: #7F0055; +} +.js-variable { + color: black; +} +.js-variabledef { + color: black; +} +.js-localvariable { + color: black; +} +.js-property { + color: black; +} +.js-comment { + color: #3F5FBF; +} +.js-string { + color: #8E00FF; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/eiffel.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/eiffel.css new file mode 100644 index 00000000000..f37a8e189d1 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/eiffel.css @@ -0,0 +1,57 @@ +/* Eiffel by Ian Joyner, converted from TextMate theme (Eiffel.tmTheme) */ + +.panelNode-script { + font-size: 11px; + background-color: #FFFFFF; + font-family: Monaco, Courier New; + color: #000000; +} + +.sourceRow.hovered { + background-color: #000000; +} + +.sourceRow[exeLine="true"] { + background-color: #C3DCFF; +} + +.js-comment, .xml-comment, .css-comment { + color: #00B418; +} + +.js-variable { + color: #0206FF; +} + +.js-keyword { + font-weight: bold; + color: #0100B6; +} + +.js-atom { + color: #CD0000; +} + +.js-atom { + color: #C5060B; +} + +.js-variable { + color: #585CF6; +} + +.js-string { + color: #D80800; +} + +.js-operator { + color: #687687; +} + +.xml-tagname { + color: #1C02FF; +} + +.xml-tagname { + font-weight: bold; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/espresso_libre.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/espresso_libre.css new file mode 100644 index 00000000000..f707231d33e --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/espresso_libre.css @@ -0,0 +1,67 @@ +/* Espresso Libre by Chris Thomas, converted from TextMate theme (Espresso Libre.tmTheme) */ + +.panelNode-script { + font-size: 11px; + background-color: #2A211C; + font-family: Monaco, Courier New; + color: #BDAE9D; +} + +.sourceRow.hovered { + background-color: #3A312C; +} + +.sourceRow[exeLine="true"] { + background-color: #C3DCFF; +} + +.js-comment, .xml-comment, .css-comment { + color: #0066FF; +} + +.js-keyword { + font-weight: bold; + color: #43A8ED; +} + +.js-atom { + color: #44AA43; +} + +.js-atom { + font-weight: bold; + color: #C5656B; +} + +.js-variable { + font-weight: bold; + color: #585CF6; +} + +.js-variabledef { + color: #318495; +} + +.js-string { + color: #049B0A; +} + +.js-operator { + color: #687687; +} + +.xml-processing { + color: #8F7E65; +} + +.xml-processing { + color: #888888; +} + +.xml-tagname { + color: #43A8ED; +} + +.xml-tagname { + font-weight: bold; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/idle.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/idle.css new file mode 100644 index 00000000000..65bf3101d5e --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/idle.css @@ -0,0 +1,32 @@ +/* IDLE by Domenico Carbotta, converted from TextMate theme (IDLE.tmTheme) */ + +.panelNode-script { + font-size: 11px; + background-color: #FFFFFF; + font-family: Monaco, Courier New; + color: #000000; +} + +.sourceRow.hovered { + background-color: #000000; +} + +.sourceRow[exeLine="true"] { + background-color: #BAD6FD; +} + +.js-comment, .xml-comment, .css-comment { + color: #919191; +} + +.js-string { + color: #00A33F; +} + +.js-variable { + color: #A535AE; +} + +.js-keyword { + color: #FF5600; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/iplastic.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/iplastic.css new file mode 100644 index 00000000000..8044b5a8365 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/iplastic.css @@ -0,0 +1,60 @@ +/* iPlastic by Jeroen van der Ham, converted from TextMate theme (iPlastic.tmTheme) */ + +.panelNode-script { + font-size: 11px; + background-color: #EEEEEE; + font-family: Monaco, Courier New; + color: #000000; +} + +.sourceRow.hovered { + background-color: #000000; +} + +.sourceRow[exeLine="true"] { + background-color: #BAD6FD; +} + +.js-string { + color: #009933; +} + +.js-atom { + color: #0066FF; +} + +.js-regexp { + color: #FF0080; +} + +.js-keyword { + color: #0000FF; +} + +.js-variable { + color: #9700CC; +} + +.js-comment, .xml-comment, .css-comment { + color: #0066FF; +} + +.xml-tagname { + color: #0033CC; +} + +.js-atom { + color: #6782D3; +} + +.xml-processing { + color: #333333; +} + +.xml-attname { + color: #3366CC; +} + +.xml-tagname { + font-weight: bold; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/ir_black.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/ir_black.css new file mode 100644 index 00000000000..0dcb6c07d6d --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/ir_black.css @@ -0,0 +1,91 @@ +/* IR_Black, converted from TextMate theme (IR_Black.tmTheme) */ + +.panelNode-script { + font-size: 11px; + background-color: #141414; + font-family: Monaco, Courier New; + color: #EDEDED; +} + +.sourceRow.hovered { + background-color: #FFFFFF; +} + +.sourceRow[exeLine="true"] { + background-color: #333333; +} + +.js-comment, .xml-comment, .css-comment { + color: #7C7C7C; +} + +.js-keyword { + color: #96CBFE; +} + +.js-atom { + color: #99CC99; +} + +.js-string { + font-weight: bold; + color: #A8FF60; +} + +.js-atom { + font-weight: bold; + color: #FF73FD; +} + +.js-variable { + color: #C6C5FE; +} + +.js-regexp { + color: #E9C062; +} + +.xml-tagname { + font-weight: bold; + color: #96CBFE; +} + +.xml-attname { + color: #96CBFE; +} + +.xml-attname { + color: #FFD7B1; +} + +.xml-attname { + color: #E18964; +} + +.css-identifier { + color: #96CBFE; +} + +.xml-attname { + color: #8F9D6A; +} + +.xml-attname { + color: #8B98AB; +} + +.xml-attname { + color: #62B1FE; +} + +.css-colorcode { + color: #EDEDED; +} + +.css-value { + color: #F9EE98; +} + +.css-at { + color: #8693A5; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/lazy.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/lazy.css new file mode 100644 index 00000000000..3e3effffbc3 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/lazy.css @@ -0,0 +1,36 @@ +/* LAZY by Domenico Carbotta, converted from TextMate theme (LAZY.tmTheme) */ + +.panelNode-script { + font-size: 11px; + background-color: #FFFFFF; + font-family: Monaco, Courier New; + color: #000000; +} + +.sourceRow.hovered { + background-color: #EFFCA6; +} + +.sourceRow[exeLine="true"] { + background-color: #E3FC8D; +} + +.js-comment, .xml-comment, .css-comment { + color: #8C868F; +} + +.js-atom { + color: #3B5BB5; +} + +.js-keyword { + color: #FF7800; +} + +.js-string { + color: #409B1C; +} + +.xml-tagname { + color: #3A4A64; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/mac_classic.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/mac_classic.css new file mode 100644 index 00000000000..2ec2eb59560 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/mac_classic.css @@ -0,0 +1,68 @@ +/* Mac Classic by Chris Thomas, converted from TextMate theme (Mac Classic.tmTheme) */ + +.panelNode-script { + font-size: 11px; + background-color: #FFFFFF; + font-family: Monaco, Courier New; + color: #000000; +} + +.sourceRow.hovered { + background-color: #000000; +} + +.sourceRow[exeLine="true"] { + background-color: #4D97FF; +} + +.js-comment, .xml-comment, .css-comment { + color: #808080; +} + +.js-keyword { + color: #0000FF; +} + +.js-atom { + color: #0000CD; +} + +.js-atom { + color: #C5060B; +} + +.js-variable { + color: #585CF6; +} + +.js-variabledef { + color: #318495; +} + +.js-string { + color: #036A07; +} + +.js-operator { + color: #687687; +} + +.xml-processing { + color: #68685B; +} + +.xml-processing { + color: #888888; +} + +.xml-tagname { + color: #0000FF; +} + +.xml-tagname { + color: #0000FF; +} + +.xml-attname { + color: #9C0202; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/magicwb_amiga.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/magicwb_amiga.css new file mode 100644 index 00000000000..430f831135e --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/magicwb_amiga.css @@ -0,0 +1,46 @@ +/* MagicWB (Amiga) by Allan Odgaard, converted from TextMate theme (MagicWB (Amiga).tmTheme) */ + +.panelNode-script { + font-size: 11px; + background-color: #969696; + font-family: Monaco, Courier New; + color: #000000; +} + +.sourceRow.hovered { + background-color: #000000; +} + +.sourceRow[exeLine="true"] { + background-color: #B1B1B1; +} + +.js-comment, .xml-comment, .css-comment { + color: #8D2E75; +} + +.js-string { + background-color: #FF0000; + color: #FFFFFF; +} + +.js-atom { + color: #FFFFFF; +} + +.js-variable { + font-weight: bold; + color: #FFA995; +} + +.js-variabledef { + color: #FFA995; +} + +.js-keyword { + font-weight: bold; +} + +.xml-attname { + color: #3A68A3; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/pastels_on_dark.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/pastels_on_dark.css new file mode 100644 index 00000000000..5a6c62c6622 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/pastels_on_dark.css @@ -0,0 +1,96 @@ +/* Pastels on Dark by Mats Persson, converted from TextMate theme (Pastels on Dark.tmTheme) */ + +/* +CHANGELOG + +1) 2010-06-18 cbalz Fixed issue where stopped line on breakpoint has background color that makes text almost invisible. + +*/ + +.panelNode-script { + font-size: 11px; + background-color: #211E1E; + font-family: Monaco, Courier New; + color: #DADADA; +} + +.sourceRow.hovered { + background-color: #353030; +} + +.sourceRow[exeLine="true"] { + background-color: #73597E; +} + +.js-comment, .xml-comment, .css-comment { + color: #555555; +} + +.js-string { + color: #AD9361; +} + +.js-atom { + color: #CCCCCC; +} + +.js-keyword { + color: #A1A1FF; +} + +.js-regexp { + color: #666666; +} + +.js-variable { + color: #C1C144; +} + +.js-atom { + color: #6782D3; +} + +.js-variable { + font-weight: bold; + color: #DE8E30; +} + +.xml-attname { + color: #9B456F; +} + +.xml-processing { + color: #68685B; +} + +.xml-processing { + color: #888888; +} + +.xml-attname { + color: #9B456F; +} + +.xml-attname { + color: #EC9E00; +} + +.xml-attname { + color: #EDCA06; +} + +.xml-attname { + color: #2E759C; +} + +.css-value { + color: #9B2E4D; +} + +.css-colorcode { + color: #E1C96B; +} + +.sourceRow[exe_line="true"] { + outline: 1px solid #D9D9B6; margin-right: 1px; background-color: purple; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/rainbow.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/rainbow.css new file mode 100644 index 00000000000..78067714806 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/rainbow.css @@ -0,0 +1,116 @@ +.panelNode-script { + background-color: #FFFFFF; + color: black; + font-family: Monaco,Monospace,Courier New !important; + font-size: 11px; +} +.sourceRow.hovered { + background-color: #EEEEEE; +} +.sourceLine { + background: #EEEEEE none no-repeat scroll 2px 0; + border-bottom: 1px solid #EEEEEE; + border-right: 1px solid #CCCCCC; + color: #888888; +} +.sourceLine:hover { + text-decoration: none; +} +.scriptTooltip { + background: LightYellow none repeat scroll 0 0; + border: 1px solid #CBE087; + color: #000000; +} +.sourceRow[exeline="true"] { + background-color: lightgoldenrodyellow; + outline-color: #D9D9B6; + outline-style: solid; + outline-width: 1px; +} +.xml-text { + color: black; +} +.whitespace { + color: black; +} +.xml-punctuation { + color: gray; +} +.xml-tagname { + color: blue; +} +.xml-attname { + color: darkred; +} +.xml-attribute { + color: darkgreen; +} +.css-at { + color: darkred; +} +.css-string { + color: red; +} +.css-punctuation { + color: midnightblue; +} +.js-keyword { + color: blue; +} +.js-variable { + color: black; +} +.js-operator { + color: black; +} +.js-punctuation { + color: darkBlue; +} +.js-variabledef { + color: darkslategray; +} +.js-localvariable { + color: darkslateBlue; +} +.js-property { + color: teal; +} +.js-string { + color: darkgreen; +} +.js-atom { + color: saddleBrown; +} +.xml-comment { + color: gray; +} +.css-identifier { + color: midnightBlue; +} +.css-select-op { + color: cadetblue; +} +.css-unit { + color: orangered; +} +.css-value { + color: black; +} +.css-colorcode { + color: magenta; +} +.js-comment { + color: gray; +} +.js-regexp { + color: magenta; +} +.xml-entity { + color: darkgoldenrod; +} +.xml-error { + color: orangered; +} +.css-comment { + color: gray; +} \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/slush_poppies.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/slush_poppies.css new file mode 100644 index 00000000000..80466d4a695 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/slush_poppies.css @@ -0,0 +1,32 @@ +/* Slush & Poppies by William D. Neumann, converted from TextMate theme (Slush & Poppies.tmTheme) */ + +.panelNode-script { + font-size: 11px; + background-color: #F1F1F1; + font-family: Monaco, Courier New; + color: #000000; +} + +.sourceRow.hovered { + background-color: #000000; +} + +.sourceRow[exeLine="true"] { + background-color: #B0B0FF; +} + +.js-comment, .xml-comment, .css-comment { + color: #406040; +} + +.js-string { + color: #C03030; +} + +.js-atom { + color: #0080A0; +} + +.js-keyword { + color: #2060A0; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/spacecadet.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/spacecadet.css new file mode 100644 index 00000000000..77109cd6ac9 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/spacecadet.css @@ -0,0 +1,28 @@ +/* SpaceCadet by Alex Ross, converted from TextMate theme (SpaceCadet.tmTheme) */ + +.panelNode-script { + font-size: 11px; + background-color: #0D0D0D; + font-family: Monaco, Courier New; + color: #DDE6CF; +} + +.sourceRow.hovered { + background-color: #000000; +} + +.sourceRow[exeLine="true"] { + background-color: #40002F; +} + +.js-comment, .xml-comment, .css-comment { + color: #473C45; +} + +.js-string { + color: #805978; +} + +.js-atom { + color: #A8885A; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/sunburst.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/sunburst.css new file mode 100644 index 00000000000..77fdb5f53c4 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/sunburst.css @@ -0,0 +1,80 @@ +/* Sunburst by Stanley Rost, converted from TextMate theme (Sunburst.tmTheme) */ + +.panelNode-script { + font-size: 11px; + background-color: #000000; + font-family: Monaco, Courier New; + color: #F8F8F8; +} + +.sourceRow.hovered { + background-color: #FFFFFF; +} + +.sourceRow[exeLine="true"] { + background-color: #DDF0FF; +} + +.js-comment, .xml-comment, .css-comment { + color: #AEAEAE; +} + +.js-atom { + color: #3387CC; +} + +.js-keyword { + color: #E28964; +} + +.js-string { + color: #65B042; +} + +.js-variable { + color: #3E87E3; +} + +.js-regexp { + color: #E9C062; +} + +.xml-tagname { + color: #89BDFF; +} + +.xml-attname { + color: #E0C589; +} + +.xml-attname { + color: #E18964; +} + +.css-identifier { + color: #CDA869; +} + +.xml-attname { + color: #8F9D6A; +} + +.xml-attname { + color: #8B98AB; +} + +.xml-attname { + color: #9B703F; +} + +.css-colorcode { + color: #C5AF75; +} + +.css-value { + color: #F9EE98; +} + +.css-at { + color: #8693A5; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/twilight.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/twilight.css new file mode 100644 index 00000000000..4f7e3a2991a --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/twilight.css @@ -0,0 +1,80 @@ +/* Twilight by Michael Sheets, converted from TextMate theme (Twilight.tmTheme) */ + +.panelNode-script { + font-size: 11px; + background-color: #141414; + font-family: Monaco, Courier New; + color: #F8F8F8; +} + +.sourceRow.hovered { + background-color: #FFFFFF; +} + +.sourceRow[exeLine="true"] { + background-color: #DDF0FF; +} + +.js-comment, .xml-comment, .css-comment { + color: #5F5A60; +} + +.js-atom { + color: #CF6A4C; +} + +.js-keyword { + color: #CDA869; +} + +.js-string { + color: #8F9D6A; +} + +.js-variable { + color: #7587A6; +} + +.js-regexp { + color: #E9C062; +} + +.xml-processing { + color: #494949; +} + +.xml-tagname { + color: #AC885B; +} + +.xml-attname { + color: #E0C589; +} + +.css-identifier { + color: #CDA869; +} + +.xml-attname { + color: #8F9D6A; +} + +.xml-attname { + color: #8B98AB; +} + +.xml-attname { + color: #9B703F; +} + +.css-colorcode { + color: #C5AF75; +} + +.css-value { + color: #F9EE98; +} + +.css-at { + color: #8693A5; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/zenburnesque.css b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/zenburnesque.css new file mode 100644 index 00000000000..ac566e8ebfb --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/themes/zenburnesque.css @@ -0,0 +1,32 @@ +/* Zenburnesque by William D. Neumann, converted from TextMate theme (Zenburnesque.tmTheme) */ + +.panelNode-script { + font-size: 11px; + background-color: #404040; + font-family: Monaco, Courier New; + color: #DEDEDE; +} + +.sourceRow.hovered { + background-color: #A08040; +} + +.sourceRow[exeLine="true"] { + background-color: #A0A0C0; +} + +.js-comment, .xml-comment, .css-comment { + color: #709070; +} + +.js-string { + color: #FF2020; +} + +.js-atom { + color: #22C0FF; +} + +.js-keyword { + color: #FFFFA0; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/utils/Rakefile b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/utils/Rakefile new file mode 100644 index 00000000000..197196677cd --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/firerainbow/utils/Rakefile @@ -0,0 +1,222 @@ +begin + require 'Plist' +rescue LoadError + raise 'You must "gem install plist" to get plist parser' +end + +ROOT = File.expand_path('..') +SRC = ROOT +DST = File.join(ROOT, 'build') +DST_THEMES = File.join(DST, 'themes') +TMP = File.join(ROOT, 'tmp') + +THEMES_DIR = File.expand_path("~/Library/Application\\ Support/TextMate/Themes") + +# http://kpumuk.info/ruby-on-rails/colorizing-console-ruby-script-output/ +begin + require 'Win32/Console/ANSI' if PLATFORM =~ /win32/ +rescue LoadError + raise 'You must "gem install win32console" to use terminal colors on Windows' +end + +def colorize(text, color_code) + "#{color_code}#{text}\e[0m" +end + +def red(text); colorize(text, "\e[31m"); end +def green(text); colorize(text, "\e[32m"); end +def yellow(text); colorize(text, "\e[33m"); end +def blue(text); colorize(text, "\e[34m"); end +def magenta(text); colorize(text, "\e[35m"); end +def azure(text); colorize(text, "\e[36m"); end +def white(text); colorize(text, "\e[37m"); end +def black(text); colorize(text, "\e[30m"); end + +def file_color(text); yellow(text); end +def dir_color(text); blue(text); end +def cmd_color(text); azure(text); end + +def detect_selector_from_scope(scope) + return ".panelNode-script" unless scope + parts = scope.split(',') + parts.each do |part| + case part + when "comment" + return ".js-comment, .xml-comment, .css-comment" + when "keyword" + return ".js-keyword" + when "variable", "constant.language" + return ".js-variable" + when "variable.language", "variable.other" + return ".js-variabledef" + when "string", "css.string" + return ".js-string" + when "string.regexp" + return ".js-regexp" + when "constant", "constant.numeric" + return ".js-atom" + when "keyword.operator.js" + return ".js-operator" + when "string.quoted.docinfo.doctype.DTD", "meta.tag.preprocessor.xml", "meta.tag.sgml.doctype", "meta.tag.sgml.doctype entity", "meta.tag.sgml.doctype string", "meta.tag.preprocessor.xml", "meta.tag.preprocessor.xml entity", "meta.tag.preprocessor.xml string" + return ".xml-processing" + when "entity.name.tag", "meta.tag", "declaration.tag" + return ".xml-tagname" + when /attribute-name/ + return ".xml-attname" + when "???" + return ".xml-text" + when "???" + return ".xml-entity" + when "???" + return ".xml-cdata" + when /property-value.css/ + return ".css-value" + when "meta.selector.css entity.name.tag" + return ".css-identifier" + when /property-name.css/ + return ".css-colorcode" + when "???" + return ".css-string" + when "???" + return ".css-unit" + when "???" + return ".css-important" + when "???" + return ".css-select-op" + when "???" + return ".css-punctuation" + when "???" + return ".css-compare" + when /at-rule/ + return ".css-at" + end + end + + nil +end + +def color(val) + return "???" unless val =~ /#([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])/ + "\##{$1}" +end + +def font_style(val) + return nil unless val=="italic" + "italic" +end + +def font_weight(val) + return nil unless val=="bold" + "bold" +end + +KNOWN_ATTRIBUTES = { + "foreground" => ["color", method(:color)], + "background" => ["background-color", method(:color)], + "fontStyle" => ["font-style", method(:font_style)], + "fontStyle" => ["font-weight", method(:font_weight)], +} + +def gen_rule(dict) + scope = dict["scope"] + selector = detect_selector_from_scope(scope) + return "" unless selector + settings = dict["settings"] + return "" unless settings + + rule = {} + KNOWN_ATTRIBUTES.each do |attr, spec| + next unless settings[attr] + spec = [spec] unless spec.is_a?(Array) + + val = settings[attr] + val = spec[1].call(val) if spec[1] + rule[spec[0]] = val if val + end + + return "" unless rule.keys.size>0 + + if (selector==".panelNode-script") then + rule["font-family"] = "Monaco, Courier New" + rule["font-size"] = "11px" + + additional = "" + highlight = color(settings["lineHighlight"]) if settings["lineHighlight"] + additional += ".sourceRow.hovered { background-color: #{highlight}; }\n\n" if highlight + selection = color(settings["selection"]) if settings["selection"] + additional += ".sourceRow[exeLine=\"true\"] { background-color: #{selection}; }\n\n" if selection + end + + res = "#{selector} {\n" + rule.each do |key, value| + res += " #{key}: #{value};\n" + end + res += "}\n\n" + + res += additional if additional + res +end + +def gen_css(data, source) + desc = "#{data["name"]}" + desc += " by #{data["author"]}" if data["author"] + desc += ", converted from TextMate theme (#{source})" + + res = "/* #{desc} */\n\n" + + data["settings"].each do |dict| + res += gen_rule(dict) + end + + { + "css" => res, + "name" => data["name"], + "author" => data["author"], + "description" => desc + } +end + +def my_mkdir(dir) + puts "#{cmd_color('creating directory')} #{dir_color(dir)}" + mkdir dir +end + +def process(dir) + files = Dir.glob(File.join(dir, "**", "*.tmTheme")) + files.each do |filename| + basename = File.basename(filename) + puts " Converting #{file_color(basename)}" + data = Plist::parse_xml(filename) + preset = gen_css(data, basename) + preset["basename"] = basename + yield preset + end +end + +task :convert do + my_mkdir(DST_THEMES) unless File.exist?(DST_THEMES) + puts "Scanning #{dir_color(THEMES_DIR)} ..." + process(THEMES_DIR) do |preset| + res = File.join(DST_THEMES, preset["basename"] + ".css") + File.open(res, "w") do |file| + file.write preset["css"] + end + end +end + +task :sql do + puts "Generating sql ..." + + res = "" + process(THEMES_DIR) do |preset| + name = preset["name"].downcase.gsub(/[\(\)&]/, "").gsub(/[ \t]/, "_").gsub(/'/, "''") + title = preset["name"].gsub(/'/, "''") + desc = preset["description"].gsub(/'/, "''") + code = preset["css"].gsub(/\n/, "\\r\\n").gsub(/'/, "''").gsub(/"/, """) + res += "('#{name}', '#{title}', '#{desc}', '#{code}', '2008-06-14 18:19:36', '2008-06-14 18:24:04'),\n" + end + + puts res +end + +task :default => :convert \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/boot.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/boot.js new file mode 100644 index 00000000000..95f8aea4793 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/boot.js @@ -0,0 +1,3 @@ +/* See license.txt for terms of usage */ + +FBL.initialize(); diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/chrome.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/chrome.js new file mode 100644 index 00000000000..04763efebe3 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/chrome.js @@ -0,0 +1,2367 @@ +/* See license.txt for terms of usage */ + +FBL.ns( /**@scope ns-chrome*/ function() { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +// Globals + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Window Options + +var WindowDefaultOptions = + { + type: "frame", + id: "FirebugUI" + //height: 350 // obsolete + }, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Instantiated objects + + commandLine, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Interface Elements Cache + + fbTop, + fbContent, + fbContentStyle, + fbBottom, + fbBtnInspect, + + fbToolbar, + + fbPanelBox1, + fbPanelBox1Style, + fbPanelBox2, + fbPanelBox2Style, + fbPanelBar2Box, + fbPanelBar2BoxStyle, + + fbHSplitter, + fbVSplitter, + fbVSplitterStyle, + + fbPanel1, + fbPanel1Style, + fbPanel2, + fbPanel2Style, + + fbConsole, + fbConsoleStyle, + fbHTML, + + fbCommandLine, + fbLargeCommandLine, + fbLargeCommandButtons, + +//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Cached size values + + topHeight, + topPartialHeight, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + chromeRedrawSkipRate = isIE ? 75 : isOpera ? 80 : 75, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + lastSelectedPanelName, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + focusCommandLineState = 0, + lastFocusedPanelName, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + lastHSplitterMouseMove = 0, + onHSplitterMouseMoveBuffer = null, + onHSplitterMouseMoveTimer = null, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + lastVSplitterMouseMove = 0; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + +// ************************************************************************************************ +// FirebugChrome + +FBL.defaultPersistedState = +{ + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + isOpen: false, + height: 300, + sidePanelWidth: 350, + + selectedPanelName: "Console", + selectedHTMLElementId: null, + + htmlSelectionStack: [] + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +}; + +/**@namespace*/ +FBL.FirebugChrome = +{ + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + //isOpen: false, + //height: 300, + //sidePanelWidth: 350, + + //selectedPanelName: "Console", + //selectedHTMLElementId: null, + + 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") + { + // TODO: xxxpedro persist - revise chrome synchronization when in persistent mode + var frame = FirebugChrome.chromeMap.frame; + if (frame) + frame.close(); + + //chrome.reattach(frame, chrome); + //TODO: xxxpedro persist synchronize? + chrome.initialize(); + } + }, + + clone: function(FBChrome) + { + for (var name in FBChrome) + { + var prop = FBChrome[name]; + if (FBChrome.hasOwnProperty(name) && !isFunction(prop)) + { + this[name] = prop; + } + } + } +}; + + + +// ************************************************************************************************ +// Chrome Window Creation + +var createChromeWindow = function(options) +{ + options = extend(WindowDefaultOptions, options || {}); + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Locals + + var 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", + + // document.body not available in XML+XSL documents in Firefox + body = context.document.getElementsByTagName("body")[0], + + formatNode = function(node) + { + if (!Env.isDebugMode) + { + node.firebugIgnore = true; + } + + 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"; // MAX z-index = 2147483647 + node.style.position = noFixedPosition ? "absolute" : "fixed"; + node.style.width = "100%"; // "102%"; IE auto margin bug + node.style.left = "0"; + node.style.bottom = noFixedPosition ? "-1px" : "0"; + node.style.height = height + "px"; + + // avoid flickering during chrome rendering + //if (isFirefox) + // node.style.display = "none"; + }, + + createChromeDiv = function() + { + //Firebug.Console.warn("Firebug Lite GUI is working in 'windowless mode'. It may behave slower and receive interferences from the page in which it is installed."); + + var node = chrome.node = createGlobalElement("div"), + style = createGlobalElement("style"), + + css = FirebugChrome.Skin.CSS + /* + .replace(/;/g, " !important;") + .replace(/!important\s!important/g, "!important") + .replace(/display\s*:\s*(\w+)\s*!important;/g, "display:$1;")*/, + + // reset some styles to minimize interference from the main page's style + rules = ".fbBody *{margin:0;padding:0;font-size:11px;line-height:13px;color:inherit;}" + + // load the chrome styles + css + + // adjust some remaining styles + ".fbBody #fbHSplitter{position:absolute !important;} .fbBody #fbHTML span{line-height:14px;} .fbBody .lineNo div{line-height:inherit !important;}"; + /* + if (isIE) + { + // IE7 CSS bug (FbChrome table bigger than its parent div) + rules += ".fbBody table.fbChrome{position: static !important;}"; + }/**/ + + style.type = "text/css"; + + if (style.styleSheet) + style.styleSheet.cssText = rules; + else + style.appendChild(context.document.createTextNode(rules)); + + document.getElementsByTagName("head")[0].appendChild(style); + + node.className = "fbBody"; + node.style.overflow = "hidden"; + node.innerHTML = getChromeDivTemplate(); + + if (isIE) + { + // IE7 CSS bug (FbChrome table bigger than its parent div) + setTimeout(function(){ + node.firstChild.style.height = "1px"; + node.firstChild.style.position = "static"; + },0); + /**/ + } + + formatNode(node); + + body.appendChild(node); + + chrome.window = window; + chrome.document = document; + onChromeLoad(chrome); + }; + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + try + { + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // create the Chrome as a "div" (windowless mode) + if (type == "div") + { + createChromeDiv(); + return; + } + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // cretate the Chrome as an "iframe" + else if (isChromeFrame) + { + // Create the Chrome Frame + var node = chrome.node = createGlobalElement("iframe"); + node.setAttribute("src", url); + node.setAttribute("frameBorder", "0"); + + formatNode(node); + + body.appendChild(node); + + // must set the id after appending to the document, otherwise will cause an + // strange error in IE, making the iframe load the page in which the bookmarklet + // was created (like getfirebug.com), before loading the injected UI HTML, + // generating an "Access Denied" error. + node.id = options.id; + } + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // create the Chrome as a "popup" + else + { + var height = 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, + // Google Chrome bug + screen.availHeight - height - 61 + ) + ); + + var popupWidth = typeof persistedState.popupWidth == "number" ? + persistedState.popupWidth : + Math.max( + 0, + Math.min( + browserWinSize.width, + // Opera opens popup in a new tab if it's too big! + 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; + } + } + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Inject the interface HTML if it is not using the local skin + + if (!useLocalSkin) + { + var tpl = getChromeTemplate(!isChromeFrame), + doc = isChromeFrame ? node.contentWindow.document : node.document; + + doc.write(tpl); + doc.close(); + } + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Wait the Window to be loaded + + var win, + + waitDelay = useLocalSkin ? isChromeFrame ? 200 : 300 : 100, + + waitForWindow = function() + { + if ( // Frame loaded... OR + isChromeFrame && (win=node.contentWindow) && + node.contentWindow.document.getElementById("fbCommandLine") || + + // Popup loaded + !isChromeFrame && (win=node.window) && node.document && + node.document.getElementById("fbCommandLine") ) + { + chrome.window = win.window; + chrome.document = win.document; + + // Prevent getting the wrong chrome height in FF when opening a popup + setTimeout(function(){ + onChromeLoad(chrome); + }, useLocalSkin ? 200 : 0); + } + else + setTimeout(waitForWindow, waitDelay); + }; + + waitForWindow(); + } + catch(e) + { + var msg = e.message || e; + + if (/access/i.test(msg)) + { + // Firebug Lite could not create a window for its Graphical User Interface due to + // a access restriction. This happens in some pages, when loading via bookmarklet. + // In such cases, the only way is to load the GUI in a "windowless mode". + + if (isChromeFrame) + body.removeChild(node); + else if(type == "popup") + node.close(); + + // Load the GUI in a "windowless mode" + createChromeDiv(); + } + else + { + alert("Firebug Error: Firebug GUI could not be created."); + } + } +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var onChromeLoad = function onChromeLoad(chrome) +{ + Env.chrome = chrome; + + if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Chrome onChromeLoad", "chrome window loaded"); + + if (Env.Options.enablePersistent) + { + // TODO: xxxpedro persist - make better chrome synchronization when in persistent mode + Env.FirebugChrome = FirebugChrome; + + chrome.window.Firebug = chrome.window.Firebug || {}; + chrome.window.Firebug.SharedEnv = Env; + + if (Env.isDevelopmentMode) + { + Env.browser.window.FBDev.loadChromeApplication(chrome); + } + else + { + var doc = chrome.document; + var script = doc.createElement("script"); + script.src = Env.Location.app + "#remote,persist"; + doc.getElementsByTagName("head")[0].appendChild(script); + } + } + else + { + if (chrome.type == "frame" || chrome.type == "div") + { + // initialize the chrome application + setTimeout(function(){ + FBL.Firebug.initialize(); + },0); + } + else if (chrome.type == "popup") + { + var oldChrome = FirebugChrome.chromeMap.frame; + + var newChrome = new Chrome(chrome); + + // TODO: xxxpedro sync detach reattach attach + dispatch(newChrome.panelMap, "detach", [oldChrome, newChrome]); + + newChrome.reattach(oldChrome, newChrome); + } + } +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var getChromeDivTemplate = function() +{ + return FirebugChrome.Skin.HTML; +}; + +var getChromeTemplate = function(isPopup) +{ + var tpl = FirebugChrome.Skin; + var r = [], i = -1; + + r[++i] = ''; + r[++i] = ''; + r[++i] = Firebug.version; + + /* + r[++i] = ''; + /**/ + + r[++i] = ''; + /**/ + + r[++i] = ''; + r[++i] = tpl.HTML; + r[++i] = ''; + + return r.join(""); +}; + + +// ************************************************************************************************ +// Chrome Class + +/**@class*/ +var Chrome = function Chrome(chrome) +{ + var type = chrome.type; + var Base = type == "frame" || type == "div" ? ChromeFrameBase : ChromePopupBase; + + append(this, Base); // inherit from base class (ChromeFrameBase or ChromePopupBase) + append(this, chrome); // inherit chrome window properties + append(this, new Context(chrome.window)); // inherit from Context class + + FirebugChrome.chromeMap[type] = this; + Firebug.chrome = this; + Env.chrome = chrome.window; + + this.commandLineVisible = false; + this.sidePanelVisible = false; + + this.create(); + + return this; +}; + +// ************************************************************************************************ +// ChromeBase + +/** + * @namespace + * @extends FBL.Controller + * @extends FBL.PanelBar + **/ +var ChromeBase = {}; +append(ChromeBase, Controller); +append(ChromeBase, PanelBar); +append(ChromeBase, +/**@extend ns-chrome-ChromeBase*/ +{ + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // inherited properties + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // inherited from createChrome function + + node: null, + type: null, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // inherited from Context.prototype + + document: null, + window: null, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // value properties + + sidePanelVisible: false, + commandLineVisible: false, + largeCommandLineVisible: false, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // object properties + + inspectButton: null, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + create: function() + { + PanelBar.create.call(this); + + if (Firebug.Inspector) + this.inspectButton = new Button({ + type: "toggle", + element: $("fbChrome_btInspect"), + owner: Firebug.Inspector, + + onPress: Firebug.Inspector.startInspecting, + onUnpress: Firebug.Inspector.stopInspecting + }); + }, + + destroy: function() + { + if(Firebug.Inspector) + this.inspectButton.destroy(); + + PanelBar.destroy.call(this); + + this.shutdown(); + }, + + testMenu: function() + { + var firebugMenu = new Menu( + { + id: "fbFirebugMenu", + + items: + [ + { + label: "Open Firebug", + type: "shortcut", + key: isFirefox ? "Shift+F12" : "F12", + checked: true, + command: "toggleChrome" + }, + { + label: "Open Firebug in New Window", + type: "shortcut", + key: isFirefox ? "Ctrl+Shift+F12" : "Ctrl+F12", + command: "openPopup" + }, + { + label: "Inspect Element", + type: "shortcut", + key: "Ctrl+Shift+C", + command: "toggleInspect" + }, + { + label: "Command Line", + type: "shortcut", + key: "Ctrl+Shift+L", + command: "focusCommandLine" + }, + "-", + { + label: "Options", + type: "group", + child: "fbFirebugOptionsMenu" + }, + "-", + { + label: "Firebug Lite Website...", + command: "visitWebsite" + }, + { + label: "Discussion Group...", + command: "visitDiscussionGroup" + }, + { + label: "Issue Tracker...", + command: "visitIssueTracker" + } + ], + + onHide: function() + { + iconButton.restore(); + }, + + toggleChrome: function() + { + Firebug.chrome.toggle(); + }, + + openPopup: function() + { + Firebug.chrome.toggle(true, true); + }, + + toggleInspect: function() + { + Firebug.Inspector.toggleInspect(); + }, + + focusCommandLine: function() + { + Firebug.chrome.focusCommandLine(); + }, + + visitWebsite: function() + { + this.visit("http://getfirebug.com/lite.html"); + }, + + visitDiscussionGroup: function() + { + this.visit("http://groups.google.com/group/firebug"); + }, + + visitIssueTracker: function() + { + this.visit("http://code.google.com/p/fbug/issues/list"); + }, + + visit: function(url) + { + window.open(url); + } + + }); + + /**@private*/ + var firebugOptionsMenu = + { + id: "fbFirebugOptionsMenu", + + getItems: function() + { + var cookiesDisabled = !Firebug.saveCookies; + + return [ + { + label: "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) + { + //console.log("testMenuClick"); + cancelEvent(event, true); + + var target = event.target || event.srcElement; + + if (menu.isVisible) + menu.hide(); + else + { + var offsetLeft = isIE6 ? 1 : -4, // IE6 problem with fixed position + + chrome = Firebug.chrome, + + box = chrome.getElementBox(target), + + offset = chrome.type == "div" ? + chrome.getElementPosition(chrome.node) : + {top: 0, left: 0}; + + menu.show( + box.left + offsetLeft - offset.left, + box.top + box.height -5 - offset.top + ); + } + + return false; + }; + + var iconButton = new IconButton({ + type: "toggle", + element: $("fbFirebugButton"), + + onClick: testMenuClick + }); + + iconButton.initialize(); + + //addEvent($("fbToolbarIcon"), "click", testMenuClick); + }, + + initialize: function() + { + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + if (Env.bookmarkletOutdated) + Firebug.Console.logFormatted([ + "A new bookmarklet version is available. " + + "Please visit http://getfirebug.com/firebuglite#Install and update it." + ], Firebug.context, "warn"); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + if (Firebug.Console) + Firebug.Console.flush(); + + if (Firebug.Trace) + FBTrace.flush(Firebug.Trace); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.chrome.initialize", "initializing chrome application"); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // initialize inherited classes + Controller.initialize.call(this); + PanelBar.initialize.call(this); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // create the interface elements cache + + fbTop = $("fbTop"); + fbContent = $("fbContent"); + fbContentStyle = fbContent.style; + fbBottom = $("fbBottom"); + fbBtnInspect = $("fbBtnInspect"); + + fbToolbar = $("fbToolbar"); + + fbPanelBox1 = $("fbPanelBox1"); + fbPanelBox1Style = fbPanelBox1.style; + fbPanelBox2 = $("fbPanelBox2"); + fbPanelBox2Style = fbPanelBox2.style; + fbPanelBar2Box = $("fbPanelBar2Box"); + fbPanelBar2BoxStyle = fbPanelBar2Box.style; + + fbHSplitter = $("fbHSplitter"); + fbVSplitter = $("fbVSplitter"); + fbVSplitterStyle = fbVSplitter.style; + + fbPanel1 = $("fbPanel1"); + fbPanel1Style = fbPanel1.style; + fbPanel2 = $("fbPanel2"); + fbPanel2Style = fbPanel2.style; + + fbConsole = $("fbConsole"); + fbConsoleStyle = fbConsole.style; + fbHTML = $("fbHTML"); + + fbCommandLine = $("fbCommandLine"); + fbLargeCommandLine = $("fbLargeCommandLine"); + fbLargeCommandButtons = $("fbLargeCommandButtons"); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // static values cache + topHeight = fbTop.offsetHeight; + topPartialHeight = fbToolbar.offsetHeight; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + disableTextSelection($("fbToolbar")); + disableTextSelection($("fbPanelBarBox")); + disableTextSelection($("fbPanelBar1")); + disableTextSelection($("fbPanelBar2")); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Add the "javascript:void(0)" href attributes used to make the hover effect in IE6 + if (isIE6 && Firebug.Selector) + { + // TODO: xxxpedro change to getElementsByClass + var as = $$(".fbHover"); + for (var i=0, a; a=as[i]; i++) + { + a.setAttribute("href", "javascript:void(0)"); + } + } + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // initialize all panels + /* + var panelMap = Firebug.panelTypes; + for (var i=0, p; p=panelMap[i]; i++) + { + if (!p.parentPanel) + { + this.addPanel(p.prototype.name); + } + } + /**/ + + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + + if(Firebug.Inspector) + this.inspectButton.initialize(); + + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + + this.addController( + [$("fbLargeCommandLineIcon"), "click", this.showLargeCommandLine] + ); + + // ************************************************************************************************ + + // Select the first registered panel + // TODO: BUG IE7 + var self = this; + setTimeout(function(){ + self.selectPanel(Firebug.context.persistedState.selectedPanelName); + + if (Firebug.context.persistedState.selectedPanelName == "Console" && Firebug.CommandLine) + Firebug.chrome.focusCommandLine(); + },0); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + //this.draw(); + + + + + + + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + var onPanelMouseDown = function onPanelMouseDown(event) + { + //console.log("onPanelMouseDown", event.target || event.srcElement, event); + + var target = event.target || event.srcElement; + + if (FBL.isLeftClick(event)) + { + var editable = FBL.getAncestorByClass(target, "editable"); + + // if an editable element has been clicked then start editing + if (editable) + { + Firebug.Editor.startEditing(editable); + FBL.cancelEvent(event); + } + // if any other element has been clicked then stop editing + else + { + if (!hasClass(target, "textEditorInner")) + Firebug.Editor.stopEditing(); + } + } + else if (FBL.isMiddleClick(event) && Firebug.getRepNode(target)) + { + // Prevent auto-scroll when middle-clicking a rep object + FBL.cancelEvent(event); + } + }; + + Firebug.getElementPanel = function(element) + { + var panelNode = getAncestorByClass(element, "fbPanel"); + var id = panelNode.id.substr(2); + + var panel = Firebug.chrome.panelMap[id]; + + if (!panel) + { + if (Firebug.chrome.selectedPanel.sidePanelBar) + panel = Firebug.chrome.selectedPanel.sidePanelBar.panelMap[id]; + } + + return panel; + }; + + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + // TODO: xxxpedro port to Firebug + + // Improved window key code event listener. Only one "keydown" event will be attached + // to the window, and the onKeyCodeListen() function will delegate which listeners + // should be called according to the event.keyCode fired. + var onKeyCodeListenersMap = []; + var onKeyCodeListen = function(event) + { + for (var keyCode in onKeyCodeListenersMap) + { + var listeners = onKeyCodeListenersMap[keyCode]; + + for (var i = 0, listener; listener = listeners[i]; i++) + { + var filter = listener.filter || FBL.noKeyModifiers; + + if (event.keyCode == keyCode && (!filter || filter(event))) + { + listener.listener(); + FBL.cancelEvent(event, true); + return false; + } + } + } + }; + + addEvent(Firebug.chrome.document, "keydown", onKeyCodeListen); + + /** + * @name keyCodeListen + * @memberOf FBL.FirebugChrome + */ + Firebug.chrome.keyCodeListen = function(key, filter, listener, capture) + { + var keyCode = KeyEvent["DOM_VK_"+key]; + + if (!onKeyCodeListenersMap[keyCode]) + onKeyCodeListenersMap[keyCode] = []; + + onKeyCodeListenersMap[keyCode].push({ + filter: filter, + listener: listener + }); + + return keyCode; + }; + + /** + * @name keyIgnore + * @memberOf FBL.FirebugChrome + */ + Firebug.chrome.keyIgnore = function(keyCode) + { + onKeyCodeListenersMap[keyCode] = null; + delete onKeyCodeListenersMap[keyCode]; + }; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + /**/ + // move to shutdown + //removeEvent(Firebug.chrome.document, "keydown", listener[0]); + + + /* + Firebug.chrome.keyCodeListen = function(key, filter, listener, capture) + { + if (!filter) + filter = FBL.noKeyModifiers; + + var keyCode = KeyEvent["DOM_VK_"+key]; + + var fn = function fn(event) + { + if (event.keyCode == keyCode && (!filter || filter(event))) + { + listener(); + FBL.cancelEvent(event, true); + return false; + } + } + + addEvent(Firebug.chrome.document, "keydown", fn); + + return [fn, capture]; + }; + + Firebug.chrome.keyIgnore = function(listener) + { + removeEvent(Firebug.chrome.document, "keydown", listener[0]); + }; + /**/ + + + this.addController( + [fbPanel1, "mousedown", onPanelMouseDown], + [fbPanel2, "mousedown", onPanelMouseDown] + ); +/**/ + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + + // menus can be used without domplate + if (FBL.domplate) + this.testMenu(); + /**/ + + //test XHR + /* + setTimeout(function(){ + + FBL.Ajax.request({url: "../content/firebug/boot.js"}); + FBL.Ajax.request({url: "../content/firebug/boot.js.invalid"}); + + },1000); + /**/ + }, + + shutdown: function() + { + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + + if(Firebug.Inspector) + this.inspectButton.shutdown(); + + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + // remove disableTextSelection event handlers + restoreTextSelection($("fbToolbar")); + restoreTextSelection($("fbPanelBarBox")); + restoreTextSelection($("fbPanelBar1")); + restoreTextSelection($("fbPanelBar2")); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // shutdown inherited classes + Controller.shutdown.call(this); + PanelBar.shutdown.call(this); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Remove the interface elements cache (this must happen after calling + // the shutdown method of all dependent components to avoid errors) + + fbTop = null; + fbContent = null; + fbContentStyle = null; + fbBottom = null; + fbBtnInspect = null; + + fbToolbar = null; + + fbPanelBox1 = null; + fbPanelBox1Style = null; + fbPanelBox2 = null; + fbPanelBox2Style = null; + fbPanelBar2Box = null; + fbPanelBar2BoxStyle = null; + + fbHSplitter = null; + fbVSplitter = null; + fbVSplitterStyle = null; + + fbPanel1 = null; + fbPanel1Style = null; + fbPanel2 = null; + + fbConsole = null; + fbConsoleStyle = null; + fbHTML = null; + + fbCommandLine = null; + fbLargeCommandLine = null; + fbLargeCommandButtons = null; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // static values cache + + topHeight = null; + topPartialHeight = null; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + toggle: function(forceOpen, popup) + { + if(popup) + { + this.detach(); + } + else + { + if (isOpera && Firebug.chrome.type == "popup" && Firebug.chrome.node.closed) + { + var frame = FirebugChrome.chromeMap.frame; + frame.reattach(); + + FirebugChrome.chromeMap.popup = null; + + frame.open(); + + return; + } + + // If the context is a popup, ignores the toggle process + if (Firebug.chrome.type == "popup") return; + + var shouldOpen = forceOpen || !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; + + // chrome synchronization + var newPanelMap = newChrome.panelMap; + var oldPanelMap = oldChrome.panelMap; + + var panel; + for(var name in newPanelMap) + { + // TODO: xxxpedro innerHTML + panel = newPanelMap[name]; + if (panel.options.innerHTMLSync) + panel.panelNode.innerHTML = oldPanelMap[name].panelNode.innerHTML; + } + + Firebug.chrome = newChrome; + + // TODO: xxxpedro sync detach reattach attach + //dispatch(Firebug.chrome.panelMap, "detach", [oldChrome, newChrome]); + + if (newChrome.type == "popup") + { + newChrome.initialize(); + //dispatch(Firebug.modules, "initialize", []); + } + else + { + // TODO: xxxpedro only needed in persistent + // should use FirebugChrome.clone, but popup FBChrome + // isn't acessible + Firebug.context.persistedState.selectedPanelName = oldChrome.selectedPanel.name; + } + + dispatch(newPanelMap, "reattach", [oldChrome, newChrome]); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + draw: function() + { + var size = this.getSize(); + + // Height related values + var commandLineHeight = Firebug.chrome.commandLineVisible ? fbCommandLine.offsetHeight : 0, + + y = Math.max(size.height /* chrome height */, topHeight), + + heightValue = Math.max(y - topHeight - commandLineHeight /* fixed height */, 0), + + height = heightValue + "px", + + // Width related values + sideWidthValue = Firebug.chrome.sidePanelVisible ? Firebug.context.persistedState.sidePanelWidth : 0, + + width = Math.max(size.width /* chrome width */ - sideWidthValue, 0) + "px"; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Height related rendering + fbPanelBox1Style.height = height; + fbPanel1Style.height = height; + + if (isIE || isOpera) + { + // Fix IE and Opera problems with auto resizing the verticall splitter + fbVSplitterStyle.height = Math.max(y - topPartialHeight - commandLineHeight, 0) + "px"; + } + //xxxpedro FF2 only? + /* + else if (isFirefox) + { + // Fix Firefox problem with table rows with 100% height (fit height) + fbContentStyle.maxHeight = Math.max(y - fixedHeight, 0)+ "px"; + }/**/ + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Width related rendering + fbPanelBox1Style.width = width; + fbPanel1Style.width = width; + + // SidePanel rendering + if (Firebug.chrome.sidePanelVisible) + { + sideWidthValue = Math.max(sideWidthValue - 6, 0); + + var sideWidth = sideWidthValue + "px"; + + fbPanelBox2Style.width = sideWidth; + + fbVSplitterStyle.right = sideWidth; + + if (Firebug.chrome.largeCommandLineVisible) + { + fbLargeCommandLine = $("fbLargeCommandLine"); + + fbLargeCommandLine.style.height = heightValue - 4 + "px"; + fbLargeCommandLine.style.width = sideWidthValue - 2 + "px"; + + fbLargeCommandButtons = $("fbLargeCommandButtons"); + fbLargeCommandButtons.style.width = sideWidth; + } + else + { + fbPanel2Style.height = height; + fbPanel2Style.width = sideWidth; + + fbPanelBar2BoxStyle.width = sideWidth; + } + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getSize: function() + { + return this.type == "div" ? + { + height: this.node.offsetHeight, + width: this.node.offsetWidth + } + : + this.getWindowSize(); + }, + + resize: function() + { + var self = this; + + // avoid partial resize when maximizing window + setTimeout(function(){ + self.draw(); + + if (noFixedPosition && (self.type == "frame" || self.type == "div")) + self.fixIEPosition(); + }, 0); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + layout: function(panel) + { + if (FBTrace.DBG_CHROME) FBTrace.sysout("Chrome.layout", ""); + + var options = panel.options; + + changeCommandLineVisibility(options.hasCommandLine); + changeSidePanelVisibility(panel.hasSidePanel); + + Firebug.chrome.draw(); + }, + + showLargeCommandLine: function(hideToggleIcon) + { + var chrome = Firebug.chrome; + + if (!chrome.largeCommandLineVisible) + { + chrome.largeCommandLineVisible = true; + + if (chrome.selectedPanel.options.hasCommandLine) + { + if (Firebug.CommandLine) + Firebug.CommandLine.blur(); + + changeCommandLineVisibility(false); + } + + changeSidePanelVisibility(true); + + fbLargeCommandLine.style.display = "block"; + fbLargeCommandButtons.style.display = "block"; + + fbPanel2Style.display = "none"; + fbPanelBar2BoxStyle.display = "none"; + + chrome.draw(); + + fbLargeCommandLine.focus(); + + if (Firebug.CommandLine) + Firebug.CommandLine.setMultiLine(true); + } + }, + + hideLargeCommandLine: function() + { + if (Firebug.chrome.largeCommandLineVisible) + { + Firebug.chrome.largeCommandLineVisible = false; + + if (Firebug.CommandLine) + Firebug.CommandLine.setMultiLine(false); + + fbLargeCommandLine.blur(); + + fbPanel2Style.display = "block"; + fbPanelBar2BoxStyle.display = "block"; + + fbLargeCommandLine.style.display = "none"; + fbLargeCommandButtons.style.display = "none"; + + changeSidePanelVisibility(false); + + if (Firebug.chrome.selectedPanel.options.hasCommandLine) + changeCommandLineVisibility(true); + + Firebug.chrome.draw(); + + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + focusCommandLine: function() + { + var selectedPanelName = this.selectedPanel.name, panelToSelect; + + if (focusCommandLineState == 0 || selectedPanelName != "Console") + { + focusCommandLineState = 0; + lastFocusedPanelName = selectedPanelName; + + panelToSelect = "Console"; + } + if (focusCommandLineState == 1) + { + panelToSelect = lastFocusedPanelName; + } + + this.selectPanel(panelToSelect); + + try + { + if (Firebug.CommandLine) + { + if (panelToSelect == "Console") + Firebug.CommandLine.focus(); + else + Firebug.CommandLine.blur(); + } + } + catch(e) + { + //TODO: xxxpedro trace error + } + + focusCommandLineState = ++focusCommandLineState % 2; + } + +}); + +// ************************************************************************************************ +// ChromeFrameBase + +/** + * @namespace + * @extends ns-chrome-ChromeBase + */ +var ChromeFrameBase = extend(ChromeBase, +/**@extend ns-chrome-ChromeFrameBase*/ +{ + create: function() + { + ChromeBase.create.call(this); + + // restore display for the anti-flicker trick + if (isFirefox) + this.node.style.display = "block"; + + if (Env.Options.startInNewWindow) + { + this.close(); + this.toggle(true, true); + return; + } + + if (Env.Options.startOpened) + this.open(); + else + this.close(); + }, + + destroy: function() + { + 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() + { + //FBTrace.sysout("Frame", "initialize();") + ChromeBase.initialize.call(this); + + this.addController( + [Firebug.browser.window, "resize", this.resize], + [$("fbWindow_btClose"), "click", this.close], + [$("fbWindow_btDetach"), "click", this.detach], + [$("fbWindow_btDeactivate"), "click", this.deactivate] + ); + + if (!Env.Options.enablePersistent) + this.addController([Firebug.browser.window, "unload", Firebug.shutdown]); + + if (noFixedPosition) + { + this.addController( + [Firebug.browser.window, "scroll", this.fixIEPosition] + ); + } + + fbVSplitter.onmousedown = onVSplitterMouseDown; + fbHSplitter.onmousedown = onHSplitterMouseDown; + + this.isInitialized = true; + }, + + shutdown: function() + { + fbVSplitter.onmousedown = null; + fbHSplitter.onmousedown = null; + + ChromeBase.shutdown.apply(this); + + this.isInitialized = false; + }, + + reattach: function() + { + var frame = FirebugChrome.chromeMap.frame; + + ChromeBase.reattach(FirebugChrome.chromeMap.popup, this); + }, + + open: function() + { + if (!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"; // Avoid flickering + + if (Firebug.showIconWhenHidden) + { + if (ChromeMini.isInitialized) + { + ChromeMini.shutdown(); + } + + } + else + node.style.display = "block"; + + var main = $("fbChrome"); + + // IE6 throws an error when setting this property! why? + //main.style.display = "table"; + main.style.display = ""; + + var self = this; + /// TODO: xxxpedro FOUC + node.style.visibility = "visible"; + setTimeout(function(){ + ///node.style.visibility = "visible"; + + //dispatch(Firebug.modules, "initialize", []); + self.initialize(); + + if (noFixedPosition) + self.fixIEPosition(); + + self.draw(); + + }, 10); + } + }, + + close: function() + { + if (Firebug.context.persistedState.isOpen) + { + if (this.isInitialized) + { + //dispatch(Firebug.modules, "shutdown", []); + 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"; // Avoid flickering + + // TODO: xxxpedro - persist IE fixed? + var main = $("fbChrome", FirebugChrome.chromeMap.frame.document); + main.style.display = "none"; + + ChromeMini.initialize(); + + node.style.visibility = "visible"; + } + else + node.style.display = "none"; + } + }, + + deactivate: function() + { + // if it is running as a Chrome extension, dispatch a message to the extension signaling + // that Firebug should be deactivated for the current tab + if (Env.isChromeExtension) + { + localStorage.removeItem("Firebug"); + Firebug.GoogleChrome.dispatch("FB_deactivate"); + + // xxxpedro problem here regarding Chrome extension. We can't deactivate the whole + // app, otherwise it won't be able to be reactivated without reloading the page. + // but we need to stop listening global keys, otherwise the key activation won't work. + Firebug.chrome.close(); + } + else + { + Firebug.shutdown(); + } + }, + + fixIEPosition: function() + { + // fix IE problem with offset when not in fullscreen mode + var doc = this.document; + var offset = isIE ? doc.body.clientTop || doc.documentElement.clientTop: 0; + + var size = Firebug.browser.getWindowSize(); + var scroll = Firebug.browser.getWindowScrollPosition(); + var maxHeight = size.height; + var height = this.node.offsetHeight; + + var bodyStyle = doc.body.currentStyle; + + this.node.style.top = maxHeight - height + scroll.top + "px"; + + if ((this.type == "frame" || this.type == "div") && + (bodyStyle.marginLeft || bodyStyle.marginRight)) + { + this.node.style.width = size.width + "px"; + } + + if (fbVSplitterStyle) + fbVSplitterStyle.right = Firebug.context.persistedState.sidePanelWidth + "px"; + + this.draw(); + } + +}); + + +// ************************************************************************************************ +// ChromeMini + +/** + * @namespace + * @extends FBL.Controller + */ +var ChromeMini = extend(Controller, +/**@extend ns-chrome-ChromeMini*/ +{ + create: function(chrome) + { + append(this, chrome); + this.type = "mini"; + }, + + initialize: function() + { + Controller.initialize.apply(this); + + var doc = FirebugChrome.chromeMap.frame.document; + + var mini = $("fbMiniChrome", doc); + mini.style.display = "block"; + + var miniIcon = $("fbMiniIcon", doc); + var width = miniIcon.offsetWidth + 10; + miniIcon.title = "Open " + Firebug.version; + + var errors = $("fbMiniErrors", doc); + if (errors.offsetWidth) + width += errors.offsetWidth + 10; + + var node = this.node; + node.style.height = "27px"; + node.style.width = width + "px"; + node.style.left = ""; + node.style.right = 0; + + if (this.node.nodeName.toLowerCase() == "iframe") + { + node.setAttribute("allowTransparency", "true"); + this.document.body.style.backgroundColor = "transparent"; + } + else + node.style.background = "transparent"; + + if (noFixedPosition) + this.fixIEPosition(); + + this.addController( + [$("fbMiniIcon", doc), "click", onMiniIconClick] + ); + + if (noFixedPosition) + { + this.addController( + [Firebug.browser.window, "scroll", this.fixIEPosition] + ); + } + + this.isInitialized = true; + }, + + shutdown: function() + { + var node = this.node; + node.style.height = 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 + +}); + + +// ************************************************************************************************ +// ChromePopupBase + +/** + * @namespace + * @extends ns-chrome-ChromeBase + */ +var ChromePopupBase = extend(ChromeBase, +/**@extend ns-chrome-ChromePopupBase*/ +{ + + initialize: function() + { + setClass(this.document.body, "FirebugPopup"); + + ChromeBase.initialize.call(this); + + this.addController( + [Firebug.chrome.window, "resize", this.resize], + [Firebug.chrome.window, "unload", this.destroy] + //[Firebug.chrome.window, "beforeunload", 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(); + + // TODO: xxxpedro sync detach reattach attach + var frame = FirebugChrome.chromeMap.frame; + + if(frame) + { + dispatch(frame.panelMap, "detach", [this, frame]); + + frame.reattach(this, frame); + } + + if (Env.Options.enablePersistent) + { + removeEvent(Firebug.browser.window, "unload", this.persist); + } + + ChromeBase.destroy.apply(this); + + FirebugChrome.chromeMap.popup = null; + + this.node.close(); + }, + + persist: function() + { + persistTimeStart = new Date().getTime(); + + removeEvent(Firebug.browser.window, "unload", this.persist); + + Firebug.Inspector.destroy(); + Firebug.browser.window.FirebugOldBrowser = true; + + var persistTimeStart = new Date().getTime(); + + var waitMainWindow = function() + { + var doc, head; + + try + { + if (window.opener && !window.opener.FirebugOldBrowser && (doc = window.opener.document)/* && + doc.documentElement && (head = doc.documentElement.firstChild)*/) + { + + try + { + // exposes the FBL to the global namespace when in debug mode + if (Env.isDebugMode) + { + window.FBL = FBL; + } + + window.Firebug = Firebug; + window.opener.Firebug = Firebug; + + Env.browser = window.opener; + Firebug.browser = Firebug.context = new Context(Env.browser); + Firebug.loadPrefs(); + + registerConsole(); + + // the delay time should be calculated right after registering the + // console, once right after the console registration, call log messages + // will be properly handled + var persistDelay = new Date().getTime() - persistTimeStart; + + var chrome = Firebug.chrome; + addEvent(Firebug.browser.window, "unload", chrome.persist); + + FBL.cacheDocument(); + Firebug.Inspector.create(); + + 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(); + } + +}); + + +//************************************************************************************************ +// UI helpers + +var changeCommandLineVisibility = function changeCommandLineVisibility(visibility) +{ + var last = Firebug.chrome.commandLineVisible; + var visible = Firebug.chrome.commandLineVisible = + typeof visibility == "boolean" ? visibility : !Firebug.chrome.commandLineVisible; + + if (visible != last) + { + if (visible) + { + fbBottom.className = ""; + + if (Firebug.CommandLine) + Firebug.CommandLine.activate(); + } + else + { + if (Firebug.CommandLine) + Firebug.CommandLine.deactivate(); + + fbBottom.className = "hide"; + } + } +}; + +var changeSidePanelVisibility = function changeSidePanelVisibility(visibility) +{ + var last = Firebug.chrome.sidePanelVisible; + Firebug.chrome.sidePanelVisible = + typeof visibility == "boolean" ? visibility : !Firebug.chrome.sidePanelVisible; + + if (Firebug.chrome.sidePanelVisible != last) + { + fbPanelBox2.className = Firebug.chrome.sidePanelVisible ? "" : "hide"; + fbPanelBar2Box.className = Firebug.chrome.sidePanelVisible ? "" : "hide"; + } +}; + + +// ************************************************************************************************ +// F12 Handler + +var onGlobalKeyDown = function onGlobalKeyDown(event) +{ + var keyCode = event.keyCode; + var shiftKey = event.shiftKey; + var ctrlKey = event.ctrlKey; + + if (keyCode == 123 /* F12 */ && (!isFirefox && !shiftKey || shiftKey && isFirefox)) + { + Firebug.chrome.toggle(false, ctrlKey); + cancelEvent(event, true); + + // TODO: xxxpedro replace with a better solution. we're doing this + // to allow reactivating with the F12 key after being deactivated + if (Env.isChromeExtension) + { + Firebug.GoogleChrome.dispatch("FB_enableIcon"); + } + } + else if (keyCode == 67 /* C */ && ctrlKey && shiftKey) + { + Firebug.Inspector.toggleInspect(); + cancelEvent(event, true); + } + else if (keyCode == 76 /* L */ && ctrlKey && shiftKey) + { + Firebug.chrome.focusCommandLine(); + cancelEvent(event, true); + } +}; + +var onMiniIconClick = function onMiniIconClick(event) +{ + Firebug.chrome.toggle(false, event.ctrlKey); + cancelEvent(event, true); +}; + + +// ************************************************************************************************ +// Horizontal Splitter Handling + +var onHSplitterMouseDown = function onHSplitterMouseDown(event) +{ + addGlobalEvent("mousemove", onHSplitterMouseMove); + addGlobalEvent("mouseup", onHSplitterMouseUp); + + if (isIE) + addEvent(Firebug.browser.document.documentElement, "mouseleave", onHSplitterMouseUp); + + fbHSplitter.className = "fbOnMovingHSplitter"; + + return false; +}; + +var onHSplitterMouseMove = function onHSplitterMouseMove(event) +{ + cancelEvent(event, true); + + var clientY = event.clientY; + var win = isIE + ? event.srcElement.ownerDocument.parentWindow + : event.target.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; + } + + /* + console.log( + typeof win.FBL != "undefined" ? "no-Chrome" : "Chrome", + //win.frameElement.id, + event.target, + clientY + );/**/ + + onHSplitterMouseMoveBuffer = clientY; // buffer + + if (new Date().getTime() - lastHSplitterMouseMove > chromeRedrawSkipRate) // frame skipping + { + lastHSplitterMouseMove = new Date().getTime(); + handleHSplitterMouseMove(); + } + else + if (!onHSplitterMouseMoveTimer) + onHSplitterMouseMoveTimer = setTimeout(handleHSplitterMouseMove, chromeRedrawSkipRate); + + // improving the resizing performance by canceling the mouse event. + // canceling events will prevent the page to receive such events, which would imply + // in more processing being expended. + cancelEvent(event, true); + return false; +}; + +var handleHSplitterMouseMove = function() +{ + if (onHSplitterMouseMoveTimer) + { + clearTimeout(onHSplitterMouseMoveTimer); + onHSplitterMouseMoveTimer = null; + } + + var clientY = onHSplitterMouseMoveBuffer; + + var windowSize = Firebug.browser.getWindowSize(); + var scrollSize = Firebug.browser.getWindowScrollSize(); + + // compute chrome fixed size (top bar and command line) + var commandLineHeight = Firebug.chrome.commandLineVisible ? fbCommandLine.offsetHeight : 0; + var fixedHeight = topHeight + commandLineHeight; + var chromeNode = Firebug.chrome.node; + + var scrollbarSize = !isIE && (scrollSize.width > windowSize.width) ? 17 : 0; + + //var height = !isOpera ? chromeNode.offsetTop + chromeNode.clientHeight : windowSize.height; + var height = windowSize.height; + + // compute the min and max size of the chrome + var chromeHeight = Math.max(height - clientY + 5 - scrollbarSize, fixedHeight); + chromeHeight = Math.min(chromeHeight, windowSize.height - scrollbarSize); + + 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(); + + // avoid text selection in IE when returning to the document + // after the mouse leaves the document during the resizing + return false; +}; + + +// ************************************************************************************************ +// Vertical Splitter Handling + +var onVSplitterMouseDown = function onVSplitterMouseDown(event) +{ + addGlobalEvent("mousemove", onVSplitterMouseMove); + addGlobalEvent("mouseup", onVSplitterMouseUp); + + return false; +}; + +var onVSplitterMouseMove = function onVSplitterMouseMove(event) +{ + if (new Date().getTime() - lastVSplitterMouseMove > chromeRedrawSkipRate) // frame skipping + { + var target = event.target || event.srcElement; + if (target && target.ownerDocument) // avoid error when cursor reaches out of the chrome + { + var clientX = event.clientX; + var win = document.all + ? event.srcElement.ownerDocument.parentWindow + : event.target.ownerDocument.defaultView; + + if (win != win.parent) + clientX += win.frameElement ? win.frameElement.offsetLeft : 0; + + var size = Firebug.chrome.getSize(); + var x = Math.max(size.width - clientX + 3, 6); + + 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(); +}; + + +// ************************************************************************************************ +}}); \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/chromeSkin.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/chromeSkin.js new file mode 100644 index 00000000000..6db6e2389fe --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/chromeSkin.js @@ -0,0 +1,13 @@ +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +FirebugChrome.Skin = +{ + HTML: '
 
 
>>>
', + 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;cursor:default;font-family:Lucida Grande,Tahoma,sans-serif;font-size:11px;line-height:13px;font-weight:bold;height:22px;color:#565656;}.fbPanelBar span{float:left;}.fbPanelBar .fbTabL,.fbPanelBar .fbTabR{height:22px;width:8px;}.fbPanelBar .fbTabText{padding:4px 1px 0;}a.fbTab:hover{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) 0 -73px;}a.fbTab:hover .fbTabL{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) -16px -96px;}a.fbTab:hover .fbTabR{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) -24px -96px;}.fbSelectedTab{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) #f1f2ee 0 -50px !important;color:#000;}.fbSelectedTab .fbTabL{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) 0 -96px !important;}.fbSelectedTab .fbTabR{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) -8px -96px !important;}#fbHSplitter{position:fixed;_position:absolute;left:0;top:0;width:100%;height:5px;overflow:hidden;cursor:n-resize !important;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/pixel_transparent.gif);z-index:9;}#fbHSplitter.fbOnMovingHSplitter{height:100%;z-index:100;}.fbVSplitter{background:#ece9d8;color:#000;border:1px solid #716f64;border-width:0 1px;border-left-color:#aca899;width:4px;cursor:e-resize;overflow:hidden;right:294px;text-decoration:none;z-index:10;position:absolute;height:100%;top:27px;}div.lineNo{font:1em/1.4545em Monaco,monospace;position:relative;float:left;top:0;left:0;margin:0 5px 0 0;padding:0 5px 0 10px;background:#eee;color:#888;border-right:1px solid #ccc;text-align:right;}.sourceBox{position:absolute;}.sourceCode{font:1em Monaco,monospace;overflow:hidden;white-space:pre;display:inline;}.nodeControl{margin-top:3px;margin-left:-14px;float:left;width:9px;height:9px;overflow:hidden;cursor:default;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/tree_open.gif);_float:none;_display:inline;_position:absolute;}div.nodeMaximized{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/tree_close.gif);}div.objectBox-element{padding:1px 3px;}.objectBox-selector{cursor:default;}.selectedElement{background:highlight;color:#fff !important;}.selectedElement span{color:#fff !important;}* html .selectedElement{position:relative;}@media screen and (-webkit-min-device-pixel-ratio:0){.selectedElement{background:#316AC5;color:#fff !important;}}.logRow *{font-size:1em;}.logRow{position:relative;border-bottom:1px solid #D7D7D7;padding:2px 4px 1px 6px;zbackground-color:#FFFFFF;}.logRow-command{font-family:Monaco,monospace;color:blue;}.objectBox-string,.objectBox-text,.objectBox-number,.objectBox-function,.objectLink-element,.objectLink-textNode,.objectLink-function,.objectBox-stackTrace,.objectLink-profile{font-family:Monaco,monospace;}.objectBox-null{padding:0 2px;border:1px solid #666666;background-color:#888888;color:#FFFFFF;}.objectBox-string{color:red;}.objectBox-number{color:#000088;}.objectBox-function{color:DarkGreen;}.objectBox-object{color:DarkGreen;font-weight:bold;font-family:Lucida Grande,sans-serif;}.objectBox-array{color:#000;}.logRow-info,.logRow-error,.logRow-warn{background:#fff no-repeat 2px 2px;padding-left:20px;padding-bottom:3px;}.logRow-info{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/infoIcon.png) !important;background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/infoIcon.gif);}.logRow-warn{background-color:cyan;background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/warningIcon.png) !important;background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/warningIcon.gif);}.logRow-error{background-color:LightYellow;background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/errorIcon.png) !important;background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/errorIcon.gif);color:#f00;}.errorMessage{vertical-align:top;color:#f00;}.objectBox-sourceLink{position:absolute;right:4px;top:2px;padding-left:8px;font-family:Lucida Grande,sans-serif;font-weight:bold;color:#0000FF;}.selectorTag,.selectorId,.selectorClass{font-family:Monaco,monospace;font-weight:normal;}.selectorTag{color:#0000FF;}.selectorId{color:DarkBlue;}.selectorClass{color:red;}.objectBox-element{font-family:Monaco,monospace;color:#000088;}.nodeChildren{padding-left:26px;}.nodeTag{color:blue;cursor:pointer;}.nodeValue{color:#FF0000;font-weight:normal;}.nodeText,.nodeComment{margin:0 2px;vertical-align:top;}.nodeText{color:#333333;font-family:Monaco,monospace;}.nodeComment{color:DarkGreen;}.nodeHidden,.nodeHidden *{color:#888888;}.nodeHidden .nodeTag{color:#5F82D9;}.nodeHidden .nodeValue{color:#D86060;}.selectedElement .nodeHidden,.selectedElement .nodeHidden *{color:SkyBlue !important;}.log-object{}.property{position:relative;clear:both;height:15px;}.propertyNameCell{vertical-align:top;float:left;width:28%;position:absolute;left:0;z-index:0;}.propertyValueCell{float:right;width:68%;background:#fff;position:absolute;padding-left:5px;display:table-cell;right:0;z-index:1;}.propertyName{font-weight:bold;}.FirebugPopup{height:100% !important;}.FirebugPopup #fbWindowButtons{display:none !important;}.FirebugPopup #fbHSplitter{display:none !important;}' +}; + +// ************************************************************************************************ +}}); \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/commandLine.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/commandLine.js new file mode 100644 index 00000000000..7c93a82782b --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/commandLine.js @@ -0,0 +1,554 @@ +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + + +// ************************************************************************************************ +// Globals + +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; +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +// ************************************************************************************************ +// CommandLine + +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); + } + + //Firebug.Console.log("activate", this.element); + + if (isOpera) + fixOperaTabKey(this.element); + + if(this.lastValue) + this.element.value = this.lastValue; + + this.isActive = true; + }, + + deactivate: function() + { + if (!this.isActive) return; + + //Firebug.Console.log("deactivate", this.element); + + 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) + { + // TODO: need to register the API in console.firebug.commandLineAPI + 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 it is the beginning of the completion + if(!isAutoCompleting) + { + + // group1 - command begin + // group2 - base object + // group3 - property prefix + var reObj = /(.*[^_$\w\d\.])?((?:[_$\w][_$\w\d]*\.)*)([_$\w][_$\w\d]*)?$/; + var r = reObj.exec(val); + + // parse command + 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; + + // find base object + 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; + } + + // map base object + 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); + } + + // if it is the continuation of the last completion + } else + buffer = autoCompleteBuffer; + + if (buffer) + { + prefix = autoCompletePrefix; + + var diff = reverse ? -1 : 1; + + for(var i=autoCompletePosition+diff, l=buffer.length, bi; i>=0 && i', msg, '', + '' + ]; + + // TODO: xxxpedro ajust to Console2 + //Firebug.Console.writeRow(html, "error"); + }, + + onKeyDown: function(e) + { + e = e || event; + + var code = e.keyCode; + + /*tab, shift, control, alt*/ + if (code != 9 && code != 16 && code != 17 && code != 18) + { + isAutoCompleting = false; + } + + if (code == 13 /* enter */) + { + this.enter(); + this.clear(); + } + else if (code == 27 /* ESC */) + { + setTimeout(this.clear, 0); + } + else if (code == 38 /* up */) + { + this.prevCommand(); + } + else if (code == 40 /* down */) + { + this.nextCommand(); + } + else if (code == 9 /* tab */) + { + this.autocomplete(e.shiftKey); + } + else + return; + + cancelEvent(e, true); + return false; + }, + + onMultiLineKeyDown: function(e) + { + e = e || event; + + var code = e.keyCode; + + if (code == 13 /* enter */ && e.ctrlKey) + { + this.enter(); + } + } +}); + +Firebug.registerModule(Firebug.CommandLine); + + +// ************************************************************************************************ +// + +function getExpressionOffset(command) +{ + // XXXjoe This is kind of a poor-man's JavaScript parser - trying + // to find the start of the expression that the cursor is inside. + // Not 100% fool proof, but hey... + + 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; +} + +// ************************************************************************************************ +// CommandLine API + +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 (o instanceof Window) + if (instanceOf(o, "Window")) + o = o.document.documentElement; + ///else if (o instanceof Document) + 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]; + } +}; + +// ************************************************************************************************ +}}); \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/context.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/context.js new file mode 100644 index 00000000000..84cad22c114 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/context.js @@ -0,0 +1,647 @@ +/* See license.txt for terms of usage */ + +FBL.ns( /**@scope s_context*/ function() { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +// Globals + +var refreshDelay = 300; + +// Opera and some versions of webkit returns the wrong value of document.elementFromPoint() +// function, without taking into account the scroll position. Safari 4 (webkit/531.21.8) +// still have this issue. Google Chrome 4 (webkit/532.5) does not. So, we're assuming this +// issue was fixed in the 532 version +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;"; + + +// ************************************************************************************************ +// Context + +/** @class */ +FBL.Context = function(win) +{ + this.window = win.window; + this.document = win.document; + + this.browser = Env.browser; + + // Some windows in IE, like iframe, doesn't have the eval() method + if (isIE && !this.window.eval) + { + // But after executing the following line the method magically appears! + this.window.execScript("null"); + // Just to make sure the "magic" really happened + if (!this.window.eval) + throw new Error("Firebug Error: eval() method not found in this window"); + } + + // Create a new "black-box" eval() method that runs in the global namespace + // of the context window, without exposing the local variables declared + // by the function that calls it + this.eval = this.window.eval("new Function('" + + "try{ return window.eval.apply(window,arguments) }catch(E){ E."+evalError+"=true; return E }" + + "')"); +}; + +FBL.Context.prototype = +{ + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // partial-port of Firebug tabContext.js + + 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 ? // IE doesn't have apply method on setTimeout + 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 ? // IE doesn't have apply method on setTimeout + 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]; + + // avoid error. need to create a better getPanel() function as explained below + if (!Firebug.chrome || !Firebug.chrome.selectedPanel) + return; + + //var panel = this.getPanel(panelName, true); + //TODO: xxxpedro context how to get all panels using a single function? + // the current workaround to make the invalidation works is invalidating + // only sidePanels. There's also a problem with panel name (LowerCase in Firebug Lite) + 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 = this.getPanel(panelName, true); + //TODO: xxxpedro context how to get all panels using a single function? + // the current workaround to make the invalidation works is invalidating + // only sidePanels. There's also a problem with panel name (LowerCase in Firebug Lite) + 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 the panel is being edited, we'll keep trying to + // refresh it until editing is done + if (panel.editing) + invalids.push(panelName); + } + } + + delete this.invalidPanels; + delete this.refreshTimeout; + + // Keep looping until every tab is valid + if (invalids.length) + this.invalidatePanels.apply(this, invalids); + }, this), refreshDelay); + }, + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Evalutation Method + + /** + * Evaluates an expression in the current context window. + * + * @param {String} expr expression to be evaluated + * + * @param {String} context string indicating the global location + * of the object that will be used as the + * context. The context is referred in + * the expression as the "this" keyword. + * If no context is informed, the "window" + * context is used. + * + * @param {String} api string indicating the global location + * of the object that will be used as the + * api of the evaluation. + * + * @param {Function} errorHandler(message) error handler to be called + * if the evaluation fails. + */ + evaluate: function(expr, context, api, errorHandler) + { + // the default context is the "window" object. It can be any string that represents + // a global accessible element as: "my.namespaced.object" + context = context || "window"; + + var isObjectLiteral = trim(expr).indexOf("{") == 0, + cmd, + result; + + // if the context is the "window" object, we don't need a closure + if (context == "window") + { + // If it is an object literal, then wrap the expression with parenthesis so we can + // capture the return value + if (isObjectLiteral) + { + cmd = api ? + "with("+api+"){ ("+expr+") }" : + "(" + expr + ")"; + } + else + { + cmd = api ? + "with("+api+"){ "+expr+" }" : + expr; + } + } + else + { + cmd = api ? + // with API and context, no return value + "(function(arguments){ with(" + api + "){ " + + expr + + " } }).call(" + context + ",undefined)" + : + // with context only, no return value + "(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; + }, + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Window Methods + + 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; + + // first try the document.documentElement scroll size + if (!isIEQuiksMode && (el=this.document.documentElement) && + (el.scrollHeight || el.scrollWidth)) + { + width = el.scrollWidth; + height = el.scrollHeight; + } + + // then we need to check if document.body has a bigger scroll size value + // because sometimes depending on the browser and the page, the document.body + // scroll size returns a smaller (and wrong) measure + 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}; + }, + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Element Methods + + getElementFromPoint: function(x, y) + { + if (shouldFixElementFromPoint) + { + var scroll = this.getWindowScrollPosition(); + return this.document.elementFromPoint(x + scroll.left, y + scroll.top); + } + else + return this.document.elementFromPoint(x, y); + }, + + getElementPosition: function(el) + { + var left = 0; + var top = 0; + + do + { + left += el.offsetLeft; + top += el.offsetTop; + } + while (el = el.offsetParent); + + return {left:left, top:top}; + }, + + getElementBox: function(el) + { + var result = {}; + + if (el.getBoundingClientRect) + { + var rect = el.getBoundingClientRect(); + + // fix IE problem with offset when not in fullscreen mode + var offset = isIE ? this.document.body.clientTop || this.document.documentElement.clientTop: 0; + + var scroll = this.getWindowScrollPosition(); + + result.top = Math.round(rect.top - offset + scroll.top); + result.left = Math.round(rect.left - offset + scroll.left); + result.height = Math.round(rect.bottom - rect.top); + result.width = Math.round(rect.right - rect.left); + } + else + { + var position = this.getElementPosition(el); + + result.top = position.top; + result.left = position.left; + result.height = el.offsetHeight; + result.width = el.offsetWidth; + } + + return result; + }, + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Measurement Methods + + getMeasurement: function(el, name) + { + var result = {value: 0, unit: "px"}; + + var cssValue = this.getStyle(el, name); + + if (!cssValue) return result; + if (cssValue.toLowerCase() == "auto") return result; + + var reMeasure = /(\d+\.?\d*)(.*)/; + var m = cssValue.match(reMeasure); + + if (m) + { + result.value = m[1]-0; + result.unit = m[2].toLowerCase(); + } + + return result; + }, + + getMeasurementInPixels: function(el, name) + { + if (!el) return null; + + var m = this.getMeasurement(el, name); + var value = m.value; + var unit = m.unit; + + if (unit == "px") + return value; + + else if (unit == "pt") + return this.pointsToPixels(name, value); + + 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); + + // TODO: add other units. Maybe create a better general way + // to calculate measurements in different units. + }, + + getMeasurementBox1: function(el, name) + { + var sufixes = ["Top", "Left", "Bottom", "Right"]; + var result = []; + + for(var i=0, sufix; sufix=sufixes[i]; i++) + result[i] = Math.round(this.getMeasurementInPixels(el, name + sufix)); + + return {top:result[0], left:result[1], bottom:result[2], right:result[3]}; + }, + + getMeasurementBox: function(el, name) + { + var result = []; + var sufixes = name == "border" ? + ["TopWidth", "LeftWidth", "BottomWidth", "RightWidth"] : + ["Top", "Left", "Bottom", "Right"]; + + if (isIE) + { + var propName, cssValue; + var autoMargin = null; + + for(var i=0, sufix; sufix=sufixes[i]; i++) + { + propName = name + sufix; + + cssValue = el.currentStyle[propName] || el.style[propName]; + + if (cssValue == "auto") + { + if (!autoMargin) + autoMargin = this.getCSSAutoMarginBox(el); + + result[i] = autoMargin[sufix.toLowerCase()]; + } + else + result[i] = this.getMeasurementInPixels(el, propName); + + } + + } + else + { + for(var i=0, sufix; sufix=sufixes[i]; i++) + result[i] = this.getMeasurementInPixels(el, name + sufix); + } + + return {top:result[0], left:result[1], bottom:result[2], right:result[3]}; + }, + + getCSSAutoMarginBox: function(el) + { + if (isIE && " meta title input script link a ".indexOf(" "+el.nodeName.toLowerCase()+" ") != -1) + return {top:0, left:0, bottom:0, right:0}; + /**/ + + if (isIE && " h1 h2 h3 h4 h5 h6 h7 ul p ".indexOf(" "+el.nodeName.toLowerCase()+" ") == -1) + return {top:0, left:0, bottom:0, right:0}; + /**/ + + var offsetTop = 0; + if (false && isIEStantandMode) + { + var scrollSize = Firebug.browser.getWindowScrollSize(); + offsetTop = scrollSize.height; + } + + var box = this.document.createElement("div"); + //box.style.cssText = "margin:0; padding:1px; border: 0; position:static; overflow:hidden; visibility: hidden;"; + box.style.cssText = "margin:0; padding:1px; border: 0; visibility: hidden;"; + + var clone = el.cloneNode(false); + var text = this.document.createTextNode(" "); + clone.appendChild(text); + + box.appendChild(clone); + + this.document.body.appendChild(box); + + var marginTop = clone.offsetTop - box.offsetTop - 1; + var marginBottom = box.offsetHeight - clone.offsetHeight - 2 - marginTop; + + var marginLeft = clone.offsetLeft - box.offsetLeft - 1; + var marginRight = box.offsetWidth - clone.offsetWidth - 2 - marginLeft; + + this.document.body.removeChild(box); + + return {top:marginTop+offsetTop, left:marginLeft, bottom:marginBottom-offsetTop, right:marginRight}; + }, + + getFontSizeInPixels: function(el) + { + var size = this.getMeasurement(el, "fontSize"); + + if (size.unit == "px") return size.value; + + // get font size, the dirty way + var computeDirtyFontSize = function(el, calibration) + { + var div = this.document.createElement("div"); + var divStyle = offscreenStyle; + + if (calibration) + divStyle += " font-size:"+calibration+"px;"; + + div.style.cssText = divStyle; + div.innerHTML = "A"; + el.appendChild(div); + + var value = div.offsetHeight; + el.removeChild(div); + return value; + }; + + /* + var calibrationBase = 200; + var calibrationValue = computeDirtyFontSize(el, calibrationBase); + var rate = calibrationBase / calibrationValue; + /**/ + + // the "dirty technique" fails in some environments, so we're using a static value + // based in some tests. + var rate = 200 / 225; + + var value = computeDirtyFontSize(el); + + return value * rate; + }, + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Unit Funtions + + pointsToPixels: function(name, value, returnFloat) + { + var axis = /Top$|Bottom$/.test(name) ? "y" : "x"; + + var result = value * pixelsPerInch[axis] / 72; + + return returnFloat ? result : Math.round(result); + }, + + emToPixels: function(el, value) + { + if (!el) return null; + + var fontSize = this.getFontSizeInPixels(el); + + return Math.round(value * fontSize); + }, + + exToPixels: function(el, value) + { + if (!el) return null; + + // get ex value, the dirty way + var div = this.document.createElement("div"); + div.style.cssText = offscreenStyle + "width:"+value + "ex;"; + + el.appendChild(div); + var value = div.offsetWidth; + el.removeChild(div); + + return value; + }, + + percentToPixels: function(el, value) + { + if (!el) return null; + + // get % value, the dirty way + var div = this.document.createElement("div"); + div.style.cssText = offscreenStyle + "width:"+value + "%;"; + + el.appendChild(div); + var value = div.offsetWidth; + el.removeChild(div); + + return value; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getStyle: isIE ? function(el, name) + { + return el.currentStyle[name] || el.style[name] || undefined; + } + : function(el, name) + { + return this.document.defaultView.getComputedStyle(el,null)[name] + || el.style[name] || undefined; + } + +}; + + +// ************************************************************************************************ +}}); \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/css/cssAnalyzer.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/css/cssAnalyzer.js new file mode 100644 index 00000000000..5e556007aff --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/css/cssAnalyzer.js @@ -0,0 +1,623 @@ +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// StyleSheet Parser + +var CssAnalyzer = {}; + +// ************************************************************************************************ +// Locals + +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; + +//************************************************************************************************ +// CSS Analyzer templates + +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") + ) +}); + +// ************************************************************************************************ +// CSS Analyzer methods + +CssAnalyzer.processAllStyleSheets = function(doc, styleSheetIterator) +{ + try + { + processAllStyleSheets(doc, styleSheetIterator); + } + catch(e) + { + // TODO: FBTrace condition + FBTrace.sysout("CssAnalyzer.processAllStyleSheets fails: ", e); + } +}; + +/** + * + * @param element + * @returns {String[]} Array of IDs of CSS Rules + */ +CssAnalyzer.getElementCSSRules = function(element) +{ + try + { + return getElementCSSRules(element); + } + catch(e) + { + // TODO: FBTrace condition + FBTrace.sysout("CssAnalyzer.getElementCSSRules fails: ", e); + } +}; + +CssAnalyzer.getRuleData = function(ruleId) +{ + return CSSRuleMap[ruleId]; +}; + +// TODO: do we need this? +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; + + // See: Issue 4776: [Firebug lite] CSS Media Types + // + // Ignore all special selectors like @media and @page + for(var i=0; i < parsedRules.length; ) + { + if (parsedRules[i].selector.indexOf("@") != -1) + { + parsedRules.splice(i, 1); + } + else + i++; + } + + return parsedRules; +}; + +//************************************************************************************************ +// Internals +//************************************************************************************************ + +// ************************************************************************************************ +// StyleSheet processing + +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 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: + // See: Issue 4777: [Firebug lite] Specificity of CSS Rules + // + // if it is a normal selector then calculate the specificity + selector && selector.indexOf(",") == -1 ? + getCSSRuleSpecificity(selector) : + // See: Issue 3262: [Firebug lite] Specificity of grouped CSS Rules + // + // if it is a grouped selector, do not calculate the specificity + // because the correct value will depend of the matched element. + // The proper specificity value for grouped selectors are calculated + // via getElementCSSRules(element) + 0, + + rule: rule, + lineNo: lineNo, + selector: selector, + cssText: rule.style ? rule.style.cssText : rule.cssText ? rule.cssText : "" + }; + + // TODO: what happens with elements added after this? Need to create a test case. + // Maybe we should place this at getElementCSSRules() but it will make the function + // a lot more expensive. + // + // Maybe add a "refresh" button? + var elements = Firebug.Selector(selector, doc); + + for (var j=0, elementsLength=elements.length; j maxSpecificity) + { + maxSpecificity = spec; + mostSpecificSelector = sel; + } + } + } + + rule.specificity = maxSpecificity; + } + } + + rules.sort(sortElementRules); + //rules.sort(solveRulesTied); + + return rules; +}; + +// ************************************************************************************************ +// Rule Specificity + +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; +}; + +// ************************************************************************************************ +// StyleSheet data + +var extractSourceData = function(href) +{ + var sourceData = + { + source: null, + startLine: 0 + }; + + if (href) + { + sourceData.source = Firebug.Lite.Proxy.load(href); + } + else + { + // TODO: create extractInternalSourceData(index) + // TODO: pre process the position of the inline styles so this will happen only once + // in case of having multiple inline styles + 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"); // normalize line breaks + + 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; +}; + +// ************************************************************************************************ +// Registration + +FBL.CssAnalyzer = CssAnalyzer; + +// ************************************************************************************************ +}}); diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/css/cssParser.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/css/cssParser.js new file mode 100644 index 00000000000..fa6a355a26d --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/css/cssParser.js @@ -0,0 +1,312 @@ +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +var CssParser = null; + +// ************************************************************************************************ + +// Simple CSS stylesheet parser from: +// https://github.com/sergeche/webkit-css + +/** + * Simple CSS stylesheet parser that remembers rule's lines in file + * @author Sergey Chikuyonok (serge.che@gmail.com) + * @link http://chikuyonok.ru + */ +CssParser = (function(){ + /** + * Returns rule object + * @param {Number} start Character index where CSS rule definition starts + * @param {Number} body_start Character index where CSS rule's body starts + * @param {Number} end Character index where CSS rule definition ends + */ + function rule(start, body_start, end) { + return { + start: start || 0, + body_start: body_start || 0, + end: end || 0, + line: -1, + selector: null, + parent: null, + + /** @type {rule[]} */ + children: [], + + addChild: function(start, body_start, end) { + var r = rule(start, body_start, end); + r.parent = this; + this.children.push(r); + return r; + }, + /** + * Returns last child element + * @return {rule} + */ + lastChild: function() { + return this.children[this.children.length - 1]; + } + }; + } + + /** + * Replaces all occurances of substring defined by regexp + * @param {String} str + * @return {RegExp} re + * @return {String} + */ + function removeAll(str, re) { + var m; + while (m = str.match(re)) { + str = str.substring(m[0].length); + } + + return str; + } + + /** + * Trims whitespace from the beginning and the end of string + * @param {String} str + * @return {String} + */ + function trim(str) { + return str.replace(/^\s+|\s+$/g, ''); + } + + /** + * Normalizes CSS rules selector + * @param {String} selector + */ + function normalizeSelector(selector) { + // remove newlines + selector = selector.replace(/[\n\r]/g, ' '); + + selector = trim(selector); + + // remove spaces after commas + selector = selector.replace(/\s*,\s*/g, ','); + + return selector; + } + + /** + * Preprocesses parsed rules: adjusts char indexes, skipping whitespace and + * newlines, saves rule selector, removes comments, etc. + * @param {String} text CSS stylesheet + * @param {rule} rule_node CSS rule node + * @return {rule[]} + */ + 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; + + // remove newlines for better regexp matching + rule_start = rule_start.replace(/[\n\r]/g, ' '); + + // remove @import rules +// rule_start = removeAll(rule_start, /^\s*@import\s*url\((['"])?.+?\1?\)\;?/g); + + // remove comments + rule_start = removeAll(rule_start, /^\s*\/\*.*?\*\/[\s\t]*/); + + // remove whitespace + rule_start = rule_start.replace(/^[\s\t]+/, ''); + + r.start += (cur_len - rule_start.length); + r.selector = normalizeSelector(rule_start); + } + + return rule_node; + } + + /** + * Saves all lise starting indexes for faster search + * @param {String} text CSS stylesheet + * @return {Number[]} + */ + 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') { + // windows line ending: CRLF. Skip next character + i++; + } + + result.push(i + 1); + } + + i++; + } + + return result; + } + + /** + * Saves line number for parsed rules + * @param {String} text CSS stylesheet + * @param {rule} rule_node Rule node + * @return {rule[]} + */ + function saveLineNumbers(text, rule_node, line_indexes, startLine) { + preprocessRules(text, rule_node); + + startLine = startLine || 0; + + // remember lines start indexes, preserving line ending characters + if (!line_indexes) + var line_indexes = saveLineIndexes(text); + + // now find each rule's line + 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 { + /** + * Parses text as CSS stylesheet, remembring each rule position inside + * text + * @param {String} text CSS stylesheet to parse + */ + 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 '/': + // xxxpedro allowing comment inside comment + if (!in_comment && ch2 == '*') { // comment start + in_comment++; + } + break; + + case '*': + if (ch2 == '/') { // comment end + 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 '}': + // found the end of the rule + if (!in_comment) { + /** @type {rule} */ + 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, + + /** + * Find matched rule by selector. + * @param {rule} rule_node Parsed rule node + * @param {String} selector CSS selector + * @param {String} source CSS stylesheet source code + * + * @return {rule[]|null} Array of matched rules, sorted by priority (most + * recent on top) + */ + 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++) { + /** @type {rule} */ + var r = rule_node.children[i]; + if (r.selector == selector) { + result.push(r); + } + } + } + + if (result.length) { + return result; + } else { + return null; + } + } + }; +})(); + + +// ************************************************************************************************ + +FBL.CssParser = CssParser; + +// ************************************************************************************************ +}}); \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/eventDelegator.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/eventDelegator.js new file mode 100644 index 00000000000..0bb27ad4a13 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/eventDelegator.js @@ -0,0 +1,676 @@ +/* See license.txt for terms of usage */ + +FBL.ns( /**@scope _eventDelegator_ */ function() { + +// ************************************************************************************************ +// Globals + +var EventCache = new Cache(); + +/** + * @namespace + * @exports _eventDelegator_-Event as Event + */ +var Event = {}; + +Event.add = function(element, type, callback, capture, owner, validator, data, bubble) +{ + var id = EventCache.set(element); + + if (!id) return; + + // the "owner" is which object means "this" inside the callback function + owner = owner || element; + + // read type and namespaces + var info = readEventNamespace(type); + var namespaces = info.namespaces; + type = info.type; + + // read eventMap, which will hold data for all types of event + var eventMap = EventCache.data(element, "eventMap"); + + // if there's no eventMap, create one + if (!eventMap) + { + eventMap = EventCache.data(element, "eventMap", {}); + } + + // read eventData + var eventData = eventMap[type]; + + // if there's no eventData, create one + if (!eventData) + { + eventData = eventMap[type] = { + listeners: [], + handler: null + }; + } + + // callback queue + var eventListeners = eventData.listeners; + + // event handler + var eventHandler = eventData.handler; + + // if there's no handler, create one + if (!eventHandler) + { + eventHandler = /** @ignore */ eventData.handler = function(event) + { + //console.time("handling "+type); + + event = fixEvent(event); + + var target = event.target; + + do + { + for (var i = 0, length = eventListeners.length; i < length; i++) + { + var listener = eventListeners[i]; + + if (validator && validator.call(owner, event, listener) || !validator) + listener.callback.call(owner, event); + } + + target = event.target = bubble && // if should bubble up + !event.isPropagationStopped() && // and propagation is not stopped + target.parentNode; // then we must look for the parent node + // otherwise target variable will be set to null + } + while(target); + + //console.timeEnd("handling "+type); + }; + } + + // add event to the queue + eventListeners.push({ + //type: type, // redundant.... remove this? + callback: callback, + capture: capture, + namespaces: namespaces, + data: data + }); + + if (eventListeners.length == 1) + { + if (element.addEventListener) + element.addEventListener(type, eventHandler, capture); + else + element.attachEvent("on"+type, eventHandler); + } +}; + +Event.remove = function(element, type, callback, capture, owner, validator) +{ + var id = EventCache.key(element); + + if (!id) return; + + // read namespaces + var info = readEventNamespace(type); + var namespaces = info.namespaces; + type = info.type; + + // event map data + var eventMap = EventCache.data(element, "eventMap"); + if (!eventMap) return; + + var eventData; + + var types = []; + + if (type) + { + types = [type]; + } + else + { + for (var name in eventMap) + { + types.push(name); + } + } + + for (var t = 0, tlength = types.length; t < tlength; t++) + { + type = types[t]; + + // event data + var eventData = eventMap[type]; + + // callback queue + var eventListeners = eventData.listeners; + if (!eventListeners) return; + + // event handler + var eventHandler = eventData.handler; + + + for (var i = 0; + // we cannot store the length as a way to improve the performance because + // we're removing elements from the array, so we need to actually read + // the length in every loop iteration to make sure we have reached the end + i < eventListeners.length; + ) + { + var listener = eventListeners[i]; + + /* + cases + - click + - click.namespace + - click.namespace.plus + - .namespace + + has type --> look for 1 type + has no type --> look for all types + + has namespace --> compare + has callback --> compare + no namespace, no callback (case removeEvent(el, "click")) --> remove all events with the given type + */ + + if ( + (callback && listener.callback == callback || !callback) && + (namespaces && compareEventNamespace(namespaces, listener.namespaces) || !namespaces) && + (validator && validator.call(owner, listener) || !validator) + ) + { + listener.callback = null; + eventListeners.splice(i, 1); + EventCache.free(element); + } + else + { + // we must advance the cursor only if current listener wasn't removed + i++; + } + } + + if (eventListeners.length == 0) + { + if (element.removeEventListener) + element.removeEventListener(type, eventHandler, capture); + else + element.detachEvent("on"+type, eventHandler); + } + + } +}; + + + +// ************************************************************************************************ +// Locals + +var readEventNamespace = function(type) +{ + var info = {}; + + if (type.indexOf(".") != -1) + { + var parts = type.split("."); + + // type is the first name + info.type = parts.shift(); + // namespaces are all remaining parts (eg: click.MyPanel.MyPanelAction) + info.namespaces = parts.length > 0 ? parts : null; + } + else + { + info.type = type; + } + + return info; +}; + + +var compareEventNamespace = function(namespaces, baseNamespaces) +{ + if (!namespaces || !baseNamespaces) return false; + + var base = " " + baseNamespaces.join(" ") + " "; + var count = 0; + var ns; + + for (var i = 0, length = namespaces.length; i < length; i++) + { + ns = namespaces[i]; + + if ( base.indexOf(" " + ns + " ") != -1 ) + { + count++; + } + } + + return count == length; +}; + +// ************************************************************************************************ + +/** + * Support for cross-browser compatible event. + */ +var expando = "helloModule"; +var fixEvent = function(event) +{ + if ( event[expando] == true ) + return event; + + // store a copy of the original event object + // and "clone" to set read-only properties + var originalEvent = event; + event = { originalEvent: originalEvent }; + // TODO: xxxpedro any particular reason to not use "for var name in originalEvent"? + var props = "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" "); + for ( var i=props.length; i; i-- ) + event[ props[i] ] = originalEvent[ props[i] ]; + + var isPropagationStopped = false; + + // Mark it as fixed + event[expando] = true; + + // add preventDefault and stopPropagation since + // they will not work on the clone + /** @ignore */ + event.preventDefault = function() { + // if preventDefault exists run it on the original event + if (originalEvent.preventDefault) + originalEvent.preventDefault(); + // otherwise set the returnValue property of the original event to false (IE) + originalEvent.returnValue = false; + }; + /** @ignore */ + event.stopPropagation = function() { + // if stopPropagation exists run it on the original event + if (originalEvent.stopPropagation) + originalEvent.stopPropagation(); + // otherwise set the cancelBubble property of the original event to true (IE) + originalEvent.cancelBubble = true; + + isPropagationStopped = true; + }; + /** @ignore */ + event.isPropagationStopped = function() + { + return isPropagationStopped; + }; + + // Fix timeStamp + //event.timeStamp = event.timeStamp || this.now(); + // TODO: xxxpedro what is this now() function? ask honza where this fixEvent function came from + event.timeStamp = event.timeStamp || new Date().getTime(); + + // Fix target property, if necessary + if ( !event.target ) + event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either + + // check if target is a textnode (safari) + if ( event.target.nodeType == 3 ) + event.target = event.target.parentNode; + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && event.fromElement ) + event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && event.clientX != null ) { + var doc = document.documentElement, body = document.body; + event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0); + event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0); + } + + // Add which for key events + if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) + event.which = event.charCode || event.keyCode; + + // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) + if ( !event.metaKey && event.ctrlKey ) + event.metaKey = event.ctrlKey; + + // Add which for click: 1 == left; 2 == middle; 3 == right + // Note: button is not normalized, so don't use it + if ( !event.which && event.button ) + event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); + + return event; +}; + +// ************************************************************************************************ + +/** + * @class A "Control" is a visual component that responds to user actions + * + * @exports _eventDelegator_-Control as Control + */ +function Control(element) +{ + this._controlElement = element; +} + +Control.prototype = +{ + addEvent: function(type, callback, capture){ + Event.add(this._controlElement, getControlType(type), callback, capture, this); + }, + removeEvent: function(type, callback, capture){ + Event.remove(this._controlElement, getControlType(type), callback, capture); + }, + removeEvents: function(){ + Event.remove(this._controlElement, getControlType("")); + } +}; + +function getControlType(type) +{ + return type + ".{Control}"; +} + +// ************************************************************************************************ + +/** + * @class A "Controller" is a special kind of "Control" that can delegate events to its + * descendants. + * + * @augments Control + * @exports _eventDelegator_-Controller as Controller + */ +function Controller(element) +{ + this._controlElement = element; +} + +Controller.prototype = FBL.extend(Control.prototype, /** @lends Controller.prototype */ +{ + + /** + * Adds a "Controller" listener. + * + * *Example* + * ~~ + * var controller = new Controller(root); // create an instance + * + * controller.onclick = function(){}; // define the handler + * + * controller.addController("div > .someClass", "click.namespace", controller.onclick); + * ~~ + * + * @param {String} selector A CSS selector representing the target Elements. + * @param {String} type A string representing the event type/namespace to listen for. + * @param {Function} callback The controller handler function. + * @param {Boolean} capture If "true", all events of the specified type/namespace + * will be captured. + * @see Event.add() + */ + addController: function(selector, type, callback, capture) + { + function addControllerValidator(e, listener) + { + return Firebug.Selector.matches(listener.data.selector, [e.target]).length > 0; + } + + Event.add(this._controlElement, getControllerType(selector, type), callback, null, + this, addControllerValidator, {selector: selector}, true); + }, + + /** + * Removes one or more "Controller" listeners. + * + * *Example* + * ~~ + * // removes a particular controller + * controller.removeController("div > .someClass", "click.namespace", controller.onclick); + * + * // removes all controllers that match the selector, + * // have the "click" type and the "namespace" namespace + * controller.removeController("div > .someClass", "click.namespace"); + * + * // removes all controllers that match the selector and have the "click" type + * controller.removeController("div > .someClass", "click"); + * + * // removes all controllers that match the selector and have the "namespace" namespace + * controller.removeController("div > .someClass", ".namespace"); + * + * // removes all controllers that match the selector + * controller.removeController("div > .someClass"); + * + * // removes all controllers that have the same type/namespace, you got the idea... + * controller.removeController(null, "click.namespace"); + * ~~ + * + * @param {String} selector A CSS selector representing the target Elements. + * @param {String} type A string representing the event type/namespace to listen for. + * @param {Function} callback The controller handler function. + * @param {Boolean} capture If "true", all events of the specified type/namespace + * will be captured. + * @see Event.remove() + */ + removeController: function(selector, type, callback, capture) + { + function removeControllerValidator(listener) + { + return listener.data.selector == selector/* && listener.callback == callback*/; + } + + Event.remove(this._controlElement, getControllerType(selector, type), callback, null, + this, removeControllerValidator); + }, + + /** + * Removes all Controller listeners. + */ + removeControllers: function() + { + Event.remove(this._controlElement, getControllerType("", "")); + } +}); + +function getControllerType(selector, type) +{ + return (type||"")+".Controller"+(selector ? ".Selector_"+selector.replace(/\s|\./g, "_") : ""); +} + +// ************************************************************************************************ + +/** + * @class + * @augments Controller + * @exports _eventDelegator_-WindowController as WindowController + */ +function WindowController(win) +{ + this._controlElement = win; +} + +WindowController.prototype = FBL.extend(Controller.prototype, /**@lends WindowController.prototype */ +{ + addKeyController: function(key, filter, listener, capture /*, priority?*/) + { + }, + + removeKeyController: function(key) + { + }, + + removeKeyControllers: function() + { + }, + + addCharController: function(character, filter, listener, capture /*, priority? */ ) + { + }, + + removeCharController: function(character) + { + }, + + removeCharControllers: function() + { + } +}); + +// ************************************************************************************************ + +/* +// TODO: remove test stuff +window.Control = Control; +window.Controller = Controller; + +h1 = function(){ console.log("t1"); }; +h2 = function(){ console.log("t2"); }; + +c = new Controller( document.body ); + +c.addController("#main", "click", function(){ console.log("main"); }); +c.addController("h1", "click", function(e){ e.stopPropagation();console.log("h1"); }); + +c.addController("h1", "mouseover", h1); +c.addController("h1", "mouseover", h2); +c.addController("h2", "mouseover", h2); + +window.c = c; +*/ + +// ************************************************************************************************ + +}); + + + +/* + + TODO: + - API + Event.add versus Event.addEvent + + - do not store objects in cache variables, use key instead + + - priority? + - sort controller callbacks based on rule specificity? + - cancel propagation for controllers? + + - use it for internal events? + - need to attach "key" attribute to individual objects + +*/ + + +/* + +Problems + - cross-browser compatibily (addEventListener versus attachEvent, event object differences) + - performance (we need to reduce the number of events attached to elements --> event delegation) + +Related-problems + - memory leak (we need to avoid circular references between DOM and JS worlds --> cache) + - remote object identification (we can't use XPATH for JavaScript objects) + +Goals + - Define an API to handle event-related problems (event handling, event delegation, key listening) + + +Tips for avoiding problem with events + - avoid adding events to elements. Use controls/controllers instead. + + - Chrome controller + - all mouse events should be delegated + - all keyboard events should be delegated + - all resize events should be delegated + - all scroll events should be delegated + +~~~~~~~~~ + +Questions + +Using expando property to cache elements + - we need this to optimize cache lookup time and avoid attaching JavaScript objects into DOM Elements (no circular references problem, less prone to memory leaks) + - Is this ok in Firebug code? Firebug Lite currently uses this + +Controller definition using CSS selectors or classes-only + - How to verify if a particular element matches a CSS selector in FF? + + +~~~~~~~~~ + +Control is a visual component that responds to user actions + +Controller is a special kind of Control that operates several sub-components (internal Controls) +using a single Control component + +http://docwiki.embarcadero.com/VCL/en/Controls.TControl + +~~~~~~~~~ + +API - draft + +---------------------------------------------------------------------------------------------------- +Lib/Event Module +---------------------------------------------------------------------------------------------------- + Lib.addEvent(element, namespace-type, callback, capture) + Lib.removeEvent(element, namespace-type, callback, capture) + Lib.removeEvents(namespace) + + Lib.cancelEvent(event, preventDefault) ? + + // KeyEvent object for non-FF browsers + Lib.KeyEvent = window.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, + ... + } + +---------------------------------------------------------------------------------------------------- +Lib/Event Module (currently in Lib) +---------------------------------------------------------------------------------------------------- + Lib.noKeyModifiers(event) + + Lib.isControl(event) + Lib.isShift(event) + Lib.isAlt(event) + Lib.isControlShift(event) + + Lib.isLeftClick(event) + Lib.isMiddleClick(event) + Lib.isRightClick(event) + Lib.isControlClick(event) + Lib.isShiftClick(event) + Lib.isAltClick(event) + +---------------------------------------------------------------------------------------------------- +Firebug.Control(context?, element) +---------------------------------------------------------------------------------------------------- + addEvent(namespace-type, callback, capture) + removeEvent(namespace-type, callback, capture) + removeEvents(namespace) + + +---------------------------------------------------------------------------------------------------- +Firebug.Controller(context?, element) +---------------------------------------------------------------------------------------------------- + addController(selector, namespace-type, callback, capture) + removeController(selector, namespace-type, callback, capture) + removeControllers(namespace) + + addKeyController(key, filter, listener, capture, priority?) + removeKeyController(key) + removeKeyControllers() + + addCharController(character, filter, listener, capture, priority?) + removeCharController(character) + removeCharControllers() + +*/ + + + diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/example/helloWorld.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/example/helloWorld.js new file mode 100644 index 00000000000..a3f69aa64ed --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/example/helloWorld.js @@ -0,0 +1,24 @@ +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +// HelloWorld Panel + +function HelloWorldPanel() {} + +HelloWorldPanel.prototype = extend(Firebug.Panel, +{ + name: "HelloWorld", + title: "Hello World!", + + initialize: function() { + Firebug.Panel.initialize.apply(this, arguments); + } +}); + +Firebug.registerPanel(HelloWorldPanel); + +// ************************************************************************************************ +}}); \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/example/pluginSample.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/example/pluginSample.js new file mode 100644 index 00000000000..9543b0d2758 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/example/pluginSample.js @@ -0,0 +1,62 @@ +/* See license.txt for terms of usage */ + +Firebug.extend(function(FBL) { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +// Plugin Module + +Firebug.Plugin = extend(Firebug.Module, +{ + getPanel: function() + { + return Firebug.chrome ? Firebug.chrome.getPanel("Plugin") : null; + }, + + clear: function() + { + alert("clear button clicked"); + this.getPanel().panelNode.innerHTML = ""; + } +}); + + +// ************************************************************************************************ +// Plugin Panel + +function PluginPanel(){}; + +PluginPanel.prototype = extend(Firebug.Panel, +{ + name: "Plugin", + title: "Plugin", + + 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.Plugin, + onClick: Firebug.Plugin.clear + }); + }, + + initialize: function(){ + Firebug.Panel.initialize.apply(this, arguments); + + this.clearButton.initialize(); + } + +}); + +Firebug.registerPanel(PluginPanel); +Firebug.registerModule(Firebug.Plugin); + +// ************************************************************************************************ +}}); \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/firebug.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/firebug.js new file mode 100644 index 00000000000..d4f118d1434 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/firebug.js @@ -0,0 +1,1360 @@ +/* See license.txt for terms of usage */ + +FBL.ns( /** @scope s_firebug */ function() { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +// Globals + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Internals + +var modules = []; +var panelTypes = []; +var panelTypeMap = {}; +var reps = []; + +var parentPanelMap = {}; + + +// ************************************************************************************************ +// Firebug + +/** + * @namespace describe Firebug + * @exports FBL.Firebug as Firebug + */ +FBL.Firebug = +{ + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + version: "Firebug Lite 1.4.0", + revision: "$Revision: 11967 $", + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + modules: modules, + panelTypes: panelTypes, + panelTypeMap: panelTypeMap, + reps: reps, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Initialization + + 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; + + // Document must be cached before chrome initialization + 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; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Registration + + 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; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Reps + + 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); + // TODO: xxxpedro add trace to FBTrace logs like in Firebug + //firebug.trace(); + } + } + } + + 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; + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Preferences + + 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(); + +// xxxpedro should we remove this? +window.Firebug = FBL.Firebug; + +if (!Env.Options.enablePersistent || + Env.Options.enablePersistent && Env.isChromeContext || + Env.isDebugMode) + Env.browser.window.Firebug = FBL.Firebug; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Other methods + +FBL.cacheDocument = function cacheDocument() +{ + var ElementCache = Firebug.Lite.Cache.Element; + var els = Firebug.browser.document.getElementsByTagName("*"); + for (var i=0, l=els.length, el; iFirebug.registerModule method. There is always one instance of a module object + * per browser window. + * @extends Firebug.Listener + */ +Firebug.Module = extend(new Firebug.Listener(), +/** @extend Firebug.Module */ +{ + /** + * Called when the window is opened. + */ + initialize: function() + { + }, + + /** + * Called when the window is closed. + */ + shutdown: function() + { + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + /** + * Called when a new context is created but before the page is loaded. + */ + initContext: function(context) + { + }, + + /** + * Called after a context is detached to a separate window; + */ + reattachContext: function(browser, context) + { + }, + + /** + * Called when a context is destroyed. Module may store info on persistedState for reloaded pages. + */ + destroyContext: function(context, persistedState) + { + }, + + // Called when a FF tab is create or activated (user changes FF tab) + // Called after context is created or with context == null (to abort?) + showContext: function(browser, context) + { + }, + + /** + * Called after a context's page gets DOMContentLoaded + */ + loadedContext: function(context) + { + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + showPanel: function(browser, panel) + { + }, + + showSidePanel: function(browser, panel) + { + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + updateOption: function(name, value) + { + }, + + getObjectByURL: function(context, url) + { + } +}); + +// ************************************************************************************************ +// Panel + +/** + * @panel Base class for all panels. Every derived panel must define a constructor and + * register with "Firebug.registerPanel" method. An instance of the panel + * object is created by the framework for each browser tab where Firebug is activated. + */ +Firebug.Panel = +{ + name: "HelloWorld", + title: "Hello World!", + + parentPanel: null, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + options: { + hasCommandLine: false, + hasStatusBar: false, + hasToolButtons: false, + + // Pre-rendered panels are those included in the skin file (firebug.html) + isPreRendered: false, + innerHTMLSync: false + + /* + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // To be used by external extensions + panelHTML: "", + panelCSS: "", + + toolButtonsHTML: "" + /**/ + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + 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"; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Create Panel + var panelNode = this.panelNode = createElement("div", { + id: panelId, + className: "fbPanel" + }); + + $("fbPanel" + containerSufix).appendChild(panelNode); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Create Panel Tab + var tabHTML = '' + + this.title + ''; + + 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"; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // create ToolButtons + if (options.hasToolButtons) + { + this.toolButtonsNode = createElement("span", { + id: panelId + "Buttons", + className: "fbToolbarButtons" + }); + + $("fbToolbarButtons").appendChild(this.toolButtonsNode); + } + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // create StatusBar + if (options.hasStatusBar) + { + this.statusBarBox = $("fbStatusBarBox"); + + this.statusBarNode = createElement("span", { + id: panelId + "StatusBar", + className: "fbToolbarButtons fbStatusBar" + }); + + this.statusBarBox.appendChild(this.statusBarNode); + } + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // create SidePanel + } + + this.containerNode = this.panelNode.parentNode; + + if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.Panel.create", this.name); + + // xxxpedro contextMenu + this.onContextMenu = bind(this.onContextMenu, this); + + /* + this.context = context; + this.document = doc; + + this.panelNode = doc.createElement("div"); + this.panelNode.ownerPanel = this; + + setClass(this.panelNode, "panelNode panelNode-"+this.name+" contextUID="+context.uid); + doc.body.appendChild(this.panelNode); + + if (FBTrace.DBG_INITIALIZE) + FBTrace.sysout("firebug.initialize panelNode for "+this.name+"\n"); + + this.initializeNode(this.panelNode); + /**/ + }, + + destroy: function(state) // Panel may store info on 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; + + //if (this.panelNode) + // delete this.panelNode.ownerPanel; + + //this.destroyNode(); + }, + + 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; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // restore persistent state + this.containerNode.scrollTop = this.lastScrollTop; + + // xxxpedro contextMenu + addEvent(this.containerNode, "contextmenu", this.onContextMenu); + + + /// TODO: xxxpedro infoTip Hack + 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); + + /// TODO: xxxpedro infoTip Hack + if (Firebug.InfoTip) + Firebug.InfoTip.uninitializeBrowser(Firebug.chrome); + + if (Firebug.chrome.largeCommandLineVisible) + Firebug.chrome.hideLargeCommandLine(); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + if (this.hasSidePanel) + { + // TODO: xxxpedro firebug1.3a6 + // new PanelBar mechanism will need to call shutdown to hide the panels (so it + // doesn't appears in other panel's sidePanelBar. Therefore, we need to implement + // a "remember selected panel" feature in the sidePanelBar + //this.sidePanelBar.shutdown(); + } + + // store persistent state + this.lastScrollTop = this.containerNode.scrollTop; + + // xxxpedro contextMenu + 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) + { + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + /** + * Toolbar helpers + */ + showToolbarButtons: function(buttonsId, show) + { + try + { + if (!this.context.browser) // XXXjjb this is bug. Somehow the panel context is not FirebugContext. + { + 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"); + } + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + /** + * Returns a number indicating the view's ability to inspect the object. + * + * Zero means not supported, and higher numbers indicate specificity. + */ + supportsObject: function(object) + { + return 0; + }, + + hasObject: function(object) // beyond type testing, is this object selectable? + { + 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); + + // TODO: xxxpedro + // XXXjoe This is kind of cheating, but, feh. + //Firebug.chrome.onPanelSelect(object, this); + //if (uiListeners.length > 0) + // dispatch(uiListeners, "onPanelSelect", [object, this]); // TODO: make Firebug.chrome a uiListener + } + }, + + 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) + { + }, + + /** + * Retrieves the search options that this modules supports. + * This is used by the search UI to present the proper options. + */ + getSearchOptionsMenuItems: function() + { + return [ + Firebug.Search.searchOptionMenu("search.Case Sensitive", "searchCaseSensitive") + ]; + }, + + /** + * Navigates to the next document whose match parameter returns true. + */ + navigateToNextDocument: function(match, reverse) + { + // This is an approximation of the UI that is displayed by the location + // selector. This should be close enough, although it may be better + // to simply generate the sorted list within the module, rather than + // sorting within the UI. + 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) { + // For the reverse case we need to implement wrap around. + 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; + } + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + // Called when "Options" clicked. Return array of + // {label: 'name', nol10n: true, type: "checkbox", checked: , command:function to set } + getOptionsMenuItems: function() + { + return null; + }, + + /* + * Called by chrome.onContextMenu to build the context menu when this panel has focus. + * See also FirebugRep for a similar function also called by onContextMenu + * Extensions may monkey patch and chain off this call + * @param object: the 'realObject', a model value, eg a DOM property + * @param target: the HTML element clicked on. + * @return an array of menu items. + */ + 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; + }, + + // An array of objects that can be passed to getObjectLocation. + // The list of things a panel can show, eg sourceFiles. + // Only shown if panel.location defined and supportsObject true + getLocationList: function() + { + return null; + }, + + getDefaultLocation: function() + { + return null; + }, + + getObjectLocation: function(object) + { + return ""; + }, + + // Text for the location list menu eg script panel source file list + // return.path: group/category label, return.name: item label + getObjectDescription: function(object) + { + var url = this.getObjectLocation(object); + return FBL.splitURLBase(url); + }, + + /* + * UI signal that a tab needs attention, eg Script panel is currently stopped on a breakpoint + * @param: show boolean, true turns on. + */ + 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; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Support for Break On Next + + /** + * Called by the framework when the user clicks on the Break On Next button. + * @param {Boolean} armed Set to true if the Break On Next feature is + * to be armed for action and set to false if the Break On Next should be disarmed. + * If 'armed' is true, then the next call to shouldBreakOnNext should be |true|. + */ + breakOnNext: function(armed) + { + }, + + /** + * Called when a panel is selected/displayed. The method should return true + * if the Break On Next feature is currently armed for this panel. + */ + shouldBreakOnNext: function() + { + return false; + }, + + /** + * Returns labels for Break On Next tooltip (one for enabled and one for disabled state). + * @param {Boolean} enabled Set to true if the Break On Next feature is + * currently activated for this panel. + */ + getBreakOnNextTooltip: function(enabled) + { + return null; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + // xxxpedro contextMenu + 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; + + /* + // TODO: xxxpedro move code to somewhere. code to get cross-browser + // window to screen coordinates + var box = Firebug.browser.getElementPosition(Firebug.chrome.node); + + var screenY = 0; + + // Firefox + if (typeof window.mozInnerScreenY != "undefined") + { + screenY = window.mozInnerScreenY; + } + // Chrome + else if (typeof window.innerHeight != "undefined") + { + screenY = window.outerHeight - window.innerHeight; + } + // IE + else if (typeof window.screenTop != "undefined") + { + screenY = window.screenTop; + } + + contextMenu.show(event.screenX-box.left, event.screenY-screenY-box.top); + /**/ + } + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +/** + * MeasureBox + * To get pixels size.width and size.height: + *
  • this.startMeasuring(view);
  • + *
  • var size = this.measureText(lineNoCharsSpacer);
  • + *
  • this.stopMeasuring();
  • + *
+ * + * @namespace + */ +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); + + ///return m ? m[1] : label; + + // if the label is in the "[object TYPE]" format return its type + if (m) + { + return m[1]; + } + // if it is IE we need to handle some special cases + else if ( + // safeToString() fails to recognize some objects in IE + isIE && + // safeToString() returns "[object]" for some objects like window.Image + (label == "[object]" || + // safeToString() returns undefined for some objects like window.clientInformation + typeof object == "object" && typeof label == "undefined") + ) + { + return "Object"; + } + else + { + return label; + } + }, + + getTooltip: function(object) + { + return null; + }, + + getContextMenuItems: function(object, target, context) + { + return []; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Convenience for domplates + + 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"; + } +}); + +// ************************************************************************************************ + + +// ************************************************************************************************ +}}); \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/gui.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/gui.js new file mode 100644 index 00000000000..6bbbf63866b --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/gui.js @@ -0,0 +1,976 @@ +/* See license.txt for terms of usage */ + +FBL.ns( /** @scope s_gui */ function() { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +// Controller + +/**@namespace*/ +FBL.Controller = { + + controllers: null, + controllerContext: null, + + initialize: function(context) + { + this.controllers = []; + this.controllerContext = context || Firebug.chrome; + }, + + shutdown: function() + { + this.removeControllers(); + + //this.controllers = null; + //this.controllerContext = null; + }, + + addController: function() + { + for (var i=0, arg; arg=arguments[i]; i++) + { + // If the first argument is a string, make a selector query + // within the controller node context + if (typeof arg[0] == "string") + { + arg[0] = $$(arg[0], this.controllerContext); + } + + // bind the handler to the proper context + var handler = arg[2]; + arg[2] = bind(handler, this); + // save the original handler as an extra-argument, so we can + // look for it later, when removing a particular controller + 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); + } + } +}; + + +// ************************************************************************************************ +// PanelBar + +/**@namespace*/ +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 ( // normal Panel of the Chrome's PanelBar + !ownerPanel && !p.prototype.parentPanel || + // Child Panel of the current Panel's SidePanelBar + 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){ + + // tab click handler + 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; + } + +}; + +//************************************************************************************************ +// Button + +/** + * options.element + * options.caption + * options.title + * + * options.owner + * options.className + * options.pressedClassName + * + * options.onPress + * options.onUnpress + * options.onClick + * + * @class + * @extends FBL.Controller + * + */ + +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, +/**@extend FBL.Button.prototype*/ +{ + type: "normal", + caption: "caption", + title: null, + + className: "", // custom class + baseClassName: "fbButton", // control class + pressedClassName: "fbBtnPressed", // control pressed class + + element: null, + container: null, + owner: null, + + state: null, + display: null, + + destroy: function() + { + this.shutdown(); + + // only remove if it is a dynamically generated button (not pre-rendered) + 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; + } +}); + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +/** + * @class + * @extends FBL.Button + */ +FBL.IconButton = function() +{ + Button.apply(this, arguments); +}; + +IconButton.prototype = extend(Button.prototype, +/**@extend FBL.IconButton.prototype*/ +{ + baseClassName: "fbIconButton", + pressedClassName: "fbIconPressed" +}); + + +//************************************************************************************************ +// Menu + +var menuItemProps = {"class": "$item.className", type: "$item.type", value: "$item.value", + _command: "$item.command"}; + +if (isIE6) + menuItemProps.href = "javascript:void(0)"; + +// Allow GUI to be loaded even when Domplate module is not installed. +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 0 ? + ('
') : ''; + + // FIXME xxxpedro remove this + //var isIE = false; + + if(isIE && nodeControl) + html.push(nodeControl); + + if (typeof uid != 'undefined') + html.push( + '
', + !isIE && nodeControl ? nodeControl: "", + '<', nodeName, '' + ); + else + html.push( + '
<', + nodeName, '' + ); + + for (var i = 0; i < node.attributes.length; ++i) + { + var attr = node.attributes[i]; + if (!attr.specified || + // Issue 4432: Firebug Lite: HTML is mixed-up with functions + // The problem here is that expando properties added to DOM elements in + // IE < 9 will behave like DOM attributes and so they'll show up when + // looking at element.attributes list. + 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(' ', name, + '="', escapeHTML(value), + '"'); + } + + /* + // source code nodes + if (nodeName == 'script' || nodeName == 'style') + { + + if(document.all){ + var src = node.innerHTML+'\n'; + + }else { + var src = '\n'+node.innerHTML+'\n'; + } + + var match = src.match(/\n/g); + var num = match ? match.length : 0; + var s = [], sl = 0; + + for(var c=1; c' + c + '
'; + } + + html.push('>
', + s.join(''), + '
',
+                            escapeHTML(src),
+                            '
', + '
</', + nodeName, + '>
', + '
' + ); + + + }/**/ + + // Just a single text node child + if (hasSingleTextChild) + { + var value = child[0].nodeValue.replace(reTrim, ''); + if(value) + { + html.push( + '>', + escapeHTML(value), + '</', + nodeName, + '>' + ); + } + else + html.push('/>'); // blank text, print as childless node + + } + else if (childLength > 0) + { + html.push('>'); + } + else + html.push('/>'); + + } + 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' + c + ''; + } + + html.push('
', + s.join(''), + '
',
+                            escapeHTML(src),
+                            '
' + ); + + } + else + { + var value = node.nodeValue.replace(reTrim, ''); + if (value) + html.push('
', escapeHTML(value),'
'); + } + } + } + }, + + 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; + + // FIXME xxxpedro remove this + //var isIE = false; + 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 = '</' + + parentNode.nodeName.toLowerCase() + '>'; + + treeParent.insertBefore(closeElement, treeNext); + + }, + + removeTreeChildren: function(treeNode) + { + var children = treeNode.nextSibling; + var closeTag = children.nextSibling; + + // FIXME xxxpedro remove this + //var isIE = false; + 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); + + // TODO: xxxpedro + if (fbPanel1) + fbPanel1.scrollTop = Math.round(node.offsetTop - fbPanel1.clientHeight/2); + } + +}); + +Firebug.registerModule(Firebug.HTML); + +// ************************************************************************************************ +// HTML Panel + +function HTMLPanel(){}; + +HTMLPanel.prototype = extend(Firebug.Panel, +{ + name: "HTML", + title: "HTML", + + options: { + hasSidePanel: true, + //hasToolButtons: true, + isPreRendered: !Firebug.flexChromeEnabled /* FIXME xxxpedro chromenew */, + 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); + } + + // TODO: xxxpedro + addEvent(fbPanel1, 'mousemove', Firebug.HTML.onListMouseMove); + addEvent($("fbContent"), 'mouseout', Firebug.HTML.onListMouseMove); + addEvent(Firebug.chrome.node, 'mouseout', Firebug.HTML.onListMouseMove); + }, + + shutdown: function() + { + // TODO: xxxpedro + 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() + { + // TODO: panel reattach + 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 ? + // IE return CSS property names in upper case, so we need to convert them + styles.replace(/([^\s]+)\s*:/g, function(m,g){return g.toLowerCase()+":";}) : + // other browsers are just fine + 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); + } +}; + + +// ************************************************************************************************ +// *** TODO: REFACTOR ************************************************************************** +// ************************************************************************************************ +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) // defeat Safari bug + targ = targ.parentNode; + + + if (targ.className.indexOf('nodeControl') != -1 || targ.className == 'nodeTag') + { + // FIXME xxxpedro remove this + //var isIE = false; + + 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; + + //FBL.Firebug.Console.log(treeNode); + + 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') + { + /* + var input = FBL.Firebug.chrome.document.getElementById('treeInput'); + + input.style.display = "block"; + input.style.left = targ.offsetLeft + 'px'; + input.style.top = FBL.topHeight + targ.offsetTop - FBL.fbPanel1.scrollTop + 'px'; + input.style.width = targ.offsetWidth + 6 + 'px'; + input.value = targ.textContent || targ.innerText; + input.focus(); + /**/ + } +}; + +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) // defeat Safari bug + 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) // defeat Safari bug + 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; + /**/ + + 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('', escapeHTML(objectToString(object)), ''); + }, + + appendString: function(object, html) + { + html.push('"', escapeHTML(objectToString(object)), + '"'); + }, + + appendInteger: function(object, html) + { + html.push('', escapeHTML(objectToString(object)), ''); + }, + + appendFloat: function(object, html) + { + html.push('', escapeHTML(objectToString(object)), ''); + }, + + appendFunction: function(object, html) + { + var reName = /function ?(.*?)\(/; + var m = reName.exec(objectToString(object)); + var name = m && m[1] ? m[1] : "function"; + html.push('', escapeHTML(name), '()'); + }, + + appendObject: function(object, html) + { + /* + var rep = Firebug.getRep(object); + var outputs = []; + + rep.tag.tag.compile(); + + var str = rep.tag.renderHTML({object: object}, outputs); + html.push(str); + /**/ + + 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('', m ? m[1] : text, ''); + }, + + appendSelector: function(object, html) + { + var uid = ElementCache(object); + var uidString = uid ? [cacheID, '="', uid, '"'].join("") : ""; + + html.push(''); + + html.push('', escapeHTML(object.nodeName.toLowerCase()), ''); + if (object.id) + html.push('#', escapeHTML(object.id), ''); + if (object.className) + html.push('.', escapeHTML(object.className), ''); + + html.push(''); + }, + + appendNode: function(node, html) + { + if (node.nodeType == 1) + { + var uid = ElementCache(node); + var uidString = uid ? [cacheID, '="', uid, '"'].join("") : ""; + + html.push( + '
', + '', + '<', node.nodeName.toLowerCase(), ''); + + 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(' ', name, + '="', escapeHTML(value), + '"'); + } + + if (node.firstChild) + { + html.push('>
'); + + for (var child = node.firstChild; child; child = child.nextSibling) + this.appendNode(child, html); + + html.push('
</', + node.nodeName.toLowerCase(), '>
'); + } + else + html.push('/>'); + } + else if (node.nodeType == 3) + { + var value = trim(node.nodeValue); + if (value) + html.push('
', escapeHTML(value),'
'); + } + }, + + appendArray: function(object, html) + { + html.push('[ '); + + for (var i = 0, l = object.length, obj; i < l; ++i) + { + this.appendObject(object[i], html); + + if (i < l-1) + html.push(', '); + } + + html.push(' ]'); + } + +}; + + + +// ************************************************************************************************ +}}); \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/i18n.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/i18n.js new file mode 100644 index 00000000000..4c3ae5f07ba --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/i18n.js @@ -0,0 +1,126 @@ +/* See license.txt for terms of usage */ + +FBL.ns( /** @scope s_i18n */ function() { with (FBL) { +// ************************************************************************************************ + +// TODO: xxxpedro localization +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) // then too few parameters for format, assume unformatted. + { + 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; +}; + +// ************************************************************************************************ +}}); \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/inspector.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/inspector.js new file mode 100644 index 00000000000..254e9e0a791 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/inspector.js @@ -0,0 +1,516 @@ +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +// Inspector Module + +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; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Inspect functions + + 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(Firebug.browser.document.documentElement, "mousemove", Firebug.Inspector.onInspectingBody); + + 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"; + + // Avoid inspecting the outline, and the FirebugUI + var id = targ.id; + if (id && /^fbOutline\w$/.test(id)) return; + if (id == "FirebugUI") return; + + // Avoid looking at text nodes in Opera + while (targ.nodeType != 1) targ = targ.parentNode; + + //Firebug.Console.log(targ); + 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"; + + // Avoid inspecting the outline, and the FirebugUI + var id = targ.id; + if (id && /^fbOutline\w$/.test(id)) return; + if (id == "FirebugUI") return; + + // Avoid looking at text nodes in Opera + while (targ.nodeType != 1) targ = targ.parentNode; + + if (targ.nodeName.toLowerCase() == "body") return; + + //Firebug.Console.log(e.clientX, e.clientY, targ); + 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(); + } + }, + + // TODO: xxxpedro remove this? + onInspectingBody: function(e) + { + if (new Date().getTime() - lastInspecting > 30) + { + var targ = e.target; + + // Avoid inspecting the outline, and the FirebugUI + var id = targ.id; + if (id && /^fbOutline\w$/.test(id)) return; + if (id == "FirebugUI") return; + + // Avoid looking at text nodes in Opera + while (targ.nodeType != 1) targ = targ.parentNode; + + if (targ.nodeName.toLowerCase() == "body") return; + + //Firebug.Console.log(e.clientX, e.clientY, targ); + Firebug.Inspector.drawOutline(targ); + + if (ElementCache.has(targ)) + FBL.Firebug.HTML.selectTreeNode(""+ElementCache.key(targ)); + + lastInspecting = new Date().getTime(); + } + }, + + /** + * + * llttttttrr + * llttttttrr + * ll rr + * ll rr + * llbbbbbbrr + * llbbbbbbrr + */ + 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 ? // is *vertical* scrollbar visible + scrollbarSize : 0); + + var freeVerticalSpace = scrollPosition.top + windowSize.height - top - height - + (!isIE && scrollSize.width > windowSize.width ? // is *horizontal* scrollbar visible + 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"; // TODO: on initialize() + 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"; // TODO: on initialize() + + style = o.fbOutlineB.style; + if (freeVerticalSpace > 0) + { + style.top = top+height + "px"; + style.left = left + "px"; + style.width = width + "px"; + //style.height = border + "px"; // TODO: on initialize() or worst case? + } + else + { + style.top = -2*border + "px"; + style.left = -2*border + "px"; + style.width = border + "px"; + //style.height = 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; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Box Model + + drawBoxModel: function(el) + { + // avoid error when the element is not attached a document + if (!el || !el.parentNode) + return; + + var box = Firebug.browser.getElementBox(el); + + var windowSize = Firebug.browser.getWindowSize(); + var scrollPosition = Firebug.browser.getWindowScrollPosition(); + + // element may be occluded by the chrome, when in frame mode + var offsetHeight = Firebug.chrome.type == "frame" ? Firebug.context.persistedState.height : 0; + + // if element box is not inside the viewport, don't draw the box model + 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; + } + +}; + +// ************************************************************************************************ +// Inspector Internals + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Shared variables + + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Internal variables + +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);"; + +//if (Env.Options.enableTrace) inspectFrameStyle = resetStyle + "z-index: 2147483550; top: 0; left: 0; background: #ff0; opacity: 0.05; _filter: alpha(opacity=5);"; + +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() +{ + +}; + +// ************************************************************************************************ +// Section + +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); +}; + +// ************************************************************************************************ +// Section + + + + +// ************************************************************************************************ +}}); \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lib.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lib.js new file mode 100644 index 00000000000..89c37cf290c --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lib.js @@ -0,0 +1,6100 @@ +/*!************************************************************* + * + * 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/ + */ + +/** @namespace describe lib */ + +// FIXME: xxxpedro if we use "var FBL = {}" the FBL won't appear in the DOM Panel in IE +var FBL = {}; + +( /** @scope s_lib @this FBL */ function() { +// ************************************************************************************************ + +// ************************************************************************************************ +// Constants + +var productionDir = "http://getfirebug.com/releases/lite/"; +var bookmarkletVersion = 4; + +// ************************************************************************************************ + +var reNotWhitespace = /[^\s]/; +var reSplitFile = /:\/{1,3}(.*?)\/([^\/]*?)\/?($|\?.*)/; + +// Globals +this.reJavascript = /\s*javascript:\s*(.*)/; +this.reChrome = /chrome:\/\/([^\/]*)\//; +this.reFile = /file:\/\/([^\/]*)\//; + + +// ************************************************************************************************ +// properties + +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; + + +// ************************************************************************************************ +// Namespaces + +var namespaces = []; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +this.ns = function(fn) +{ + var ns = {}; + namespaces.push(fn, ns); + return ns; +}; + +var FBTrace = null; + +this.initialize = function() +{ + // Firebug Lite is already running in persistent mode so we just quit + if (window.firebug && firebug.firebuglite || window.console && console.firebuglite) + return; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // initialize environment + + // point the FBTrace object to the local variable + if (FBL.FBTrace) + FBTrace = FBL.FBTrace; + else + FBTrace = FBL.FBTrace = {}; + + // check if the actual window is a persisted chrome context + var isChromeContext = window.Firebug && typeof window.Firebug.SharedEnv == "object"; + + // chrome context of the persistent application + if (isChromeContext) + { + // TODO: xxxpedro persist - make a better synchronization + sharedEnv = window.Firebug.SharedEnv; + delete window.Firebug.SharedEnv; + + FBL.Env = sharedEnv; + FBL.Env.isChromeContext = true; + FBTrace.messageQueue = FBL.Env.traceMessageQueue; + } + // non-persistent application + 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; + + // find the URL location of the loaded application + findLocation(); + + // TODO: get preferences here... + // The problem is that we don't have the Firebug object yet, so we can't use + // Firebug.loadPrefs. We're using the Store module directly instead. + 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; + } + + // exposes the FBL to the global namespace when in debug mode + if (FBL.Env.isDebugMode) + { + FBL.Env.browser.FBL = FBL; + } + + // check browser compatibilities + 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; + + // after creating/synchronizing the environment, initialize the FBTrace module + if (FBL.Env.Options.enableTrace) FBTrace.initialize(); + + if (FBTrace.DBG_INITIALIZE && isChromeContext) FBTrace.sysout("FBL.initialize - persistent application", "initialize chrome context"); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // initialize namespaces + + 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(); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // finish environment initialization + FBL.Firebug.loadPrefs(); + + if (FBL.Env.Options.enablePersistent) + { + // TODO: xxxpedro persist - make a better synchronization + if (isChromeContext) + { + FBL.FirebugChrome.clone(FBL.Env.FirebugChrome); + } + else + { + FBL.Env.FirebugChrome = FBL.FirebugChrome; + FBL.Env.traceMessageQueue = FBTrace.messageQueue; + } + } + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // wait document load + + waitForDocument(); +}; + +var waitForDocument = function waitForDocument() +{ + // document.body not available in XML+XSL documents in Firefox + 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"); + + // fix IE6 problem with cache of background images, causing a lot of flickering + if (FBL.isIE6) + fixIE6BackgroundImageCache(); + + // chrome context of the persistent application + if (FBL.Env.Options.enablePersistent && FBL.Env.isChromeContext) + { + // finally, start the application in the chrome context + FBL.Firebug.initialize(); + + // if is not development mode, remove the shared environment cache object + // used to synchronize the both persistent contexts + if (!FBL.Env.isDevelopmentMode) + { + sharedEnv.destroy(); + sharedEnv = null; + } + } + // non-persistent application + else + { + FBL.FirebugChrome.create(); + } +}; + +// ************************************************************************************************ +// Env + +var sharedEnv; + +this.Env = +{ + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Env Options (will be transported to Firebug options) + 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 + + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Library location + Location: + { + sourceDir: null, + baseDir: null, + skinDir: null, + skin: null, + app: null + }, + + skin: "xp", + useLocalSkin: false, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Env states + isDevelopmentMode: false, + isDebugMode: false, + isChromeContext: false, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Env references + browser: null, + chrome: null +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var destroyEnvironment = function destroyEnvironment() +{ + setTimeout(function() + { + FBL = null; + }, 100); +}; + +// ************************************************************************************************ +// Library location + +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; + + // Firebug Lite 1.3.0 bookmarklet identification + var script = doc.getElementById("FirebugLite"); + + var scriptSrc; + var hasSrcAttribute = true; + + // If the script was loaded via bookmarklet, we already have the script tag + 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; + } + } + // otherwise we must search for the correct script tag + 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; + } + } + } + + // mark the script tag to be ignored by Firebug Lite + if (script) + script.firebugIgnore = true; + + if (file) + { + var fileName = file[1]; + var fileOptions = file[2]; + + // absolute path + if (reProtocol.test(scriptSrc)) { + path = rePath.exec(scriptSrc)[1]; + + } + // relative path + else + { + var r = rePath.exec(scriptSrc); + var src = r ? r[1] : scriptSrc; + var backDir = /^((?:\.\.\/)+)(.*)/.exec(src); + var reLastDir = /^(.*\/)[^\/]+\/$/; + path = rePath.exec(location.href)[1]; + + // "../some/path" + 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) + { + // "./some/path" + if(/^\.\/./.test(src)) + { + path += src.substring(2); + } + // "/some/path" + else if(/^\/./.test(src)) + { + var domain = /^(\w+:\/\/[^\/]+)/.exec(path); + path = domain[1] + src; + } + // "some/path" + 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) + { + // See Issue 4587 - If we are loading the script from getfirebug.com shortcut, like + // https://getfirebug.com/firebug-lite.js, then we must manually add the full path, + // otherwise the Env.Location will hold the wrong path, which will in turn lead to + // undesirable effects like the problem in Issue 4587 + path += "releases/lite/" + (fileName == "firebug-lite-beta.js" ? "beta/" : "latest/"); + } + + var m = path && path.match(/([^\/]+)\/$/) || null; + + if (path && m) + { + var Env = FBL.Env; + + // Always use the local skin when running in the same domain + // See Issue 3554: Firebug Lite should use local images when loaded locally + Env.useLocalSkin = path.indexOf(location.protocol + "//" + location.host + "/") == 0 && + // but we cannot use the locan skin when loaded from getfirebug.com, otherwise + // the bookmarklet won't work when visiting getfirebug.com + !isGetFirebugSite; + + // detecting development and debug modes via file name + if (fileName == "firebug-lite-dev.js") + { + Env.isDevelopmentMode = true; + Env.isDebugMode = true; + } + else if (fileName == "firebug-lite-debug.js") + { + Env.isDebugMode = true; + } + + // process the + if (Env.browser.document.documentElement.getAttribute("debug") == "true") + { + Env.Options.startOpened = true; + } + + // process the Script URL Options + 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; + } + } + } + + // process the Script JSON Options + 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"); + + // process the Debug Mode + 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"); + } +}; + +// ************************************************************************************************ +// Basics + +this.bind = function() // fn, thisObject, args => thisObject.fn(args, arguments); +{ + var args = cloneArray(arguments), fn = args.shift(), object = args.shift(); + return function() { return fn.apply(object, arrayInsert(cloneArray(args), 0, arguments)); }; +}; + +this.bindFixed = function() // fn, thisObject, args => thisObject.fn(args); +{ + 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) // At least sometimes the keys will be on user-level window objects +{ + var keys = []; + try + { + for (var name in map) // enumeration is safe + keys.push(name); // name is string, safe + } + catch (exc) + { + // Sometimes we get exceptions trying to iterate properties + } + + return keys; // return is safe +}; + +this.values = function(map) +{ + var values = []; + try + { + for (var name in map) + { + try + { + values.push(map[name]); + } + catch (exc) + { + // Sometimes we get exceptions trying to access properties + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("lib.values FAILED ", exc); + } + + } + } + catch (exc) + { + // Sometimes we get exceptions trying to iterate properties + 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) +{ + //TODO: xxxpedro + //var style = doc.createElementNS("http://www.w3.org/1999/xhtml", "style"); + 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); + + //TODO: xxxpedro + //style.innerHTML = this.getResource(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) +{ + // Make sure the stylesheet is not appended twice. + 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 + { + // See issue 1079, the svg test case gives this error + 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; + }; + + +// ************************************************************************************************ +// Whitespace and Entity conversions + +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(0x0022, 'quot', attr, css); +e(0x0026, 'amp', attr, text, css); +e(0x0027, 'apos', css); +e(0x003c, 'lt', attr, text, css); +e(0x003e, 'gt', attr, text, css); +e(0xa9, 'copy', text, editor); +e(0xae, 'reg', text, editor); +e(0x2122, 'trade', text, editor); + +// See http://en.wikipedia.org/wiki/Dash +e(0x2012, '#8210', attr, text, editor); // figure dash +e(0x2013, 'ndash', attr, text, editor); // en dash +e(0x2014, 'mdash', attr, text, editor); // em dash +e(0x2015, '#8213', attr, text, editor); // horizontal bar + +e(0x00a0, 'nbsp', attr, text, white, editor); +e(0x2002, 'ensp', attr, text, white, editor); +e(0x2003, 'emsp', attr, text, white, editor); +e(0x2009, 'thinsp', attr, text, white, editor); +e(0x200c, 'zwnj', attr, text, white, editor); +e(0x200d, 'zwj', attr, text, white, editor); +e(0x200e, 'lrm', attr, text, white, editor); +e(0x200f, 'rlm', attr, text, white, editor); +e(0x200b, '#8203', attr, text, white, editor); // zero-width space (ZWSP) + +//************************************************************************************************ +// Entity escaping + +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]; // faster for special case + } else { + list = {}; // perhaps should print out an error here? + } + 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 (cur == ' ' && list.group == 'whitespace' && last == ' ') // only show for runs of more than one space + // r = ' '; + if (r) + { + results[ri] = { + 'str' : r, + 'class' : list['class'], + 'extra' : list.extra[cur] ? list['class'] + + list.extra[cur] : '' + }; + break; + } + } + // last=cur; + 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('') || ''; +}; + + +// ************************************************************************************************ +// String escaping + +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'); + +// deprecated compatibility functions +//this.deprecateEscapeHTML = createSimpleEscape('text', 'normal'); +//this.deprecatedUnescapeHTML = createSimpleEscape('text', 'reverse'); +//this.escapeHTML = deprecated("use appropriate escapeFor... function", this.deprecateEscapeHTML); +//this.unescapeHTML = deprecated("use appropriate unescapeFor... function", this.deprecatedUnescapeHTML); + +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 + { + // FIXME: xxxpedro this is failing in IE for the global "external" object + 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) + { + // xxxpedro it is not safe to use ob+""? + return ob + ""; + ///return "[an object with no toString() function]"; + } +}; + +// ************************************************************************************************ + +this.hasProperties = function(ob) +{ + try + { + for (var name in ob) + return true; + } catch (exc) {} + return false; +}; + +// ************************************************************************************************ +// String Util + +var reTrim = /^\s+|\s+$/g; +this.trim = function(s) +{ + return s.replace(reTrim, ""); +}; + + +// ************************************************************************************************ +// Empty + +this.emptyFn = function(){}; + + + +// ************************************************************************************************ +// Visibility + +this.isVisible = function(elt) +{ + /* + if (elt instanceof XULElement) + { + //FBTrace.sysout("isVisible elt.offsetWidth: "+elt.offsetWidth+" offsetHeight:"+ elt.offsetHeight+" localName:"+ elt.localName+" nameSpace:"+elt.nameSpaceURI+"\n"); + return (!elt.hidden && !elt.collapsed); + } + /**/ + + 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) +{ + // IE6 doesn't support the [collapsed] CSS selector. IE7 does support the selector, + // but it is causing a bug (the element disappears when you set the "collapsed" + // attribute, but it doesn't appear when you remove the attribute. So, for those + // cases, we need to use the class attribute. + 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 "; + + // IE can't use innerHTML of table elements + if (this.isIE && ignoreTags.indexOf(nodeName) != -1) + this.eraseNode(node); + else + node.innerHTML = ""; +}; + +this.eraseNode = function(node) +{ + while (node.lastChild) + node.removeChild(node.lastChild); +}; + +// ************************************************************************************************ +// Window iteration + +this.iterateWindows = function(win, handler) +{ + if (!win || !win.document) + return; + + handler(win); + + if (win == top || !win.frames) return; // XXXjjb hack for chromeBug + + 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; +}; + +// ************************************************************************************************ +// Graphics + +this.getClientOffset = function(elt) +{ + var addOffset = function addOffset(elt, coords, view) + { + var p = elt.offsetParent; + + ///var style = isIE ? elt.currentStyle : view.getComputedStyle(elt, ""); + var chrome = Firebug.chrome; + + if (elt.offsetLeft) + ///coords.x += elt.offsetLeft + parseInt(style.borderLeftWidth); + coords.x += elt.offsetLeft + chrome.getMeasurementInPixels(elt, "borderLeft"); + if (elt.offsetTop) + ///coords.y += elt.offsetTop + parseInt(style.borderTopWidth); + 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; + // IE will fail when reading the frameElement property of a popup window. + // We don't need it anyway once it is outside the (popup) viewport, so we're + // ignoring the frameElement check when the window is a popup + 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) // {before: int, after: int} +{ + 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); +}; + + +// ************************************************************************************************ +// CSS + +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 ? // Array.indexOf is not available in IE + 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 ? // Array.indexOf is not available in IE + 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; + + // TODO: xxxpedro need to create a FBL.getComputedStyle() because IE + // returns wrong computed styles for inherited properties (like font-*) + // + // Also would be good to create a FBL.getStyle() + 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) +{ + //http://www.w3.org/TR/DOM-Level-2-Style/stylesheets.html#StyleSheets-StyleSheet. For inline style sheets, the value of this attribute is null. + 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; +}; + +/** + * Retrieves the instance number for a given style sheet. The instance number + * is sheet's index within the set of all other sheets whose URL is the same. + */ +this.getInstanceForStyleSheet = function(styleSheet, ownerDocument) +{ + // System URLs are always unique (or at least we are making this assumption) + if (FBL.isSystemStyleSheet(styleSheet)) + return 0; + + // ownerDocument is an optional hint for performance + 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; +}; + +// ************************************************************************************************ +// HTML and XML Serialization + + +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]; + + // Hide attributes set by Firebug + if (attr.localName.indexOf("firebug-") == 0) + continue; + + // MathML + if (attr.localName.indexOf("-moz-math") == 0) + { + // just hide for now + 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(''); + } + else if (isElementSVG(elt) || isElementMathML(elt)) + { + html.push('/>'); + } + else if (self.isSelfClosing(elt)) + { + html.push((isElementXHTML(elt))?'/>':'>'); + } + else + { + html.push('>'); + } + } + else if (elt.nodeType == Node.TEXT_NODE) + html.push(escapeForTextNode(elt.textContent)); + else if (elt.nodeType == Node.CDATA_SECTION_NODE) + html.push(''); + else if (elt.nodeType == Node.COMMENT_NODE) + html.push(''); + } + + 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]; + + // Hide attributes set by Firebug + if (attr.localName.indexOf("firebug-") == 0) + continue; + + // MathML + if (attr.localName.indexOf("-moz-math") == 0) + { + // just hide for now + 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(''); + } + else + xml.push('/>'); + } + else if (elt.nodeType == Node.TEXT_NODE) + xml.push(elt.nodeValue); + else if (elt.nodeType == Node.CDATA_SECTION_NODE) + xml.push(''); + else if (elt.nodeType == Node.COMMENT_NODE) + xml.push(''); + } + + var xml = []; + toXML(element); + return xml.join(""); +}; + + +// ************************************************************************************************ +// CSS classes + +this.hasClass = function(node, name) // className, className, ... +{ + // TODO: xxxpedro when lib.hasClass is called with more than 2 arguments? + // this function can be optimized a lot if assumed 2 arguments only, + // which seems to be what happens 99% of the time + if (arguments.length == 2) + return (' '+node.className+' ').indexOf(' '+name+' ') != -1; + + if (!node || node.nodeType != 1) + return false; + else + { + for (var i=1; i= 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) + ///if (this.hasClass(elt, name)) + 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; + } +}; + + +// ************************************************************************************************ +// DOM queries + +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) // ,classname, classname, classname... +{ + 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) // className, 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; // For non-HTML docs +}; + +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; + } +}; + + +// ************************************************************************************************ +// DOM Modification + +// TODO: xxxpedro use doc fragments in Context API +var appendFragment = null; + +this.appendInnerHTML = function(element, html, referenceElement) +{ + // if undefined, we must convert it to null otherwise it will throw an error in IE + // when executing element.insertBefore(firstChild, referenceElement) + referenceElement = referenceElement || null; + + var doc = element.ownerDocument; + + // doc.createRange not available in IE + if (doc.createRange) + { + var range = doc.createRange(); // a helper object + range.selectNodeContents(element); // the environment to interpret the html + + var fragment = range.createContextualFragment(html); // parse + 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; +}; + + +// ************************************************************************************************ +// DOM creation + +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+")"; + } +}; + +// ************************************************************************************************ +// Events + +this.isLeftClick = function(event) +{ + return (this.isIE && event.type != "click" && event.type != "dblclick" ? + event.button == 1 : // IE "click" and "dblclick" button model + event.button == 0) && // others + this.noKeyModifiers(event); +}; + +this.isMiddleClick = function(event) +{ + return (this.isIE && event.type != "click" && event.type != "dblclick" ? + event.button == 4 : // IE "click" and "dblclick" button model + event.button == 1) && + this.noKeyModifiers(event); +}; + +this.isRightClick = function(event) +{ + return (this.isIE && event.type != "click" && event.type != "dblclick" ? + event.button == 2 : // IE "click" and "dblclick" button model + 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 : // IE "click" and "dblclick" button model + event.button == 0) && + this.isControl(event); +}; + +this.isShiftClick = function(event) +{ + return (this.isIE && event.type != "click" && event.type != "dblclick" ? + event.button == 1 : // IE "click" and "dblclick" button model + 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 : // IE "click" and "dblclick" button model + 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) + { + // Avoid acess denied + } + } +}; + +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) + { + // Avoid acess denied + } + } +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +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); + //FBTrace.dumpProperties(" Exception in lib.dispatch listener", listener); + } + } + /**/ +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var disableTextSelectionHandler = function(event) +{ + FBL.cancelEvent(event, true); + + return false; +}; + +this.disableTextSelection = function(e) +{ + if (typeof e.onselectstart != "undefined") // IE + this.addEvent(e, "selectstart", disableTextSelectionHandler); + + else // others + { + e.style.cssText = "user-select: none; -khtml-user-select: none; -moz-user-select: none;"; + + // canceling the event in FF will prevent the menu popups to close when clicking over + // text-disabled elements + if (!this.isFirefox) + this.addEvent(e, "mousedown", disableTextSelectionHandler); + } + + e.style.cursor = "default"; +}; + +this.restoreTextSelection = function(e) +{ + if (typeof e.onselectstart != "undefined") // IE + this.removeEvent(e, "selectstart", disableTextSelectionHandler); + + else // others + { + e.style.cssText = "cursor: default;"; + + // canceling the event in FF will prevent the menu popups to close when clicking over + // text-disabled elements + if (!this.isFirefox) + this.removeEvent(e, "mousedown", disableTextSelectionHandler); + } +}; + +// ************************************************************************************************ +// DOM Events + +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]; +}; + + +// ************************************************************************************************ +// URLs + +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; // the first 5 chars must be 'data:' + + var point = url.indexOf(',', mark+1); + if (point < mark) + return false; // syntax error + + 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]; + } + + // Additional Firebug-specific properties + if (props.hasOwnProperty('fileName')) + { + var caller_URL = decodeURIComponent(props['fileName']); + var caller_split = this.splitURLTrue(caller_URL); + + if (props.hasOwnProperty('baseLineNumber')) // this means it's probably an eval() + { + 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; + + // Remove query string from the URL if any. + var queryString = url.indexOf("?"); + if (queryString != -1) + url = url.substr(0, queryString); + + // Now get the file extension. + 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; + + // Detect pages for pretty printed XML + 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) + { + // Sometimes documents just aren't ready to be manipulated here, but don't let that + // gum up the works + 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) +{ + // data:text/javascript;fileName=x%2Cy.js;baseLineNumber=10, + 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) // this gets called a lot, any performance improvement welcome +{ + if (!url) + return ""; + // Replace one or more characters that are not forward-slash followed by /.., by space. + if (url.length < 255) // guard against monsters. + { + // Replace one or more characters that are not forward-slash followed by /.., by space. + url = url.replace(/[^\/]+\/\.\.\//, "", "g"); + // Issue 1496, avoid # + url = url.replace(/#.*/,""); + // For some reason, JSDS reports file URLs like "file:/" instead of "file:///", so they + // don't match up with the URLs we get back from the DOM + url = url.replace(/file:\/([^\/])/g, "file:///$1"); + if (url.indexOf('chrome:')==0) + { + var m = reChromeCase.exec(url); // 1 is package name, 2 is path + 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 = []; + + // Unescape '+' characters that are used to encode a space. + // See section 2.2.in RFC 3986: http://www.ietf.org/rfc/rfc3986.txt + 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; +}; + +// TODO: xxxpedro lib. why loops in domplate are requiring array in parameters +// as in response/request headers and get/post parameters in Net module? +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 = []; + + // Unescape '+' characters that are used to encode a space. + // See section 2.2.in RFC 3986: http://www.ietf.org/rfc/rfc3986.txt + 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) +{ + // See if this is a Prototype style *-secure request. + 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]; + } + + // throw on the extra parentheses + jsonString = "(" + jsonString + ")"; + + ///var s = Components.utils.Sandbox(originURL); + var jsonObject = null; + + try + { + ///jsonObject = Components.utils.evalInSandbox(jsonString, s); + + //jsonObject = Firebug.context.eval(jsonString); + jsonObject = Firebug.context.evaluate(jsonString, null, null, function(){return null;}); + } + catch(e) + { + /*** + if (e.message.indexOf("is not defined")) + { + var parts = e.message.split(" "); + s[parts[0]] = function(str){ return str; }; + try { + jsonObject = Components.utils.evalInSandbox(jsonString, s); + } catch(ex) { + if (FBTrace.DBG_ERRORS || FBTrace.DBG_JSONVIEWER) + FBTrace.sysout("jsonviewer.parseJSON EXCEPTION", e); + return null; + } + } + else + {/**/ + 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; + } +}; + +// ************************************************************************************************ +// Input Caret Position + +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(); + } +}; + +// ************************************************************************************************ +// Input Selection Start / Caret Position + +this.getInputSelectionStart = function(input) +{ + if (document.selection) + { + var range = input.ownerDocument.selection.createRange(); + var text = range.text; + + //console.log("range", range.text); + + // if there is a selection, find the start position + if (text) + { + return input.value.indexOf(text); + } + // if there is no selection, find the caret position + else + { + range.moveStart("character", -input.value.length); + + return range.text.length; + } + } + else if (typeof input.selectionStart != "undefined") + return input.selectionStart; + + return 0; +}; + +// ************************************************************************************************ +// Opera Tab Fix + +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) +{ + // Because event objects are destroyed arbitrarily by Gecko, we must make a copy of them to + // represent them long term in the inspector. + for (var name in event) + { + try { + this[name] = event[name]; + } catch (exc) { } + } +} + +this.EventCopy = EventCopy; + + +// ************************************************************************************************ +// Type Checking + +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 + { + // FIXME: xxxpedro this is failing in IE for the global "external" object + 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; + } +}; + + +// ************************************************************************************************ +// Instance Checking + +this.instanceOf = function(object, className) +{ + if (!object || typeof object != "object") + return false; + + // Try to use the native instanceof operator. We can only use it when we know + // exactly the window where the object is located at + if (object.ownerDocument) + { + // find the correct window of the object + var win = object.ownerDocument.defaultView || object.ownerDocument.parentWindow; + + // if the class is accessible in the window, uses the native instanceof operator + // if the instanceof evaluates to "true" we can assume it is a instance, but if it + // evaluates to "false" we must continue with the duck type detection below because + // the native object may be extended, thus breaking the instanceof result + // See Issue 3524: Firebug Lite Style Panel doesn't work if the native Element is extended + if (className in win && object instanceof win[className]) + return true; + } + // If the object doesn't have the ownerDocument property, we'll try to look at + // the current context's window + else + { + // TODO: xxxpedro context + // Since we're not using yet a Firebug.context, we'll just use the top window + // (browser) as a reference + var win = Firebug.browser.window; + if (className in win) + return object instanceof win[className]; + } + + // get the duck type model from the cache + var cache = instanceCheckMap[className]; + if (!cache) + return false; + + // starts the hacky duck type detection + for(var n in cache) + { + var obj = cache[n]; + var type = typeof obj; + obj = type == "object" ? obj : [obj]; + + for(var name in obj) + { + // avoid problems with extended native objects + // See Issue 3524: Firebug Lite Style Panel doesn't work if the native Element is extended + 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 = +{ + // DuckTypeCheck: + // { + // property: ["window", "document"], + // method: "setTimeout", + // value: {nodeType: 1} + // }, + + 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"] + } + +}; + + +// ************************************************************************************************ +// DOM Constants + +/* + +Problems: + + - IE does not have window.Node, window.Element, etc + - for (var name in Node.prototype) return nothing on FF + +*/ + + +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 = domMemberMap2Sandbox[name]; + //object = object.prototype || object; + + 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) + { + //object = object.prototype || object; + + //props = 'addEventListener,document,location,navigator,window'.split(','); + + for (var n in object) + props.push(n); + } + /**/ + + return props; + return extendArray(props, domMemberMap[name]); +}; + +// xxxpedro experimental get DOM members +this.getDOMMembers = function(object) +{ + if (!domMemberCache) + { + FBL.domMemberCache = domMemberCache = {}; + + for (var name in domMemberMap) + { + var builtins = getDomMemberMap2(name); + var cache = domMemberCache[name] = {}; + + /* + if (name.indexOf("Element") != -1) + { + this.append(cache, this.getDOMMembers("Node")); + this.append(cache, this.getDOMMembers("Element")); + } + /**/ + + 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.getDOMMembers = function(object) +{ + if (!domMemberCache) + { + domMemberCache = {}; + + for (var name in domMemberMap) + { + var builtins = domMemberMap[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 (object instanceof Document || object instanceof XMLDocument) + { return domMemberCache.Document; } + else if (object instanceof Location) + { return domMemberCache.Location; } + else if (object instanceof HTMLImageElement) + { return domMemberCache.HTMLImageElement; } + else if (object instanceof HTMLAnchorElement) + { return domMemberCache.HTMLAnchorElement; } + else if (object instanceof HTMLInputElement) + { return domMemberCache.HTMLInputElement; } + else if (object instanceof HTMLButtonElement) + { return domMemberCache.HTMLButtonElement; } + else if (object instanceof HTMLFormElement) + { return domMemberCache.HTMLFormElement; } + else if (object instanceof HTMLBodyElement) + { return domMemberCache.HTMLBodyElement; } + else if (object instanceof HTMLHtmlElement) + { return domMemberCache.HTMLHtmlElement; } + else if (object instanceof HTMLScriptElement) + { return domMemberCache.HTMLScriptElement; } + else if (object instanceof HTMLTableElement) + { return domMemberCache.HTMLTableElement; } + else if (object instanceof HTMLTableRowElement) + { return domMemberCache.HTMLTableRowElement; } + else if (object instanceof HTMLTableCellElement) + { return domMemberCache.HTMLTableCellElement; } + else if (object instanceof HTMLIFrameElement) + { return domMemberCache.HTMLIFrameElement; } + else if (object instanceof SVGSVGElement) + { return domMemberCache.SVGSVGElement; } + else if (object instanceof SVGElement) + { return domMemberCache.SVGElement; } + else if (object instanceof Element) + { return domMemberCache.Element; } + else if (object instanceof Text || object instanceof CDATASection) + { return domMemberCache.Text; } + else if (object instanceof Attr) + { return domMemberCache.Attr; } + else if (object instanceof Node) + { return domMemberCache.Node; } + else if (object instanceof Event || object instanceof EventCopy) + { return domMemberCache.Event; } + else + return {}; + } + catch(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" // FF3 +]; + +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 = +{ // End tags for void elements are forbidden http://wiki.whatwg.org/wiki/HTML_vs._XHTML + "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 + /* + "window": 1, + "browser": 1, + "frame": 1, + "tabbrowser": 1, + "WINDOW": 1, + "BROWSER": 1, + "FRAME": 1, + "TABBROWSER": 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 + }; +} + + +// ************************************************************************************************ +// Ajax + +/** + * @namespace + */ +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; + } + }, + + + /** + * Create a AJAX request. + * + * @name request + * @param {Object} options request options + * @param {String} options.url URL to be requested + * @param {String} options.type Request type ("get" ou "post"). Default is "get". + * @param {Boolean} options.async Asynchronous flag. Default is "true". + * @param {String} options.dataType Data type ("text", "html", "xml" or "json"). Default is "text". + * @param {String} options.contentType Content-type of the data being sent. Default is "application/x-www-form-urlencoded". + * @param {Function} options.onLoading onLoading callback + * @param {Function} options.onLoaded onLoaded callback + * @param {Function} options.onInteractive onInteractive callback + * @param {Function} options.onComplete onComplete callback + * @param {Function} options.onUpdate onUpdate callback + * @param {Function} options.onSuccess onSuccess callback + * @param {Function} options.onFailure onFailure callback + */ + request: function(options) + { + // process options + var o = FBL.extend( + { + // default values + 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; + + // open XHR object + t.open(r.type, r.url, r.async); + + //setRequestHeaders(); + + // indicates that it is a XHR request to the server + t.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + + // if data is being sent, sets the appropriate content-type + if (data = FBL.Ajax.serialize(r.data)) + t.setRequestHeader("Content-Type", r.contentType); + + /** @ignore */ + // onreadystatechange handler + t.onreadystatechange = function() + { + FBL.Ajax.onStateChange(r); + }; + + // send the request + t.send(data); + }, + + /** + * Handles the state change + */ + 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); + } + }, + + /** + * gets the appropriate response value according the type + */ + 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 + ")"); + }, + + /** + * returns the current state of the XHR object + */ + getState: function() + { + return this.states[this.transport.readyState]; + } + +}; + + +// ************************************************************************************************ +// Cookie, from http://www.quirksmode.org/js/cookies.html + +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); +}; + + +// ************************************************************************************************ +// http://www.mister-pixel.com/#Content__state=is_that_simple +var fixIE6BackgroundImageCache = function(doc) +{ + doc = doc || document; + try + { + doc.execCommand("BackgroundImageCache", false, true); + } + catch(E) + { + + } +}; + +// ************************************************************************************************ +// calculatePixelsPerInch + +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() // until 3.1... + { + 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); \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lib/cache.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lib/cache.js new file mode 100644 index 00000000000..6c65f703674 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lib/cache.js @@ -0,0 +1,203 @@ +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + + +// ************************************************************************************************ + +/** + * TODO: if a cached element is cloned, the expando property will be cloned too in IE + * which will result in a bug. Firebug Lite will think the new cloned node is the old + * one. + */ + +var id = "firebug" + new Date().getTime(); +var uniqueKey = 0; +var cacheMap = {}; + +function Cache() +{ + this._ref = {}; +} + +Cache.id = id; + +Cache.prototype = +{ + // load + get: function(key) + { + return this._ref.hasOwnProperty(key) ? + cacheMap[key].object : + null; + }, + + // save + set: function(object) + { + var key = this._getValidatedKey(object); + + if (!key) + { + key = ++uniqueKey; + object[id] = key; + } + + if (this._ref.hasOwnProperty(key)) + this._ref[key]++; + else + this._ref[key] = 1; + + if (cacheMap.hasOwnProperty(key)) + cacheMap[key].ref++; + else + cacheMap[key] = {object: object, data: {}, ref: 1}; + + return key; + }, + + // delete? + unset: function(object) + { + var key = this._getValidatedKey(object); + + if (!key) return; + + var amount = this._ref[key]; + + this._ref[key] -= amount; + cacheMap[key].ref -= amount; + + this.free(object); + }, + + free: function(object) + { + var key = this._getValidatedKey(object); + + if (!key) return; + + if (!this._ref.hasOwnProperty(key)) return; + + if (--this._ref[key] <= 0) + delete this._ref[key]; + + var cache = cacheMap[key]; + if (--cache.ref <= 0) + { + unmarkObject(object); + + cache = cache.object = cache.data = cacheMap[key] = null; + delete cacheMap[key]; + } + }, + + key: function(object) + { + return this._getValidatedKey(object); + }, + + has: function(object) + { + var key = this._getValidatedKey(object); + return key && this._ref.hasOwnProperty(key); + }, + + each: function(callback) + { + var map = this._ref; + + for (var key in map) + { + if (map.hasOwnProperty(key)) + { + callback.call(this, key, this.get(key)); + } + } + }, + + data: function(object, name, value) + { + var key, data; + + if (!name) return null; + + // set data + if (value) + { + key = this.key(object); + + if (!key) return null; + + return cacheMap[key].data[name] = value; + } + // get data + else + { + key = this.key(object); + + if (!key) return null; + + data = cacheMap[key].data; + + return data.hasOwnProperty(name) ? data[name] : null; + } + }, + + clear: function() + { + this.each(function(key, object){ + this.unset(object); + }); + }, + + _getValidatedKey: function(object) + { + var key = object[id]; + + // If a cached element is cloned in IE, the expando property id will be also + // cloned (differently than other browsers) resulting in a bug: Firebug Lite + // will think the new cloned node is the old one. To prevent this problem we're + // checking if the cached element matches the given element. + if ( + //!supportsDeleteExpando && // the problem happens when supportsDeleteExpando is false + key && // the element has the expando property + cacheMap.hasOwnProperty(key) && // there is a cached element with the same key + cacheMap[key].object !== object // but it is a different element than the current one + ) + { + // remove the problematic property + unmarkObject(object); + + key = null; + } + + return key; + } +}; + + +function unmarkObject(object) +{ + try + { + delete object[id]; + } + catch(e) + { + if (object.removeAttribute) + object.removeAttribute(id); + else + object[id] = null; + } +} + +// ************************************************************************************************ + +// xxxpedro exposing variables for debugging +window.cacheMap = cacheMap ; +window.Cache = Cache; + +// ************************************************************************************************ +}}); diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lite.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lite.js new file mode 100644 index 00000000000..17f40937328 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lite.js @@ -0,0 +1,11 @@ +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +Firebug.Lite = +{ +}; + +// ************************************************************************************************ +}}); diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lite/browser.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lite/browser.js new file mode 100644 index 00000000000..dd7812cf756 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lite/browser.js @@ -0,0 +1,27 @@ +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + + +Firebug.Lite.Browser = function(window) +{ + this.contentWindow = window; + this.contentDocument = window.document; + this.currentURI = + { + spec: window.location.href + }; +}; + +Firebug.Lite.Browser.prototype = +{ + toString: function() + { + return "Firebug.Lite.Browser"; + } +}; + + +// ************************************************************************************************ +}}); diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lite/cache.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lite/cache.js new file mode 100644 index 00000000000..319aa0e0533 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lite/cache.js @@ -0,0 +1,180 @@ +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +Firebug.Lite.Cache = +{ + ID: "firebug-" + new Date().getTime() +}; + +// ************************************************************************************************ + +/** + * TODO: if a cached element is cloned, the expando property will be cloned too in IE + * which will result in a bug. Firebug Lite will think the new cloned node is the old + * one. + * + * TODO: Investigate a possibility of cache validation, to be customized by each + * kind of cache. For ElementCache it should validate if the element still is + * inserted at the DOM. + */ +var cacheUID = 0; +var createCache = function() +{ + var map = {}; + var data = {}; + + var CID = Firebug.Lite.Cache.ID; + + // better detection + var supportsDeleteExpando = !document.all; + + var cacheFunction = function(element) + { + return cacheAPI.set(element); + }; + + var cacheAPI = + { + get: function(key) + { + return map.hasOwnProperty(key) ? + map[key] : + null; + }, + + set: function(element) + { + var id = getValidatedKey(element); + + if (!id) + { + id = ++cacheUID; + element[CID] = id; + } + + if (!map.hasOwnProperty(id)) + { + map[id] = element; + data[id] = {}; + } + + return id; + }, + + unset: function(element) + { + var id = getValidatedKey(element); + + if (!id) return; + + if (supportsDeleteExpando) + { + delete element[CID]; + } + else if (element.removeAttribute) + { + element.removeAttribute(CID); + } + + delete map[id]; + delete data[id]; + + }, + + key: function(element) + { + return getValidatedKey(element); + }, + + has: function(element) + { + var id = getValidatedKey(element); + return id && map.hasOwnProperty(id); + }, + + each: function(callback) + { + for (var key in map) + { + if (map.hasOwnProperty(key)) + { + callback(key, map[key]); + } + } + }, + + data: function(element, name, value) + { + // set data + if (value) + { + if (!name) return null; + + var id = cacheAPI.set(element); + + return data[id][name] = value; + } + // get data + else + { + var id = cacheAPI.key(element); + + return data.hasOwnProperty(id) && data[id].hasOwnProperty(name) ? + data[id][name] : + null; + } + }, + + clear: function() + { + for (var id in map) + { + var element = map[id]; + cacheAPI.unset(element); + } + } + }; + + var getValidatedKey = function(element) + { + var id = element[CID]; + + // If a cached element is cloned in IE, the expando property CID will be also + // cloned (differently than other browsers) resulting in a bug: Firebug Lite + // will think the new cloned node is the old one. To prevent this problem we're + // checking if the cached element matches the given element. + if ( + !supportsDeleteExpando && // the problem happens when supportsDeleteExpando is false + id && // the element has the expando property + map.hasOwnProperty(id) && // there is a cached element with the same id + map[id] != element // but it is a different element than the current one + ) + { + // remove the problematic property + element.removeAttribute(CID); + + id = null; + } + + return id; + }; + + FBL.append(cacheFunction, cacheAPI); + + return cacheFunction; +}; + +// ************************************************************************************************ + +// TODO: xxxpedro : check if we need really this on FBL scope +Firebug.Lite.Cache.StyleSheet = createCache(); +Firebug.Lite.Cache.Element = createCache(); + +// TODO: xxxpedro +Firebug.Lite.Cache.Event = createCache(); + + +// ************************************************************************************************ +}}); diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lite/proxy.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lite/proxy.js new file mode 100644 index 00000000000..f9135f697b1 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lite/proxy.js @@ -0,0 +1,134 @@ +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +var sourceMap = {}; + +// ************************************************************************************************ +Firebug.Lite.Proxy = +{ + // jsonp callbacks + _callbacks: {}, + + /** + * Load a resource, either locally (directly) or externally (via proxy) using + * synchronous XHR calls. Loading external resources requires the proxy plugin to + * be installed and configured (see /plugin/proxy/proxy.php). + */ + load: function(url) + { + var resourceDomain = getDomain(url); + var isLocalResource = + // empty domain means local URL + !resourceDomain || + // same domain means local too + resourceDomain == Firebug.context.window.location.host; // TODO: xxxpedro context + + return isLocalResource ? fetchResource(url) : fetchProxyResource(url); + }, + + /** + * Load a resource using JSONP technique. + */ + loadJSONP: function(url, callback) + { + var script = createGlobalElement("script"), + doc = Firebug.context.document, + + uid = "" + new Date().getTime(), + callbackName = "callback=Firebug.Lite.Proxy._callbacks." + uid, + + jsonpURL = url.indexOf("?") != -1 ? + url + "&" + callbackName : + url + "?" + callbackName; + + Firebug.Lite.Proxy._callbacks[uid] = function(data) + { + if (callback) + callback(data); + + script.parentNode.removeChild(script); + delete Firebug.Lite.Proxy._callbacks[uid]; + }; + + script.src = jsonpURL; + + if (doc.documentElement) + doc.documentElement.appendChild(script); + }, + + /** + * Load a resource using YQL (not reliable). + */ + YQL: function(url, callback) + { + var yql = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22" + + encodeURIComponent(url) + "%22&format=xml"; + + this.loadJSONP(yql, function(data) + { + var source = data.results[0]; + + // clean up YQL bogus elements + var match = /\s+

([\s\S]+)<\/p>\s+<\/body>$/.exec(source); + if (match) + source = match[1]; + + console.log(source); + }); + } +}; + +// ************************************************************************************************ + +Firebug.Lite.Proxy.fetchResourceDisabledMessage = + "/* Firebug Lite resource fetching is disabled.\n" + + "To enabled it set the Firebug Lite option \"disableResourceFetching\" to \"false\".\n" + + "More 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]; + + // Getting the native XHR object so our calls won't be logged in the Console Panel + 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; +}; + + +// ************************************************************************************************ +}}); diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lite/script.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lite/script.js new file mode 100644 index 00000000000..4ce53c0a0e4 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lite/script.js @@ -0,0 +1,31 @@ +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +Firebug.Lite.Script = function(window) +{ + this.fileName = null; + this.isValid = null; + this.baseLineNumber = null; + this.lineExtent = null; + this.tag = null; + + this.functionName = null; + this.functionSource = null; +}; + +Firebug.Lite.Script.prototype = +{ + isLineExecutable: function(){}, + pcToLine: function(){}, + lineToPc: function(){}, + + toString: function() + { + return "Firebug.Lite.Script"; + } +}; + +// ************************************************************************************************ +}}); diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lite/style.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lite/style.js new file mode 100644 index 00000000000..5bec86c9eb4 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/lite/style.js @@ -0,0 +1,11 @@ +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +Firebug.Lite.Style = +{ +}; + +// ************************************************************************************************ +}}); diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/plugin.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/plugin.js new file mode 100644 index 00000000000..59f1e321aa7 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/plugin.js @@ -0,0 +1,95 @@ +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +// Globals + +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); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Registration + + 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) + { + // TODO: xxxpedro investigate why Dev Panel throws an error + 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); + + // tab click handler + 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); + } + +}); + + + + +// ************************************************************************************************ +}}); \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/script.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/script.js new file mode 100644 index 00000000000..e10dd8892df --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/script.js @@ -0,0 +1,301 @@ +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +// Script Module + +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); + + +// ************************************************************************************************ +// Script Panel + +function ScriptPanel(){}; + +ScriptPanel.prototype = extend(Firebug.Panel, +{ + name: "Script", + title: "Script", + + selectIndex: 0, // index of the current selectNode's option + sourceIndex: -1, // index of the script node, based in doc.getElementsByTagName("script") + + 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++) + { + // Don't show Firebug Lite source code in the list of options + 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() + { + // we must render the code first, so the persistent state can be restore + 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' : // IE put an extra line when reading source of local resources + '\n'+src; + + // find the number of lines of code + src = src.replace(/\n\r|\r\n/g, "\n"); + var match = src.match(/[\n]/g); + var lines=match ? match.length : 0; + + // render the full source code + line numbers html + html[hl++] = '

';
+                html[hl++] = escapeHTML(src);
+                html[hl++] = '
'; + + // render the line number divs + for(var l=1, lines; l<=lines; l++) + { + html[hl++] = '
'; + html[hl++] = l; + html[hl++] = '
'; + } + + html[hl++] = '
'; + + updatePanel(html); + }; + + var updatePanel = function(html) + { + self.panelNode.innerHTML = html.join(""); + + // IE needs this timeout, otherwise the panel won't scroll + 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]; + + // absolute path + if (reProtocol.test(script.src)) { + path = rePath.exec(script.src)[1]; + + } + // relative path + 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]; + + // "../some/path" + 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) + { + // "./some/path" + if(/^\.\/./.test(src)) + { + path += src.substring(2); + } + // "/some/path" + else if(/^\/./.test(src)) + { + var domain = /^(\w+:\/\/[^\/]+)/.exec(path); + path = domain[1] + src; + } + // "some/path" + 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; +}; + + +// ************************************************************************************************ +}}); \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/selector.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/selector.js new file mode 100644 index 00000000000..2a3ce1cedf2 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/selector.js @@ -0,0 +1,1031 @@ +/* See license.txt for terms of usage */ + +FBL.ns( /**@scope s_selector*/ function() { with (FBL) { +// ************************************************************************************************ + +/* + * Sizzle CSS Selector Engine - v1.0 + * Copyright 2009, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ + +var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, + done = 0, + toString = Object.prototype.toString, + hasDuplicate = false, + baseHasDuplicate = true; + +// Here we check if the JavaScript engine is using some sort of +// optimization where it does not always call our comparision +// function. If that is the case, discard the hasDuplicate value. +// Thus far that includes Google Chrome. +[0, 0].sort(function(){ + baseHasDuplicate = false; + return 0; +}); + +/** + * @name Firebug.Selector + * @namespace + */ + +/** + * @exports Sizzle as Firebug.Selector + */ +var Sizzle = function(selector, context, results, seed) { + results = results || []; + var origContext = context = context || document; + + if ( context.nodeType !== 1 && context.nodeType !== 9 ) { + return []; + } + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + var parts = [], m, set, checkSet, check, mode, extra, prune = true, contextXML = isXML(context), + soFar = selector; + + // Reset the position of the chunker regexp (start from head) + while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) { + soFar = m[3]; + + parts.push( m[1] ); + + if ( m[2] ) { + extra = m[3]; + break; + } + } + + if ( parts.length > 1 && origPOS.exec( selector ) ) { + if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { + set = posProcess( parts[0] + parts[1], context ); + } else { + set = Expr.relative[ parts[0] ] ? + [ context ] : + Sizzle( parts.shift(), context ); + + while ( parts.length ) { + selector = parts.shift(); + + if ( Expr.relative[ selector ] ) + selector += parts.shift(); + + set = posProcess( selector, set ); + } + } + } else { + // Take a shortcut and set the context if the root selector is an ID + // (but not if it'll be faster if the inner selector is an ID) + if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && + Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { + var ret = Sizzle.find( parts.shift(), context, contextXML ); + context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0]; + } + + if ( context ) { + var ret = seed ? + { expr: parts.pop(), set: makeArray(seed) } : + Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); + set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set; + + if ( parts.length > 0 ) { + checkSet = makeArray(set); + } else { + prune = false; + } + + while ( parts.length ) { + var cur = parts.pop(), pop = cur; + + if ( !Expr.relative[ cur ] ) { + cur = ""; + } else { + pop = parts.pop(); + } + + if ( pop == null ) { + pop = context; + } + + Expr.relative[ cur ]( checkSet, pop, contextXML ); + } + } else { + checkSet = parts = []; + } + } + + if ( !checkSet ) { + checkSet = set; + } + + if ( !checkSet ) { + throw "Syntax error, unrecognized expression: " + (cur || selector); + } + + if ( toString.call(checkSet) === "[object Array]" ) { + if ( !prune ) { + results.push.apply( results, checkSet ); + } else if ( context && context.nodeType === 1 ) { + for ( var i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) { + results.push( set[i] ); + } + } + } else { + for ( var i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && checkSet[i].nodeType === 1 ) { + results.push( set[i] ); + } + } + } + } else { + makeArray( checkSet, results ); + } + + if ( extra ) { + Sizzle( extra, origContext, results, seed ); + Sizzle.uniqueSort( results ); + } + + return results; +}; + +Sizzle.uniqueSort = function(results){ + if ( sortOrder ) { + hasDuplicate = baseHasDuplicate; + results.sort(sortOrder); + + if ( hasDuplicate ) { + for ( var i = 1; i < results.length; i++ ) { + if ( results[i] === results[i-1] ) { + results.splice(i--, 1); + } + } + } + } + + return results; +}; + +Sizzle.matches = function(expr, set){ + return Sizzle(expr, null, null, set); +}; + +Sizzle.find = function(expr, context, isXML){ + var set, match; + + if ( !expr ) { + return []; + } + + for ( var i = 0, l = Expr.order.length; i < l; i++ ) { + var type = Expr.order[i], match; + + if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { + var left = match[1]; + match.splice(1,1); + + if ( left.substr( left.length - 1 ) !== "\\" ) { + match[1] = (match[1] || "").replace(/\\/g, ""); + set = Expr.find[ type ]( match, context, isXML ); + if ( set != null ) { + expr = expr.replace( Expr.match[ type ], "" ); + break; + } + } + } + } + + if ( !set ) { + set = context.getElementsByTagName("*"); + } + + return {set: set, expr: expr}; +}; + +Sizzle.filter = function(expr, set, inplace, not){ + var old = expr, result = [], curLoop = set, match, anyFound, + isXMLFilter = set && set[0] && isXML(set[0]); + + while ( expr && set.length ) { + for ( var type in Expr.filter ) { + if ( (match = Expr.match[ type ].exec( expr )) != null ) { + var filter = Expr.filter[ type ], found, item; + anyFound = false; + + if ( curLoop == result ) { + result = []; + } + + if ( Expr.preFilter[ type ] ) { + match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); + + if ( !match ) { + anyFound = found = true; + } else if ( match === true ) { + continue; + } + } + + if ( match ) { + for ( var i = 0; (item = curLoop[i]) != null; i++ ) { + if ( item ) { + found = filter( item, match, i, curLoop ); + var pass = not ^ !!found; + + if ( inplace && found != null ) { + if ( pass ) { + anyFound = true; + } else { + curLoop[i] = false; + } + } else if ( pass ) { + result.push( item ); + anyFound = true; + } + } + } + } + + if ( found !== undefined ) { + if ( !inplace ) { + curLoop = result; + } + + expr = expr.replace( Expr.match[ type ], "" ); + + if ( !anyFound ) { + return []; + } + + break; + } + } + } + + // Improper expression + if ( expr == old ) { + if ( anyFound == null ) { + throw "Syntax error, unrecognized expression: " + expr; + } else { + break; + } + } + + old = expr; + } + + return curLoop; +}; + +/**#@+ @ignore */ +var Expr = Sizzle.selectors = { + order: [ "ID", "NAME", "TAG" ], + match: { + ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/, + CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/, + NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/, + ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/, + TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/, + CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/, + POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/, + PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/ + }, + leftMatch: {}, + attrMap: { + "class": "className", + "for": "htmlFor" + }, + attrHandle: { + href: function(elem){ + return elem.getAttribute("href"); + } + }, + relative: { + "+": function(checkSet, part, isXML){ + var isPartStr = typeof part === "string", + isTag = isPartStr && !/\W/.test(part), + isPartStrNotTag = isPartStr && !isTag; + + if ( isTag && !isXML ) { + part = part.toUpperCase(); + } + + for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { + if ( (elem = checkSet[i]) ) { + while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} + + checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ? + elem || false : + elem === part; + } + } + + if ( isPartStrNotTag ) { + Sizzle.filter( part, checkSet, true ); + } + }, + ">": function(checkSet, part, isXML){ + var isPartStr = typeof part === "string"; + + if ( isPartStr && !/\W/.test(part) ) { + part = isXML ? part : part.toUpperCase(); + + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + if ( elem ) { + var parent = elem.parentNode; + checkSet[i] = parent.nodeName === part ? parent : false; + } + } + } else { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + if ( elem ) { + checkSet[i] = isPartStr ? + elem.parentNode : + elem.parentNode === part; + } + } + + if ( isPartStr ) { + Sizzle.filter( part, checkSet, true ); + } + } + }, + "": function(checkSet, part, isXML){ + var doneName = done++, checkFn = dirCheck; + + if ( !/\W/.test(part) ) { + var nodeCheck = part = isXML ? part : part.toUpperCase(); + checkFn = dirNodeCheck; + } + + checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML); + }, + "~": function(checkSet, part, isXML){ + var doneName = done++, checkFn = dirCheck; + + if ( typeof part === "string" && !/\W/.test(part) ) { + var nodeCheck = part = isXML ? part : part.toUpperCase(); + checkFn = dirNodeCheck; + } + + checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML); + } + }, + find: { + ID: function(match, context, isXML){ + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + return m ? [m] : []; + } + }, + NAME: function(match, context, isXML){ + if ( typeof context.getElementsByName !== "undefined" ) { + var ret = [], results = context.getElementsByName(match[1]); + + for ( var i = 0, l = results.length; i < l; i++ ) { + if ( results[i].getAttribute("name") === match[1] ) { + ret.push( results[i] ); + } + } + + return ret.length === 0 ? null : ret; + } + }, + TAG: function(match, context){ + return context.getElementsByTagName(match[1]); + } + }, + preFilter: { + CLASS: function(match, curLoop, inplace, result, not, isXML){ + match = " " + match[1].replace(/\\/g, "") + " "; + + if ( isXML ) { + return match; + } + + for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { + if ( elem ) { + if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) { + if ( !inplace ) + result.push( elem ); + } else if ( inplace ) { + curLoop[i] = false; + } + } + } + + return false; + }, + ID: function(match){ + return match[1].replace(/\\/g, ""); + }, + TAG: function(match, curLoop){ + for ( var i = 0; curLoop[i] === false; i++ ){} + return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase(); + }, + CHILD: function(match){ + if ( match[1] == "nth" ) { + // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' + var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec( + match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" || + !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); + + // calculate the numbers (first)n+(last) including if they are negative + match[2] = (test[1] + (test[2] || 1)) - 0; + match[3] = test[3] - 0; + } + + // TODO: Move to normal caching system + match[0] = done++; + + return match; + }, + ATTR: function(match, curLoop, inplace, result, not, isXML){ + var name = match[1].replace(/\\/g, ""); + + if ( !isXML && Expr.attrMap[name] ) { + match[1] = Expr.attrMap[name]; + } + + if ( match[2] === "~=" ) { + match[4] = " " + match[4] + " "; + } + + return match; + }, + PSEUDO: function(match, curLoop, inplace, result, not){ + if ( match[1] === "not" ) { + // If we're dealing with a complex expression, or a simple one + if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { + match[3] = Sizzle(match[3], null, null, curLoop); + } else { + var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); + if ( !inplace ) { + result.push.apply( result, ret ); + } + return false; + } + } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { + return true; + } + + return match; + }, + POS: function(match){ + match.unshift( true ); + return match; + } + }, + filters: { + enabled: function(elem){ + return elem.disabled === false && elem.type !== "hidden"; + }, + disabled: function(elem){ + return elem.disabled === true; + }, + checked: function(elem){ + return elem.checked === true; + }, + selected: function(elem){ + // Accessing this property makes selected-by-default + // options in Safari work properly + elem.parentNode.selectedIndex; + return elem.selected === true; + }, + parent: function(elem){ + return !!elem.firstChild; + }, + empty: function(elem){ + return !elem.firstChild; + }, + has: function(elem, i, match){ + return !!Sizzle( match[3], elem ).length; + }, + header: function(elem){ + return /h\d/i.test( elem.nodeName ); + }, + text: function(elem){ + return "text" === elem.type; + }, + radio: function(elem){ + return "radio" === elem.type; + }, + checkbox: function(elem){ + return "checkbox" === elem.type; + }, + file: function(elem){ + return "file" === elem.type; + }, + password: function(elem){ + return "password" === elem.type; + }, + submit: function(elem){ + return "submit" === elem.type; + }, + image: function(elem){ + return "image" === elem.type; + }, + reset: function(elem){ + return "reset" === elem.type; + }, + button: function(elem){ + return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON"; + }, + input: function(elem){ + return /input|select|textarea|button/i.test(elem.nodeName); + } + }, + setFilters: { + first: function(elem, i){ + return i === 0; + }, + last: function(elem, i, match, array){ + return i === array.length - 1; + }, + even: function(elem, i){ + return i % 2 === 0; + }, + odd: function(elem, i){ + return i % 2 === 1; + }, + lt: function(elem, i, match){ + return i < match[3] - 0; + }, + gt: function(elem, i, match){ + return i > match[3] - 0; + }, + nth: function(elem, i, match){ + return match[3] - 0 == i; + }, + eq: function(elem, i, match){ + return match[3] - 0 == i; + } + }, + filter: { + PSEUDO: function(elem, match, i, array){ + var name = match[1], filter = Expr.filters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + } else if ( name === "contains" ) { + return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0; + } else if ( name === "not" ) { + var not = match[3]; + + for ( var i = 0, l = not.length; i < l; i++ ) { + if ( not[i] === elem ) { + return false; + } + } + + return true; + } + }, + CHILD: function(elem, match){ + var type = match[1], node = elem; + switch (type) { + case 'only': + case 'first': + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) return false; + } + if ( type == 'first') return true; + node = elem; + case 'last': + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) return false; + } + return true; + case 'nth': + var first = match[2], last = match[3]; + + if ( first == 1 && last == 0 ) { + return true; + } + + var doneName = match[0], + parent = elem.parentNode; + + if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) { + var count = 0; + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + node.nodeIndex = ++count; + } + } + parent.sizcache = doneName; + } + + var diff = elem.nodeIndex - last; + if ( first == 0 ) { + return diff == 0; + } else { + return ( diff % first == 0 && diff / first >= 0 ); + } + } + }, + ID: function(elem, match){ + return elem.nodeType === 1 && elem.getAttribute("id") === match; + }, + TAG: function(elem, match){ + return (match === "*" && elem.nodeType === 1) || elem.nodeName === match; + }, + CLASS: function(elem, match){ + return (" " + (elem.className || elem.getAttribute("class")) + " ") + .indexOf( match ) > -1; + }, + ATTR: function(elem, match){ + var name = match[1], + result = Expr.attrHandle[ name ] ? + Expr.attrHandle[ name ]( elem ) : + elem[ name ] != null ? + elem[ name ] : + elem.getAttribute( name ), + value = result + "", + type = match[2], + check = match[4]; + + return result == null ? + type === "!=" : + type === "=" ? + value === check : + type === "*=" ? + value.indexOf(check) >= 0 : + type === "~=" ? + (" " + value + " ").indexOf(check) >= 0 : + !check ? + value && result !== false : + type === "!=" ? + value != check : + type === "^=" ? + value.indexOf(check) === 0 : + type === "$=" ? + value.substr(value.length - check.length) === check : + type === "|=" ? + value === check || value.substr(0, check.length + 1) === check + "-" : + false; + }, + POS: function(elem, match, i, array){ + var name = match[2], filter = Expr.setFilters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + } + } + } +}; + +var origPOS = Expr.match.POS; + +for ( var type in Expr.match ) { + Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source ); + Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source ); +} + +var makeArray = function(array, results) { + array = Array.prototype.slice.call( array, 0 ); + + if ( results ) { + results.push.apply( results, array ); + return results; + } + + return array; +}; + +// Perform a simple check to determine if the browser is capable of +// converting a NodeList to an array using builtin methods. +try { + Array.prototype.slice.call( document.documentElement.childNodes, 0 ); + +// Provide a fallback method if it does not work +} catch(e){ + makeArray = function(array, results) { + var ret = results || []; + + if ( toString.call(array) === "[object Array]" ) { + Array.prototype.push.apply( ret, array ); + } else { + if ( typeof array.length === "number" ) { + for ( var i = 0, l = array.length; i < l; i++ ) { + ret.push( array[i] ); + } + } else { + for ( var i = 0; array[i]; i++ ) { + ret.push( array[i] ); + } + } + } + + return ret; + }; +} + +var sortOrder; + +if ( document.documentElement.compareDocumentPosition ) { + sortOrder = function( a, b ) { + if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { + if ( a == b ) { + hasDuplicate = true; + } + return 0; + } + + var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1; + if ( ret === 0 ) { + hasDuplicate = true; + } + return ret; + }; +} else if ( "sourceIndex" in document.documentElement ) { + sortOrder = function( a, b ) { + if ( !a.sourceIndex || !b.sourceIndex ) { + if ( a == b ) { + hasDuplicate = true; + } + return 0; + } + + var ret = a.sourceIndex - b.sourceIndex; + if ( ret === 0 ) { + hasDuplicate = true; + } + return ret; + }; +} else if ( document.createRange ) { + sortOrder = function( a, b ) { + if ( !a.ownerDocument || !b.ownerDocument ) { + if ( a == b ) { + hasDuplicate = true; + } + return 0; + } + + var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange(); + aRange.setStart(a, 0); + aRange.setEnd(a, 0); + bRange.setStart(b, 0); + bRange.setEnd(b, 0); + var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange); + if ( ret === 0 ) { + hasDuplicate = true; + } + return ret; + }; +} + +// Check to see if the browser returns elements by name when +// querying by getElementById (and provide a workaround) +(function(){ + // We're going to inject a fake input element with a specified name + var form = document.createElement("div"), + id = "script" + (new Date).getTime(); + form.innerHTML = ""; + + // Inject it into the root element, check its status, and remove it quickly + var root = document.documentElement; + root.insertBefore( form, root.firstChild ); + + // The workaround has to do additional checks after a getElementById + // Which slows things down for other browsers (hence the branching) + if ( !!document.getElementById( id ) ) { + Expr.find.ID = function(match, context, isXML){ + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : []; + } + }; + + Expr.filter.ID = function(elem, match){ + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + return elem.nodeType === 1 && node && node.nodeValue === match; + }; + } + + root.removeChild( form ); + root = form = null; // release memory in IE +})(); + +(function(){ + // Check to see if the browser returns only elements + // when doing getElementsByTagName("*") + + // Create a fake element + var div = document.createElement("div"); + div.appendChild( document.createComment("") ); + + // Make sure no comments are found + if ( div.getElementsByTagName("*").length > 0 ) { + Expr.find.TAG = function(match, context){ + var results = context.getElementsByTagName(match[1]); + + // Filter out possible comments + if ( match[1] === "*" ) { + var tmp = []; + + for ( var i = 0; results[i]; i++ ) { + if ( results[i].nodeType === 1 ) { + tmp.push( results[i] ); + } + } + + results = tmp; + } + + return results; + }; + } + + // Check to see if an attribute returns normalized href attributes + div.innerHTML = ""; + if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && + div.firstChild.getAttribute("href") !== "#" ) { + Expr.attrHandle.href = function(elem){ + return elem.getAttribute("href", 2); + }; + } + + div = null; // release memory in IE +})(); + +if ( document.querySelectorAll ) (function(){ + var oldSizzle = Sizzle, div = document.createElement("div"); + div.innerHTML = "

"; + + // Safari can't handle uppercase or unicode characters when + // in quirks mode. + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function(query, context, extra, seed){ + context = context || document; + + // Only use querySelectorAll on non-XML documents + // (ID selectors don't work in non-HTML documents) + if ( !seed && context.nodeType === 9 && !isXML(context) ) { + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(e){} + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; + } + + div = null; // release memory in IE +})(); + +if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){ + var div = document.createElement("div"); + div.innerHTML = "
"; + + // Opera can't find a second classname (in 9.6) + if ( div.getElementsByClassName("e").length === 0 ) + return; + + // Safari caches class attributes, doesn't catch changes (in 3.2) + div.lastChild.className = "e"; + + if ( div.getElementsByClassName("e").length === 1 ) + return; + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS = function(match, context, isXML) { + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { + return context.getElementsByClassName(match[1]); + } + }; + + div = null; // release memory in IE +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + var sibDir = dir == "previousSibling" && !isXML; + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + if ( elem ) { + if ( sibDir && elem.nodeType === 1 ){ + elem.sizcache = doneName; + elem.sizset = i; + } + elem = elem[dir]; + var match = false; + + while ( elem ) { + if ( elem.sizcache === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem.sizcache = doneName; + elem.sizset = i; + } + + if ( elem.nodeName === cur ) { + match = elem; + break; + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + var sibDir = dir == "previousSibling" && !isXML; + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + if ( elem ) { + if ( sibDir && elem.nodeType === 1 ) { + elem.sizcache = doneName; + elem.sizset = i; + } + elem = elem[dir]; + var match = false; + + while ( elem ) { + if ( elem.sizcache === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem.sizcache = doneName; + elem.sizset = i; + } + if ( typeof cur !== "string" ) { + if ( elem === cur ) { + match = true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match = elem; + break; + } + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +var contains = document.compareDocumentPosition ? function(a, b){ + return a.compareDocumentPosition(b) & 16; +} : function(a, b){ + return a !== b && (a.contains ? a.contains(b) : true); +}; + +var isXML = function(elem){ + return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" || + !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML"; +}; + +var posProcess = function(selector, context){ + var tmpSet = [], later = "", match, + root = context.nodeType ? [context] : context; + + // Position selectors must be done after the filter + // And so must :not(positional) so we move all PSEUDOs to the end + while ( (match = Expr.match.PSEUDO.exec( selector )) ) { + later += match[0]; + selector = selector.replace( Expr.match.PSEUDO, "" ); + } + + selector = Expr.relative[selector] ? selector + "*" : selector; + + for ( var i = 0, l = root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE + +Firebug.Selector = Sizzle; + +/**#@-*/ + +// ************************************************************************************************ +}}); \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/store/json.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/store/json.js new file mode 100644 index 00000000000..6f3862ae522 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/store/json.js @@ -0,0 +1,493 @@ +/* See license.txt for terms of usage */ + +/* + http://www.JSON.org/json2.js + 2010-03-20 + + Public Domain. + + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + + See http://www.JSON.org/js.html + + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. + + + This file creates a global JSON object containing two methods: stringify + and parse. + + JSON.stringify(value, replacer, space) + value any JavaScript value, usually an object or array. + + replacer an optional parameter that determines how object + values are stringified for objects. It can be a + function or an array of strings. + + space an optional parameter that specifies the indentation + of nested structures. If it is omitted, the text will + be packed without extra whitespace. If it is a number, + it will specify the number of spaces to indent at each + level. If it is a string (such as '\t' or ' '), + it contains the characters used to indent at each level. + + This method produces a JSON text from a JavaScript value. + + When an object value is found, if the object contains a toJSON + method, its toJSON method will be called and the result will be + stringified. A toJSON method does not serialize: it returns the + value represented by the name/value pair that should be serialized, + or undefined if nothing should be serialized. The toJSON method + will be passed the key associated with the value, and this will be + bound to the value + + For example, this would serialize Dates as ISO strings. + + Date.prototype.toJSON = function (key) { + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z'; + }; + + You can provide an optional replacer method. It will be passed the + key and value of each member, with this bound to the containing + object. The value that is returned from your method will be + serialized. If your method returns undefined, then the member will + be excluded from the serialization. + + If the replacer parameter is an array of strings, then it will be + used to select the members to be serialized. It filters the results + such that only members with keys listed in the replacer array are + stringified. + + Values that do not have JSON representations, such as undefined or + functions, will not be serialized. Such values in objects will be + dropped; in arrays they will be replaced with null. You can use + a replacer function to replace those with JSON values. + JSON.stringify(undefined) returns undefined. + + The optional space parameter produces a stringification of the + value that is filled with line breaks and indentation to make it + easier to read. + + If the space parameter is a non-empty string, then that string will + be used for indentation. If the space parameter is a number, then + the indentation will be that many spaces. + + Example: + + text = JSON.stringify(['e', {pluribus: 'unum'}]); + // text is '["e",{"pluribus":"unum"}]' + + + text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); + // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' + + text = JSON.stringify([new Date()], function (key, value) { + return this[key] instanceof Date ? + 'Date(' + this[key] + ')' : value; + }); + // text is '["Date(---current time---)"]' + + + JSON.parse(text, reviver) + This method parses a JSON text to produce an object or array. + It can throw a SyntaxError exception. + + The optional reviver parameter is a function that can filter and + transform the results. It receives each of the keys and values, + and its return value is used instead of the original value. + If it returns what it received, then the structure is not modified. + If it returns undefined then the member is deleted. + + Example: + + // Parse the text. Values that look like ISO date strings will + // be converted to Date objects. + + myData = JSON.parse(text, function (key, value) { + var a; + if (typeof value === 'string') { + a = +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); + if (a) { + return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], + +a[5], +a[6])); + } + } + return value; + }); + + myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { + var d; + if (typeof value === 'string' && + value.slice(0, 5) === 'Date(' && + value.slice(-1) === ')') { + d = new Date(value.slice(5, -1)); + if (d) { + return d; + } + } + return value; + }); + + + This is a reference implementation. You are free to copy, modify, or + redistribute. +*/ + +/*jslint evil: true, strict: false */ + +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, + call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, prototype, push, replace, slice, stringify, + test, toJSON, toString, valueOf +*/ + + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +// ************************************************************************************************ + +var JSON = window.JSON || {}; + +// ************************************************************************************************ + +(function () { + + function f(n) { + // Format integers to have at least two digits. + 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 = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + 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) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 ? '[]' : + gap ? '[\n' + gap + + partial.join(',\n' + gap) + '\n' + + mind + ']' : + '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + 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 { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 ? '{}' : + gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + + mind + '}' : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== 'function') { + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + 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); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + 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); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + 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, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' ? + walk({'': j}, '') : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } + +// ************************************************************************************************ +// registration + +FBL.JSON = JSON; + +// ************************************************************************************************ +}()); \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/store/package.json b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/store/package.json new file mode 100644 index 00000000000..d26db7bc9e9 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/store/package.json @@ -0,0 +1,40 @@ +{ + "name": "store", + "description": "A localStorage wrapper for all browsers without using cookies or flash. Uses localStorage, globalStorage, and userData behavior under the hood", + "version": "1.1.1", + "homepage": "https://github.com/marcuswestin/store.js", + "author": "Marcus Westin (http://marcuswest.in)", + "contributors": [ + "Matt Pizzimenti (http://mjpizz.com)", + "Long Ouyang (https://github.com/longouyang)", + "Paul Irish (http://paulirish.com)", + "Guillermo Rauch (https://github.com/guille)", + "whitmer (https://github.com/whitmer)", + "Steven Black (https://github.com/StevenBlack)", + "Marcus Tucker (https://github.com/MarcusJT)" + ], + "repository": { + "type": "git", + "url": "git://github.com/marcuswestin/store.js.git" + }, + "bugs": { + "url": "http://github.com/marcuswestin/store.js/issues" + }, + "engines": { + "browser": "*", + "node": "*" + }, + "licenses": [ + { + "type": "MIT", + "url": "http://github.com/marcuswestin/store.js/raw/master/LICENSE" + } + ], + "main": "store", + "directories": { + "lib": "." + }, + "files": [ + "" + ] +} \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/store/store.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/store/store.js new file mode 100644 index 00000000000..f17571faf9d --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/store/store.js @@ -0,0 +1,142 @@ +/* See license.txt for terms of usage */ + +(function(){ +// ************************************************************************************************ + +/* Copyright (c) 2010-2011 Marcus Westin + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +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) + } + + // Functions to encapsulate questionable FireFox 3.6.13 behavior + // when about.config::dom.storage.enabled === false + // See https://github.com/marcuswestin/store.js/issues#issue/13 + 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) + // See http://msdn.microsoft.com/en-us/library/ms531081(v=VS.85).aspx + // and http://msdn.microsoft.com/en-us/library/ms531424(v=VS.85).aspx + // TODO: xxxpedro doc.body is not always available so we must use doc.documentElement. + // We need to make sure this change won't affect the behavior of this library. + 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 } + + +// ************************************************************************************************ +// registration + +FBL.Store = store; + +// ************************************************************************************************ +})(); \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/temp/chrome2.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/temp/chrome2.js new file mode 100644 index 00000000000..05828529d94 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/temp/chrome2.js @@ -0,0 +1,1747 @@ +/* See license.txt for terms of usage */ + +var Firebug = null; + +/* The 'context' in this file is always 'Firebug.currentContext' */ + +(function() { + +// ************************************************************************************************ +// Constants + +///const Cc = Components.classes; +///const Ci = Components.interfaces; +///const nsIWebNavigation = Ci.nsIWebNavigation; + +///const observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService); +///const wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator); + +///const LOAD_FLAGS_BYPASS_PROXY = nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY; +///const LOAD_FLAGS_BYPASS_CACHE = nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE; +///const LOAD_FLAGS_NONE = nsIWebNavigation.LOAD_FLAGS_NONE; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +///const panelURL = "chrome://firebug/content/panel.html"; + +var statusCropSize = 20; + +var positiveZoomFactors = [1, 1.1, 1.2, 1.3, 1.5, 2, 3]; +var negativeZoomFactors = [1, 0.95, 0.8, 0.7, 0.5, 0.2, 0.1]; + +// ************************************************************************************************ +// Globals + +var panelBox, panelSplitter, sidePanelDeck, panelBar1, panelBar2, locationList, locationButtons, + panelStatus, panelStatusSeparator, cmdPreview, cmdPreviewBrowser; + +var waitingPanelBarCount = 2; + +var inDetachedScope = (window.location == "chrome://firebug/content/firebug.xul"); + +var disabledHead = null; +var disabledCaption = null; +var enableSiteLink = null; +var enableSystemPagesLink = null; +var enableAlwaysLink = null; + +// ************************************************************************************************ + +top.FirebugChrome = +{ + window: window, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Initialization + + panelBarReady: function(panelBar) + { + try + { + // Wait until all panelBar bindings are ready before initializing + if (--waitingPanelBarCount == 0) + this.initialize(); + else + return false; + } + catch (exc) + { + // Disaster! + window.dump("getStackDump:"+FBL.getStackDump()+"\n"); + Components.utils.reportError("Firebug initialization FAILS "+exc); + if (FBTrace.sysout) + FBTrace.sysout("chrome.panelBarReady FAILS: "+exc, exc); + return false; + } + return true; // the panel bar is ready + }, + + initialize: function() + { + panelBox = $("fbPanelBox"); + panelSplitter = $("fbPanelSplitter"); + sidePanelDeck = $("fbSidePanelDeck"); + panelBar1 = $("fbPanelBar1"); + panelBar2 = $("fbPanelBar2"); + locationList = $("fbLocationList"); + locationButtons = $("fbLocationButtons"); + panelStatus = $("fbPanelStatus"); + panelStatusSeparator = $("fbStatusSeparator"); + + cmdPreview = $("fbCommandPreview"); + cmdPreviewBrowser = $("fbCommandPreviewBrowser"); + + if (window.arguments) + var detachArgs = window.arguments[0]; + + if (FBTrace.DBG_INITIALIZE) + FBTrace.sysout("chrome.initialize w/detachArgs=", detachArgs); + + if (detachArgs && detachArgs.Firebug) + { + // we've been opened in a new window by an already initialized Firebug + top.FBL = detachArgs.FBL; + Firebug = detachArgs.Firebug; + Firebug.currentContext = detachArgs.Firebug.currentContext; + } + else + { + // Firebug has not been initialized yet + if (!Firebug.isInitialized) + Firebug.initialize(); + } + + // FBL should be available + if (FBTrace.sysout && (!FBL || !FBL.initialize) ) + FBTrace.sysout("Firebug is broken, FBL incomplete, if the last function is QI, check lib.js:", FBL); + + Firebug.internationalizeUI(window.document); + + var browser1 = panelBar1.browser; + browser1.addEventListener("load", browser1Loaded, true); + browser1.droppedLinkHandler = function() + { + return false; + }; + + var browser2 = panelBar2.browser; + browser2.addEventListener("load", browser2Loaded, true); + browser2.droppedLinkHandler = function() + { + return false; + }; + + window.addEventListener("blur", onBlur, true); + + // Initialize Firebug Tools & Firebug Icon menus. + var firebugMenuPopup = $("fbFirebugMenuPopup"); + this.initializeMenu($("menu_firebug"), firebugMenuPopup); + this.initializeMenu($("fbFirebugMenu"), firebugMenuPopup); + + if (FBTrace.DBG_INITIALIZE) + FBTrace.sysout("chrome.initialized ", window); + }, + + initializeMenu: function(parentMenu, popupMenu) + { + if (!parentMenu) + return; + + if (parentMenu.getAttribute("initialized")) + return; + + parentMenu.appendChild(popupMenu.cloneNode(true)); + parentMenu.setAttribute("initialized", "true"); + }, + + /** + * Called when the UI is ready to be initialized, once the panel browsers are loaded. + */ + initializeUI: function() + { + // we listen for panel update + Firebug.registerUIListener(this); + + try + { + if (window.arguments) + var detachArgs = window.arguments[0]; + + this.applyTextSize(Firebug.textSize); + + var doc1 = panelBar1.browser.contentDocument; + doc1.addEventListener("mouseover", onPanelMouseOver, false); + doc1.addEventListener("mouseout", onPanelMouseOut, false); + doc1.addEventListener("mousedown", onPanelMouseDown, false); + doc1.addEventListener("click", onPanelClick, false); + panelBar1.addEventListener("selectingPanel", onSelectingPanel, false); + + var doc2 = panelBar2.browser.contentDocument; + doc2.addEventListener("mouseover", onPanelMouseOver, false); + doc2.addEventListener("mouseout", onPanelMouseOut, false); + doc2.addEventListener("click", onPanelClick, false); + doc2.addEventListener("mousedown", onPanelMouseDown, false); + panelBar2.addEventListener("selectPanel", onSelectedSidePanel, false); + + var doc3 = cmdPreviewBrowser.contentDocument; + doc3.addEventListener("mouseover", onPanelMouseOver, false); + doc3.addEventListener("mouseout", onPanelMouseOut, false); + doc3.addEventListener("mousedown", onPanelMouseDown, false); + doc3.addEventListener("click", onPanelClick, false); + + var mainTabBox = panelBar1.ownerDocument.getElementById("fbPanelBar1-tabBox"); + mainTabBox.addEventListener("mousedown", onMainTabBoxMouseDown, false); + + // The side panel bar doesn't care about this event. It must, however, + // prevent it from bubbling now that we allow the side panel bar to be + // *inside* the main panel bar. + function stopBubble(event) { event.stopPropagation(); } + panelBar2.addEventListener("selectingPanel", stopBubble, false); + + locationList.addEventListener("selectObject", onSelectLocation, false); + + this.updatePanelBar1(Firebug.panelTypes); + + if (inDetachedScope) + this.attachBrowser(Firebug.currentContext); + else + Firebug.initializeUI(detachArgs); + + // Append all registered styleesheets into Firebug UI. + for (var uri in Firebug.stylesheets) + { + FBL.appendStylesheet(doc1, Firebug.stylesheets[uri]); + FBL.appendStylesheet(doc2, Firebug.stylesheets[uri]); + FBL.appendStylesheet(doc3, Firebug.stylesheets[uri]); + } + + FirstRunPage.initializeUI(); + } + catch (exc) + { + FBTrace.sysout("chrome.initializeUI fails "+exc, exc); + } + }, + + shutdown: function() + { + if (FBTrace.DBG_INITIALIZE || !panelBar1) + FBTrace.sysout("chrome.shutdown entered for "+window.location+"\n"); + + var doc1 = panelBar1.browser.contentDocument; + doc1.removeEventListener("mouseover", onPanelMouseOver, false); + doc1.removeEventListener("mouseout", onPanelMouseOut, false); + doc1.removeEventListener("mousedown", onPanelMouseDown, false); + doc1.removeEventListener("click", onPanelClick, false); + + var doc2 = panelBar2.browser.contentDocument; + doc2.removeEventListener("mouseover", onPanelMouseOver, false); + doc2.removeEventListener("mouseout", onPanelMouseOut, false); + doc2.removeEventListener("mousedown", onPanelMouseDown, false); + doc2.removeEventListener("click", onPanelClick, false); + + var doc3 = cmdPreviewBrowser.contentDocument; + doc3.removeEventListener("mouseover", onPanelMouseOver, false); + doc3.removeEventListener("mouseout", onPanelMouseOut, false); + doc3.removeEventListener("mousedown", onPanelMouseDown, false); + doc3.removeEventListener("click", onPanelClick, false); + + var mainTabBox = panelBar1.ownerDocument.getElementById("fbPanelBar1-tabBox"); + mainTabBox.removeEventListener("mousedown", onMainTabBoxMouseDown, false); + + locationList.removeEventListener("selectObject", onSelectLocation, false); + + window.removeEventListener("blur", onBlur, true); + + Firebug.unregisterUIListener(this); + + if (inDetachedScope) + this.undetach(); + else + Firebug.shutdown(); + }, + + updateOption: function(name, value) + { + if (panelBar1.selectedPanel) + panelBar1.selectedPanel.updateOption(name, value); + if (panelBar2.selectedPanel) + panelBar2.selectedPanel.updateOption(name, value); + + if (name == "textSize") + this.applyTextSize(value); + if (name =="omitObjectPathStack") + this.obeyOmitObjectPathStack(value); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + attachBrowser: function(context) // XXXjjb context == (Firebug.currentContext || null) and inDetachedScope == true + { + if (FBTrace.DBG_ACTIVATION) + FBTrace.sysout("chrome.attachBrowser with inDetachedScope="+inDetachedScope + + " context="+context+" context==Firebug.currentContext: "+(context==Firebug.currentContext)+ + " in window: "+window.location); + + if (inDetachedScope) // then we are initializing in external window + { + Firebug.setChrome(this, "detached"); // 1.4 + + Firebug.selectContext(context); + + if (FBTrace.DBG_ACTIVATION) + FBTrace.sysout("attachBrowser inDetachedScope in Firebug.chrome.window: "+ + Firebug.chrome.window.location); + } + }, + + undetach: function() + { + var detachedChrome = Firebug.chrome; + Firebug.setChrome(Firebug.originalChrome, "minimized"); + + Firebug.showBar(false); + Firebug.resetTooltip(); + + // when we are done here the window.closed will be true so we don't want to hang on to the ref. + detachedChrome.window = "This is detached chrome!"; + }, + + disableOff: function(collapse) + { + FBL.collapse($("fbCloseButton"), collapse); // disable/enable this button in the Firebug.chrome window. + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getBrowsers: function() + { + return Firebug.tabBrowser.browsers; + }, + + getCurrentBrowser: function() + { + return Firebug.tabBrowser.selectedBrowser; + }, + + getCurrentURI: function() + { + try + { + return Firebug.tabBrowser.currentURI; + } + catch (exc) + { + return null; + } + }, + + getPanelDocument: function(panelType) + { + // Console panel can be displayed for all the other panels + // (except of the console panel itself) + // XXXjjb, xxxHonza: this should be somehow betterm, more generic and extensible... + var consolePanelType = Firebug.getPanelType("console"); + if (consolePanelType == panelType) + { + if (!FBL.isCollapsed(cmdPreview)) + return cmdPreviewBrowser.contentDocument; + } + + // Standard panel and side panel documents. + if (!panelType.prototype.parentPanel) + return panelBar1.browser.contentDocument; + else + return panelBar2.browser.contentDocument; + }, + + getPanelBrowser: function(panel) + { + if (!panel.parentPanel) + return panelBar1.browser; + else + return panelBar2.browser; + }, + + savePanels: function() + { + var path = this.writePanels(panelBar1.browser.contentDocument); + $("fbStatusText").setAttribute("value", path); + if (FBTrace.DBG_PANELS) + FBTrace.sysout("Wrote panels to "+path+"\n"); + }, + + writePanels: function(doc) + { + var serializer = new XMLSerializer(); + var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"] + .createInstance(Components.interfaces.nsIFileOutputStream); + var file = Components.classes["@mozilla.org/file/directory_service;1"] + .getService(Components.interfaces.nsIProperties) + .get("TmpD", Components.interfaces.nsIFile); + + file.append("firebug"); // extensions sub-directory + file.append("panelSave.html"); + file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666); + foStream.init(file, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate + serializer.serializeToStream(doc, foStream, ""); // rememeber, doc is the DOM tree + foStream.close(); + return file.path; + }, + + updatePanelBar1: function(panelTypes) // part of initializeUI + { + var mainPanelTypes = []; + for (var i = 0; i < panelTypes.length; ++i) + { + var panelType = panelTypes[i]; + if (!panelType.prototype.parentPanel && !panelType.hidden) + mainPanelTypes.push(panelType); + } + panelBar1.updatePanels(mainPanelTypes); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getName: function() + { + return window ? window.location.href : null; + }, + + close: function() + { + if (FBTrace.DBG_INITIALIZE) + FBTrace.sysout("chrome.close closing window "+window.location); + window.close(); + }, + + focus: function() + { + window.focus(); + panelBar1.browser.contentWindow.focus(); + }, + + isFocused: function() + { + return wm.getMostRecentWindow(null) == window; + }, + + focusWatch: function(context) + { + if (Firebug.isDetached()) + Firebug.chrome.focus(); + else + Firebug.toggleBar(true); + + Firebug.chrome.selectPanel("script"); + + var watchPanel = context.getPanel("watches", true); + if (watchPanel) + { + Firebug.CommandLine.isReadyElsePreparing(context); + watchPanel.editNewWatch(); + } + }, + + isOpen: function() + { + return !($("fbContentBox").collapsed); + }, + + reload: function(skipCache) + { + var reloadFlags = skipCache + ? LOAD_FLAGS_BYPASS_PROXY | LOAD_FLAGS_BYPASS_CACHE + : LOAD_FLAGS_NONE; + + // Make sure the selected tab in the attached browser window is refreshed. + var browser = Firebug.chrome.getCurrentBrowser(); + browser.firebugReload = true; + browser.webNavigation.reload(reloadFlags); + + if (FBTrace.DBG_WINDOWS) + FBTrace.sysout("chrome.reload; " + skipCache + ", " + browser.currentURI.spec); + }, + + gotoPreviousTab: function() + { + if (Firebug.currentContext.previousPanelName) + this.selectPanel(Firebug.currentContext.previousPanelName); + }, + + gotoSiblingTab : function(goRight) + { + if ($('fbContentBox').collapsed) + return; + var i, currentIndex = newIndex = -1, currentPanel = this.getSelectedPanel(), newPanel; + var panelTypes = Firebug.getMainPanelTypes(Firebug.currentContext); + + /*get current panel's index (is there a simpler way for this?*/ + for (i = 0; i < panelTypes.length; i++) + { + if (panelTypes[i].prototype.name === currentPanel.name) + { + currentIndex = i; + break; + } + } + + if (currentIndex != -1) + { + newIndex = goRight ? (currentIndex == panelTypes.length - 1 ? 0 : ++currentIndex) : (currentIndex == 0 ? panelTypes.length - 1 : --currentIndex); + newPanel = panelTypes[newIndex].prototype; + if (newPanel && newPanel.name) + { + this.selectPanel(newPanel.name); + } + } + }, + + getNextObject: function(reverse) + { + var panel = Firebug.currentContext.getPanel(Firebug.currentContext.panelName); + if (panel) + { + var item = panelStatus.getItemByObject(panel.selection); + if (item) + { + if (reverse) + item = item.previousSibling ? item.previousSibling.previousSibling : null; + else + item = item.nextSibling ? item.nextSibling.nextSibling : null; + + if (item) + return item.repObject; + } + } + }, + + gotoNextObject: function(reverse) + { + var nextObject = this.getNextObject(reverse); + if (nextObject) + this.select(nextObject); + else + beep(); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Panels + + /* + * Set this.location on the current panel or one given by name. + * The location object should be known to the caller to be of the correct type for the panel, + * eg SourceFile for Script panel + * @param object the location object, null selects default location + * @param panelName the .name field for the desired panel, null means current panel + * @param sidePanelName I don't know how this affects the outcome + */ + navigate: function(object, panelName, sidePanelName) + { + var panel; + if (panelName || sidePanelName) + panel = this.selectPanel(panelName, sidePanelName); + else + panel = this.getSelectedPanel(); + + if (panel) + panel.navigate(object); + }, + + /* + * Set this.selection by object type analysis, passing the object to all panels to find the best match + * @param object the new this.selection object + * @param panelName matching panel.name will be used if its supportsObject returns true value + * @param sidePanelName default side panel name, used if its supportObject returns true value + * @param forceUpdate if true, then (object === this.selection) is ignored and updateSelection is called + */ + select: function(object, panelName, sidePanelName, forceUpdate) + { + if (FBTrace.DBG_PANELS) + FBTrace.sysout("chrome.select object:"+object+" panelName:"+panelName+" sidePanelName:"+sidePanelName+" forceUpdate:"+forceUpdate+"\n"); + var bestPanelName = getBestPanelName(object, Firebug.currentContext, panelName); + var panel = this.selectPanel(bestPanelName, sidePanelName, true); + if (panel) + panel.select(object, forceUpdate); + }, + + selectPanel: function(panelName, sidePanelName, noRefresh) + { + if (panelName && sidePanelName) + Firebug.currentContext.sidePanelNames[panelName] = sidePanelName; + + return panelBar1.selectPanel(panelName, false, noRefresh); // cause panel visibility changes and events + }, + + selectSidePanel: function(panelName) + { + return panelBar2.selectPanel(panelName); + }, + + selectSupportingPanel: function(object, context, forceUpdate) + { + var bestPanelName = getBestPanelSupportingObject(object, context); + var panel = this.selectPanel(bestPanelName, false, true); + if (panel) + panel.select(object, forceUpdate); + }, + + clearPanels: function() + { + panelBar1.hideSelectedPanel(); + panelBar1.selectedPanel = null; + panelBar2.selectedPanel = null; + }, + + getSelectedPanel: function() + { + return panelBar1.selectedPanel; + }, + + getSelectedSidePanel: function() + { + return panelBar2.selectedPanel; + }, + + switchToPanel: function(context, switchToPanelName) + { + // Remember the previous panel and bar state so we can revert if the user cancels + this.previousPanelName = context.panelName; + this.previousSidePanelName = context.sidePanelName; + this.previouslyCollapsed = $("fbContentBox").collapsed; + this.previouslyFocused = Firebug.isDetached() && this.isFocused(); // TODO previouslyMinimized + + var switchPanel = this.selectPanel(switchToPanelName); + if (switchPanel) + this.previousObject = switchPanel.selection; + + return switchPanel; + }, + + unswitchToPanel: function(context, switchToPanelName, cancelled) + { + var switchToPanel = context.getPanel(switchToPanelName); + + if (this.previouslyFocused) + this.focus(); + + if (cancelled && this.previousPanelName) // revert + { + if (this.previouslyCollapsed) + Firebug.showBar(false); + + if (this.previousPanelName == switchToPanelName) + this.select(this.previousObject); + else + this.selectPanel(this.previousPanelName, this.previousSidePanelName); + } + else // else stay on the switchToPanel + { + this.selectPanel(switchToPanelName); + if (switchToPanel.selection) + this.select(switchToPanel.selection); + this.getSelectedPanel().panelNode.focus(); + } + + delete this.previousObject; + delete this.previousPanelName; + delete this.previousSidePanelName; + delete this.inspectingChrome; + + return switchToPanel; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Location interface provider for binding.xml panelFileList + + getLocationProvider: function() + { + // a function that returns an object with .getObjectDescription() and .getLocationList() + return function getSelectedPanelFromCurrentContext() + { + return Firebug.chrome.getSelectedPanel(); // panels provide location, use the selected panel + }; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // UI Synchronization + + setFirebugContext: function(context) + { + // This sets the global value of Firebug.currentContext in the window that this chrome is compiled into. + // Note that for firebug.xul, the Firebug object is shared across windows, but not FirebugChrome and Firebug.currentContext + FirebugContext = context; + Firebug.currentContext = context; + + if (FBTrace.DBG_WINDOWS || FBTrace.DBG_DISPATCH) + FBTrace.sysout("setFirebugContext "+(Firebug.currentContext?Firebug.currentContext.getName():" **> NULL <** ") + " in "+window.location); + }, + + hidePanel: function() + { + if (panelBar1.selectedPanel) + panelBar1.hideSelectedPanel(); + + if (panelBar2.selectedPanel) + panelBar2.hideSelectedPanel(); + }, + + syncPanel: function(panelName) + { + var context = Firebug.currentContext; + + if (FBTrace.DBG_PANELS) + FBTrace.sysout("chrome.syncPanel Firebug.currentContext=" + + (context ? context.getName() : "undefined")); + + panelStatus.clear(); + + if (context) + { + if (!panelName) + panelName = context.panelName? context.panelName : Firebug.defaultPanelName; + + // Make HTML panel the default panel, which is displayed + // to the user the very first time. + if (!panelName || !Firebug.getPanelType(panelName)) + panelName = "html"; + + this.syncMainPanels(); + panelBar1.selectPanel(panelName, true); + } + else + { + panelBar1.selectPanel(null, true); + } + + if (Firebug.isDetached()) + this.syncTitle(); + }, + + syncMainPanels: function() + { + var panelTypes = Firebug.getMainPanelTypes(Firebug.currentContext); + panelBar1.updatePanels(panelTypes); + }, + + syncSidePanels: function() + { + if(FBTrace.DBG_PANELS) + FBTrace.sysout("syncSidePanels "+panelBar1.selectedPanel); + if (!panelBar1.selectedPanel) + return; + + var panelTypes = Firebug.getSidePanelTypes(Firebug.currentContext, panelBar1.selectedPanel); + panelBar2.updatePanels(panelTypes); + + if (Firebug.currentContext && Firebug.currentContext.sidePanelNames) + { + if ( !panelBar2.selectedPanel || (panelBar2.selectedPanel.parentPanel !== panelBar1.selectedPanel.name) ) + { + var sidePanelName = Firebug.currentContext.sidePanelNames[Firebug.currentContext.panelName]; + sidePanelName = getBestSidePanelName(sidePanelName, panelTypes); + panelBar2.selectPanel(sidePanelName, true); + } + else + { + // if the context changes we need to refresh the panel + panelBar2.selectPanel(panelBar2.selectedPanel.name, true); + } + } + else + panelBar2.selectPanel(null); + + sidePanelDeck.selectedPanel = panelBar2; + FBL.collapse(sidePanelDeck, !panelBar2.selectedPanel); + FBL.collapse(panelSplitter, !panelBar2.selectedPanel); + }, + + syncTitle: function() + { + if (Firebug.currentContext) + { + var title = Firebug.currentContext.getTitle(); + window.document.title = FBL.$STRF("WindowTitle", [title]); + } + else + window.document.title = FBL.$STR("Firebug"); + }, + + focusLocationList: function() + { + locationList.popup.showPopup(locationList, -1, -1, "popup", "bottomleft", "topleft"); + }, + + syncLocationList: function() + { + var panel = panelBar1.selectedPanel; + if (panel && panel.location) + { + locationList.location = panel.location; + FBL.collapse(locationButtons, false); + } + else + { + FBL.collapse(locationButtons, true); + } + }, + + clearStatusPath: function() + { + panelStatus.clear(); + }, + + syncStatusPath: function() + { + var panel = panelBar1.selectedPanel; + if (!panel || (panel && !panel.selection)) + { + panelStatus.clear(); + } + else + { + var path = panel.getObjectPath(panel.selection); + if (!path || !path.length) + { + FBL.hide(panelStatusSeparator, true); + panelStatus.clear(); + } + else + { + // Alright, let's update visibility of the separator. The separator + // is displayed only if there are some other buttons on the left side. + // Before showing the status separator let's see whethere there are any other + // button on the left. + var hide = true; + var sibling = panelStatusSeparator.parentNode.previousSibling; + while (sibling) + { + if (!FBL.isCollapsed(sibling)) + { + hide = false; + break; + } + sibling = sibling.previousSibling; + } + FBL.hide(panelStatusSeparator, hide); + + if (panel.name != panelStatus.lastPanelName) + panelStatus.clear(); + + panelStatus.lastPanelName = panel.name; + + // If the object already exists in the list, just select it and keep the path + var selection = panel.selection; + var existingItem = panelStatus.getItemByObject(panel.selection); + if (existingItem) + panelStatus.selectItem(existingItem); + else + { + panelStatus.clear(); + + for (var i = 0; i < path.length; ++i) + { + var object = path[i]; + + var rep = Firebug.getRep(object, Firebug.currentContext); + var objectTitle = rep.getTitle(object, Firebug.currentContext); + + var title = FBL.cropMultipleLines(objectTitle, statusCropSize); + panelStatus.addItem(title, object, rep, panel.statusSeparator); + } + + panelStatus.selectObject(panel.selection); + if (FBTrace.DBG_PANELS) + FBTrace.sysout("syncStatusPath "+path.length+" items ", path); + } + } + } + }, + + toggleOrient: function() + { + var panelPane = $("fbPanelPane"); + panelSplitter.orient = panelPane.orient + = panelPane.orient == "vertical" ? "horizontal" : "vertical"; + var option = $('menu_toggleOrient').getAttribute("option"); + Firebug.setPref(Firebug.prefDomain, option, panelPane.orient != "vertical"); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + addTab: function(context, url, title, parentPanel) + { + context.addPanelType(url, title, parentPanel); + if (context == Firebug.currentContext) + { + if (parentPanel) + { + var currentPanel = this.getSelectedPanel(); + if (currentPanel && parentPanel == currentPanel.name) + this.syncSidePanels(); + } + else + { + this.syncMainPanels(); + } + } + }, + + removeTab: function(context, url) + { + context.removePanelType(url); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getGlobalAttribute: function(id, name) + { + var elt = $(id); + return elt.getAttribute(name); + }, + + setGlobalAttribute: function(id, name, value) + { + var elt = $(id); + if (elt) + { + if (value == null) + elt.removeAttribute(name); + else + elt.setAttribute(name, value); + } + + if (Firebug.externalChrome) + Firebug.externalChrome.setGlobalAttribute(id, name, value); + }, + + + setChromeDocumentAttribute: function(id, name, value) + { + // Call as Firebug.chrome.setChromeDocumentAttribute() to set attributes in another window. + var elt = $(id); + if (elt) + elt.setAttribute(name, value); + }, + + keyCodeListen: function(key, filter, listener, capture) + { + if (!filter) + filter = FBL.noKeyModifiers; + + var keyCode = KeyEvent["DOM_VK_"+key]; + + function fn(event) + { + if (event.keyCode == keyCode && (!filter || filter(event))) + { + listener(); + FBL.cancelEvent(event); + } + } + + window.addEventListener("keypress", fn, capture); + + return [fn, capture]; + }, + + keyListen: function(ch, filter, listener, capture) + { + if (!filter) + filter = FBL.noKeyModifiers; + + var charCode = ch.charCodeAt(0); + + function fn(event) + { + if (event.charCode == charCode && (!filter || filter(event))) + { + listener(); + FBL.cancelEvent(event); + } + } + + window.addEventListener("keypress", fn, capture); + + return [fn, capture]; + }, + + keyIgnore: function(listener) + { + window.removeEventListener("keypress", listener[0], listener[1]); + }, + + $: function(id) + { + return $(id); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + applyTextSize: function(value) + { + var zoom = value >= 0 ? positiveZoomFactors[value] : negativeZoomFactors[Math.abs(value)]; + + panelBar1.browser.markupDocumentViewer.textZoom = zoom; + panelBar2.browser.markupDocumentViewer.textZoom = zoom; + + + var aNode = panelBar1.selectedPanel ? panelBar1.selectedPanel.panelNode : null ; + if (aNode) + { + Firebug.MeasureBox.startMeasuring(aNode); + var size = Firebug.MeasureBox.measureText(); + Firebug.MeasureBox.stopMeasuring(); + var box = $("fbCommandBox"); + box.style.height = size.height; + box.style.fontSize = (zoom * 100)+"%"; + } + + $("fbLargeCommandLine").style.fontSize = (zoom * 100)+"%"; + + Firebug.dispatchToPanels("onTextSizeChange", [zoom]); + }, + + obeyOmitObjectPathStack: function(value) + { + FBL.hide(panelStatus, (value?true:false)); + }, + + getPanelStatusElements: function() + { + return panelStatus; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // UI Event Listeners uilisteners or "panelListeners" + + onPanelNavigate: function(object, panel) + { + this.syncLocationList(); + }, + + onObjectSelected: function(object, panel) + { + if (panel == panelBar1.selectedPanel) + { + this.syncStatusPath(); + + var sidePanel = panelBar2.selectedPanel; + if (sidePanel) + sidePanel.select(object); + } + }, + + onApplyDecorator: function(sourceBox) // called on setTimeout after sourceBox viewport has been repainted + { + }, + + onViewportChange: function(sourceLink) // called on scrollTo, passing in the selected line + { + }, + + showUI: function(browser, context) // called when the Firebug UI comes up in browser or detached + { + }, + + hideUI: function(browser, context) // called when the Firebug UI comes down; context may be null + { + }, + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + onMenuShowing: function(popup) + { + var detachFirebug = FBL.getElementsByAttribute(popup, "id", "menu_detachFirebug")[0]; + if (detachFirebug) + { + detachFirebug.setAttribute("label", (Firebug.isDetached() ? + FBL.$STR("firebug.AttachFirebug") : FBL.$STR("firebug.DetachFirebug"))); + } + }, + + onOptionsShowing: function(popup) + { + for (var child = popup.firstChild; child; child = child.nextSibling) + { + if (child.localName == "menuitem") + { + var option = child.getAttribute("option"); + if (option) + { + var checked = false; + if (option == "profiling") + checked = fbs.profiling; + else + checked = Firebug.getPref(Firebug.prefDomain, option); + + child.setAttribute("checked", checked); + } + } + } + }, + + onToggleOption: function(menuitem) + { + var option = menuitem.getAttribute("option"); + var checked = menuitem.getAttribute("checked") == "true"; + + Firebug.setPref(Firebug.prefDomain, option, checked); + }, + + onContextShowing: function(event) + { + // xxxHonza: This context-menu support can be used even in separate window, which + // doesn't contain the FBUI (panels). + //if (!panelBar1.selectedPanel) + // return false; + + var popup = $("fbContextMenu"); + var target = document.popupNode; + var panel = target ? Firebug.getElementPanel(target) : null; + + if (!panel) + panel = panelBar1 ? panelBar1.selectedPanel : null; // the event must be on our chrome not inside the panel + + FBL.eraseNode(popup); + + // Make sure the Copy action is only available if there is actually someting + // selected in the panel. + var sel = target.ownerDocument.defaultView.getSelection(); + if (!this.contextMenuObject && !$("cmd_copy").getAttribute("disabled") && !sel.isCollapsed) + { + var menuitem = FBL.createMenuItem(popup, {label: "Copy"}); + menuitem.setAttribute("command", "cmd_copy"); + } + + var object; + if (this.contextMenuObject) + object = this.contextMenuObject; + else if (target && target.ownerDocument == document) + object = Firebug.getRepObject(target); + else if (target && panel) + object = panel.getPopupObject(target); + else if (target) + object = Firebug.getRepObject(target); // xxxHonza: What about a node from different document? Is that OK? + + this.contextMenuObject = null; + + var rep = Firebug.getRep(object, Firebug.currentContext); + var realObject = rep ? rep.getRealObject(object, Firebug.currentContext) : null; + var realRep = realObject ? Firebug.getRep(realObject, Firebug.currentContext) : null; + + if (FBTrace.DBG_OPTIONS) + FBTrace.sysout("chrome.onContextShowing object:"+object+" rep: "+rep+" realObject: "+realObject+" realRep:"+realRep+"\n"); + + if (realObject && realRep) + { + // 1. Add the custom menu items from the realRep + var menu = realRep.getContextMenuItems(realObject, target, Firebug.currentContext); + if (menu) + { + for (var i = 0; i < menu.length; ++i) + FBL.createMenuItem(popup, menu[i]); + } + } + + if (object && rep && rep != realRep) + { + // 1. Add the custom menu items from the original rep + var items = rep.getContextMenuItems(object, target, Firebug.currentContext); + if (items) + { + for (var i = 0; i < items.length; ++i) + FBL.createMenuItem(popup, items[i]); + } + } + + // 1. Add the custom menu items from the panel + if (panel) + { + var items = panel.getContextMenuItems(realObject, target); + if (items) + { + for (var i = 0; i < items.length; ++i) + FBL.createMenuItem(popup, items[i]); + } + } + + // 2. Add the inspect menu items + if (realObject && rep && rep.inspectable) + { + var separator = null; + + var items = this.getInspectMenuItems(realObject); + for (var i = 0; i < items.length; ++i) + { + if (popup.firstChild && !separator) + separator = FBL.createMenuSeparator(popup); + + FBL.createMenuItem(popup, items[i]); + } + } + + if (!popup.firstChild) + return false; + }, + + onEditorsShowing: function(popup) // TODO move to Firebug.Editors module in editors.js + { + var editors = Firebug.registeredEditors; + if ( editors.length > 0 ) + { + var lastChild = popup.lastChild; + FBL.eraseNode(popup); + var disabled = (!Firebug.currentContext); + for( var i = 0; i < editors.length; ++i ) + { + if (editors[i] == "-") + { + FBL.createMenuItem(popup, "-"); + continue; + } + var item = {label: editors[i].label, image: editors[i].image, + nol10n: true, disabled: disabled }; + var menuitem = FBL.createMenuItem(popup, item); + menuitem.setAttribute("command", "cmd_openInEditor"); + menuitem.value = editors[i].id; + } + FBL.createMenuItem(popup, "-"); + popup.appendChild(lastChild); + } + }, + + getInspectMenuItems: function(object) + { + var items = []; + + // Domplate (+ support for context menus) can be used even in separate + // windows when Firebug.currentContext doesn't have to be defined. + if (!Firebug.currentContext) + return items; + + for (var i = 0; i < Firebug.panelTypes.length; ++i) + { + var panelType = Firebug.panelTypes[i]; + if (!panelType.prototype.parentPanel + && panelType.prototype.name != Firebug.currentContext.panelName + && panelSupportsObject(panelType, object, Firebug.currentContext)) + { + var panelName = panelType.prototype.name; + + var title = Firebug.getPanelTitle(panelType); + var label = FBL.$STRF("InspectInTab", [title]); + + var command = bindFixed(this.select, this, object, panelName); + items.push({label: label, command: command, nol10n: true}); + } + } + + return items; + }, + + onTooltipShowing: function(event) + { + // xxxHonza: This tooltip support can be used even in separate window, which + // doesn't contain the FBUI (panels). + //if (!panelBar1.selectedPanel) + // return false; + + var tooltip = $("fbTooltip"); + var target = document.tooltipNode; + + var panel = target ? Firebug.getElementPanel(target) : null; + + var object; + /* XXXjjb This causes the Script panel to show the function body over and over. We need to clear it at least, + * but really we need to understand why the tooltip should show the context menu object at all. + * One thing the contextMenuObject supports is peeking at function bodies when stopped a breakpoint. + * That case could be supported with clearing the contextMenuObject, but we don't know if that breaks + * something else. So maybe a popupMenuObject should be set on the context if that is what we want to support + * The other complication is that there seems to be another tooltip. + if (this.contextMenuObject) + { + object = this.contextMenuObject; + FBTrace.sysout("tooltip by contextMenuObject"); + } + else*/ + if (target && target.ownerDocument == document) + object = Firebug.getRepObject(target); + else if (panel) + object = panel.getTooltipObject(target); + + var rep = object ? Firebug.getRep(object, Firebug.currentContext) : null; + object = rep ? rep.getRealObject(object, Firebug.currentContext) : null; + rep = object ? Firebug.getRep(object) : null; + + if (object && rep) + { + var label = rep.getTooltip(object, Firebug.currentContext); + if (label) + { + tooltip.setAttribute("label", label); + return true; + } + } + + if (FBL.hasClass(target, 'noteInToolTip')) + FBL.setClass(tooltip, 'noteInToolTip'); + else + FBL.removeClass(tooltip, 'noteInToolTip'); + + if (target && target.hasAttribute("title")) + { + tooltip.setAttribute("label", target.getAttribute("title")); + return true; + } + + return false; + }, + + openAboutDialog: function() + { + if (FBTrace.DBG_WINDOWS) + FBTrace.sysout("Firebug.openAboutDialog"); + + try + { + // Firefox 4.0 implements new AddonManager. In case of Firefox 3.6 the module + // is not avaialble and there is an exception. + Components.utils.import("resource://gre/modules/AddonManager.jsm"); + } + catch (err) + { + } + + if (typeof(AddonManager) != "undefined") + { + AddonManager.getAddonByID("firebug@software.joehewitt.com", function(addon) { + openDialog("chrome://mozapps/content/extensions/about.xul", "", + "chrome,centerscreen,modal", addon); + }); + } + else + { + var extensionManager = FBL.CCSV("@mozilla.org/extensions/manager;1", + "nsIExtensionManager"); + + openDialog("chrome://mozapps/content/extensions/about.xul", "", + "chrome,centerscreen,modal", "urn:mozilla:item:firebug@software.joehewitt.com", + extensionManager.datasource); + } + }, + + breakOnNext: function(context, event) + { + // Avoid bubbling from associated options. + if (event.target.id != "cmd_breakOnNext") + return; + + if (!context) + { + if (FBTrace.DBG_BP) + FBTrace.sysout("Firebug chrome: breakOnNext with no context??"); + return; + } + + var panel = panelBar1.selectedPanel; + + if (FBTrace.DBG_BP) + FBTrace.sysout("Firebug chrome: breakOnNext for panel " + + (panel ? panel.name : "NO panel"), panel); + + if (panel && panel.breakable) + Firebug.Breakpoint.toggleBreakOnNext(panel); + } +}; + +// ************************************************************************************************ +// Welcome Page (first run) + +var FirstRunPage = +{ + initializeUI: function() + { + // If the version in preferences is smaller than the current version + // display the welcome page. + if (FBL.checkFirebugVersion(Firebug.currentVersion) > 0) + { + FBTrace.sysout("FirstRunPage.initializeUI; current: " + Firebug.getVersion() + + "preferences: " + Firebug.currentVersion); + + // Wait for session restore and display the welcome page. + observerService.addObserver(this, "sessionstore-windows-restored" , false); + } + }, + + observe: function(subjet, topic, data) + { + if (topic != "sessionstore-windows-restored") + return; + + setTimeout(function() + { + // Open the page in the top most window so, the user can see it immediately. + if (wm.getMostRecentWindow("navigator:browser") != window) + return; + + // Avoid opening of the page in a second browser window. + if (FBL.checkFirebugVersion(Firebug.currentVersion) > 0) + { + // Don't forget to update the preference so, the page is not displayed again + var version = Firebug.getVersion(); + Firebug.setPref(Firebug.prefDomain, "currentVersion", version); + version = version.replace('X', '', "g"); + + // xxxHonza: put the URL in firebugURLs as soon as it's in chrome.js + FBL.openNewTab("http://getfirebug.com/firstrun#Firebug " + version); + } + }, 500); + } +}; + +// ************************************************************************************************ +// Local Helpers + +function panelSupportsObject(panelType, object, context) +{ + if (panelType) + { + try { + // This tends to throw exceptions often because some objects are weird + return panelType.prototype.supportsObject(object, typeof object, context); + } catch (exc) {} + } + + return 0; +} + +function getBestPanelName(object, context, panelName) +{ + if (!panelName) + panelName = context.panelName; + + // Check if the suggested panel name supports the object, and if so, go with it + if (panelName) + { + panelType = Firebug.getPanelType(panelName); + if (panelSupportsObject(panelType, object, context)) + return panelType.prototype.name; + } + + // The suggested name didn't pan out, so search for the panel type with the + // most specific level of support + return getBestPanelSupportingObject(object, context); +} + +function getBestPanelSupportingObject(object, context) +{ + var bestLevel = 0; + var bestPanel = null; + + for (var i = 0; i < Firebug.panelTypes.length; ++i) + { + var panelType = Firebug.panelTypes[i]; + if (!panelType.prototype.parentPanel) + { + var level = panelSupportsObject(panelType, object, context); + if (!bestLevel || (level && (level > bestLevel) )) + { + bestLevel = level; + bestPanel = panelType; + } + if (FBTrace.DBG_PANELS) + FBTrace.sysout("chrome.getBestPanelName panelType: "+panelType.prototype.name+" level: "+level+" bestPanel: "+ (bestPanel ? bestPanel.prototype.name : "null")+" bestLevel: "+bestLevel+"\n"); + } + } + + return bestPanel ? bestPanel.prototype.name : null; +} + +function getBestSidePanelName(sidePanelName, panelTypes) +{ + if (sidePanelName) + { + // Verify that the suggested panel name is in the acceptable list + for (var i = 0; i < panelTypes.length; ++i) + { + if (panelTypes[i].prototype.name == sidePanelName) + return sidePanelName; + } + } + + // Default to the first panel type in the list + return panelTypes.length ? panelTypes[0].prototype.name : null; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Event listeners + +function browser1Loaded() +{ + if (FBTrace.DBG_INITIALIZE) + FBTrace.sysout("browse1Loaded\n"); + var browser1 = panelBar1.browser; + browser1.removeEventListener("load", browser1Loaded, true); + + browser1.contentDocument.title = "Firebug Main Panel"; + browser1Loaded.complete = true; + + if (browser1Loaded.complete && browser2Loaded.complete) + FirebugChrome.initializeUI(); +} + +function browser2Loaded() +{ + if (FBTrace.DBG_INITIALIZE) + FBTrace.sysout("browse2Loaded\n"); + var browser2 = panelBar2.browser; + browser2.removeEventListener("load", browser2Loaded, true); + + browser2.contentDocument.title = "Firebug Side Panel"; + browser2Loaded.complete = true; + + if (browser1Loaded.complete && browser2Loaded.complete) + FirebugChrome.initializeUI(); // the chrome bound into this scope + + if (FBTrace.DBG_INITIALIZE) + FBTrace.sysout("browse2Loaded complete\n"); +} + +function onBlur(event) +{ + // XXXjjb this seems like a waste: called continuously to clear possible highlight I guess. + // XXXhh Is this really necessary? I disabled it for now as this was preventing me to show highlights on focus + //Firebug.Inspector.highlightObject(null, Firebug.currentContext); +} + +function onSelectLocation(event) +{ + var location = locationList.repObject; + FirebugChrome.navigate(location); +} + +function onSelectingPanel(event) +{ + var panel = panelBar1.selectedPanel; + var panelName = panel ? panel.name : null; + + if (FBTrace.DBG_PANELS) + FBTrace.sysout("chrome.onSelectingPanel="+panelName+" Firebug.currentContext=" + + (Firebug.currentContext?Firebug.currentContext.getName():"undefined")); + + if (Firebug.currentContext) + { + Firebug.currentContext.previousPanelName = Firebug.currentContext.panelName; + Firebug.currentContext.panelName = panelName; + + Firebug.currentContext.sidePanelName = + Firebug.currentContext.sidePanelNames && panelName in Firebug.currentContext.sidePanelNames + ? Firebug.currentContext.sidePanelNames[panelName] + : null; + } + + if (panel) + panel.navigate(panel.location); + + // Hide all toolbars now. It's a responsibility of the new selected panel to show + // those toolbars that are necessary. This avoids the situation when naughty panel + // doesn't clean up its toolbars. This must be done before showPanel where visibility + // of the BON buttons is managed. + var toolbar = $("fbToolbarInner"); + var child = toolbar.firstChild; + while (child) + { + FBL.collapse(child, true); + child = child.nextSibling; + } + + // Calling Firebug.showPanel causes dispatching "showPanel" to all modules. + var browser = panel ? panel.context.browser : FirebugChrome.getCurrentBrowser(); + Firebug.showPanel(browser, panel); + + // Synchronize UI around panels. Execute the sync after showPanel so the logic + // can decide whether to display separators or not. + // xxxHonza: The command line should be synced here as well. + Firebug.chrome.syncLocationList(); + Firebug.chrome.syncStatusPath(); + + //xxxjjb unfortunately the callstack side panel depends on the status path (sync after.) + Firebug.chrome.syncSidePanels(); +} + +function onSelectedSidePanel(event) +{ + var sidePanel = panelBar2.selectedPanel; + if (Firebug.currentContext) + { + var panelName = Firebug.currentContext.panelName; + if (panelName) + { + var sidePanelName = sidePanel ? sidePanel.name : null; + Firebug.currentContext.sidePanelNames[panelName] = sidePanelName; + } + } + + if (FBTrace.DBG_PANELS) + FBTrace.sysout("chrome.onSelectedSidePanel name="+(sidePanel?sidePanel.name:"undefined")+"\n"); + + var panel = panelBar1.selectedPanel; + if (panel && sidePanel) + sidePanel.select(panel.selection); + + var browser = sidePanel ? sidePanel.context.browser : FirebugChrome.getCurrentBrowser(); + Firebug.showSidePanel(browser, sidePanel); // dispatch to modules +} + +function onPanelMouseOver(event) +{ + var object = Firebug.getRepObject(event.target); + if(!object) + return; + + var rep = Firebug.getRep(object, Firebug.currentContext); + if(rep) + rep.highlightObject(object, Firebug.currentContext); +} + +function onPanelMouseOut(event) +{ + var object = Firebug.getRepObject(event.target); + if(!object) + return; + + var rep = Firebug.getRep(object, Firebug.currentContext); + if(rep) + rep.unhighlightObject(object, Firebug.currentContext); +} + +function onPanelClick(event) +{ + var repNode = Firebug.getRepNode(event.target); + if (repNode) + { + var object = repNode.repObject; + var rep = Firebug.getRep(object, Firebug.currentContext); + var realObject = rep ? rep.getRealObject(object, Firebug.currentContext) : null; + var realRep = realObject ? Firebug.getRep(realObject, Firebug.currentContext) : rep; + if (!realObject) + realObject = object; + + if (FBL.isLeftClick(event)) + { + if (FBL.hasClass(repNode, "objectLink")) + { + if (realRep) + { + realRep.inspectObject(realObject, Firebug.currentContext); + FBL.cancelEvent(event); + } + } + } + else if (FBL.isControlClick(event) || FBL.isMiddleClick(event)) + { + if (!realRep || !realRep.browseObject(realObject, Firebug.currentContext)) + { + if (rep && !(rep != realRep && rep.browseObject(object, Firebug.currentContext))) + { + var panel = Firebug.getElementPanel(event.target); + if (!panel || !panel.browseObject(realObject)) + return; + } + } + FBL.cancelEvent(event); + } + } +} + +function onPanelMouseDown(event) +{ + if (FBL.isLeftClick(event)) + { + var editable = FBL.getAncestorByClass(event.target, "editable"); + if (editable) + { + Firebug.Editor.startEditing(editable); + FBL.cancelEvent(event); + } + } + else if (FBL.isMiddleClick(event) && Firebug.getRepNode(event.target)) + { + // Prevent auto-scroll when middle-clicking a rep object + FBL.cancelEvent(event); + } +} + +function onMainTabBoxMouseDown(event) +{ + if (Firebug.isInBrowser()) + { + var contentSplitter = Firebug.chrome.$("fbContentSplitter"); + // TODO: grab the splitter here. + } +} + +function getRealObject(object) +{ + var rep = Firebug.getRep(object, Firebug.currentContext); + var realObject = rep ? rep.getRealObject(object, Firebug.currentContext) : null; + return realObject ? realObject : object; +} + +// ************************************************************************************************ +// Utils (duplicated from lib.js) + +function $(id, doc) +{ + if (doc) + return doc.getElementById(id); + else + return document.getElementById(id); +} + +function cloneArray(array, fn) +{ + var newArray = []; + + for (var i = 0; i < array.length; ++i) + newArray.push(array[i]); + + return newArray; +} + +function bindFixed() +{ + var args = cloneArray(arguments), fn = args.shift(), object = args.shift(); + return function() { return fn.apply(object, args); }; +} + +})(); + +// ************************************************************************************************ + +// XXXjoe This horrible hack works around a focus bug in Firefox which is caused when +// the HTML Validator extension and Firebug are installed. It causes the keyboard to +// behave erratically when typing, and the only solution I've found is to delay +// the initialization of HTML Validator by overriding this function with a timeout. +// XXXrobc Do we still need this? Does this extension even exist anymore? +if (top.hasOwnProperty('TidyBrowser')) +{ + var prev = TidyBrowser.prototype.updateStatusBar; + TidyBrowser.prototype.updateStatusBar = function() + { + var self = this, args = arguments; + setTimeout(function() + { + prev.apply(self, args); + }); + }; +} + +// ************************************************************************************************ + +function dddx() +{ + Firebug.Console.logFormatted(arguments); +} + diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/temp/html2.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/temp/html2.js new file mode 100644 index 00000000000..4651f7fc701 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/temp/html2.js @@ -0,0 +1,1906 @@ +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// Constants +/* +const Cc = Components.classes; +const Ci = Components.interfaces; + +const MODIFICATION = MutationEvent.MODIFICATION; +const ADDITION = MutationEvent.ADDITION; +const REMOVAL = MutationEvent.REMOVAL; +/**/ + +var AttrTag = + SPAN({"class": "nodeAttr editGroup"}, + " ", SPAN({"class": "nodeName editable"}, "$attr.nodeName"), "="", + SPAN({"class": "nodeValue editable"}, "$attr.nodeValue"), """ + ); + +// ************************************************************************************************ + +Firebug.HTMLModule = extend(Firebug.Module, +{ + deleteNode: function(node, context) + { + dispatch(this.fbListeners, "onBeginFirebugChange", [node, context]); + node.parentNode.removeChild(node); + dispatch(this.fbListeners, "onEndFirebugChange", [node, context]); + }, + deleteAttribute: function(node, attr, context) + { + dispatch(this.fbListeners, "onBeginFirebugChange", [node, context]); + node.removeAttribute(attr); + dispatch(this.fbListeners, "onEndFirebugChange", [node, context]); + } +}); + +Firebug.HTMLPanel = function() {}; + +Firebug.HTMLPanel.prototype = extend(Firebug.Panel, +{ + toggleEditing: function() + { + if (this.editing) + Firebug.Editor.stopEditing(); + else + this.editNode(this.selection); + }, + + resetSearch: function() + { + delete this.lastSearch; + }, + + selectNext: function() + { + var objectBox = this.ioBox.createObjectBox(this.selection); + var next = this.ioBox.getNextObjectBox(objectBox); + if (next) + { + this.select(next.repObject); + + if (Firebug.Inspector.inspecting) + Firebug.Inspector.inspectNode(next.repObject); + + } + }, + + selectPrevious: function() + { + var objectBox = this.ioBox.createObjectBox(this.selection); + var previous = this.ioBox.getPreviousObjectBox(objectBox); + if (previous) + { + this.select(previous.repObject); + + if (Firebug.Inspector.inspecting) + Firebug.Inspector.inspectNode(previous.repObject); + } + }, + + selectNodeBy: function(dir) + { + if (dir == "up") + this.selectPrevious(); + else if (dir == "down") + this.selectNext(); + else if (dir == "left") + { + var box = this.ioBox.createObjectBox(this.selection); + if (!hasClass(box, "open")) + this.select(this.ioBox.getParentObjectBox(box).repObject); + else + this.ioBox.contractObject(this.selection); + } + else if (dir == "right") + this.ioBox.expandObject(this.selection); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + editNewAttribute: function(elt) + { + var objectNodeBox = this.ioBox.findObjectBox(elt); + if (objectNodeBox) + { + var labelBox = objectNodeBox.firstChild.lastChild; + var bracketBox = getChildByClass(labelBox, "nodeBracket"); + Firebug.Editor.insertRow(bracketBox, "before"); + } + }, + + editAttribute: function(elt, attrName) + { + var objectNodeBox = this.ioBox.findObjectBox(elt); + if (objectNodeBox) + { + var attrBox = findNodeAttrBox(objectNodeBox, attrName); + if (attrBox) + { + var attrValueBox = attrBox.childNodes[3]; + var value = elt.getAttribute(attrName); + Firebug.Editor.startEditing(attrValueBox, value); + } + } + }, + + deleteAttribute: function(elt, attrName) + { + Firebug.HTMLModule.deleteAttribute(elt, attrName, this.context); + }, + + editNode: function(node) + { + if ( nonEditableTags.hasOwnProperty(node.localName) ) + return; + + var objectNodeBox = this.ioBox.findObjectBox(node); + if (objectNodeBox) + { + if (!this.htmlEditor) + this.htmlEditor = new HTMLEditor(this.document); + + this.htmlEditor.innerEditMode = node.localName in innerEditableTags; + + var html = this.htmlEditor.innerEditMode ? node.innerHTML : getElementHTML(node); + Firebug.Editor.startEditing(objectNodeBox, html, this.htmlEditor); + } + }, + + deleteNode: function(node) + { + Firebug.HTMLModule.deleteNode(node, this.context); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getElementSourceText: function(node) + { + if (this.sourceElements) + { + var index = this.sourceElementNodes.indexOf(node); + if (index != -1) + return this.sourceElements[index]; + } + + var lines; + + var url = getSourceHref(node); + if (url) + lines = this.context.sourceCache.load(url); + else + { + var text = getSourceText(node); + lines = splitLines(text); + } + + var sourceElt = new SourceText(lines, node); + + if (!this.sourceElements) + { + this.sourceElements = [sourceElt]; + this.sourceElementNodes = [node]; + } + else + { + this.sourceElements.push(sourceElt); + this.sourceElementNodes.push(node); + } + + return sourceElt; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + mutateAttr: function(target, attrChange, attrName, attrValue) + { + // Every time the user scrolls we get this pointless mutation event, which + // is only bad for performance + if (attrName == "curpos") + return; + if (FBTrace.DBG_HTML) + FBTrace.sysout("html.mutateAttr target:"+target+" attrChange:"+attrChange+" attrName:"+attrName, target); + + this.markChange(); + + var objectNodeBox = Firebug.scrollToMutations || Firebug.expandMutations + ? this.ioBox.createObjectBox(target) + : this.ioBox.findObjectBox(target); + + if (!objectNodeBox) + return; + + if (isVisible(objectNodeBox.repObject)) + removeClass(objectNodeBox, "nodeHidden"); + else + setClass(objectNodeBox, "nodeHidden"); + + if (attrChange == MODIFICATION || attrChange == ADDITION) + { + var nodeAttr = findNodeAttrBox(objectNodeBox, attrName); + if (FBTrace.DBG_HTML) + FBTrace.sysout("mutateAttr "+attrChange+" "+attrName+"="+attrValue+" node: "+nodeAttr, nodeAttr); + if (nodeAttr && nodeAttr.childNodes.length > 3) + { + var attrValueBox = nodeAttr.childNodes[3]; + var attrValueText = nodeAttr.childNodes[3].firstChild; + if (attrValueText) + attrValueText.nodeValue = attrValue; + + this.highlightMutation(attrValueBox, objectNodeBox, "mutated"); + } + else + { + var attr = target.getAttributeNode(attrName); + if (FBTrace.DBG_HTML) + FBTrace.sysout("mutateAttr getAttributeNode "+attrChange+" "+attrName+"="+attrValue+" node: "+attr, attr); + if (attr) + { + var nodeAttr = Firebug.HTMLPanel.AttrNode.tag.replace({attr: attr}, + this.document); + + var labelBox = objectNodeBox.firstChild.lastChild; + var bracketBox = getChildByClass(labelBox, "nodeBracket"); + labelBox.insertBefore(nodeAttr, bracketBox); + + this.highlightMutation(nodeAttr, objectNodeBox, "mutated"); + } + } + } + else if (attrChange == REMOVAL) + { + var nodeAttr = findNodeAttrBox(objectNodeBox, attrName); + if (nodeAttr) + { + nodeAttr.parentNode.removeChild(nodeAttr); + + this.highlightMutation(objectNodeBox, objectNodeBox, "mutated"); + } + } + }, + + mutateText: function(target, parent, textValue) + { + this.markChange(); + + var parentNodeBox = Firebug.scrollToMutations || Firebug.expandMutations + ? this.ioBox.createObjectBox(parent) + : this.ioBox.findObjectBox(parent); + + if (!parentNodeBox) + return; + + if (!Firebug.showFullTextNodes) + textValue = cropMultipleLines(textValue, 50); + + var parentTag = getNodeBoxTag(parentNodeBox); + if (parentTag == Firebug.HTMLPanel.TextElement.tag) + { + var nodeText = getTextElementTextBox(parentNodeBox); + if (!nodeText.firstChild) + return; + + nodeText.firstChild.nodeValue = textValue; + + this.highlightMutation(nodeText, parentNodeBox, "mutated"); + } + else + { + var childBox = this.ioBox.getChildObjectBox(parentNodeBox); + if (!childBox) + return; + + var textNodeBox = this.ioBox.findChildObjectBox(childBox, target); + if (textNodeBox) + { + textNodeBox.firstChild.lastChild.nodeValue = textValue; + + this.highlightMutation(textNodeBox, parentNodeBox, "mutated"); + } + } + }, + + mutateNode: function(target, parent, nextSibling, removal) + { + if (FBTrace.DBG_HTML) + FBTrace.sysout("\nhtml.mutateNode target:"+target+" parent:"+parent+(removal?"REMOVE":"")+"\n"); + + this.markChange(); // This invalidates the panels for every mutate + + var parentNodeBox = Firebug.scrollToMutations || Firebug.expandMutations + ? this.ioBox.createObjectBox(parent) + : this.ioBox.findObjectBox(parent); + + if (FBTrace.DBG_HTML) + FBTrace.sysout("html.mutateNode parent:"+parent+" parentNodeBox:"+parentNodeBox+"\n"); + + if (!parentNodeBox) + return; + + if (!Firebug.showWhitespaceNodes && this.isWhitespaceText(target)) + return; + + // target is only whitespace + + var newParentTag = getNodeTag(parent); + var oldParentTag = getNodeBoxTag(parentNodeBox); + + if (newParentTag == oldParentTag) + { + if (parentNodeBox.populated) + { + if (removal) + { + this.ioBox.removeChildBox(parentNodeBox, target); + + this.highlightMutation(parentNodeBox, parentNodeBox, "mutated"); + } + else + { + var objectBox = nextSibling + ? this.ioBox.insertChildBoxBefore(parentNodeBox, target, nextSibling) + : this.ioBox.appendChildBox(parentNodeBox, target); + + this.highlightMutation(objectBox, objectBox, "mutated"); + } + } + else + { + var newParentNodeBox = newParentTag.replace({object: parent}, this.document); + parentNodeBox.parentNode.replaceChild(newParentNodeBox, parentNodeBox); + + this.highlightMutation(newParentNodeBox, newParentNodeBox, "mutated"); + + if (Firebug.scrollToMutations || Firebug.expandMutations) + { + var objectBox = this.ioBox.createObjectBox(target); + this.highlightMutation(objectBox, objectBox, "mutated"); + } + } + } + else + { + var newParentNodeBox = newParentTag.replace({object: parent}, this.document); + if (parentNodeBox.parentNode) + parentNodeBox.parentNode.replaceChild(newParentNodeBox, parentNodeBox); + + if (hasClass(parentNodeBox, "open")) + this.ioBox.toggleObjectBox(newParentNodeBox, true); + + if (this.selection && (!this.selection.parentNode || parent == this.selection)) + this.ioBox.select(parent, true); + + this.highlightMutation(newParentNodeBox, newParentNodeBox, "mutated"); + } + }, + + highlightMutation: function(elt, objectBox, type) + { + if (!elt) + return; + + if (Firebug.scrollToMutations || Firebug.expandMutations) + { + if (this.context.mutationTimeout) + { + this.context.clearTimeout(this.context.mutationTimeout); + delete this.context.mutationTimeout; + } + + var ioBox = this.ioBox; + var panelNode = this.panelNode; + + this.context.mutationTimeout = this.context.setTimeout(function() + { + ioBox.openObjectBox(objectBox); + + if (Firebug.scrollToMutations) + scrollIntoCenterView(objectBox, panelNode); + }, 200); + } + + if (Firebug.highlightMutations) + setClassTimed(elt, type, this.context); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // SourceBox proxy + + createObjectBox: function(object, isRoot) + { + if (FBTrace.DBG_HTML) FBTrace.sysout("html.createObjectBox("+(object.tagName?object.tagName:object)+", isRoot:"+(isRoot?"true":"false")+")\n"); + var tag = getNodeTag(object); + if (tag) + return tag.replace({object: object}, this.document); + }, + + getParentObject: function(node) + { + if (node instanceof SourceText) + return node.owner; + + if (this.rootElement && node == this.rootElement) // this.rootElement is never set + return null; + + var parentNode = node ? node.parentNode : null; + if (parentNode) + if (parentNode.nodeType == 9) + { + if (FBTrace.DBG_HTML) + FBTrace.sysout("html.getParentObject parentNode.nodeType 9\n"); + if (parentNode.defaultView) + return parentNode.defaultView.frameElement; + else + { + if (FBTrace.DBG_HTML || FBTrace.DBG_ERRORS) + FBTrace.sysout("html.getParentObject parentNode.nodeType 9 but no defaultView?", parentNode); + } + } + else + return parentNode; + else + if (node && node.nodeType == 9) // document type + { + var embeddingFrame = node.defaultView.frameElement; + if (embeddingFrame) + return embeddingFrame.parentNode; + else + return null; // top level has no parent + } + + }, + + getChildObject: function(node, index, previousSibling) + { + if (isSourceElement(node)) + { + if (index == 0) + return this.getElementSourceText(node); + } + else if (previousSibling) + { + return this.findNextSibling(previousSibling); + } + else + { + if (index == 0 && node.contentDocument) + return node.contentDocument.documentElement; + else if (Firebug.showWhitespaceNodes) + return node.childNodes[index]; + else + { + var childIndex = 0; + for (var child = node.firstChild; child; child = child.nextSibling) + { + if (!this.isWhitespaceText(child) && childIndex++ == index) + return child; + } + } + } + + return null; + }, + + isWhitespaceText: function(node) + { + if (node instanceof HTMLAppletElement) + return false; + return node.nodeType == 3 && isWhitespace(node.nodeValue); + }, + + findNextSibling: function (node) + { + if (Firebug.showWhitespaceNodes) + return node.nextSibling; + else + { + for (var child = node.nextSibling; child; child = child.nextSibling) + { + if (!this.isWhitespaceText(child)) + return child; + } + } + }, + + isSourceElement: function(element) + { + var tag = element.localName.toLowerCase(); + return tag == "script" || tag == "link" || tag == "style" + || (tag == "link" && element.getAttribute("rel") == "stylesheet"); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Events + + onMutateAttr: function(event) + { + var target = event.target; + if (target.firebugIgnore) + return; + + var attrChange = event.attrChange; + var attrName = event.attrName; + var newValue = event.newValue; + + this.context.delay(function() + { + this.mutateAttr(target, attrChange, attrName, newValue); + }, this); + }, + + onMutateText: function(event) + { + var target = event.target; + var parent = target.parentNode; + + var newValue = event.newValue; + + this.context.delay(function() + { + this.mutateText(target, parent, newValue); + }, this); + }, + + onMutateNode: function(event) + { + var target = event.target; + if (target.firebugIgnore) + return; + + var parent = event.relatedNode; + var removal = event.type == "DOMNodeRemoved"; + var nextSibling = removal ? null : this.findNextSibling(target); + + this.context.delay(function() + { + try + { + this.mutateNode(target, parent, nextSibling, removal); + } + catch (exc) + { + if (FBTrace.DBG_ERRORS || FBTrace.DBG_HTML) + FBTrace.sysout("html.onMutateNode FAILS:", exc); + } + }, this); + }, + + onClick: function(event) + { + if (isLeftClick(event) && event.detail == 2) + { + if (getAncestorByClass(event.target, "nodeTag")) + { + var node = Firebug.getRepObject(event.target); + this.editNode(node); + } + } + }, + + onMouseDown: function(event) + { + if (!isLeftClick(event)) + return; + + if (getAncestorByClass(event.target, "nodeTag")) + { + var node = Firebug.getRepObject(event.target); + this.noScrollIntoView = true; + this.select(node); + delete this.noScrollIntoView; + var box = this.ioBox.createObjectBox(node); + if (!hasClass(box, "open")) + this.ioBox.expandObject(node); + else + this.ioBox.contractObject(this.selection); + } + }, + + onKeyPress: function(event) + { + if (this.editing || isControl(event) || isShift(event)) + return; + + if (event.keyCode == KeyEvent.DOM_VK_UP) + this.selectNodeBy("up"); + else if (event.keyCode == KeyEvent.DOM_VK_DOWN) + this.selectNodeBy("down"); + else if (event.keyCode == KeyEvent.DOM_VK_LEFT) + this.selectNodeBy("left"); + else if (event.keyCode == KeyEvent.DOM_VK_RIGHT) + this.selectNodeBy("right"); + else + return; + + cancelEvent(event); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "HTML2", + title: "HTML2", + + options: {}, + + create: function(){ + Firebug.Panel.create.apply(this, arguments); + + var style = this.panelNode.style; + style.fontFamily = "Monaco,monospace"; + style.padding = "0 1px"; + + this.onClick = bind(this.onClick, this); + this.onMouseDown = bind(this.onMouseDown, this); + this.onKeyPress = bind(this.onKeyPress, this); + + //var object = Firebug.browser.document.documentElement; + //Firebug.HTMLPanel.Element.tag.replace({object: object}, this.panelNode); + }, + + initialize: function(){ + Firebug.Panel.initialize.apply(this, arguments); + + this.document = Firebug.chrome.document; + + if (!this.ioBox) + this.ioBox = new InsideOutBox(this, this.panelNode); + + var object = Firebug.browser.document.documentElement; + this.select(object); + + addEvent(this.panelNode, "click", this.onClick); + addEvent(this.panelNode, "mousedown", this.onMouseDown); + }, + + /* + name: "html", + searchable: true, + dependents: ["css", "computed", "layout", "dom", "domSide", "watch"], + inspectorHistory: new Array(5), + + initialize: function() + { + this.onMutateText = bind(this.onMutateText, this); + this.onMutateAttr = bind(this.onMutateAttr, this); + this.onMutateNode = bind(this.onMutateNode, this); + this.onClick = bind(this.onClick, this); + this.onMouseDown = bind(this.onMouseDown, this); + this.onKeyPress = bind(this.onKeyPress, this); + + Firebug.Panel.initialize.apply(this, arguments); + }, + + destroy: function(state) + { + persistObjects(this, state); + + Firebug.Panel.destroy.apply(this, arguments); + }, + + initializeNode: function(oldPanelNode) + { + this.panelNode.addEventListener("click", this.onClick, false); + this.panelNode.addEventListener("mousedown", this.onMouseDown, false); + dispatch([Firebug.A11yModel], "onInitializeNode", [this]); + }, + + destroyNode: function() + { + this.panelNode.removeEventListener("click", this.onClick, false); + this.panelNode.removeEventListener("mousedown", this.onMouseDown, false); + this.panelNode.ownerDocument.removeEventListener("keypress", this.onKeyPress, true); + + if (this.ioBox) + { + this.ioBox.destroy(); + delete this.ioBox; + } + dispatch([Firebug.A11yModel], "onDestroyNode", [this]); + }, + /**/ + /* + show: function(state) + { + this.showToolbarButtons("fbHTMLButtons", true); + + if (!this.ioBox) + this.ioBox = new InsideOutBox(this, this.panelNode); + + this.panelNode.ownerDocument.addEventListener("keypress", this.onKeyPress, true); + + if (this.context.loaded) + { + if (!this.context.attachedMutation) + { + this.context.attachedMutation = true; + + iterateWindows(this.context.window, bind(function(win) + { + var doc = win.document; + doc.addEventListener("DOMAttrModified", this.onMutateAttr, false); + doc.addEventListener("DOMCharacterDataModified", this.onMutateText, false); + doc.addEventListener("DOMNodeInserted", this.onMutateNode, false); + doc.addEventListener("DOMNodeRemoved", this.onMutateNode, false); + }, this)); + } + + restoreObjects(this, state); + } + }, + + hide: function() + { + this.showToolbarButtons("fbHTMLButtons", false); + delete this.infoTipURL; // clear the state that is tracking the infotip so it is reset after next show() + this.panelNode.ownerDocument.removeEventListener("keypress", this.onKeyPress, true); + }, + + watchWindow: function(win) + { + if (this.context.window && this.context.window != win) // then I guess we are an embedded window + { + var htmlPanel = this; + iterateWindows(this.context.window, function(subwin) + { + if (win == subwin) + { + if (FBTrace.DBG_HTML) + FBTrace.sysout("html.watchWindow found subwin.location.href="+win.location.href+"\n"); + htmlPanel.mutateDocumentEmbedded(win, false); + } + }); + + } + if (this.context.attachedMutation) + { + var doc = win.document; + doc.addEventListener("DOMAttrModified", this.onMutateAttr, false); + doc.addEventListener("DOMCharacterDataModified", this.onMutateText, false); + doc.addEventListener("DOMNodeInserted", this.onMutateNode, false); + doc.addEventListener("DOMNodeRemoved", this.onMutateNode, false); + } + }, + + unwatchWindow: function(win) + { + if (this.context.window && this.context.window != win) // then I guess we are an embedded window + { + var htmlPanel = this; + iterateWindows(this.context.window, function(subwin) + { + if (win == subwin) + { + if (FBTrace.DBG_HTML) + FBTrace.sysout("html.unwatchWindow found subwin.location.href="+win.location.href+"\n"); + htmlPanel.mutateDocumentEmbedded(win, true); + } + }); + + } + var doc = win.document; + doc.removeEventListener("DOMAttrModified", this.onMutateAttr, false); + doc.removeEventListener("DOMCharacterDataModified", this.onMutateText, false); + doc.removeEventListener("DOMNodeInserted", this.onMutateNode, false); + doc.removeEventListener("DOMNodeRemoved", this.onMutateNode, false); + }, + /**/ + + mutateDocumentEmbedded: function(win, remove) + { + // document.documentElement Returns the Element that is a direct child of document. For HTML documents, this normally the HTML element. + var target = win.document.documentElement; + var parent = win.frameElement; + var nextSibling = this.findNextSibling(target); + this.mutateNode(target, parent, nextSibling, remove); + }, + + supportsObject: function(object) + { + if (object instanceof Element || object instanceof Text || object instanceof CDATASection) + return 2; + else if (object instanceof SourceLink && object.type == "css" && !reCSS.test(object.href)) + return 2; + else + return 0; + }, + + updateOption: function(name, value) + { + var viewOptionNames = {showCommentNodes:1, showWhitespaceNodes:1 , showFullTextNodes:1}; + if (name in viewOptionNames) + { + this.resetSearch(); + clearNode(this.panelNode); + if (this.ioBox) + this.ioBox.destroy(); + + this.ioBox = new InsideOutBox(this, this.panelNode); + this.ioBox.select(this.selection, true, true); + } + }, + + updateSelection: function(object) + { + if (FBTrace.DBG_HTML) + FBTrace.sysout("html.updateSelection "+object); + if (this.ioBox.sourceRow) + this.ioBox.sourceRow.removeAttribute("exeLine"); + + if (object instanceof SourceLink) // && object.type == "css" and !reCSS(object.href) by supports + { + var sourceLink = object; + var stylesheet = getStyleSheetByHref(sourceLink.href, this.context); + if (stylesheet) + { + var ownerNode = stylesheet.ownerNode; + if (FBTrace.DBG_CSS) + FBTrace.sysout("html panel updateSelection stylesheet.ownerNode="+stylesheet.ownerNode + +" href:"+sourceLink.href+"\n"); + if (ownerNode) + { + var objectbox = this.ioBox.select(ownerNode, true, true, this.noScrollIntoView); + + // XXXjjb seems like this could be bad for errors at the end of long files + // + var sourceRow = FBL.getElementByClass(objectbox, "sourceRow"); // first source row in style + for (var lineNo = 1; lineNo < sourceLink.line; lineNo++) + { + if (!sourceRow) break; + sourceRow = FBL.getNextByClass(sourceRow, "sourceRow"); + } + if (FBTrace.DBG_CSS) + FBTrace.sysout("html panel updateSelection sourceLink.line="+sourceLink.line + +" sourceRow="+(sourceRow?sourceRow.innerHTML:"undefined")+"\n"); + if (sourceRow) + { + this.ioBox.sourceRow = sourceRow; + this.ioBox.sourceRow.setAttribute("exeLine", "true"); + scrollIntoCenterView(sourceRow); + this.ioBox.selectObjectBox(sourceRow, false); // sourceRow isn't an objectBox, but the function should work anyway... + } + } + } + } + else if (Firebug.Inspector.inspecting) + { + this.ioBox.highlight(object); + } + else + { + this.ioBox.select(object, true, false, this.noScrollIntoView); + + // TODO: xxxpedro + //this.inspectorHistory.unshift(object); + //if (this.inspectorHistory.length > 5) + // this.inspectorHistory.pop(); + } + }, + + stopInspecting: function(object, cancelled) + { + if (object != this.inspectorHistory) + { + // Manage history of selection for later access in the command line. + this.inspectorHistory.unshift(object); + if (this.inspectorHistory.length > 5) + this.inspectorHistory.pop(); + + if (FBTrace.DBG_HTML) + FBTrace.sysout("html.stopInspecting: inspectoryHistory updated", this.inspectorHistory); + } + + this.ioBox.highlight(null); + + if (!cancelled) + this.ioBox.select(object, true); + }, + + search: function(text, reverse) + { + if (!text) + return; + + var search; + if (text == this.searchText && this.lastSearch) + search = this.lastSearch; + else + { + var doc = this.context.window.document; + if (Firebug.searchSelector) + search = this.lastSearch = new SelectorSearch(text, doc, this.panelNode, this.ioBox); + else + search = this.lastSearch = new NodeSearch(text, doc, this.panelNode, this.ioBox); + } + + var loopAround = search.find(reverse, Firebug.searchCaseSensitive); + if (loopAround) + { + this.resetSearch(); + this.search(text, reverse); + } + + return !search.noMatch; + }, + + getSearchOptionsMenuItems: function() + { + return [ + optionMenu("search.html.CSS_Selector", "searchSelector") + ]; + }, + + getDefaultSelection: function() + { + try + { + var doc = this.context.window.document; + return doc.body ? doc.body : getPreviousElement(doc.documentElement.lastChild); + } + catch (exc) + { + return null; + } + }, + + getObjectPath: function(element) + { + var path = []; + for (; element; element = this.getParentObject(element)) + path.push(element); + + return path; + }, + + getPopupObject: function(target) + { + return Firebug.getRepObject(target); + }, + + getTooltipObject: function(target) + { + return null; + }, + + getOptionsMenuItems: function() + { + return [ + optionMenu("ShowFullText", "showFullTextNodes"), + optionMenu("ShowWhitespace", "showWhitespaceNodes"), + optionMenu("ShowComments", "showCommentNodes"), + "-", + optionMenu("HighlightMutations", "highlightMutations"), + optionMenu("ExpandMutations", "expandMutations"), + optionMenu("ScrollToMutations", "scrollToMutations") + ]; + }, + + getContextMenuItems: function(node, target) + { + if (!node) + return null; + + var items = []; + + if (node && node.nodeType == 1) + { + items.push( + "-", + {label: "NewAttribute", command: bindFixed(this.editNewAttribute, this, node) } + ); + + var attrBox = getAncestorByClass(target, "nodeAttr"); + if (getAncestorByClass(target, "nodeAttr")) + { + var attrName = attrBox.childNodes[1].textContent; + + items.push( + {label: $STRF("EditAttribute", [attrName]), nol10n: true, + command: bindFixed(this.editAttribute, this, node, attrName) }, + {label: $STRF("DeleteAttribute", [attrName]), nol10n: true, + command: bindFixed(this.deleteAttribute, this, node, attrName) } + ); + } + + if (!( nonEditableTags.hasOwnProperty(node.localName) )) + { + items.push( + "-", + {label: "EditElement", command: bindFixed(this.editNode, this, node) }, + {label: "DeleteElement", command: bindFixed(this.deleteNode, this, node) } + ); + } + + } + else + { + items.push( + "-", + {label: "EditNode", command: bindFixed(this.editNode, this, node) }, + {label: "DeleteNode", command: bindFixed(this.deleteNode, this, node) } + ); + } + + return items; + }, + + showInfoTip: function(infoTip, target, x, y) + { + if (!hasClass(target, "nodeValue")) + return; + + var targetNode = Firebug.getRepObject(target); + if (targetNode && targetNode.nodeType == 1 && targetNode.localName.toUpperCase() == "IMG") + { + var url = targetNode.src; + if (url == this.infoTipURL) // This state cleared in hide() + return true; + + this.infoTipURL = url; + return Firebug.InfoTip.populateImageInfoTip(infoTip, url); + } + }, + + getEditor: function(target, value) + { + if (hasClass(target, "nodeName") || hasClass(target, "nodeValue") || hasClass(target, "nodeBracket")) + { + if (!this.attrEditor) + this.attrEditor = new AttributeEditor(this.document); + + return this.attrEditor; + } + else if (hasClass(target, "nodeText")) + { + // XXXjoe Implement special text node editor + if (!this.textEditor) + this.textEditor = new AttributeEditor(this.document); + + return this.textEditor; + } + }, + + getInspectorVars: function() + { + var vars = {}; + for (var i=0; i<2; i++) + vars["$"+i] = this.inspectorHistory[i]; + + return vars; + } +}); + +// ************************************************************************************************ + +Firebug.HTMLPanel.CompleteElement = domplate(FirebugReps.Element, +{ + tag: + DIV({"class": "nodeBox open $object|getHidden repIgnore", _repObject: "$object", role : 'presentation'}, + DIV({"class": "nodeLabel", role: "presentation"}, + SPAN({"class": "nodeLabelBox repTarget repTarget", role : 'treeitem', 'aria-expanded' : 'false'}, + "<", + SPAN({"class": "nodeTag"}, "$object.localName|toLowerCase"), + FOR("attr", "$object|attrIterator", AttrTag), + SPAN({"class": "nodeBracket"}, ">") + ) + ), + DIV({"class": "nodeChildBox", role :"group"}, + FOR("child", "$object|childIterator", + TAG("$child|getNodeTag", {object: "$child"}) + ) + ), + DIV({"class": "nodeCloseLabel", role:"presentation"}, + "</", + SPAN({"class": "nodeTag"}, "$object.localName|toLowerCase"), + ">" + ) + ), + + getNodeTag: function(node) + { + return getNodeTag(node, true); + }, + + childIterator: function(node) + { + if (node.contentDocument) + return [node.contentDocument.documentElement]; + + if (Firebug.showWhitespaceNodes) + return cloneArray(node.childNodes); + else + { + var nodes = []; + for (var child = node.firstChild; child; child = child.nextSibling) + { + if (child.nodeType != 3 || !isWhitespaceText(child)) + nodes.push(child); + } + return nodes; + } + } +}); + +Firebug.HTMLPanel.SoloElement = domplate(Firebug.HTMLPanel.CompleteElement, +{ + tag: + DIV({"class": "soloElement", onmousedown: "$onMouseDown"}, + Firebug.HTMLPanel.CompleteElement.tag + ), + + onMouseDown: function(event) + { + for (var child = event.target; child; child = child.parentNode) + { + if (child.repObject) + { + var panel = Firebug.getElementPanel(child); + Firebug.chrome.select(child.repObject); + break; + } + } + } +}); + +Firebug.HTMLPanel.Element = domplate(FirebugReps.Element, +{ + tag: + DIV({"class": "nodeBox containerNodeBox $object|getHidden repIgnore", _repObject: "$object", role :"presentation"}, + DIV({"class": "nodeLabel", role: "presentation"}, + IMG({"class": "twisty", role: "presentation"}), + SPAN({"class": "nodeLabelBox repTarget", role : 'treeitem', 'aria-expanded' : 'false'}, + "<", + SPAN({"class": "nodeTag"}, "$object.localName|toLowerCase"), + FOR("attr", "$object|attrIterator", AttrTag), + SPAN({"class": "nodeBracket editable insertBefore"}, ">") + ) + ), + DIV({"class": "nodeChildBox", role :"group"}), + DIV({"class": "nodeCloseLabel", role : "presentation"}, + SPAN({"class": "nodeCloseLabelBox repTarget"}, + "</", + SPAN({"class": "nodeTag"}, "$object.localName|toLowerCase"), + ">" + ) + ) + ) +}); + +Firebug.HTMLPanel.TextElement = domplate(FirebugReps.Element, +{ + tag: + DIV({"class": "nodeBox textNodeBox $object|getHidden repIgnore", _repObject: "$object", role : 'presentation'}, + DIV({"class": "nodeLabel", role: "presentation"}, + SPAN({"class": "nodeLabelBox repTarget", role : 'treeitem'}, + "<", + SPAN({"class": "nodeTag"}, "$object.localName|toLowerCase"), + FOR("attr", "$object|attrIterator", AttrTag), + SPAN({"class": "nodeBracket editable insertBefore"}, ">"), + SPAN({"class": "nodeText editable"}, "$object|getNodeText"), + "</", + SPAN({"class": "nodeTag"}, "$object.localName|toLowerCase"), + ">" + ) + ) + ) +}); + +Firebug.HTMLPanel.EmptyElement = domplate(FirebugReps.Element, +{ + tag: + DIV({"class": "nodeBox emptyNodeBox $object|getHidden repIgnore", _repObject: "$object", role : 'presentation'}, + DIV({"class": "nodeLabel", role: "presentation"}, + SPAN({"class": "nodeLabelBox repTarget", role : 'treeitem'}, + "<", + SPAN({"class": "nodeTag"}, "$object.localName|toLowerCase"), + FOR("attr", "$object|attrIterator", AttrTag), + SPAN({"class": "nodeBracket editable insertBefore"}, ">") + ) + ) + ) +}); + +Firebug.HTMLPanel.XEmptyElement = domplate(FirebugReps.Element, +{ + tag: + DIV({"class": "nodeBox emptyNodeBox $object|getHidden repIgnore", _repObject: "$object", role : 'presentation'}, + DIV({"class": "nodeLabel", role: "presentation"}, + SPAN({"class": "nodeLabelBox repTarget", role : 'treeitem'}, + "<", + SPAN({"class": "nodeTag"}, "$object.localName|toLowerCase"), + FOR("attr", "$object|attrIterator", AttrTag), + SPAN({"class": "nodeBracket editable insertBefore"}, "/>") + ) + ) + ) +}); + +Firebug.HTMLPanel.AttrNode = domplate(FirebugReps.Element, +{ + tag: AttrTag +}), + +Firebug.HTMLPanel.TextNode = domplate(FirebugReps.Element, +{ + tag: + DIV({"class": "nodeBox", _repObject: "$object"}, + SPAN({"class": "nodeText editable"}, "$object.nodeValue") + ) +}), + +Firebug.HTMLPanel.WhitespaceNode = domplate(FirebugReps.Element, +{ + tag: + DIV({"class": "nodeBox", _repObject: "$object"}, + FOR("char", "$object|charIterator", + SPAN({"class": "nodeText nodeWhiteSpace editable"}, "$char") + ) + ), + charIterator: function(node) + { + var str = node.nodeValue; + var arr = []; + for(var i = 0; i < str.length; i++) + { + // http://www.w3.org/TR/html401/struct/text.html + var char = str[i]; + switch(char) + { + case ' ': arr[i] = ' ';break; + case '\t': arr[i] = '\\t';break; + case '\n': arr[i] = '\\n';break; + case '\u200B': arr[i] = '\\u200B';break; // Zero width space http://www.fileformat.info/info/unicode/char/200b/index.htm + default: arr[i] = '?'; break; + } + } + return arr; + } +}), + +Firebug.HTMLPanel.CDATANode = domplate(FirebugReps.Element, +{ + tag: + DIV({"class": "nodeBox", _repObject: "$object"}, + "<![CDATA[", + SPAN({"class": "nodeText editable"}, "$object.nodeValue"), + "]]>" + ) +}), + +Firebug.HTMLPanel.CommentNode = domplate(FirebugReps.Element, +{ + tag: + DIV({"class": "nodeBox", _repObject: "$object"}, + DIV({"class": "nodeComment editable"}, + "<!--$object.nodeValue-->" + ) + ) +}); + +// ************************************************************************************************ +// AttributeEditor + +function AttributeEditor(doc) +{ + this.initializeInline(doc); +} +/* +AttributeEditor.prototype = domplate(Firebug.InlineEditor.prototype, +{ + saveEdit: function(target, value, previousValue) + { + var element = Firebug.getRepObject(target); + if (!element) + return; + + target.innerHTML = escapeHTML(value); + + if (hasClass(target, "nodeName")) + { + if (value != previousValue) + element.removeAttribute(previousValue); + + if (value) + { + var attrValue = getNextByClass(target, "nodeValue").textContent; + element.setAttribute(value, attrValue); + } + else + element.removeAttribute(value); + } + else if (hasClass(target, "nodeValue")) + { + var attrName = getPreviousByClass(target, "nodeName").textContent; + element.setAttribute(attrName, value); + } + else if (hasClass(target, "nodeText")) + { + if (element instanceof Element) + element.innerHTML = value; + else + element.nodeValue = value; + } + + //this.panel.markChange(); + }, + + advanceToNext: function(target, charCode) + { + if (charCode == 61 && hasClass(target, "nodeName")) + return true; + }, + + insertNewRow: function(target, insertWhere) + { + var emptyAttr = {nodeName: "", nodeValue: ""}; + var sibling = insertWhere == "before" ? target.previousSibling : target; + + return AttrTag.insertAfter({attr: emptyAttr}, sibling); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getAutoCompleteRange: function(value, offset) + { + }, + + getAutoCompleteList: function(preExpr, expr, postExpr) + { + } +}); +/**/ +// ************************************************************************************************ +// HTMLEditor + +function HTMLEditor(doc) +{ + this.box = this.tag.replace({}, doc, this); + this.input = this.box.firstChild; + + this.multiLine = true; + this.tabNavigation = false; + this.arrowCompletion = false; +} + +HTMLEditor.prototype = domplate(Firebug.BaseEditor, +{ + tag: DIV( + TEXTAREA({"class": "htmlEditor 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.editingElements = [target.repObject, null]; + + this.panel.panelNode.appendChild(this.box); + + this.input.value = value; + this.input.focus(); + + var command = Firebug.chrome.$("cmd_toggleHTMLEditing"); + command.setAttribute("checked", true); + }, + + hide: function() + { + var command = Firebug.chrome.$("cmd_toggleHTMLEditing"); + command.setAttribute("checked", false); + + this.panel.panelNode.removeChild(this.box); + + delete this.editingElements; + delete this.target; + delete this.panel; + }, + + saveEdit: function(target, value, previousValue) + { + // Remove all of the nodes in the last range we created, except for + // the first one, because setOuterHTML will replace it + var first = this.editingElements[0], last = this.editingElements[1]; + if (last && last != first) + { + for (var child = first.nextSibling; child;) + { + var next = child.nextSibling; + child.parentNode.removeChild(child); + if (child == last) + break; + else + child = next; + } + } + + // Make sure that we create at least one node here, even if it's just + // an empty space, because this code depends on having something to replace + if (!value) + value = " "; + + if (this.innerEditMode) + this.editingElements[0].innerHTML = value; + else + this.editingElements = setOuterHTML(this.editingElements[0], value); + }, + + endEditing: function() + { + //this.panel.markChange(); + return true; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + onInput: function() + { + Firebug.Editor.update(); + } +}); + +// ************************************************************************************************ +// Local Helpers + +function getEmptyElementTag(node) +{ + if (node.ownerDocument.documentElement.namespaceURI == "http://www.w3.org/1999/xhtml") + return Firebug.HTMLPanel.XEmptyElement.tag; + else + return Firebug.HTMLPanel.EmptyElement.tag; +} + +function getNodeTag(node, expandAll) +{ + if (node instanceof Element) + { + if (node instanceof HTMLAppletElement) + return getEmptyElementTag(node); + else if (node.firebugIgnore) + return null; + else if (isContainerElement(node)) + return expandAll ? Firebug.HTMLPanel.CompleteElement.tag : Firebug.HTMLPanel.Element.tag; + else if (isEmptyElement(node)) + return getEmptyElementTag(node); + else if (hasNoElementChildren(node)) + return Firebug.HTMLPanel.TextElement.tag; + else + return expandAll ? Firebug.HTMLPanel.CompleteElement.tag : Firebug.HTMLPanel.Element.tag; + } + else if (node instanceof Text) + return Firebug.showWhitespaceNodes ? Firebug.HTMLPanel.WhitespaceNode.tag : Firebug.HTMLPanel.TextNode.tag; + else if (node instanceof CDATASection) + return Firebug.HTMLPanel.CDATANode.tag; + else if (node instanceof Comment && (Firebug.showCommentNodes || expandAll)) + return Firebug.HTMLPanel.CommentNode.tag; + else if (node instanceof SourceText) + return FirebugReps.SourceText.tag; + else + return FirebugReps.Nada.tag; +} + +function getNodeBoxTag(nodeBox) +{ + var re = /([^\s]+)NodeBox/; + var m = re.exec(nodeBox.className); + if (!m) + return null; + + var nodeBoxType = m[1]; + if (nodeBoxType == "container") + return Firebug.HTMLPanel.Element.tag; + else if (nodeBoxType == "text") + return Firebug.HTMLPanel.TextElement.tag; + else if (nodeBoxType == "empty") + return Firebug.HTMLPanel.EmptyElement.tag; +} + +function getSourceHref(element) +{ + var tag = element.localName.toLowerCase(); + if (tag == "script" && element.src) + return element.src; + else if (tag == "link") + return element.href; + else + return null; +} + +function getSourceText(element) +{ + var tag = element.localName.toLowerCase(); + if (tag == "script" && !element.src) + return element.textContent; + else if (tag == "style") + return element.textContent; + else + return null; +} + +function isContainerElement(element) +{ + var tag = element.localName.toLowerCase(); + switch (tag) + { + case "script": + case "style": + case "iframe": + case "frame": + case "tabbrowser": + case "browser": + return true; + case "link": + return element.getAttribute("rel") == "stylesheet"; + } + return false; +} + +var hasNoElementChildren = function hasNoElementChildren(element) +{ + if (element.childElementCount != 0) // FF 3.5+ + return false; + + // https://developer.mozilla.org/en/XBL/XBL_1.0_Reference/DOM_Interfaces + // TODO: xxxpedro + /* + if (element.ownerDocument instanceof Ci.nsIDOMDocumentXBL) + { + var anonChildren = element.ownerDocument.getAnonymousNodes(element); + if (anonChildren) + { + for (var i = 0; i < anonChildren.length; i++) + { + if (anonChildren[i].nodeType == 1) + return false; + } + } + } + /**/ + if (FBTrace.DBG_HTML) + FBTrace.sysout("hasNoElementChildren TRUE "+element.tagName, element); + return true; +}; + +// Duplicate of HTMLPanel.prototype isWhitespaceText +var isWhitespaceText = function isWhitespaceText(node) +{ + if (node instanceof HTMLAppletElement) + return false; + return node.nodeType == 3 && isWhitespace(node.nodeValue); +}; + +// Duplicate of HTMLPanel.prototype TODO: create a namespace for all of these functions so +// they can be called outside of this file. +function isSourceElement(element) +{ + var tag = element.localName.toLowerCase(); + return tag == "script" || tag == "link" || tag == "style" + || (tag == "link" && element.getAttribute("rel") == "stylesheet"); +} + +function isEmptyElement(element) +{ + // XXXjjb the commented code causes issues 48, 240, and 244. I think the lines should be deleted. + // If the DOM has whitespace children, then the element is not empty even if + // we decide not to show the whitespace in the UI. + + // XXXsroussey reverted above but added a check for self closing tags + if (Firebug.showWhitespaceNodes) + { + return !element.firstChild && isSelfClosing(element); + } + else + { + for (var child = element.firstChild; child; child = child.nextSibling) + { + if (!isWhitespaceText(child)) + return false; + } + } + return isSelfClosing(element); +} + +function findNextSibling(node) +{ + if (Firebug.showWhitespaceNodes) + return node.nextSibling; + else + { + // only return a non-whitespace node + for (var child = node.nextSibling; child; child = child.nextSibling) + { + if (!isWhitespaceText(child)) + return child; + } + } +} + +function findNodeAttrBox(objectNodeBox, attrName) +{ + var child = objectNodeBox.firstChild.lastChild.firstChild; + for (; child; child = child.nextSibling) + { + if (hasClass(child, "nodeAttr") && child.childNodes[1].firstChild + && child.childNodes[1].firstChild.nodeValue == attrName) + { + return child; + } + } +} + +function getTextElementTextBox(nodeBox) +{ + var nodeLabelBox = nodeBox.firstChild.lastChild; + return getChildByClass(nodeLabelBox, "nodeText"); +} + +function findElementNameBox(objectNodeBox) +{ + return objectNodeBox.getElementsByClassName("nodeTag")[0]; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +function NodeSearch(text, doc, panelNode, ioBox) +{ + var walker = new DOMWalker(doc, doc.documentElement); + var re = new ReversibleRegExp(text, "m"); + var matchCount = 0; + + this.find = function(reverse, caseSensitive) + { + var match = this.findNextMatch(reverse, caseSensitive); + if (match) + { + this.lastMatch = match; + ++matchCount; + + var node = match.node; + var nodeBox = this.openToNode(node, match.isValue); + + this.selectMatched(nodeBox, node, match, reverse); + } + else if (matchCount) + return true; + else + { + this.noMatch = true; + dispatch([Firebug.A11yModel], 'onHTMLSearchNoMatchFound', [panelNode.ownerPanel, text]); + } + }; + + this.reset = function() + { + delete this.lastMatch; + delete this.lastRange; + }; + + this.findNextMatch = function(reverse, caseSensitive) + { + + var innerMatch = this.findNextInnerMatch(reverse, caseSensitive); + if (innerMatch) + return innerMatch; + else + this.reset(); + + function walkNode() { return reverse ? walker.previousNode() : walker.nextNode(); } + + var node; + while (node = walkNode()) + { + if (node.nodeType == Node.TEXT_NODE) + { + if (isSourceElement(node.parentNode)) + continue; + } + + var m = this.checkNode(node, reverse, caseSensitive); + if (m) + return m; + } + }; + + this.findNextInnerMatch = function(reverse, caseSensitive) + { + if (this.lastRange) + { + var lastMatchNode = this.lastMatch.node; + var lastReMatch = this.lastMatch.match; + var m = re.exec(lastReMatch.input, reverse, lastReMatch.caseSensitive, lastReMatch); + if (m) + { + return { + node: lastMatchNode, + isValue: this.lastMatch.isValue, + match: m + }; + } + + // May need to check the pair for attributes + if (lastMatchNode.nodeType == Node.ATTRIBUTE_NODE + && this.lastMatch.isValue == reverse) + { + return this.checkNode(lastMatchNode, reverse, caseSensitive, 1); + } + } + }; + + this.checkNode = function(node, reverse, caseSensitive, firstStep) + { + var checkOrder; + if (node.nodeType != Node.TEXT_NODE) + { + var nameCheck = { name: "nodeName", isValue: false, caseSensitive: false }; + var valueCheck = { name: "nodeValue", isValue: true, caseSensitive: caseSensitive }; + checkOrder = reverse ? [ valueCheck, nameCheck ] : [ nameCheck, valueCheck ]; + } + else + { + checkOrder = [{name: "nodeValue", isValue: false, caseSensitive: caseSensitive }]; + } + + for (var i = firstStep || 0; i < checkOrder.length; i++) { + var m = re.exec(node[checkOrder[i].name], reverse, checkOrder[i].caseSensitive); + if (m) + return { + node: node, + isValue: checkOrder[i].isValue, + match: m + }; + } + }; + + this.openToNode = function(node, isValue) + { + if (node.nodeType == Node.ELEMENT_NODE) + { + var nodeBox = ioBox.openToObject(node); + return findElementNameBox(nodeBox); + } + else if (node.nodeType == Node.ATTRIBUTE_NODE) + { + var nodeBox = ioBox.openToObject(node.ownerElement); + if (nodeBox) + { + var attrNodeBox = findNodeAttrBox(nodeBox, node.nodeName); + if (isValue) + return getChildByClass(attrNodeBox, "nodeValue"); + else + return getChildByClass(attrNodeBox, "nodeName"); + } + } + else if (node.nodeType == Node.TEXT_NODE) + { + var nodeBox = ioBox.openToObject(node); + if (nodeBox) + return nodeBox; + else + { + var nodeBox = ioBox.openToObject(node.parentNode); + if (hasClass(nodeBox, "textNodeBox")) + nodeBox = getTextElementTextBox(nodeBox); + return nodeBox; + } + } + }; + + this.selectMatched = function(nodeBox, node, match, reverse) + { + setTimeout(bindFixed(function() + { + var reMatch = match.match; + this.selectNodeText(nodeBox, node, reMatch[0], reMatch.index, reverse, reMatch.caseSensitive); + dispatch([Firebug.A11yModel], 'onHTMLSearchMatchFound', [panelNode.ownerPanel, match]); + }, this)); + }; + + this.selectNodeText = function(nodeBox, node, text, index, reverse, caseSensitive) + { + var row, range; + + // If we are still inside the same node as the last search, advance the range + // to the next substring within that node + if (nodeBox == this.lastNodeBox) + { + var target = this.lastRange.startContainer; + range = this.lastRange = panelNode.ownerDocument.createRange(); + range.setStart(target, index); + range.setEnd(target, index+text.length); + + row = this.lastRow; + } + + if (!range) + { + // Search for the first instance of the string inside the node + function findRow(node) { return node.nodeType == 1 ? node : node.parentNode; } + var search = new TextSearch(nodeBox, findRow); + row = this.lastRow = search.find(text, reverse, caseSensitive); + range = this.lastRange = search.range; + this.lastNodeBox = nodeBox; + } + + if (row) + { + var sel = panelNode.ownerDocument.defaultView.getSelection(); + sel.removeAllRanges(); + sel.addRange(range); + + scrollIntoCenterView(row, panelNode); + return true; + } + }; + +} + +//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +function SelectorSearch(text, doc, panelNode, ioBox) +{ + this.parent = new NodeSearch(text, doc, panelNode, ioBox); + + this.find = this.parent.find; + this.reset = this.parent.reset; + this.openToNode = this.parent.openToNode; + + try + { + // http://dev.w3.org/2006/webapi/selectors-api/ + this.matchingNodes = doc.querySelectorAll(text); + this.matchIndex = 0; + } + catch(exc) + { + FBTrace.sysout("SelectorSearch FAILS "+exc, exc); + } + + this.findNextMatch = function(reverse, caseSensitive) + { + if (!this.matchingNodes || !this.matchingNodes.length) + return undefined; + + if (reverse) + { + if (this.matchIndex > 0) + return { node: this.matchingNodes[this.matchIndex--], isValue: false, match: "?XX?"}; + else + return undefined; + } + else + { + if (this.matchIndex < this.matchingNodes.length) + return { node: this.matchingNodes[this.matchIndex++], isValue: false, match: "?XX?"}; + else + return undefined; + } + }; + + this.selectMatched = function(nodeBox, node, match, reverse) + { + setTimeout(bindFixed(function() + { + ioBox.select(node, true, true); + dispatch([Firebug.A11yModel], 'onHTMLSearchMatchFound', [panelNode.ownerPanel, match]); + }, this)); + }; +} +// ************************************************************************************************ + +Firebug.registerPanel(Firebug.HTMLPanel); + +// ************************************************************************************************ + +}}); diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/temp/html3.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/temp/html3.js new file mode 100644 index 00000000000..8aff8016976 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/temp/html3.js @@ -0,0 +1,2200 @@ +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// Constants +/* +const Cc = Components.classes; +const Ci = Components.interfaces; + +const MODIFICATION = MutationEvent.MODIFICATION; +const ADDITION = MutationEvent.ADDITION; +const REMOVAL = MutationEvent.REMOVAL; + +const BP_BREAKONATTRCHANGE = 1; +const BP_BREAKONCHILDCHANGE = 2; +const BP_BREAKONREMOVE = 3; +const BP_BREAKONTEXT = 4; +/**/ + +/// TODO: xxxpedro hack +Firebug.A11yModel = {}; + +var HTMLLib = Firebug.HTMLLib; + +// ************************************************************************************************ + +Firebug.HTMLModule = extend(Firebug.Module, +{ + initialize: function(prefDomain, prefNames) + { + Firebug.Module.initialize.apply(this, arguments); + Firebug.Debugger.addListener(this.DebuggerListener); + }, + + initContext: function(context, persistedState) + { + Firebug.Module.initContext.apply(this, arguments); + context.mutationBreakpoints = new MutationBreakpointGroup(); + }, + + loadedContext: function(context, persistedState) + { + context.mutationBreakpoints.load(context); + }, + + destroyContext: function(context, persistedState) + { + Firebug.Module.destroyContext.apply(this, arguments); + + context.mutationBreakpoints.store(context); + }, + + shutdown: function() + { + Firebug.Module.shutdown.apply(this, arguments); + Firebug.Debugger.removeListener(this.DebuggerListener); + }, + + deleteNode: function(node, context) + { + dispatch(this.fbListeners, "onBeginFirebugChange", [node, context]); + node.parentNode.removeChild(node); + dispatch(this.fbListeners, "onEndFirebugChange", [node, context]); + }, + + deleteAttribute: function(node, attr, context) + { + dispatch(this.fbListeners, "onBeginFirebugChange", [node, context]); + node.removeAttribute(attr); + dispatch(this.fbListeners, "onEndFirebugChange", [node, context]); + } +}); + +// ************************************************************************************************ + +Firebug.HTMLPanel = function() {}; + +Firebug.HTMLPanel.prototype = extend(Firebug.Panel, +{ + toggleEditing: function() + { + if (this.editing) + Firebug.Editor.stopEditing(); + else + this.editNode(this.selection); + }, + + resetSearch: function() + { + delete this.lastSearch; + }, + + selectNext: function() + { + var objectBox = this.ioBox.createObjectBox(this.selection); + var next = this.ioBox.getNextObjectBox(objectBox); + if (next) + { + this.select(next.repObject); + + if (Firebug.Inspector.inspecting) + Firebug.Inspector.inspectNode(next.repObject); + + } + }, + + selectPrevious: function() + { + var objectBox = this.ioBox.createObjectBox(this.selection); + var previous = this.ioBox.getPreviousObjectBox(objectBox); + if (previous) + { + this.select(previous.repObject); + + if (Firebug.Inspector.inspecting) + Firebug.Inspector.inspectNode(previous.repObject); + } + }, + + selectNodeBy: function(dir) + { + if (dir == "up") + this.selectPrevious(); + else if (dir == "down") + this.selectNext(); + else if (dir == "left") + { + var box = this.ioBox.createObjectBox(this.selection); + if (!hasClass(box, "open")) + this.select(this.ioBox.getParentObjectBox(box).repObject); + else + this.ioBox.contractObject(this.selection); + } + else if (dir == "right") + { + var box = this.ioBox.createObjectBox(this.selection); + if (!hasClass(box, "open")) + this.ioBox.expandObject(this.selection); + else + this.selectNext(); + } + Firebug.Inspector.highlightObject(this.selection, this.context); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + editNewAttribute: function(elt) + { + var objectNodeBox = this.ioBox.findObjectBox(elt); + if (objectNodeBox) + { + var labelBox = objectNodeBox.firstChild.lastChild; + var bracketBox = labelBox.getElementsByClassName("nodeBracket").item(0); + Firebug.Editor.insertRow(bracketBox, "before"); + } + }, + + editAttribute: function(elt, attrName) + { + var objectNodeBox = this.ioBox.findObjectBox(elt); + if (objectNodeBox) + { + var attrBox = HTMLLib.findNodeAttrBox(objectNodeBox, attrName); + if (attrBox) + { + var attrValueBox = attrBox.childNodes[3]; + var value = elt.getAttribute(attrName); + Firebug.Editor.startEditing(attrValueBox, value); + } + } + }, + + deleteAttribute: function(elt, attrName) + { + Firebug.HTMLModule.deleteAttribute(elt, attrName, this.context); + }, + + localEditors:{}, // instantiated editor cache + editNode: function(node) + { + var objectNodeBox = this.ioBox.findObjectBox(node); + if (objectNodeBox) + { + var type = getElementType(node); + var editor = this.localEditors[type]; + if (!editor) + { + // look for special purpose editor (inserted by an extension), otherwise use our html editor + var specializedEditor = Firebug.HTMLPanel.Editors[type] || Firebug.HTMLPanel.Editors['html']; + editor = this.localEditors[type] = new specializedEditor(this.document); + } + this.startEditingNode(node, objectNodeBox, editor, type); + } + }, + + startEditingNode: function(node, box, editor, type) + { + switch (type) + { + case 'html': + case 'xhtml': + this.startEditingHTMLNode(node, box, editor); + break; + default: + this.startEditingXMLNode(node, box, editor); + } + }, + + startEditingXMLNode: function(node, box, editor) + { + var xml = getElementXML(node); + Firebug.Editor.startEditing(box, xml, editor); + }, + + startEditingHTMLNode: function(node, box, editor) + { + if ( nonEditableTags.hasOwnProperty(node.localName) ) + return; + editor.innerEditMode = node.localName in innerEditableTags; + + var html = editor.innerEditMode ? node.innerHTML : getElementHTML(node); + Firebug.Editor.startEditing(box, html, editor); + }, + + deleteNode: function(node, dir) + { + dir = dir || 'up'; + var box = this.ioBox.createObjectBox(node); + if (hasClass(box, "open")) + this.ioBox.contractObject(this.selection); + this.selectNodeBy(dir); + Firebug.HTMLModule.deleteNode(node, this.context); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getElementSourceText: function(node) + { + if (this.sourceElements) + { + var index = this.sourceElementNodes.indexOf(node); + if (index != -1) + return this.sourceElements[index]; + } + + var lines; + + var url = HTMLLib.getSourceHref(node); + if (url) + lines = this.context.sourceCache.load(url); + else + { + var text = HTMLLib.getSourceText(node); + lines = splitLines(text); + } + + var sourceElt = new SourceText(lines, node); + + if (!this.sourceElements) + { + this.sourceElements = [sourceElt]; + this.sourceElementNodes = [node]; + } + else + { + this.sourceElements.push(sourceElt); + this.sourceElementNodes.push(node); + } + + return sourceElt; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + mutateAttr: function(target, attrChange, attrName, attrValue) + { + // Every time the user scrolls we get this pointless mutation event, which + // is only bad for performance + if (attrName == "curpos") + return; + + // Due to the delay call this may or may not exist in the tree anymore + if (!this.ioBox.isInExistingRoot(target)) + { + if (FBTrace.DBG_HTML) FBTrace.sysout("mutateAttr: different tree " + target, target); + return; + } + + if (FBTrace.DBG_HTML) + FBTrace.sysout("html.mutateAttr target:"+target+" attrChange:"+attrChange+" attrName:"+attrName+" attrValue: "+attrValue, target); + + this.markChange(); + + var objectNodeBox = Firebug.scrollToMutations || Firebug.expandMutations + ? this.ioBox.createObjectBox(target) + : this.ioBox.findObjectBox(target); + + if (!objectNodeBox) + return; + + if (isVisible(objectNodeBox.repObject)) + removeClass(objectNodeBox, "nodeHidden"); + else + setClass(objectNodeBox, "nodeHidden"); + + if (attrChange == MODIFICATION || attrChange == ADDITION) + { + var nodeAttr = HTMLLib.findNodeAttrBox(objectNodeBox, attrName); + if (FBTrace.DBG_HTML) + FBTrace.sysout("mutateAttr "+attrChange+" "+attrName+"="+attrValue+" node: "+nodeAttr, nodeAttr); + if (nodeAttr && nodeAttr.childNodes.length > 3) + { + var attrValueBox = nodeAttr.childNodes[3]; + var attrValueText = nodeAttr.childNodes[3].firstChild; + if (attrValueText) + attrValueText.nodeValue = attrValue; + + this.highlightMutation(attrValueBox, objectNodeBox, "mutated"); + } + else + { + var attr = target.getAttributeNode(attrName); + if (FBTrace.DBG_HTML) + FBTrace.sysout("mutateAttr getAttributeNode "+attrChange+" "+attrName+"="+attrValue+" node: "+attr, attr); + if (attr) + { + var nodeAttr = Firebug.HTMLPanel.AttrNode.tag.replace({attr: attr}, + this.document); + + var labelBox = objectNodeBox.firstChild.lastChild; + var bracketBox = labelBox.getElementsByClassName("nodeBracket").item(0); + labelBox.insertBefore(nodeAttr, bracketBox); + + this.highlightMutation(nodeAttr, objectNodeBox, "mutated"); + } + } + } + else if (attrChange == REMOVAL) + { + var nodeAttr = HTMLLib.findNodeAttrBox(objectNodeBox, attrName); + if (nodeAttr) + { + nodeAttr.parentNode.removeChild(nodeAttr); + } + + // We want to highlight regardless as the domplate may have been + // generated after the attribute was removed from the node + this.highlightMutation(objectNodeBox, objectNodeBox, "mutated"); + } + }, + + mutateText: function(target, parent, textValue) + { + // Due to the delay call this may or may not exist in the tree anymore + if (!this.ioBox.isInExistingRoot(target)) + { + if (FBTrace.DBG_HTML) FBTrace.sysout("mutateText: different tree " + target, target); + return; + } + + this.markChange(); + + var parentNodeBox = Firebug.scrollToMutations || Firebug.expandMutations + ? this.ioBox.createObjectBox(parent) + : this.ioBox.findObjectBox(parent); + + if (!parentNodeBox) + { + if (FBTrace.DBG_HTML) FBTrace.sysout("html.mutateText failed to update text, parent node box does not exist"); + return; + } + + if (!Firebug.showFullTextNodes) + textValue = cropMultipleLines(textValue); + + var parentTag = getNodeBoxTag(parentNodeBox); + if (parentTag == Firebug.HTMLPanel.TextElement.tag) + { + if (FBTrace.DBG_HTML) + FBTrace.sysout("html.mutateText target: " + target + " parent: " + parent); + + var nodeText = HTMLLib.getTextElementTextBox(parentNodeBox); + if (!nodeText.firstChild) + { + if (FBTrace.DBG_HTML) FBTrace.sysout("html.mutateText failed to update text, TextElement firstChild does not exist"); + return; + } + + nodeText.firstChild.nodeValue = textValue; + + this.highlightMutation(nodeText, parentNodeBox, "mutated"); + } + else + { + var childBox = this.ioBox.getChildObjectBox(parentNodeBox); + if (!childBox) + { + if (FBTrace.DBG_HTML) FBTrace.sysout("html.mutateText failed to update text, no child object box found"); + return; + } + + var textNodeBox = this.ioBox.findChildObjectBox(childBox, target); + if (textNodeBox) + { + // structure for comment and cdata. Are there others? + textNodeBox.children[0].firstChild.nodeValue = textValue; + + this.highlightMutation(textNodeBox, parentNodeBox, "mutated"); + } + else if (Firebug.scrollToMutations || Firebug.expandMutations) + { + // We are not currently rendered but we are set to highlight + var objectBox = this.ioBox.createObjectBox(target); + this.highlightMutation(objectBox, objectBox, "mutated"); + } + } + }, + + mutateNode: function(target, parent, nextSibling, removal) + { + if (FBTrace.DBG_HTML) + FBTrace.sysout("\nhtml.mutateNode target:"+target+" parent:"+parent+(removal?"REMOVE":"")+"\n"); + + // Due to the delay call this may or may not exist in the tree anymore + if (!removal && !this.ioBox.isInExistingRoot(target)) + { + if (FBTrace.DBG_HTML) FBTrace.sysout("mutateNode: different tree " + target, target); + return; + } + + this.markChange(); // This invalidates the panels for every mutate + + var parentNodeBox = Firebug.scrollToMutations || Firebug.expandMutations + ? this.ioBox.createObjectBox(parent) + : this.ioBox.findObjectBox(parent); + + if (FBTrace.DBG_HTML) + FBTrace.sysout("html.mutateNode parent:"+parent+" parentNodeBox:"+parentNodeBox+"\n"); + + if (!parentNodeBox) + return; + + if (!Firebug.showTextNodesWithWhitespace && this.isWhitespaceText(target)) + return; + + // target is only whitespace + + var newParentTag = getNodeTag(parent); + var oldParentTag = getNodeBoxTag(parentNodeBox); + + if (newParentTag == oldParentTag) + { + if (parentNodeBox.populated) + { + if (removal) + { + this.ioBox.removeChildBox(parentNodeBox, target); + + this.highlightMutation(parentNodeBox, parentNodeBox, "mutated"); + } + else + { + if (nextSibling) + { + while ( + (!Firebug.showTextNodesWithWhitespace && Firebug.HTMLLib.isWhitespaceText(nextSibling)) || + (!Firebug.showCommentNodes && nextSibling instanceof Comment) + ) + { + nextSibling = this.findNextSibling(nextSibling); + } + } + + var objectBox = nextSibling + ? this.ioBox.insertChildBoxBefore(parentNodeBox, target, nextSibling) + : this.ioBox.appendChildBox(parentNodeBox, target); + + this.highlightMutation(objectBox, objectBox, "mutated"); + } + } + else // !parentNodeBox.populated + { + var newParentNodeBox = newParentTag.replace({object: parent}, this.document); + parentNodeBox.parentNode.replaceChild(newParentNodeBox, parentNodeBox); + + if (this.selection && (!this.selection.parentNode || parent == this.selection)) + this.ioBox.select(parent, true); + + this.highlightMutation(newParentNodeBox, newParentNodeBox, "mutated"); + + if (!removal && (Firebug.scrollToMutations || Firebug.expandMutations)) + { + var objectBox = this.ioBox.createObjectBox(target); + this.highlightMutation(objectBox, objectBox, "mutated"); + } + } + } + else // newParentTag != oldParentTag + { + var newParentNodeBox = newParentTag.replace({object: parent}, this.document); + if (parentNodeBox.parentNode) + parentNodeBox.parentNode.replaceChild(newParentNodeBox, parentNodeBox); + + if (hasClass(parentNodeBox, "open")) + this.ioBox.toggleObjectBox(newParentNodeBox, true); + + if (this.selection && (!this.selection.parentNode || parent == this.selection)) + this.ioBox.select(parent, true); + + this.highlightMutation(newParentNodeBox, newParentNodeBox, "mutated"); + + if (!removal && (Firebug.scrollToMutations || Firebug.expandMutations)) + { + var objectBox = this.ioBox.createObjectBox(target); + this.highlightMutation(objectBox, objectBox, "mutated"); + } + } + }, + + highlightMutation: function(elt, objectBox, type) + { + if (!elt) + return; + + if (Firebug.scrollToMutations || Firebug.expandMutations) + { + if (this.context.mutationTimeout) + { + this.context.clearTimeout(this.context.mutationTimeout); + delete this.context.mutationTimeout; + } + + var ioBox = this.ioBox; + var panelNode = this.panelNode; + + this.context.mutationTimeout = this.context.setTimeout(function() + { + ioBox.openObjectBox(objectBox); + + if (Firebug.scrollToMutations) + scrollIntoCenterView(objectBox, panelNode); + }, 200); + } + + if (Firebug.highlightMutations) + setClassTimed(elt, type, this.context); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // SourceBox proxy + + createObjectBox: function(object, isRoot) + { + if (FBTrace.DBG_HTML) FBTrace.sysout("html.createObjectBox("+(object.tagName?object.tagName:object)+", isRoot:"+(isRoot?"true":"false")+")\n"); + var tag = getNodeTag(object); + if (tag) + return tag.replace({object: object}, this.document); + }, + + getParentObject: function(node) + { + if (node instanceof SourceText) + return node.owner; + + var parentNode = node ? node.parentNode : null; + + if (FBTrace.DBG_HTML) + FBTrace.sysout("ChromeBugPanel.getParentObject for "+node.nodeName+" parentNode:"+(parentNode?parentNode.nodeName:"null-or-false")+"\n"); + + if (parentNode) + { + + if (parentNode.nodeType == 9) // then parentNode is Document element + { + if (parentNode.defaultView) + { + if (parentNode.defaultView == this.context.window) // for chromebug to avoid climbing put to browser.xul + return null; + + if (FBTrace.DBG_HTML) + FBTrace.sysout("getParentObject parentNode.nodeType 9, frameElement:"+parentNode.defaultView.frameElement+"\n"); /*@explore*/ + return parentNode.defaultView.frameElement; + } + else if (this.embeddedBrowserParents) + { + var skipParent = this.embeddedBrowserParents[node]; // better be HTML element, could be iframe + if (FBTrace.DBG_HTML) + FBTrace.sysout("getParentObject skipParent:"+(skipParent?skipParent.nodeName:"none")+"\n"); /*@explore*/ + if (skipParent) + return skipParent; + } + else // parent is document element, but no window at defaultView. + return null; + } + else if (!parentNode.localName) + { + if (FBTrace.DBG_HTML) + FBTrace.sysout("getParentObject: null localName must be window, no parentObject"); + return null; + } + else + return parentNode; + } + else // Documents have no parentNode; Attr, Document, DocumentFragment, Entity, and Notation. top level windows have no parentNode + { + if (node && node.nodeType == 9) // document type + { + if (node.defaultView) // generally a reference to the window object for the document, however that is not defined in the specification + { + var embeddingFrame = node.defaultView.frameElement; + if (embeddingFrame) + return embeddingFrame.parentNode; + } + else // a Document object without a parentNode or window + return null; // top level has no parent + } + } + }, + + getChildObject: function(node, index, previousSibling) + { + if (!node) + { + FBTrace.sysout("getChildObject: null node"); + return; + } + if (FBTrace.DBG_HTML) + FBTrace.sysout("getChildObject "+node.tagName+" index "+index+" previousSibling: "+previousSibling, {node: node, previousSibling:previousSibling}); + + if (this.isSourceElement(node)) + { + if (index == 0) + return this.getElementSourceText(node); + else + return null; // no siblings of source elements + } + else if (node.contentDocument) // then the node is a frame + { + if (index == 0) + { + if (!this.embeddedBrowserParents) + this.embeddedBrowserParents = {}; + var skipChild = node.contentDocument.documentElement; // unwrap + this.embeddedBrowserParents[skipChild] = node; + + return skipChild; // (the node's).(type 9 document).(HTMLElement) + } + else + return null; + } + else if (node.getSVGDocument && node.getSVGDocument()) // then the node is a frame + { + if (index == 0) + { + if (!this.embeddedBrowserParents) + this.embeddedBrowserParents = {}; + var skipChild = node.getSVGDocument().documentElement; // unwrap + this.embeddedBrowserParents[skipChild] = node; + + return skipChild; // (the node's).(type 9 document).(SVGElement) + } + else + return null; + } + + if (previousSibling) // then we are walking + var child = this.getNextSibling(previousSibling); // may return null, meaning done with iteration. + else + var child = this.getFirstChild(node); // child is set to at the beginning of an iteration. + + if (Firebug.showTextNodesWithWhitespace) // then the index is true to the node list + return child; + else + { + for (; child; child = this.getNextSibling(child)) + { + if (!this.isWhitespaceText(child)) + return child; + } + } + return null; // we have no children worth showing. + }, + + isWhitespaceText: function(node) + { + return HTMLLib.isWhitespaceText(node); + }, + + getFirstChild: function(node) + { + this.treeWalker = node.ownerDocument.createTreeWalker( + node, NodeFilter.SHOW_ALL, null, false); + return this.treeWalker.firstChild(); + }, + + getNextSibling: function(node) + { + if (FBTrace.DBG_HTML || FBTrace.DBG_ERRORS) + { + if (node != this.treeWalker.currentNode) + FBTrace.sysout("getNextSibling FAILS treeWalker "+this.treeWalker.currentNode+" out of sync with node "+node, this.treeWalker); + } + var next = this.treeWalker.nextSibling(); + + if (!next) + delete this.treeWalker; + + return next; + }, + + findNextSibling: function (node) + { + return HTMLLib.findNextSibling(node); + }, + + isSourceElement: function(element) + { + return HTMLLib.isSourceElement(element); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Events + + onMutateAttr: function(event) + { + var target = event.target; + if (unwrapObject(target).firebugIgnore) + return; + + var attrChange = event.attrChange; + var attrName = event.attrName; + var newValue = event.newValue; + + this.context.delay(function() + { + this.mutateAttr(target, attrChange, attrName, newValue); + }, this); + + Firebug.HTMLModule.MutationBreakpoints.onMutateAttr(event, this.context); + }, + + onMutateText: function(event) + { + if (FBTrace.DBG_HTML) + FBTrace.sysout("html.onMutateText; ", event); + + var target = event.target; + var parent = target.parentNode; + + var newValue = event.newValue; + + this.context.delay(function() + { + this.mutateText(target, parent, newValue); + }, this); + + Firebug.HTMLModule.MutationBreakpoints.onMutateText(event, this.context); + }, + + onMutateNode: function(event) + { + var target = event.target; + if (unwrapObject(target).firebugIgnore) + return; + + var parent = event.relatedNode; + var removal = event.type == "DOMNodeRemoved"; + var nextSibling = removal ? null : this.findNextSibling(target); + + this.context.delay(function() + { + try + { + this.mutateNode(target, parent, nextSibling, removal); + } + catch (exc) + { + if (FBTrace.DBG_ERRORS || FBTrace.DBG_HTML) + FBTrace.sysout("html.onMutateNode FAILS:", exc); + } + }, this); + + Firebug.HTMLModule.MutationBreakpoints.onMutateNode(event, this.context); + }, + + onClick: function(event) + { + if (isLeftClick(event) && event.detail == 2) + { + this.toggleNode(event); + } + else if (isAltClick(event) && event.detail == 2 && !this.editing) + { + this.editNode(this.selection); + } + }, + + onMouseDown: function(event) + { + if (!isLeftClick(event)) + return; + + if (getAncestorByClass(event.target, "nodeTag")) + { + var node = Firebug.getRepObject(event.target); + this.noScrollIntoView = true; + this.select(node); + delete this.noScrollIntoView; + if (hasClass(event.target, "twisty")) + this.toggleNode(event); + } + }, + + toggleNode: function(event) + { + var node = Firebug.getRepObject(event.target); + var box = this.ioBox.createObjectBox(node); + if (!hasClass(box, "open")) + this.ioBox.expandObject(node); + else + this.ioBox.contractObject(this.selection); + }, + + onKeyPress: function(event) + { + if (this.editing || isControl(event) || isShift(event)) + return; + + var node = this.selection; + if (!node) + return; + if (event.keyCode == KeyEvent.DOM_VK_UP) + this.selectNodeBy("up"); + else if (event.keyCode == KeyEvent.DOM_VK_DOWN) + this.selectNodeBy("down"); + else if (event.keyCode == KeyEvent.DOM_VK_LEFT) + this.selectNodeBy("left"); + else if (event.keyCode == KeyEvent.DOM_VK_RIGHT) + this.selectNodeBy("right"); + else if (event.keyCode == KeyEvent.DOM_VK_BACK_SPACE && !(node.localName in innerEditableTags) && !(nonEditableTags.hasOwnProperty(node.localName))) + this.deleteNode(node, "up"); + else if (event.keyCode == KeyEvent.DOM_VK_DELETE && !(node.localName in innerEditableTags) && !(nonEditableTags.hasOwnProperty(node.localName))) + this.deleteNode(node, "down"); + else + return; + + cancelEvent(event); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "HTML3", + title: "HTML3", + + searchable: true, + breakable: true, + dependents: ["css", "computed", "layout", "dom", "domSide", "watch"], + inspectorHistory: new Array(5), + + create: function() + { + Firebug.Panel.create.apply(this, arguments); + + var doc = Firebug.chrome.document; + var styleSheet = createStyleSheet(doc, Env.Location.skinDir + "html.css"); + addStyleSheet(doc, styleSheet); + }, + + initialize: function() + { + this.onMutateText = bind(this.onMutateText, this); + this.onMutateAttr = bind(this.onMutateAttr, this); + this.onMutateNode = bind(this.onMutateNode, this); + this.onClick = bind(this.onClick, this); + this.onMouseDown = bind(this.onMouseDown, this); + this.onKeyPress = bind(this.onKeyPress, this); + + Firebug.Panel.initialize.apply(this, arguments); + + // TODO: xxxpedro html3 + this.panelNode.style.padding = "4px 0"; + this.context = Firebug.browser; + this.document = Firebug.chrome.document; + this.initializeNode(); + }, + + destroy: function(state) + { + // TODO: xxxpedro html html3 + //persistObjects(this, state); + + Firebug.Panel.destroy.apply(this, arguments); + }, + + initializeNode: function(oldPanelNode) + { + if (!this.ioBox) + this.ioBox = new InsideOutBox(this, this.panelNode); + + // TODO: xxxpedro html3 + var object = Firebug.browser.document.documentElement; + this.select(object); + // END: xxxpedro html3 + + this.panelNode.addEventListener("click", this.onClick, false); + this.panelNode.addEventListener("mousedown", this.onMouseDown, false); + dispatch([Firebug.A11yModel], "onInitializeNode", [this]); + }, + + destroyNode: function() + { + this.panelNode.removeEventListener("click", this.onClick, false); + this.panelNode.removeEventListener("mousedown", this.onMouseDown, false); + this.panelNode.ownerDocument.removeEventListener("keypress", this.onKeyPress, true); + + if (this.ioBox) + { + this.ioBox.destroy(); + delete this.ioBox; + } + dispatch([Firebug.A11yModel], "onDestroyNode", [this]); + }, + + // TODO: xxxpedro html3 + ishow: function(state) + { + this.showToolbarButtons("fbHTMLButtons", true); + + this.panelNode.ownerDocument.addEventListener("keypress", this.onKeyPress, true); + + if (this.context.loaded) + { + if (!this.context.attachedMutation) + { + this.context.attachedMutation = true; + + iterateWindows(this.context.window, bind(function(win) + { + var doc = win.document; + doc.addEventListener("DOMAttrModified", this.onMutateAttr, false); + doc.addEventListener("DOMCharacterDataModified", this.onMutateText, false); + doc.addEventListener("DOMNodeInserted", this.onMutateNode, false); + doc.addEventListener("DOMNodeRemoved", this.onMutateNode, false); + }, this)); + } + + restoreObjects(this, state); + } + }, + + // TODO: xxxpedro html3 + ihide: function() + { + this.showToolbarButtons("fbHTMLButtons", false); + delete this.infoTipURL; // clear the state that is tracking the infotip so it is reset after next show() + this.panelNode.ownerDocument.removeEventListener("keypress", this.onKeyPress, true); + }, + + watchWindow: function(win) + { + if (this.context.window && this.context.window != win) // then I guess we are an embedded window + { + var htmlPanel = this; + iterateWindows(this.context.window, function(subwin) + { + if (win == subwin) + { + if (FBTrace.DBG_HTML) + FBTrace.sysout("html.watchWindow found subwin.location.href="+win.location.href+"\n"); + htmlPanel.mutateDocumentEmbedded(win, false); + } + }); + + } + if (this.context.attachedMutation) + { + var doc = win.document; + doc.addEventListener("DOMAttrModified", this.onMutateAttr, false); + doc.addEventListener("DOMCharacterDataModified", this.onMutateText, false); + doc.addEventListener("DOMNodeInserted", this.onMutateNode, false); + doc.addEventListener("DOMNodeRemoved", this.onMutateNode, false); + } + }, + + unwatchWindow: function(win) + { + if (this.context.window && this.context.window != win) // then I guess we are an embedded window + { + var htmlPanel = this; + iterateWindows(this.context.window, function(subwin) + { + if (win == subwin) + { + if (FBTrace.DBG_HTML) + FBTrace.sysout("html.unwatchWindow found subwin.location.href="+win.location.href+"\n"); + htmlPanel.mutateDocumentEmbedded(win, true); + } + }); + + } + var doc = win.document; + doc.removeEventListener("DOMAttrModified", this.onMutateAttr, false); + doc.removeEventListener("DOMCharacterDataModified", this.onMutateText, false); + doc.removeEventListener("DOMNodeInserted", this.onMutateNode, false); + doc.removeEventListener("DOMNodeRemoved", this.onMutateNode, false); + }, + + mutateDocumentEmbedded: function(win, remove) + { + // document.documentElement Returns the Element that is a direct child of document. For HTML documents, this normally the HTML element. + var target = win.document.documentElement; + var parent = win.frameElement; + var nextSibling = this.findNextSibling(target || parent); + this.mutateNode(target, parent, nextSibling, remove); + }, + + supportsObject: function(object, type) + { + if (object instanceof Element || object instanceof Text || object instanceof CDATASection) + return 2; + else if (object instanceof SourceLink && object.type == "css" && !reCSS.test(object.href)) + return 2; + else + return 0; + }, + + updateOption: function(name, value) + { + var viewOptionNames = { + showCommentNodes:1, + showTextNodesWithEntities:1, + showTextNodesWithWhitespace:1, + showFullTextNodes:1 + }; + if (name in viewOptionNames) + { + this.resetSearch(); + clearNode(this.panelNode); + if (this.ioBox) + this.ioBox.destroy(); + + this.ioBox = new InsideOutBox(this, this.panelNode); + this.ioBox.select(this.selection, true, true); + } + }, + + updateSelection: function(object) + { + if (FBTrace.DBG_HTML) + FBTrace.sysout("html.updateSelection "+object); + if (this.ioBox.sourceRow) + this.ioBox.sourceRow.removeAttribute("exe_line"); + + if (object instanceof SourceLink) // && object.type == "css" and !reCSS(object.href) by supports + { + var sourceLink = object; + var stylesheet = getStyleSheetByHref(sourceLink.href, this.context); + if (stylesheet) + { + var ownerNode = stylesheet.ownerNode; + if (FBTrace.DBG_CSS) + FBTrace.sysout("html panel updateSelection stylesheet.ownerNode="+stylesheet.ownerNode + +" href:"+sourceLink.href+"\n"); + if (ownerNode) + { + var objectbox = this.ioBox.select(ownerNode, true, true, this.noScrollIntoView); + + // XXXjjb seems like this could be bad for errors at the end of long files + // + var sourceRow = objectbox.getElementsByClassName("sourceRow").item(0); // first source row in style + for (var lineNo = 1; lineNo < sourceLink.line; lineNo++) + { + if (!sourceRow) break; + sourceRow = FBL.getNextByClass(sourceRow, "sourceRow"); + } + if (FBTrace.DBG_CSS) + FBTrace.sysout("html panel updateSelection sourceLink.line="+sourceLink.line + +" sourceRow="+(sourceRow?sourceRow.innerHTML:"undefined")+"\n"); + if (sourceRow) + { + this.ioBox.sourceRow = sourceRow; + this.ioBox.sourceRow.setAttribute("exe_line", "true"); + scrollIntoCenterView(sourceRow); + this.ioBox.selectObjectBox(sourceRow, false); // sourceRow isn't an objectBox, but the function should work anyway... + } + } + } + } + else if (Firebug.Inspector.inspecting) + { + this.ioBox.highlight(object); + } + else + { + // TODO: xxxpedro html3 + //Firebug.chrome.getSelectedSidePanel().panelNode.scrollTop = 0; + this.ioBox.select(object, true, false, this.noScrollIntoView); + this.inspectorHistory.unshift(object); + if (this.inspectorHistory.length > 5) + this.inspectorHistory.pop(); + } + }, + + stopInspecting: function(object, cancelled) + { + if (object != this.inspectorHistory) + { + // Manage history of selection for later access in the command line. + this.inspectorHistory.unshift(object); + if (this.inspectorHistory.length > 5) + this.inspectorHistory.pop(); + + if (FBTrace.DBG_HTML) + FBTrace.sysout("html.stopInspecting: inspectoryHistory updated", this.inspectorHistory); + } + + this.ioBox.highlight(null); + + if (!cancelled) + this.ioBox.select(object, true); + }, + + search: function(text, reverse) + { + if (!text) + return; + + var search; + if (text == this.searchText && this.lastSearch) + search = this.lastSearch; + else + { + var doc = this.context.window.document; + search = this.lastSearch = new HTMLLib.NodeSearch(text, doc, this.panelNode, this.ioBox); + } + + var loopAround = search.find(reverse, Firebug.Search.isCaseSensitive(text)); + if (loopAround) + { + this.resetSearch(); + this.search(text, reverse); + } + + return !search.noMatch; + }, + + getSearchOptionsMenuItems: function() + { + return [ + Firebug.Search.searchOptionMenu("search.Case_Sensitive", "searchCaseSensitive") + ]; + }, + + getDefaultSelection: function() + { + try + { + var doc = this.context.window.document; + return doc.body ? doc.body : getPreviousElement(doc.documentElement.lastChild); + } + catch (exc) + { + return null; + } + }, + + getObjectPath: function(element) + { + var path = []; + for (; element; element = this.getParentObject(element)) + path.push(element); + + return path; + }, + + getPopupObject: function(target) + { + return Firebug.getRepObject(target); + }, + + getTooltipObject: function(target) + { + return null; + }, + + getOptionsMenuItems: function() + { + return [ + optionMenu("ShowFullText", "showFullTextNodes"), + optionMenu("ShowWhitespace", "showTextNodesWithWhitespace"), + optionMenu("ShowComments", "showCommentNodes"), + optionMenu("ShowTextNodesWithEntities", "showTextNodesWithEntities"), + "-", + optionMenu("HighlightMutations", "highlightMutations"), + optionMenu("ExpandMutations", "expandMutations"), + optionMenu("ScrollToMutations", "scrollToMutations"), + "-", + optionMenu("ShadeBoxModel", "shadeBoxModel"), + optionMenu("ShowQuickInfoBox","showQuickInfoBox") + ]; + }, + + getContextMenuItems: function(node, target) + { + if (!node) + return null; + + var items = []; + + if (node && node.nodeType == 1) + { + items.push( + "-", + {label: "NewAttribute", command: bindFixed(this.editNewAttribute, this, node) } + ); + + var attrBox = getAncestorByClass(target, "nodeAttr"); + if (getAncestorByClass(target, "nodeAttr")) + { + var attrName = attrBox.childNodes[1].textContent; + + items.push( + {label: $STRF("EditAttribute", [attrName]), nol10n: true, + command: bindFixed(this.editAttribute, this, node, attrName) }, + {label: $STRF("DeleteAttribute", [attrName]), nol10n: true, + command: bindFixed(this.deleteAttribute, this, node, attrName) } + ); + } + + if (!( nonEditableTags.hasOwnProperty(node.localName) )) + { + var EditElement = "EditHTMLElement"; + + if (isElementMathML(node)) + EditElement = "EditMathMLElement"; + else if (isElementSVG(node)) + EditElement = "EditSVGElement"; + + items.push("-", { label: EditElement, command: bindFixed(this.editNode, this, node)}, + { label: "DeleteElement", command: bindFixed(this.deleteNode, this, node), disabled:(node.localName in innerEditableTags)} + ); + } + } + else + { + items.push( + "-", + {label: "EditNode", command: bindFixed(this.editNode, this, node) }, + {label: "DeleteNode", command: bindFixed(this.deleteNode, this, node) } + ); + } + + Firebug.HTMLModule.MutationBreakpoints.getContextMenuItems( + this.context,node, target, items); + + return items; + }, + + showInfoTip: function(infoTip, target, x, y) + { + if (!hasClass(target, "nodeValue")) + return; + + var targetNode = Firebug.getRepObject(target); + if (targetNode && targetNode.nodeType == 1 && targetNode.localName.toUpperCase() == "IMG") + { + var url = targetNode.src; + if (url == this.infoTipURL) // This state cleared in hide() + return true; + + this.infoTipURL = url; + return Firebug.InfoTip.populateImageInfoTip(infoTip, url); + } + }, + + getEditor: function(target, value) + { + if (hasClass(target, "nodeName") || hasClass(target, "nodeValue") || hasClass(target, "nodeBracket")) + { + if (!this.attrEditor) + this.attrEditor = new Firebug.HTMLPanel.Editors.Attribute(this.document); + + return this.attrEditor; + } + else if (hasClass(target, "nodeComment") || hasClass(target, "nodeCDATA")) + { + if (!this.textDataEditor) + this.textDataEditor = new Firebug.HTMLPanel.Editors.TextData(this.document); + + return this.textDataEditor; + } + else if (hasClass(target, "nodeText")) + { + if (!this.textNodeEditor) + this.textNodeEditor = new Firebug.HTMLPanel.Editors.TextNode(this.document); + + return this.textNodeEditor; + } + }, + + getInspectorVars: function() + { + var vars = {}; + for (var i=0; i<2; i++) + vars["$"+i] = this.inspectorHistory[i]; + + return vars; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Break on Mutate + + breakOnNext: function(breaking) + { + Firebug.HTMLModule.MutationBreakpoints.breakOnNext(this.context, breaking); + }, + + shouldBreakOnNext: function() + { + return this.context.breakOnNextMutate; + }, + + getBreakOnNextTooltip: function(enabled) + { + return (enabled ? $STR("html.Disable Break On Mutate") : $STR("html.Break On Mutate")); + } +}); + +// ************************************************************************************************ + +var AttrTag = Firebug.HTMLPanel.AttrTag = + SPAN({"class": "nodeAttr editGroup"}, + " ", SPAN({"class": "nodeName editable"}, "$attr.nodeName"), "="", + SPAN({"class": "nodeValue editable"}, "$attr.nodeValue"), """ + ); + +var TextTag = Firebug.HTMLPanel.TextTag = + SPAN({"class": "nodeText editable"}, + FOR("char", "$object|getNodeTextGroups", + SPAN({"class": "$char.class $char.extra"}, "$char.str") + ) + ); + +// ************************************************************************************************ + +Firebug.HTMLPanel.CompleteElement = domplate(FirebugReps.Element, +{ + tag: + DIV({"class": "nodeBox open $object|getHidden repIgnore", _repObject: "$object", role : 'presentation'}, + DIV({"class": "nodeLabel", role: "presentation"}, + SPAN({"class": "nodeLabelBox repTarget repTarget", role : 'treeitem', 'aria-expanded' : 'false'}, + "<", + SPAN({"class": "nodeTag"}, "$object.nodeName|toLowerCase"), + FOR("attr", "$object|attrIterator", AttrTag), + SPAN({"class": "nodeBracket"}, ">") + ) + ), + DIV({"class": "nodeChildBox", role :"group"}, + FOR("child", "$object|childIterator", + TAG("$child|getNodeTag", {object: "$child"}) + ) + ), + DIV({"class": "nodeCloseLabel", role:"presentation"}, + "</", + SPAN({"class": "nodeTag"}, "$object.nodeName|toLowerCase"), + ">" + ) + ), + + getNodeTag: function(node) + { + return getNodeTag(node, true); + }, + + childIterator: function(node) + { + if (node.contentDocument) + return [node.contentDocument.documentElement]; + + if (Firebug.showTextNodesWithWhitespace) + return cloneArray(node.childNodes); + else + { + var nodes = []; + for (var child = node.firstChild; child; child = child.nextSibling) + { + if (child.nodeType != Node.TEXT_NODE || !HTMLLib.isWhitespaceText(child)) + nodes.push(child); + } + return nodes; + } + } +}); + +Firebug.HTMLPanel.SoloElement = domplate(Firebug.HTMLPanel.CompleteElement, +{ + tag: + DIV({"class": "soloElement", onmousedown: "$onMouseDown"}, + Firebug.HTMLPanel.CompleteElement.tag + ), + + onMouseDown: function(event) + { + for (var child = event.target; child; child = child.parentNode) + { + if (child.repObject) + { + var panel = Firebug.getElementPanel(child); + Firebug.chrome.select(child.repObject); + break; + } + } + } +}); + +Firebug.HTMLPanel.Element = domplate(FirebugReps.Element, +{ + tag: + DIV({"class": "nodeBox containerNodeBox $object|getHidden repIgnore", _repObject: "$object", role :"presentation"}, + DIV({"class": "nodeLabel", role: "presentation"}, + IMG({"class": "twisty", role: "presentation"}), + SPAN({"class": "nodeLabelBox repTarget", role : 'treeitem', 'aria-expanded' : 'false'}, + "<", + SPAN({"class": "nodeTag"}, "$object.nodeName|toLowerCase"), + FOR("attr", "$object|attrIterator", AttrTag), + SPAN({"class": "nodeBracket editable insertBefore"}, ">") + ) + ), + DIV({"class": "nodeChildBox", role :"group"}), /* nodeChildBox is special signal in insideOutBox */ + DIV({"class": "nodeCloseLabel", role : "presentation"}, + SPAN({"class": "nodeCloseLabelBox repTarget"}, + "</", + SPAN({"class": "nodeTag"}, "$object.nodeName|toLowerCase"), + ">" + ) + ) + ) +}); + +Firebug.HTMLPanel.TextElement = domplate(FirebugReps.Element, +{ + tag: + DIV({"class": "nodeBox textNodeBox $object|getHidden repIgnore", _repObject: "$object", role : 'presentation'}, + DIV({"class": "nodeLabel", role: "presentation"}, + SPAN({"class": "nodeLabelBox repTarget", role : 'treeitem'}, + "<", + SPAN({"class": "nodeTag"}, "$object.nodeName|toLowerCase"), + FOR("attr", "$object|attrIterator", AttrTag), + SPAN({"class": "nodeBracket editable insertBefore"}, ">"), + TextTag, + "</", + SPAN({"class": "nodeTag"}, "$object.nodeName|toLowerCase"), + ">" + ) + ) + ) +}); + +Firebug.HTMLPanel.EmptyElement = domplate(FirebugReps.Element, +{ + tag: + DIV({"class": "nodeBox emptyNodeBox $object|getHidden repIgnore", _repObject: "$object", role : 'presentation'}, + DIV({"class": "nodeLabel", role: "presentation"}, + SPAN({"class": "nodeLabelBox repTarget", role : 'treeitem'}, + "<", + SPAN({"class": "nodeTag"}, "$object.nodeName|toLowerCase"), + FOR("attr", "$object|attrIterator", AttrTag), + SPAN({"class": "nodeBracket editable insertBefore"}, ">") + ) + ) + ) +}); + +Firebug.HTMLPanel.XEmptyElement = domplate(FirebugReps.Element, +{ + tag: + DIV({"class": "nodeBox emptyNodeBox $object|getHidden repIgnore", _repObject: "$object", role : 'presentation'}, + DIV({"class": "nodeLabel", role: "presentation"}, + SPAN({"class": "nodeLabelBox repTarget", role : 'treeitem'}, + "<", + SPAN({"class": "nodeTag"}, "$object.nodeName|toLowerCase"), + FOR("attr", "$object|attrIterator", AttrTag), + SPAN({"class": "nodeBracket editable insertBefore"}, "/>") + ) + ) + ) +}); + +Firebug.HTMLPanel.AttrNode = domplate(FirebugReps.Element, +{ + tag: AttrTag +}); + +Firebug.HTMLPanel.TextNode = domplate(FirebugReps.Element, +{ + tag: + DIV({"class": "nodeBox", _repObject: "$object", role : 'presentation'}, + TextTag + ) +}); + +Firebug.HTMLPanel.CDATANode = domplate(FirebugReps.Element, +{ + tag: + DIV({"class": "nodeBox", _repObject: "$object", role : 'presentation'}, + "<![CDATA[", + SPAN({"class": "nodeText nodeCDATA editable"}, "$object.nodeValue"), + "]]>" + ) +}); + +Firebug.HTMLPanel.CommentNode = domplate(FirebugReps.Element, +{ + tag: + DIV({"class": "nodeBox nodeComment", _repObject: "$object", role : 'presentation'}, + "<!--", + SPAN({"class": "nodeComment editable"}, "$object.nodeValue"), + "-->" + ) +}); + + +// ************************************************************************************************ +// TextDataEditor + +/* + * TextDataEditor deals with text of comments and cdata nodes + */ + +function TextDataEditor(doc) +{ + this.initializeInline(doc); +} + +TextDataEditor.prototype = domplate(Firebug.InlineEditor.prototype, +{ + + saveEdit: function(target, value, previousValue) + { + var node = Firebug.getRepObject(target); + if (!node) + return; + target.data = value; + node.data = value; + } +}); + +//************************************************************************************************ +// TextNodeEditor + +/* + * TextNodeEditor deals with text nodes that do and do not have sibling elements. If + * there are no sibling elements, the parent is known as a TextElement. In other cases + * we keep track of their position via a range (this is in part because as people type + * html, the range will keep track of the text nodes and elements that the user + * is creating as they type, and this range could be in the middle of the parent + * elements children). + */ + +function TextNodeEditor(doc) +{ + this.initializeInline(doc); +} + +TextNodeEditor.prototype = domplate(Firebug.InlineEditor.prototype, +{ + + beginEditing: function(target, value) + { + var node = Firebug.getRepObject(target); + if (!node || node instanceof Element) + return; + var document = node.ownerDocument; + this.range = document.createRange(); + this.range.setStartBefore(node); + this.range.setEndAfter(node); + }, + + endEditing: function(target, value, cancel) + { + if (this.range) + { + this.range.detach(); + delete this.range; + } + // Remove empty groups by default + return true; + }, + + saveEdit: function(target, value, previousValue) + { + var node = Firebug.getRepObject(target); + if (!node) + return; + value = unescapeForTextNode(value || ''); + target.innerHTML = escapeForTextNode(value); + if (node instanceof Element) + { + if (isElementMathML(node) || isElementSVG(node)) + node.textContent=value; + else + node.innerHTML=value; + } + else + { + try + { + var documentFragment = this.range.createContextualFragment(value); + var cnl=documentFragment.childNodes.length; + this.range.deleteContents(); + this.range.insertNode(documentFragment); + var r = this.range, sc = r.startContainer, so = r.startOffset; + this.range.setEnd(sc,so+cnl); + } catch (e) {} + } + } +}); + +//************************************************************************************************ +//AttributeEditor + +function AttributeEditor(doc) +{ + this.initializeInline(doc); +} + +AttributeEditor.prototype = domplate(Firebug.InlineEditor.prototype, +{ + saveEdit: function(target, value, previousValue) + { + var element = Firebug.getRepObject(target); + if (!element) + return; + + // XXXstr unescape value + + target.innerHTML = escapeForElementAttribute(value); + + if (hasClass(target, "nodeName")) + { + if (value != previousValue) + element.removeAttribute(previousValue); + if (value) + { + var attrValue = getNextByClass(target, "nodeValue").textContent; + element.setAttribute(value, attrValue); + } + else + element.removeAttribute(value); + } + else if (hasClass(target, "nodeValue")) + { + var attrName = getPreviousByClass(target, "nodeName").textContent; + element.setAttribute(attrName, value); + } + //this.panel.markChange(); + }, + + advanceToNext: function(target, charCode) + { + if (charCode == 61 && hasClass(target, "nodeName")) + return true; + }, + + insertNewRow: function(target, insertWhere) + { + var emptyAttr = {nodeName: "", nodeValue: ""}; + var sibling = insertWhere == "before" ? target.previousSibling : target; + return AttrTag.insertAfter({attr: emptyAttr}, sibling); + } +}); + +//************************************************************************************************ +//HTMLEditor + +function HTMLEditor(doc) +{ + this.box = this.tag.replace({}, doc, this); + this.input = this.box.firstChild; + + this.multiLine = true; + this.tabNavigation = false; + this.arrowCompletion = false; +} + +HTMLEditor.prototype = domplate(Firebug.BaseEditor, +{ + tag: DIV( + TEXTAREA({"class": "htmlEditor 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.editingElements = [target.repObject, null]; + + this.panel.panelNode.appendChild(this.box); + + this.input.value = value; + this.input.focus(); + + var command = Firebug.chrome.$("cmd_toggleHTMLEditing"); + command.setAttribute("checked", true); + }, + + hide: function() + { + var command = Firebug.chrome.$("cmd_toggleHTMLEditing"); + command.setAttribute("checked", false); + + this.panel.panelNode.removeChild(this.box); + + delete this.editingElements; + delete this.target; + delete this.panel; + }, + + saveEdit: function(target, value, previousValue) + { + // Remove all of the nodes in the last range we created, except for + // the first one, because setOuterHTML will replace it + var first = this.editingElements[0], last = this.editingElements[1]; + if (last && last != first) + { + for (var child = first.nextSibling; child;) + { + var next = child.nextSibling; + child.parentNode.removeChild(child); + if (child == last) + break; + else + child = next; + } + } + + // Make sure that we create at least one node here, even if it's just + // an empty space, because this code depends on having something to replace + if (!value) + value = " "; + + if (this.innerEditMode) + this.editingElements[0].innerHTML = value; + else + this.editingElements = setOuterHTML(this.editingElements[0], value); + }, + + endEditing: function() + { + //this.panel.markChange(); + return true; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + onInput: function() + { + Firebug.Editor.update(); + } +}); + + +// ************************************************************************************************ +// Editors + +Firebug.HTMLPanel.Editors = { + html : HTMLEditor, + Attribute : AttributeEditor, + TextNode: TextNodeEditor, + TextData: TextDataEditor +}; + + +// ************************************************************************************************ +// Local Helpers + +var getEmptyElementTag = function getEmptyElementTag(node) +{ + var isXhtml= isElementXHTML(node); + if (isXhtml) + return Firebug.HTMLPanel.XEmptyElement.tag; + else + return Firebug.HTMLPanel.EmptyElement.tag; +}; + +// xxxpedro HTML3 +var getNodeTag = function getNodeTag(node, expandAll) +{ + // TODO: xxxpedro html3 instanceof problem with different windows + //if (node instanceof Element) + if (instanceOf(node, "Element")) + { + if (node instanceof HTMLAppletElement) + return getEmptyElementTag(node); + // TODO: xxxpedro html3 + //else if (unwrapObject(node).firebugIgnore) + else if (node.firebugIgnore) + return null; + else if (HTMLLib.isContainerElement(node)) + return expandAll ? Firebug.HTMLPanel.CompleteElement.tag : Firebug.HTMLPanel.Element.tag; + else if (HTMLLib.isEmptyElement(node)) + return getEmptyElementTag(node); + else if (Firebug.showCommentNodes && HTMLLib.hasCommentChildren(node)) + return expandAll ? Firebug.HTMLPanel.CompleteElement.tag : Firebug.HTMLPanel.Element.tag; + else if (HTMLLib.hasNoElementChildren(node)) + return Firebug.HTMLPanel.TextElement.tag; + else + return expandAll ? Firebug.HTMLPanel.CompleteElement.tag : Firebug.HTMLPanel.Element.tag; + } + else if (node instanceof Text) + return Firebug.HTMLPanel.TextNode.tag; + else if (node instanceof CDATASection) + return Firebug.HTMLPanel.CDATANode.tag; + else if (node instanceof Comment && (Firebug.showCommentNodes || expandAll)) + return Firebug.HTMLPanel.CommentNode.tag; + else if (node instanceof SourceText) + return FirebugReps.SourceText.tag; + else + return FirebugReps.Nada.tag; +}; + +var getNodeBoxTag = function getNodeBoxTag(nodeBox) +{ + var re = /([^\s]+)NodeBox/; + var m = re.exec(nodeBox.className); + if (!m) + return null; + + var nodeBoxType = m[1]; + if (nodeBoxType == "container") + return Firebug.HTMLPanel.Element.tag; + else if (nodeBoxType == "text") + return Firebug.HTMLPanel.TextElement.tag; + else if (nodeBoxType == "empty") + return Firebug.HTMLPanel.EmptyElement.tag; +}; + +// ************************************************************************************************ +// Mutation Breakpoints + +/** + * @class Represents {@link Firebug.Debugger} listener. This listener is reponsible for + * providing a list of mutation-breakpoints into the Breakpoints side-panel. + */ +Firebug.HTMLModule.DebuggerListener = +{ + getBreakpoints: function(context, groups) + { + if (!context.mutationBreakpoints.isEmpty()) + groups.push(context.mutationBreakpoints); + } +}; + +Firebug.HTMLModule.MutationBreakpoints = +{ + breakOnNext: function(context, breaking) + { + context.breakOnNextMutate = breaking; + }, + + breakOnNextMutate: function(event, context, type) + { + if (!context.breakOnNextMutate) + return false; + + // Ignore changes in trees marked with firebugIgnore. + if (isAncestorIgnored(event.target)) + return false; + + context.breakOnNextMutate = false; + + this.breakWithCause(event, context, type); + }, + + breakWithCause: function(event, context, type) + { + var changeLabel = Firebug.HTMLModule.BreakpointRep.getChangeLabel({type: type}); + context.breakingCause = { + title: $STR("net.Break On Mutate"), + message: changeLabel, + type: event.type, + target: event.target, + relatedNode: event.relatedNode, // http://www.w3.org/TR/DOM-Level-2-Events/events.html + prevValue: event.prevValue, + newValue: event.newValue, + attrName: event.attrName, + attrChange: event.attrChange + }; + + Firebug.Breakpoint.breakNow(context.getPanel("html", true)); + return true; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Mutation event handlers. + + onMutateAttr: function(event, context) + { + if (this.breakOnNextMutate(event, context, BP_BREAKONATTRCHANGE)) + return; + + var breakpoints = context.mutationBreakpoints; + var self = this; + breakpoints.enumerateBreakpoints(function(bp) { + if (bp.checked && bp.node == event.target && bp.type == BP_BREAKONATTRCHANGE) { + self.breakWithCause(event, context, BP_BREAKONATTRCHANGE); + return true; + } + }); + }, + + onMutateText: function(event, context) + { + if (this.breakOnNextMutate(event, context, BP_BREAKONTEXT)) + return; + }, + + onMutateNode: function(event, context) + { + var node = event.target; + var removal = event.type == "DOMNodeRemoved"; + + if (this.breakOnNextMutate(event, context, removal ? BP_BREAKONREMOVE : BP_BREAKONCHILDCHANGE)) + return; + + var breakpoints = context.mutationBreakpoints; + var breaked = false; + + if (removal) + { + var self = this; + breaked = breakpoints.enumerateBreakpoints(function(bp) { + if (bp.checked && bp.node == node && bp.type == BP_BREAKONREMOVE) { + self.breakWithCause(event, context, BP_BREAKONREMOVE); + return true; + } + }); + } + + if (!breaked) + { + // Collect all parents of the mutated node. + var parents = []; + for (var parent = node.parentNode; parent; parent = parent.parentNode) + parents.push(parent); + + // Iterate over all parents and see if some of them has a breakpoint. + var self = this; + breakpoints.enumerateBreakpoints(function(bp) { + for (var i=0; i"); + appendText(object, html); + html.push(""); + } + 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); \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/tracePanel.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/tracePanel.js new file mode 100644 index 00000000000..8a73d50b8f7 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/tracePanel.js @@ -0,0 +1,72 @@ +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +// If application isn't in trace mode, the FBTrace panel won't be loaded +if (!Env.Options.enableTrace) return; + +// ************************************************************************************************ +// FBTrace Module + +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); + + +// ************************************************************************************************ +// FBTrace Panel + +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); + +// ************************************************************************************************ +}}); \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/xhr.js b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/xhr.js new file mode 100644 index 00000000000..9b3b3b8f807 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/content/lite/xhr.js @@ -0,0 +1,543 @@ +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +if (Env.Options.disableXHRListener) + return; + +// ************************************************************************************************ +// XHRSpy + +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, // {href:"file.html", line: 22} + + getURL: function() + { + return this.href; + } +}; + +// ************************************************************************************************ +// XMLHttpRequestWrapper + +var XMLHttpRequestWrapper = function(activeXObject) +{ + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // XMLHttpRequestWrapper internal variables + + var xhrRequest = typeof activeXObject != "undefined" ? + activeXObject : + new _XMLHttpRequest(), + + spy = new XHRSpy(), + + self = this, + + reqType, + reqUrl, + reqStartTS; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // XMLHttpRequestWrapper internal methods + + 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) + { + //console.log(propName, E.message); + } + } + } + else + { + // will fail to read these xhrRequest properties if the request is not completed + 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) + { + //console.log(propName, E.message); + } + } + }; + + 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 0; + + /**/ + + return this; +}; + +// ************************************************************************************************ +// ActiveXObject Wrapper (IE6 only) + +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; + } + }; +} + +// ************************************************************************************************ + +// Register the XMLHttpRequestWrapper for non-IE6 browsers +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; + } +}; + +// ************************************************************************************************ +}}); diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/plugin/proxy/proxy.php b/Frameworks/Misc/ERFirebug/WebServerResources/plugin/proxy/proxy.php new file mode 100644 index 00000000000..0975bbffe2b --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/plugin/proxy/proxy.php @@ -0,0 +1,258 @@ + and +// are disabled by default, see for more information. +// callback - If specified, the response JSON will be wrapped in this named +// function call. This parameter and are disabled by +// default, see for more information. +// user_agent - This value will be sent to the remote URL request as the +// `User-Agent:` HTTP request header. If omitted, the browser user agent +// will be passed through. +// send_cookies - If send_cookies=1, all cookies will be forwarded through to +// the remote URL request. +// send_session - If send_session=1 and send_cookies=1, the SID cookie will be +// forwarded through to the remote URL request. +// full_headers - If a JSON request and full_headers=1, the JSON response will +// contain detailed header information. +// full_status - If a JSON request and full_status=1, the JSON response will +// contain detailed cURL status information, otherwise it will just contain +// the `http_code` property. +// +// Topic: POST Parameters +// +// All POST parameters are automatically passed through to the remote URL +// request. +// +// Topic: JSON requests +// +// This request will return the contents of the specified url in JSON format. +// +// Request: +// +// > ba-simple-proxy.php?url=http://example.com/ +// +// Response: +// +// > { "contents": "...", "headers": {...}, "status": {...} } +// +// JSON object properties: +// +// contents - (String) The contents of the remote URL resource. +// headers - (Object) A hash of HTTP headers returned by the remote URL +// resource. +// status - (Object) A hash of status codes returned by cURL. +// +// Topic: JSONP requests +// +// This request will return the contents of the specified url in JSONP format +// (but only if $enable_jsonp is enabled in the PHP script). +// +// Request: +// +// > ba-simple-proxy.php?url=http://example.com/&callback=foo +// +// Response: +// +// > foo({ "contents": "...", "headers": {...}, "status": {...} }) +// +// JSON object properties: +// +// contents - (String) The contents of the remote URL resource. +// headers - (Object) A hash of HTTP headers returned by the remote URL +// resource. +// status - (Object) A hash of status codes returned by cURL. +// +// Topic: Native requests +// +// This request will return the contents of the specified url in the format it +// was received in, including the same content-type and other headers (but only +// if $enable_native is enabled in the PHP script). +// +// Request: +// +// > ba-simple-proxy.php?url=http://example.com/&mode=native +// +// Response: +// +// > ... +// +// Topic: Notes +// +// * Assumes magic_quotes_gpc = Off in php.ini +// +// Topic: Configuration Options +// +// These variables can be manually edited in the PHP file if necessary. +// +// $enable_jsonp - Only enable if you really need to. If you +// install this script on the same server as the page you're calling it +// from, plain JSON will work. Defaults to false. +// $enable_native - You can enable , but you should only do +// this if you also whitelist specific URLs using $valid_url_regex, to avoid +// possible XSS vulnerabilities. Defaults to false. +// $valid_url_regex - This regex is matched against the url parameter to +// ensure that it is valid. This setting only needs to be used if either +// $enable_jsonp or $enable_native are enabled. Defaults to '/.*/' which +// validates all URLs. +// +// ############################################################################ + +// Change these configuration options if needed, see above descriptions for info. +$enable_jsonp = false; +$enable_native = false; +$valid_url_regex = '/.*/'; + +// ############################################################################ + +$url = $_GET['url']; + +if ( !$url ) { + + // Passed url not specified. + $contents = 'ERROR: url not specified'; + $status = array( 'http_code' => 'ERROR' ); + +} else if ( !preg_match( $valid_url_regex, $url ) ) { + + // Passed url doesn't match $valid_url_regex. + $contents = 'ERROR: invalid url'; + $status = array( 'http_code' => 'ERROR' ); + +} else { + $ch = curl_init( $url ); + + if ( strtolower($_SERVER['REQUEST_METHOD']) == 'post' ) { + curl_setopt( $ch, CURLOPT_POST, true ); + curl_setopt( $ch, CURLOPT_POSTFIELDS, $_POST ); + } + + if ( $_GET['send_cookies'] ) { + $cookie = array(); + foreach ( $_COOKIE as $key => $value ) { + $cookie[] = $key . '=' . $value; + } + if ( $_GET['send_session'] ) { + $cookie[] = SID; + } + $cookie = implode( '; ', $cookie ); + + curl_setopt( $ch, CURLOPT_COOKIE, $cookie ); + } + + curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true ); + curl_setopt( $ch, CURLOPT_HEADER, true ); + curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); + + curl_setopt( $ch, CURLOPT_USERAGENT, $_GET['user_agent'] ? $_GET['user_agent'] : $_SERVER['HTTP_USER_AGENT'] ); + + list( $header, $contents ) = preg_split( '/([\r\n][\r\n])\\1/', curl_exec( $ch ), 2 ); + + $status = curl_getinfo( $ch ); + + curl_close( $ch ); +} + +// Split header text into an array. +$header_text = preg_split( '/[\r\n]+/', $header ); + +if ( $_GET['mode'] == 'native' ) { + if ( !$enable_native ) { + $contents = 'ERROR: invalid mode'; + $status = array( 'http_code' => 'ERROR' ); + } + + // Propagate headers to response. + foreach ( $header_text as $header ) { + if ( preg_match( '/^(?:Content-Type|Content-Language|Set-Cookie):/i', $header ) ) { + header( $header ); + } + } + + print $contents; + +} else { + + // $data will be serialized into JSON data. + $data = array(); + + // Propagate all HTTP headers into the JSON data object. + if ( $_GET['full_headers'] ) { + $data['headers'] = array(); + + foreach ( $header_text as $header ) { + preg_match( '/^(.+?):\s+(.*)$/', $header, $matches ); + if ( $matches ) { + $data['headers'][ $matches[1] ] = $matches[2]; + } + } + } + + // Propagate all cURL request / response info to the JSON data object. + if ( $_GET['full_status'] ) { + $data['status'] = $status; + } else { + $data['status'] = array(); + $data['status']['http_code'] = $status['http_code']; + } + + // Set the JSON data object contents, decoding it from JSON if possible. + $decoded_json = json_decode( $contents ); + $data['contents'] = $decoded_json ? $decoded_json : $contents; + + // Generate appropriate content-type header. + $is_xhr = strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'; + header( 'Content-type: application/' . ( $is_xhr ? 'json' : 'x-javascript' ) ); + header('Access-Control-Allow-Origin: *'); + + // Get JSONP callback. + $jsonp_callback = $enable_jsonp && isset($_GET['callback']) ? $_GET['callback'] : null; + + // Generate JSON/JSONP string + $json = json_encode( $data ); + + print $jsonp_callback ? "$jsonp_callback($json)" : $json; + +} + +?> diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/blank.gif b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/blank.gif new file mode 100644 index 0000000000000000000000000000000000000000..6865c960497cdd5663acb5548596d00dba342063 GIT binary patch literal 43 vcmZ?wbhEHbWMp7uXkcL2!@$Lm%Aoj@g;j)sfk6j|f#Qq|3`|Tej11NQl}80X literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/buttonBg.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/buttonBg.png new file mode 100644 index 0000000000000000000000000000000000000000..f367b427e60e67272b9a2bec37f71054a3269f74 GIT binary patch literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^j6f{R!3HD)xzi;<0>we@P7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-pp~bKV+hCf(36II4Gug<9Mb>)4|i}V@624c zaHEOQ-P127%)EC~hDl(;irH2!_0HWPp3B55=Xc+Eevp069PP;+tLL2nn!@1e>gTe~ HDWM4fu+KD3 literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/buttonBgHover.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/buttonBgHover.png new file mode 100644 index 0000000000000000000000000000000000000000..cd37a0d52de85c54f3e502c9a4fb6c93c4ebcc46 GIT binary patch literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^j6f{R!3HD)xzi;<0>we@P7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-pq;0SV+hA}+fy5P8w^B_1ROu*f8^ifi%MaN z?t+e)KMUj2=R7_T$DElU6!ZEZgVO|-$@brW6qqs2=3ULdX4am+55(@39-C|hG>O5} L)z4*}Q$iB}Zf-R* literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/close.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/close.png new file mode 100644 index 0000000000000000000000000000000000000000..ada59d8ac1c40449a11a44840b17b7378b98f291 GIT binary patch literal 3490 zcmV;T4PEkyP)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0008bNkl%AL#>?j{-wz#ovT?rxE91)lUjYCB0RR60WB{B00q*YZ5PntN#H10s;R6{{ZFo|8=yoRL(6AL17$*@%#V0%n4?5%-AS`FJc5t zF^WQ?kTr#1Hf*ZTAerDhNF*DI*YXTI8xGE+2wd@(uD`F}#BIKicSrhsUm)6cJE1|3 zW{H%U&N`1L2~M1At(labLPlKl+jN|8t;9ei#i~CvY#RVuz8Vq(Jh{m933?zqw3S1Rw>C2^t2>J_J`Xd6trKKeZY?W#V zgrcRILZY%rOAYhmdhfaCZMYX&8hZEVeV*UX<>=ks)emxJt@bCA777n$QlX^<_futO zHx!@eUN0#H0E(OzIJOxW<3wnj9E~03IRIJv05to%Bb%+E#7uNG#Q@oCMbgPgI!Q)f z83vh_9t;D}0X#@EZuX>ULfPf>;>6lYbR*-8IosP07B9oh$B3Q+cFYNst^Vxi8>GcK zA6?FVb-EhY`rWSZd8fCx*yFo+t#Dm0*@oNDP?lDCVPv;La(07`c+6gfJ( Qk^lez07*qoM6N<$f^Eu$H~;_u literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/closeHover.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/closeHover.png new file mode 100644 index 0000000000000000000000000000000000000000..be0145d2e164da5ab1cfd8c1e071ea6a8dd82e6d GIT binary patch literal 3480 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 literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/disable.gif b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/disable.gif new file mode 100644 index 0000000000000000000000000000000000000000..dd9eb0e3ef6ae354e2ceb653ad48839d27ba83e4 GIT binary patch literal 340 zcmZ?wbhEHb)YR16+}zUA(%RbE(b3V_+1b_A)!p6Q z+uPgM*EeCpgozU;PMS1n^5n@=rc9YSb?S^6GiJ`5IeYf(`Sa&5Sg>HxqD4!VELpZ} z+4AMfSFBjEe*OAQn>PKYF;M&`=v}?EMTFVmhmRH-h=@!%H(`U1mWjL~(r(9$jZjy>BwLW0Bd-< AumAu6 literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/disable.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/disable.png new file mode 100644 index 0000000000000000000000000000000000000000..c28bcdf24a88d4d1266486af283b3557011e916f GIT binary patch literal 543 zcmV+)0^t3LP)x3Se~ z6`Rdw>Ucah*6THwB#AIg5(ME2(GQ@(Ktm}Oiyw-jOuF4}$mMdq0C<3425O0ZzyB?w zG!F)YEE0)iG)?PM7Ep{MxC7835;9bI9SjCUm5V5UB+D}KZ98BrZv^)Fd<+#H0nARP zQ)U>(v8{m|K_IKw>w7Q>#(lF;D3rirvolE&A?Rx~8nO9&p2b7wKRBPy-|iA#kVa_f zNy%i=1n?4ep5s9#8zHu-s;UjH)oO9r-65TzcW3vZTrNK$vxY`l(P*>{?$@ZuCX

zSS&c+6eN1i<#IPJ%7UN@%1Hq6;c$2c$9~94N=7cBH!TRR>^toYUDxfe0SXBMg4!q6 hR;g6le~mu@1^}m-%vu#A_1FLa002ovPDHLkV1iC4;#>d# literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/disableHover.gif b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/disableHover.gif new file mode 100644 index 0000000000000000000000000000000000000000..70565a83cce61a6ce84ced32713fe11dfe32ad32 GIT binary patch literal 344 zcmb8qy-Gr100!XKJeKL_&p{0{mG9UuD279lD4bHr&LBv10SQS(TL?8ow74`xPC-j8 z&2q0GiEI6k05_T4}da2s#{eI_YvzRq652>!r`fK!Cv@Lm_G!BN0ZU zjK!EpFqvd3#dMmP40WA_0_W%Xe_BV)t(8la@}gW{sVvL9Q7A%dD<&Is#PI7citdH8 z!{(A&o4Y7AUW+m;uj}%BNE_SVs~Pd|!PQB3-vKr2s6vs%_Gnj+LH>~wJ-A1;nr&k!$NdEx3Rg!1` literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/disableHover.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/disableHover.png new file mode 100644 index 0000000000000000000000000000000000000000..26fe37542f865a5fc668ceaaa597261351416abf GIT binary patch literal 512 zcmV+b0{{JqP)B9UvD<_Rt@Fa9A3cn2&8 zsB&(OLveLQ9g(&fjgs5jRpxS*W_>#78#q)z2})fFv@41YM6bY}(`dWTB8p3#fBpflR0K9xPy7!y|#6zbl^UQ?6C> ziLs8A6~MOL#(GM{<*3a92_qDO&+k9_0E*B0XQ#8__5i~GMk5TTVbcWs{xXKcgCD>d zPss3n0XJwgfR~q|ccusdH{^Eisu~qG{#@uF){aM55v@S-*L}h!u=!w0000vmZ_X00G%aL_t(I zjir-6Xj4%XhritS^4b@Z=1IwrrO=KdrKp>WpbkMn+#K8l16@p^xL9l&?2^Se*4bSI zZ3h(s5_C`}$I=d>gHQ~KukZgo4ljuYOAUIadoTC*oqNykoQ#O@KVc3RpRQi719t%D zFPbj!==Afab%2bB@czoRb!FT2*-Mw1Idc|e+ea$3=h6H4frD2s(Vka7_u|=x2@r^` z%`PrsmCE>^zaE?3DwWACE^+X#Qv*_fFWSk?Eue#NqJQV+7Wne^jRS)k_#&u`LZWyg zfXXQRLGe?7)<_%?CkgYnZyqb&fBXc~Fz~hh4ImoaL&7kiy|&4P2lv>yd!MY4niM55 zm1cwX+9qY^B&Ic$Y5+9^NUu-U^{~T;?d4S}%?5=;Q%E$GW`phJRqQY#>v~A9KLY%E zL9d4il(b+egHCmY^IH!A=u}rIXDy0aFkP3CW*pET9Tc^OAf$cc768SmX^NsS_CY+V%VO=|af7lf^PJM_L#r!hSbm*AK`Wss)2t0NAQrTnB1QHcYMR&g+daz`w>% X_aN9B#@k{#00000NkvXXu0mjfMjaKM literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/downActive.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/downActive.png new file mode 100644 index 0000000000000000000000000000000000000000..f4312b2ffbc485366e5b3eb2d52fac976597b256 GIT binary patch literal 543 zcmV+)0^t3LP)vmZ_X00DbRL_t(I zjir;lN&`UU}0fnZKwDGo-ZJ=v$nCY@Ck$jQ3OS~ z!%8ev5NyplSR@yfwM_ljM z8jB*`Hb4wcNo$%HXKe{eS`(X6ZGZ^i>XM`_{4FB0rx}o(pOF9q2M0fbrz0a+hWRA0 zo}YLDc0HG|AY|Kf-&@oKDnZDu=h6%0TLc}cAO~om1k^p3N)Y1kR%j&%se3LZb0?RT zL9S(KAoN_kAOv&nH}W*AOaU#Ddjn#?atr)T5CMsK8B=2(NWW9(7x;lMU7%2C99vCi z!un`rT1r;zB^D%h<6WT3xz>HE$zyj?J hQ*}dR`IF$U@d_-*f~iPPaE<@~002ovPDHLkV1gf_)cF7a literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/downHover.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/downHover.png new file mode 100644 index 0000000000000000000000000000000000000000..8144e63787d3015e5ab2219bf24fab87b9fe1141 GIT binary patch literal 526 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf4nJ za0`Jja>QWe}Xi&D$;i?WOTH_Q7mFfe9$x;Tbd^e&xj@9h*QajbrQoamc4Q>{6x z_ytW`lXX-V5t7R4YFksyd&xV$`T4iwda7R! zJhXjYP{)71@w;f~Q~OPae7%pbmNneb_u;>xynx1mHSr=7#+7eGwA%h*Z*MZ+XTsH-c1$v(;2R~YOE~MaXMrp z#grQQO6f^sMM#s10JG77PL9;jC?y7w5KF;Cwi!kjwzI7CKh1VaNyKOJR@VrYO*JNd zDNH`T4E=0J8X}A3Pf43g%&J)E`RTHyE!+3wyh#^!drZ_;wU=v+?+hwt*eG80o^5kL zHecaeo;4{7vfXU+;}`yAIs31J(U_azwvuSV^pkBXx2=!*oAe=kFC#Z!&8|0*agxB8 OVeoYIb6Mw<&;$T_rpeI& literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/errorIcon-sm.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/errorIcon-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..0c377e307e54c7d1ac78b316b6b949085aa368a6 GIT binary patch literal 447 zcmV;w0YLtVP)z^Q>-8KIssI20AY({UO#lFGm;eBCjsO7aNB{ta0001Y z?*IVM@BjcZ_W%GKbhgrL3jhECHAzH4RCwBKl08eqP!xurR1gFQcfld}1BAN@f~4SF z@*4vFk1iRU6beo*g41nrsg!_|n{jZexJXq{gcLysKj`al6LV8~;J`hX^Kjnt5lF(f zeh};dF|Y-E06B2nfxG`CNl3!Nj)k);&;w`+dIQ~qMj#6Z4ama!0Q3mb0{;c&4m|Xs z?ii#fk|ZffYA8u0NwX-@r31IIu+#^AffR;PQPf}ws3@c`)WkujSlGDmC5>cn7<1bWUJj$ZS+iPe7jBcSDR!8x$w6_L3u)yphaIGl zNwmvu6p_Y-3q=&oV#+9g^BMelzQE&f+IxEaa^$28Y{53{z%Ha=5BA{z4j~Iia0=&e z30H6pH*g2{@BokS1kdmSd3c2ayumvZ;R8OQ1YhtCLOG2_Fd7A`RR{)!cwES2gnVB3 zAN7yI5()UDfpJxQA{tUToNf>5QiVv0nQqGdMh7IZ?3$-qFHTs`LebF;-)7Dmi7pLa z1ac;?Oq5u(71vFY<5qEca;3d;EHtvv=W?ASZ#z>3?OfaJkVw{`RMtx!7IAYp>@(A( p)p5Ui~H0X8YDC6$Gxpb|xtYf@N==`2Jc z7Ah8ji(kR7VtwakC$}D$g(o{ZGjC>QZ;f+~bR8H|#%4hcOnLVm*j;w6MZq#Egs5(a zc4lEugK?iQ0QcYtDcH902T2xS;XcvY8O)TA|L_Qo0dkkJVlXBT;dmV(QXWLO$HEed zt}ftbg3DK{l45N>4BPBOtRiE?7^^l0JFaL_w@cLT6E&N;kZtyH3~NT_jk(q5@35sP zaxP8XaIwukAMZ)K?GhDNr$f|e@AO4;e+3u-uo^Lr*!;%I00000NkvXXu0mjfj3mDh literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/firebug.css b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/firebug.css new file mode 100644 index 00000000000..6b093b06cc3 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/firebug.css @@ -0,0 +1,3063 @@ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/* Loose */ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/* +.netInfoResponseHeadersTitle, netInfoResponseHeadersBody { + display: none; +} +/**/ + +/* IE6 need a separated rule, otherwise it will not recognize it */ +.collapsed { + display: none; +} + +[collapsed="true"] { + display: none; +} + +#fbCSS { + padding: 0 !important; +} + +.cssPropDisable { + float: left; + display: block; + width: 2em; + cursor: default; +} + +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/* panelBase */ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ + +/************************************************************************************************/ + +.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(chrome://firebug/skin/loading_16.gif) no-repeat; +} + +.infoTipImageBox { + min-width: 100px; + text-align: center; +} + +.infoTipCaption { + font: message-box; +} + +.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(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; + /* + _margin-left: -7px; + _margin-top: -5px; + /**/ +} + +.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; + + /* + _border: 1px solid #999 !important; + _padding: 1px !important; + _filter:progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color="#55404040"); + /**/ +} + +.textEditorInner1 { + padding-left: 11px; + background: url(textEditorBorders.png) repeat-y; + _background: url(textEditorBorders.gif) repeat-y; + _overflow: hidden; +} + +.textEditorInner2 { + position: relative; + padding-right: 2px; + background: url(textEditorBorders.png) repeat-y 100% 0; + _background: url(textEditorBorders.gif) repeat-y 100% 0; + _position: fixed; +} + +.textEditorTop1 { + background: url(textEditorCorners.png) no-repeat 100% 0; + margin-left: 11px; + height: 10px; + _background: url(textEditorCorners.gif) no-repeat 100% 0; + _overflow: hidden; +} + +.textEditorTop2 { + position: relative; + left: -11px; + width: 11px; + height: 10px; + background: url(textEditorCorners.png) no-repeat; + _background: url(textEditorCorners.gif) no-repeat; +} + +.textEditorBottom1 { + position: relative; + background: url(textEditorCorners.png) no-repeat 100% 100%; + margin-left: 11px; + height: 12px; + _background: url(textEditorCorners.gif) no-repeat 100% 100%; +} + +.textEditorBottom2 { + position: relative; + left: -11px; + width: 11px; + height: 12px; + background: url(textEditorCorners.png) no-repeat 0 100%; + _background: url(textEditorCorners.gif) no-repeat 0 100%; +} + + +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/* CSS */ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ + +/* See license.txt for terms of usage */ + +.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 { + /*padding-left: 2em;*/ +} + +.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(disable.png) no-repeat 2px 1px; + _background: url(disable.gif) no-repeat 2px 1px; +} + +.cssProp.editGroup.editing { + background: none; +} + +.cssProp.disabledStyle { + background: url(disableHover.png) no-repeat 2px 1px; + _background: url(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%; +} +/* +.useA11y .a11yCSSView .focusRow:focus { + outline: none; + background-color: transparent + } + + .useA11y .a11yCSSView .focusRow:focus .cssSelector, + .useA11y .a11yCSSView .focusRow:focus .cssPropName, + .useA11y .a11yCSSView .focusRow:focus .cssPropValue, + .useA11y .a11yCSSView .computedStyleRow:focus, + .useA11y .a11yCSSView .groupHeader:focus { + outline: 2px solid #FF9933; + outline-offset: -2px; + background-color: #FFFFD6; + } + + .useA11y .a11yCSSView .groupHeader:focus { + outline-offset: -2px; + } +/**/ + + +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/* Net */ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ + +/* See license.txt for terms of usage */ + +.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(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; +} + +/************************************************************************************************/ +/* Header for Net panel table */ + +.netHeaderRow { + height: 16px; +} + +.netHeaderCell { + cursor: pointer; + -moz-user-select: none; + border-bottom: 1px solid #9C9C9C; + padding: 0 !important; + font-weight: bold; + background: #BBBBBB url(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(chrome://firebug/skin/tableHeaderActive.gif) repeat-x; +} + +.netHeaderSorted { + background: #7D93B2 url(chrome://firebug/skin/tableHeaderSorted.gif) repeat-x; +} + +.netHeaderSorted > .netHeaderCellBox { + border-right-color: #6B7C93; + background: url(chrome://firebug/skin/arrowDown.png) no-repeat right; +} + +.netHeaderSorted.sortedAscending > .netHeaderCellBox { + background-image: url(chrome://firebug/skin/arrowUp.png); +} + +.netHeaderSorted:hover:active { + background: #536B90 url(chrome://firebug/skin/tableHeaderSortedActive.gif) repeat-x; +} + +/************************************************************************************************/ +/* Breakpoints */ + +.panelNode-net .netRowHeader { + display: block; +} + +.netRowHeader { + cursor: pointer; + display: none; + height: 15px; + margin-right: 0 !important; +} + +/* Display brekpoint disc */ +.netRow .netRowHeader { + background-position: 5px 1px; +} + +.netRow[breakpoint="true"] .netRowHeader { + background-image: url(chrome://firebug/skin/breakpoint.png); +} + +.netRow[breakpoint="true"][disabledBreakpoint="true"] .netRowHeader { + background-image: url(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; +} + +/************************************************************************************************/ +/* Column visibility */ + +.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(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(chrome://firebug/skin/netBarResolving.gif) repeat-x; + z-index:60; +} + +.netConnectingBar { + position: absolute; + left: 0; + top: 0; + bottom: 0; + background: #FFFFFF url(chrome://firebug/skin/netBarConnecting.gif) repeat-x; + z-index:50; +} + +.netBlockingBar { + position: absolute; + left: 0; + top: 0; + bottom: 0; + background: #FFFFFF url(chrome://firebug/skin/netBarWaiting.gif) repeat-x; + z-index:40; +} + +.netSendingBar { + position: absolute; + left: 0; + top: 0; + bottom: 0; + background: #FFFFFF url(chrome://firebug/skin/netBarSending.gif) repeat-x; + z-index:30; +} + +.netWaitingBar { + position: absolute; + left: 0; + top: 0; + bottom: 0; + background: #FFFFFF url(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(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; +} + +/* + * Timing info tip is reusing net timeline styles to display the same + * colors for individual request phases. Notice that the info tip must + * respect also loaded and fromCache styles that also modify the + * actual color. These are used both on the same element in case + * of the tooltip. + */ +.loaded .netReceivingBar, +.loaded.netReceivingBar { + background: #B6B6B6 url(chrome://firebug/skin/netBarLoaded.gif) repeat-x; + border-color: #B6B6B6; +} + +.fromCache .netReceivingBar, +.fromCache.netReceivingBar { + background: #D6D6D6 url(chrome://firebug/skin/netBarCached.gif) repeat-x; + border-color: #D6D6D6; +} + +.netSummaryRow .netTimeLabel, +.loaded .netTimeLabel { + background: transparent; +} + +/************************************************************************************************/ +/* Time Info tip */ + +.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; +} + +/************************************************************************************************/ +/* Size Info tip */ + +.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; +} + +/************************************************************************************************/ +/* Summary */ + +.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(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; +} + +/*.netInfoTab:hover { + cursor: pointer; +}*/ + +/* replaced by .netInfoTabSelected for IE6 support +.netInfoTab[selected="true"] { + cursor: default !important; + border: 1px solid #D7D7D7 !important; + border-bottom: none !important; + -moz-border-radius: 4px 4px 0 0; + background-color: #FFFFFF; +} +/**/ +.netInfoTabSelected { + cursor: default !important; + border: 1px solid #D7D7D7 !important; + border-bottom: none !important; + -moz-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; */ + /*overflow-x: auto; HTML is damaged in case of big (2-3MB) responses */ +} + +/* replaced by .netInfoTextSelected for IE6 support +.netInfoText[selected="true"] { + display: block; +} +/**/ +.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; /* Google Chrome need this otherwise the first column of + the post variables table will be larger than expected */ +} + +.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%; +} + +/************************************************************************************************/ +/* Request & Response Headers */ + +.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(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; +} +/* +.useA11y .panelNode-net .a11yFocus:focus, +.useA11y .panelNode-net .focusRow:focus { + outline-offset: -2px; + background-color: #FFFFD6 !important; +} + +.useA11y .panelNode-net .netHeaderCell:focus, +.useA11y .panelNode-net :focus .netHeaderCell, +.useA11y .panelNode-net :focus .netReceivingBar, +.useA11y .netSummaryRow :focus .netBar, +.useA11y .netSummaryRow:focus .netBar { + background-color: #FFFFD6; + background-image: none; + border-color: #FFFFD6; +} +/**/ + +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/* Windows */ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ + + +/************************************************************************************************/ +/* Twisties */ + +/* IE6 has problems with > operator, and multiple classes */ +/*.twisty, +.logRow-errorMessage > .hasTwisty > .errorTitle, + /* avoid rule not being parsed IE6 */ +.logRow-spy .spyHead .spyTitle, +.logGroup .logGroupLabel, +.hasChildren .memberLabelCell .memberLabel, +.hasHeaders .netHrefLabel { + background-image: url(tree_open.gif); + background-repeat: no-repeat; + background-position: 2px 2px; +} +/* +.logRow-errorMessage > .hasTwisty.opened > .errorTitle, +/* avoid rule not being parsed IE6 */ +.opened .spyHead .spyTitle, +.opened .logGroupLabel, +.opened .memberLabelCell .memberLabel/*, +.nodeBox.highlightOpen > .nodeLabel > .twisty, +.nodeBox.open > .nodeLabel > .twisty, +.netRow.opened > .netCol > .netHrefLabel /* avoid rule not being parsed IE6 */ { + background-image: url(tree_close.gif); +} + +.twisty { + background-position: 2px 0; +} + + + + + +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/* Console */ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ + + +/* See license.txt for terms of usage */ + +.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; /* IE need this to avoid disappearing bug with collapsed logs */ +} + +.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(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 { + /*background-image: url(chrome://firebug/skin/infoIcon.png);*/ +} + +.logRow-warn, +.logRow-warningMessage { + /*background-image: url(chrome://firebug/skin/warningIcon.png);*/ +} + +.logRow-error, +.logRow-assert, +.logRow-errorMessage { + /*background-image: url(chrome://firebug/skin/errorIcon.png);*/ +} + +/*****************************************************************************************/ + +.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; + /*background: url(chrome://firebug/skin/errorIcon-sm.png) no-repeat 0 0;*/ + 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; + /*background: url(chrome://firebug/skin/breakpoint.png) no-repeat;*/ + 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 { + /*background: transparent url(chrome://firebug/skin/loading_16.gif) no-repeat 2px 0 !important;*/ + 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; + /*background: #BBBBBB url(chrome://firebug/skin/tableHeader.gif) repeat-x;*/ +} + +.headerCellBox { + padding: 2px 4px; + border-left: 1px solid #D9D9D9; + border-right: 1px solid #9C9C9C; +} + +.headerCell:hover:active { + /*background: #959595 url(chrome://firebug/skin/tableHeaderActive.gif) repeat-x;*/ +} + +.headerSorted { + /*background: #7D93B2 url(chrome://firebug/skin/tableHeaderSorted.gif) repeat-x;*/ +} + +.headerSorted > .headerCellBox { + border-right-color: #6B7C93; + /*background: url(chrome://firebug/skin/arrowDown.png) no-repeat right;*/ +} + +.headerSorted.sortedAscending > .headerCellBox { + /*background-image: url(chrome://firebug/skin/arrowUp.png);*/ +} + +.headerSorted:hover:active { + /*background: #536B90 url(chrome://firebug/skin/tableHeaderSortedActive.gif) repeat-x;*/ +} + +.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; +} + +.objectPropValue { + font-weight: normal; + font-style: italic; + color: #555555; +} + +/************************************************************************************************/ + +.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; +} + +/*****************************************************************************************/ + +.arrayLeftBracket, +.arrayRightBracket, +.arrayComma { + font-family: Monaco, monospace; +} + +.arrayLeftBracket, +.arrayRightBracket { + font-weight: bold; +} + +.arrayLeftBracket { + margin-right: 4px; +} + +.arrayRightBracket { + margin-left: 4px; +} + +/*****************************************************************************************/ + +.logRow-dir { + padding: 0; +} + +/************************************************************************************************/ + +/* +.logRow-errorMessage > .hasTwisty > .errorTitle, +.logRow-spy .spyHead .spyTitle, +.logGroup > .logRow +*/ +.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(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(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(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; +} + + + + +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/* DOM */ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ + + +/* See license.txt for terms of usage */ + +.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; + /*position: absolute;*/ + padding-left: 18px; + /*max-width: 30%;*/ + /*white-space: nowrap;*/ + 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; +} + + +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/* FROM ORIGINAL FIREBUG */ + + + + +/************************************************************************************************ + CSS Not organized +*************************************************************************************************/ +#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; } + + +/************************************************************************************************ + Not organized +*************************************************************************************************/ + +#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: 5px; + height: 23px; + clip: rect(0, 2048px, 27px, 0); +} + +.fbTabMenuTarget { + display: none !important; + float: left; + width: 10px; + height: 10px; + margin-top: 6px; + background: url(tabMenuTarget.png); +} + +.fbTabMenuTarget:hover { + background: url(tabMenuTargetHover.png); +} + +.fbShadow { + float: left; + background: url(shadowAlpha.png) no-repeat bottom right !important; + background: url(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; + 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(tabMenuPin.png) no-repeat right 0; +} + +.fbMenuGroup:hover { + background: #316AC5 url(tabMenuPin.png) no-repeat right -17px; +} + +.fbMenuGroupSelected { + color: #fff; + background: #316AC5 url(tabMenuPin.png) no-repeat right -17px; +} + +.fbMenuChecked { + background: transparent url(tabMenuCheckbox.png) no-repeat 4px 0; +} + +.fbMenuChecked:hover { + background: #316AC5 url(tabMenuCheckbox.png) no-repeat 4px -17px; +} + +.fbMenuRadioSelected { + background: transparent url(tabMenuRadio.png) no-repeat 4px 0; +} + +.fbMenuRadioSelected:hover { + background: #316AC5 url(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; +} + + + +/************************************************************************************************ + Error Popup +*************************************************************************************************/ +#fbErrorPopup { + position: absolute; + right: 0; + bottom: 0; + height: 19px; + width: 75px; + background: url(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; +} + +/************************************************************************************************ + General +*************************************************************************************************/ +.fbBody { + margin: 0; + padding: 0; + overflow: hidden; + + font-family: Lucida Grande, Tahoma, sans-serif; + font-size: 11px; + background: #fff; +} + +.clear { + clear: both; +} + +/************************************************************************************************ + Mini Chrome +*************************************************************************************************/ +#fbMiniChrome { + display: none; + right: 0; + height: 27px; + background: url(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(search.png) no-repeat 4px 2px !important; + background: #fff url(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(errorIcon.png) no-repeat !important; + background: url(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(sprite.png) 0 -135px; + cursor: pointer; +} + + +/************************************************************************************************ + Master Layout +*************************************************************************************************/ +#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; + background: #fff; + overflow: hidden; +} + +#fbTop { + height: 50px; +} + +#fbToolbar { + background: url(sprite.png) #eee 0 0; + height: 27px; + font-size: 11px; +} + +#fbPanelBarBox { + background: url(sprite.png) #d9d9d9 0 -27px; + height: 23px; +} + +#fbContent { + height: 100%; + vertical-align: top; +} + +#fbBottom { + height: 18px; + background: #fff; +} + +/************************************************************************************************ + Sub-Layout +*************************************************************************************************/ + +/* fbToolbar +*************************************************************************************************/ +#fbToolbarIcon { + float: left; + padding: 0 5px 0; +} + +#fbToolbarIcon a { + background: url(sprite.png) 0 -135px; +} + +#fbToolbarButtons { + padding: 0 2px 0 5px; +} + +#fbToolbarButtons { + padding: 0 2px 0 5px; +} +/* +#fbStatusBarBox a { + text-decoration: none; + display: block; + float: left; + color: #000; + padding: 4px 5px; + margin: 0 0 0 1px; + cursor: default; +} + +#fbStatusBarBox a:hover { + color: #333; + padding: 3px 4px; + border: 1px solid #fff; + border-bottom: 1px solid #bbb; + border-right: 1px solid #bbb; +} +/**/ + +.fbButton { + text-decoration: none; + display: block; + float: left; + color: #000; + padding: 4px 6px 4px 7px; + cursor: default; +} + +.fbButton:hover { + color: #333; + padding: 3px 5px 3px 6px; + border: 1px solid #fff; + border-bottom: 1px solid #bbb; + border-right: 1px solid #bbb; +} + +.fbBtnPressed { + background: #ECEBE3; + 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: 50px; + padding: 7px 0 4px 5px; + z-index: 6; + background: url(sprite.png) #eee 0 0; +} + +/* fbPanelBarBox +*************************************************************************************************/ + +#fbPanelBar1 { + width: 1024px; /* fixed width to avoid tabs breaking line */ + z-index: 8; + left: 0; + white-space: nowrap; + background: url(sprite.png) #d9d9d9 0 -27px; + position: absolute; + left: 4px; +} + +#fbPanelBar2Box { + background: url(sprite.png) #d9d9d9 0 -27px; + position: absolute; + height: 23px; + width: 300px; /* fixed width to avoid tabs breaking line */ + z-index: 9; + right: 0; +} + +#fbPanelBar2 { + position: absolute; + width: 290px; /* fixed width to avoid tabs breaking line */ + height: 23px; + padding-left: 4px; +} + +/* body +*************************************************************************************************/ +.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: #EEEEEE; + bottom: 0; + right: 0; + width: 294px; + height: 21px; + padding-top: 1px; + position: fixed; + border-top: 1px solid #ACA899; + z-index: 9; +} + +#fbSmallCommandLineIcon { + background: url(down.png) no-repeat; + position: absolute; + right: 2px; + bottom: 3px; + + z-index: 99; +} + +#fbSmallCommandLineIcon:hover { + background: url(downHover.png) no-repeat; +} + +.hide { + overflow: hidden !important; + position: fixed !important; + display: none !important; + visibility: hidden !important; +} + +/* fbBottom +*************************************************************************************************/ + +#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: 7px; + 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(up.png) no-repeat; + position: absolute; + right: 1px; + bottom: 1px; + z-index: 10; +} + +#fbLargeCommandLineIcon:hover { + background: url(upHover.png) no-repeat; +} + +div.fbFitHeight { + overflow: auto; + position: relative; +} + + +/************************************************************************************************ + Layout Controls +*************************************************************************************************/ + +/* fbToolbar buttons +*************************************************************************************************/ +.fbSmallButton { + overflow: hidden; + width: 16px; + height: 16px; + display: block; + text-decoration: none; + cursor: default; +} + +#fbWindowButtons .fbSmallButton { + float: right; +} + +#fbWindow_btClose { + background: url(min.png); +} + +#fbWindow_btClose:hover { + background: url(minHover.png); +} + +#fbWindow_btDetach { + background: url(detach.png); +} + +#fbWindow_btDetach:hover { + background: url(detachHover.png); +} + +#fbWindow_btDeactivate { + background: url(off.png); +} + +#fbWindow_btDeactivate:hover { + background: url(offHover.png); +} + + +/* fbPanelBarBox tabs +*************************************************************************************************/ +.fbTab { + text-decoration: none; + display: none; + float: left; + width: auto; + float: left; + cursor: default; + font-family: Lucida Grande, Tahoma, sans-serif; + font-size: 11px; + font-weight: bold; + height: 23px; + color: #565656; +} + +.fbPanelBar span { + /*display: block; TODO: safe to remove this? */ + float: left; +} + +.fbPanelBar .fbTabL,.fbPanelBar .fbTabR { + height: 23px; + width: 8px; +} + +.fbPanelBar .fbTabText { + padding: 4px 1px 0; +} + +a.fbTab:hover { + background: url(sprite.png) 0 -73px; +} + +a.fbTab:hover .fbTabL { + background: url(sprite.png) -16px -96px; +} + +a.fbTab:hover .fbTabR { + background: url(sprite.png) -24px -96px; +} + +.fbSelectedTab { + background: url(sprite.png) #EEEEEE 0 -50px !important; + color: #000; +} + +.fbSelectedTab .fbTabL { + background: url(sprite.png) 0 -96px !important; +} + +.fbSelectedTab .fbTabR { + background: url(sprite.png) -8px -96px !important; +} + +/* splitters +*************************************************************************************************/ +#fbHSplitter { + position: fixed; + _position: absolute; + left: 0; + top: 0; + width: 100%; + height: 5px; + overflow: hidden; + cursor: n-resize !important; + background: url(pixel_transparent.gif); + z-index: 9; +} + +#fbHSplitter.fbOnMovingHSplitter { + height: 100%; + z-index: 100; +} + +.fbVSplitter { + background: #eee; + color: #000; + border: 1px solid #777; + border-width: 0 1px; + border-left-color: #aca899; + width: 4px; + cursor: e-resize; + overflow: hidden; + right: 294px; + text-decoration: none; + z-index: 9; + position: absolute; + height: 100%; + top: 27px; +} + +/************************************************************************************************/ +div.lineNo { + font: 1em Monaco, monospace; + position: relative; + float: left; + top: 0; + left: 0; + margin: 0 5px 0 0; + padding: 0 5px 0 10px; + background: #eee; + color: #888; + border-right: 1px solid #ccc; + text-align: right; +} + +.sourceBox { + position: absolute; +} + +.sourceCode { + font: 1em Monaco, monospace; + overflow: hidden; + white-space: pre; + display: inline; +} + +/************************************************************************************************/ +.nodeControl { + margin-top: 3px; + margin-left: -14px; + float: left; + width: 9px; + height: 9px; + overflow: hidden; + cursor: default; + background: url(tree_open.gif); + _float: none; + _display: inline; + _position: absolute; +} + +div.nodeMaximized { + background: url(tree_close.gif); +} + +div.objectBox-element { + padding: 1px 3px; +} +.objectBox-selector{ + cursor: default; +} + +.selectedElement{ + background: highlight; + /* background: url(roundCorner.svg); Opera */ + color: #fff !important; +} +.selectedElement span{ + color: #fff !important; +} + +/* IE6 need this hack */ +* html .selectedElement { + position: relative; +} + +/* Webkit CSS Hack - bug in "highlight" named color */ +@media screen and (-webkit-min-device-pixel-ratio:0) { + .selectedElement{ + background: #316AC5; + color: #fff !important; + } +} + +/************************************************************************************************/ +/************************************************************************************************/ +.logRow * { + font-size: 1em; +} + +/* TODO: remove this? */ +/* TODO: xxxpedro - IE need this in windowless mode (cnn.com) check if the issue is related to +position. if so, override it at chrome.js initialization when creating the div */ +.logRow { + position: relative; + border-bottom: 1px solid #D7D7D7; + padding: 2px 4px 1px 6px; + zbackground-color: #FFFFFF; +} +/**/ + +.logRow-command { + font-family: Monaco, monospace; + color: blue; +} + +.objectBox-string, +.objectBox-text, +.objectBox-number, +.objectBox-function, +.objectLink-element, +.objectLink-textNode, +.objectLink-function, +.objectBox-stackTrace, +.objectLink-profile { + font-family: Monaco, monospace; +} + +.objectBox-null { + padding: 0 2px; + border: 1px solid #666666; + background-color: #888888; + color: #FFFFFF; +} + +.objectBox-string { + color: red; + + /* TODO: xxxpedro make long strings break line */ + /*white-space: pre; */ +} + +.objectBox-number { + color: #000088; +} + +.objectBox-function { + color: DarkGreen; +} + +.objectBox-object { + color: DarkGreen; + font-weight: bold; + font-family: Lucida Grande, sans-serif; +} + +.objectBox-array { + color: #000; +} + +/************************************************************************************************/ +.logRow-info,.logRow-error,.logRow-warn { + background: #fff no-repeat 2px 2px; + padding-left: 20px; + padding-bottom: 3px; +} + +.logRow-info { + background-image: url(infoIcon.png) !important; + background-image: url(infoIcon.gif); +} + +.logRow-warn { + background-color: cyan; + background-image: url(warningIcon.png) !important; + background-image: url(warningIcon.gif); +} + +.logRow-error { + background-color: LightYellow; + background-image: url(errorIcon.png) !important; + background-image: url(errorIcon.gif); + color: #f00; +} + +.errorMessage { + vertical-align: top; + color: #f00; +} + +.objectBox-sourceLink { + position: absolute; + right: 4px; + top: 2px; + padding-left: 8px; + font-family: Lucida Grande, sans-serif; + font-weight: bold; + color: #0000FF; +} + +/************************************************************************************************/ +/* +//TODO: remove this when console2 is finished +*/ +/* +.logRow-group { + background: #EEEEEE; + border-bottom: none; +} + +.logGroup { + background: #EEEEEE; +} + +.logGroupBox { + margin-left: 24px; + border-top: 1px solid #D7D7D7; + border-left: 1px solid #D7D7D7; +}/**/ + +/************************************************************************************************/ +.selectorTag,.selectorId,.selectorClass { + font-family: Monaco, monospace; + font-weight: normal; +} + +.selectorTag { + color: #0000FF; +} + +.selectorId { + color: DarkBlue; +} + +.selectorClass { + color: red; +} + +/************************************************************************************************/ +.objectBox-element { + font-family: Monaco, monospace; + color: #000088; +} + +.nodeChildren { + padding-left: 26px; +} + +.nodeTag { + color: blue; + cursor: pointer; +} + +.nodeValue { + color: #FF0000; + font-weight: normal; +} + +.nodeText,.nodeComment { + margin: 0 2px; + vertical-align: top; +} + +.nodeText { + color: #333333; + font-family: Monaco, monospace; +} + +.nodeComment { + color: DarkGreen; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +.nodeHidden, .nodeHidden * { + color: #888888; +} + +.nodeHidden .nodeTag { + color: #5F82D9; +} + +.nodeHidden .nodeValue { + color: #D86060; +} + +.selectedElement .nodeHidden, .selectedElement .nodeHidden * { + color: SkyBlue !important; +} + + +/************************************************************************************************/ +.log-object { + /* + _position: relative; + _height: 100%; + /**/ +} + +.property { + position: relative; + clear: both; + height: 15px; +} + +.propertyNameCell { + vertical-align: top; + float: left; + width: 28%; + position: absolute; + left: 0; + z-index: 0; +} + +.propertyValueCell { + float: right; + width: 68%; + background: #fff; + position: absolute; + padding-left: 5px; + display: table-cell; + right: 0; + z-index: 1; + /* + _position: relative; + /**/ +} + +.propertyName { + font-weight: bold; +} + +.FirebugPopup { + height: 100% !important; +} + +.FirebugPopup #fbWindowButtons { + display: none !important; +} + +.FirebugPopup #fbHSplitter { + display: none !important; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/firebug.html b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/firebug.html new file mode 100644 index 00000000000..8c91c688d55 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/firebug.html @@ -0,0 +1,213 @@ + + + + +Firebug Lite + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+   +   +   +
+ + +
+
+ + + +   + + + + + + + + + Inspect + + + + + Clear + + + + + + + + + + + + + +
+ +
+ + + + + +
 
+ +
+
+
+
+
+
+ + +
 
+ + +
+ + +
+
+
+ +
+ + + + + +
+ Run + Clear + + +
+ +
+
+
>>>
+ + +
+
+ + + + 2 errors + + + + + \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/firebug.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/firebug.png new file mode 100644 index 0000000000000000000000000000000000000000..338dc5a141ea62d8c9c35e69b04f1ea4a2de5097 GIT binary patch literal 1037 zcmV+o1oHcdP)W>$azVg!mke)1F~z;Spo z2ls6iy}I`9-Fw!?dJNtT009Kj1k~{7&z~oE&MRn`vM_+b_xtBBZdv~P{a+BDd3X2y zTlYikZGM|tu&i3Qk^l68kAhl^Tt>PK3?ThK-@jz!7Gz^%1F8iGAgFl|@bl;QLq|`! zI@uowgY4{VsPP{^zCF1Au-5bK7Q!N2XCAxj*~z>GO8tlG-nDGT_ty`lzCYyT;$&jy z`^LcfQr1b0?G{wG)Z?8uUVh_HQT)UqWtCL-cb`m5jDe14LRNd`{8>>^QFRUN?K^ku*|X>G-@j118UKF&&&+w{ z&NF+4IV?tAr%s&w05p}65o-9tMf269M6KU!`@*dtZfwUWBKw|M;=-Au2)o}c$~pY- zSD?A{r|;|%qP$^5El`Jh-H9iBKORqiD01e^DSl37#`Oz( zP3;3GmBi)Q2=|_4%rN4TfnN#d8PNpveINK!Bly8ZtP0>Hx?4OTv1g!lI)8{{H>* z`^T@}e{SEtd+5+1U_^6ra^lkr1c#3tk&}^?SCD6ZcmKzo)A3!4c_kF3#Y9+HS=rgy zH8nL+G@m@UL6Q4Azi!}zM^B$UdCYumtE0#_WwAU+Q~!N?ckliGkKcaE2=l0Ds4_5fF$l;q@(BF;`Te)7`R_k}Zd|{C z(ERJyul1X^tNgyL@%h5`_mc15zcUs4Z>lbF<;mywU;b)H35YO%d8y*}O<3*TqbJ&` z3If8SjEDDbR+iwo{N(rRm(Q%l{@g#if6dizo?`FKRK+em{&e;ohq9EAwFJZK_n&U5 zgxNbdvM@6PZMt^pgp8~T$mak5{{z$0ug~vJPs)Dz?!Ae!(3OWDkAD+4RTg*Qd%-TQ z!suMEdFLJvS4Va(KI~ET@B7C`8`?kJzy9GjtEQILKSj%v*Y1DimJSc_WnyOf`t|em zi$|0-%>@O82*mTURcrJ$Rkd~X8SnxYtfIzxDvW>sF%SX(T42Lu%uUQ100000NkvXX Hu0mjfgXAGY literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/group.gif b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/group.gif new file mode 100644 index 0000000000000000000000000000000000000000..8db97c2104b6479a74c6a268ab7175e60d8a5ff5 GIT binary patch literal 158 zcmXwyI|{-;6ab%~Alh08+NAdY5!;{yM6gWhAv}PM=dkh!p1?-161;@F*=#oZ&Hf~U zQw-D1CSRw^Lk|+T1F(kCx~>@uJ~-!0+cum_DYZ5wA-1(jY43wJMoAe$u-1C-Fd;ES zgb)|JqErZh%MxMyL5NgUj1m4MrvJ-D=k5uE+2y(~&iUh3oM8GsrsLOSlx0u4o$rRQ F`U22=Vrl>Y literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/infoIcon.gif b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/infoIcon.gif new file mode 100644 index 0000000000000000000000000000000000000000..0618e208c3488f9d332eff840219c4b37806a396 GIT binary patch literal 359 zcmZ?wbhEHbMdn4SjS?t zoyB-Jv&kW5)5FYWr^BHcuFBo-x|KV6=V7X!nNE z?k%I;dq(?@3=Urz9KJI+{9thW#o+W`(Eq=2#($TR|K+p(uR8F5_u2oH1I2%W&PAz- zC8;S2<(VZJ3hti10St;iSs1w(>=|?zfB@uC2e$kJ^8+|EnA%*k!W#MOQK{ljl)GVz=%0?7rtE9wY7Lo;JgN;%aBBhkF zup$d#AvGJB@i#x7d!6%U9&aT1>bvKh+xgD9@4TZarC_79XA_3Y)u z4jj;IA&G`4T$SEtNOwJyD9b09DTwq1MCN*%!X+xO|0N{Rs4^;&b|i*sHEGPq;n|zOEfbH<6(;%L`k^mT)7z~ywlRx3h4?$ zl>}*o?-02Jb-IWCddBfMi57}>wIB`^Hlv*vh?pjx5|0aenzD001sDKWl9*QR=`djc O0000nb99Af5rT)t{mCEg5urg=A(g z{C|6SPb~9Xage|wB`SrZk2FOMYM!buln2sX?5Y+T78iB(Zu9cS7|LZyZ++}u$^oi1 z_j@S}bW9OzU2R+RMy&~OT>X-oZ98$jq#ogNfJ!BM-42wHGZk*6s2KD}U*IA%epmxb zm}|6BK9YoIF;*xSL!+z@<64lB7->LTW2Vi4ostCA(z&2XniwNIv}fFo-`MbG;)u4G z^p@F!)|9HhZprHd_vXjDoxs6WkK-6P0@lfxnGT>*p(QHoUV=u1FAqb@b%*W=a3{`LsH5k^AvQNL>6fPpy#oU(&MuH(*aEX4b35*} zn4n7)`I2U%=+Z=?BVZQ?vjQFW4gD@~XSOO6b{qu81`4&LFuU2(ilxW+1|ZkNMnWe79C$gs zWT?Ele|HR{JGPe)5BTW>0Ey?-Ls6S#GoV0tbt6ku7B&*0 z;i9QM$W1Rj*rRIdceL)rAOSl+sDe3LkB87<%){;ZdHp6|SNlopDXRx< zxBDF9-lTo&v`8$humFygUij@qgT=Qzhj8{ym2-{Xciwqq_Xwk%=O3B-MNAL_6e`3U zyxwmXex4`g0^1RYw~Dth3av3Dl^AAlpO3mG!nLr#&ZZ7c_wUboI+deC+&%TFjK2Lm z!Y&f1h|T_On%RCV&=4bx`!>(YezqGVhl&QpED?N6GV)HmzJ9&rh$x*i?*@o9#6QI< z5ZI_MRX;0+pY8$`j)eF#TlUyG(eE%E7S!rj;mj^M5vhUicPm zVWQ2z+imFyg}SRABmOBY_@osR!>7Ov!ioK`NB6_Rv}7Ud?35ed5Sb@?yND?kv~RCa wqs^a3Sh>&&L4)!LKI?D2&k@))k(LESaga|C278ChSzn3NWVkcuNoY&{0f?~U_5c6? literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/min.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/min.png new file mode 100644 index 0000000000000000000000000000000000000000..1034d66fb4405598401302e3e624b1674d2bf1e4 GIT binary patch literal 552 zcmV+@0@wYCP)vmZ_X00D$aL_t(I zjiuAUOB+EH$MNsZCL1?R8&!4bS6fS<)tz`g=*viD*Jl^CK z`t%GY-@^kYv5587_1khrGe5s5z@kn#$OJ&Z!eFXD1Sm(L2g^?Y zYmr`er0{)dYkvX6!fog80Qn7&_6-2NexGu6D>c-py(Qzi=>Y9E03D+rytQ-Lq?j9f z2uM00HtcO|a&62|cs!S*R1Cm$(*e`E!c#83wM^skESnnwvbgx22+@Yv_J;w1RwKFy zozi=wY0ONJ#dDq19mIX%q}AnE8w#$f!{9Ff q>@2^m0u@I4O!e0v_iIDIzt$ZPov@8OQ*!|T00004nJ za0`Jja>QWe}Xi&D$;i?WOTH_Q7mFfclLx;Tbd^e&ye){i+*pmo2d_v|Tm-%WA| zXmI?Fy){a=&u=f4TRr{YyjOcz1)84U;wyZtH?bkx zx+N`yTY>4zLPu-Cz0D_%tZP1UcQ?mxR;7exlD+Hw9x3Ds8E&w9mVc-F%e}wTn|nOB zsFnO>dbZ5cgE>_2UfT)14Y$J0A1JWga=XiV?aW^J%?{U&Jlo*F)ij&up5HFxF55(& zhFj`OqF8JjSv9WT`ccMbRy@JCSFNt*@K@_Avt;>Z#4=cjXfhpFiC*?;WmcxcgY`cc YmzC#;_!)WW0t1}E)78&qol`;+0Lys1;s5{u literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/off.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/off.png new file mode 100644 index 0000000000000000000000000000000000000000..b70b1d24d881014f43bbc8f6ac6e5d84921c0ece GIT binary patch literal 742 zcmVPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FZT01FZU(%pXi0007cNklqH)0mG!ByR2T(Q_4JHo86*cHY zh~fooLU0lPU?Oy!fyZLq%=)}Z(j3lpdV?PzJq7_g47OL4;4Cdfcc&3D43;LRvAT0esjMcVWGjFG2rKDI*|i%PS;bLS zOj^x8?AdMrgjL6pn?>%C8nl8ug2ocIJP%

yFlpb(nCwj+ns@?rq|_a5+Sz>mY} zr1X%NW9QG3U*lzXY6iI&#FUa>3Zz8EqS%W(06f3b&D#M#ZMSc7>DpDCfv>#leGEWO zRXKAD^Q^?;4+{R z*+y2$wpbIZSBe$Gz!q6u%R;fVxJXEDRS*mknw|xqwB`U-O+&?E#A9&?hjA3<128}S z8BCLil3M}G82%vuYA?5-7kT*D(ni<03miUKkNb2303$sQNtKG|np%Aw5HY@^{4e<8 zPN(2ZBUQ~!(A>nHO@}mm_der&PbqPwGre}hdcqaPq`BZKOL4H$-NnmK@5!yJW2e_k z)HInN8)KxWhw=V?3Y<=&!bE7Au>sg-5uFp^WuMKtN`AVIJ~PC`^=AyOm>A(GLW9&~ zD|Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FZT01FZU(%pXi0006zNklLBO?ccg<(Vi96RihU3|k%V;awJqJeI@l%)iVo_6hv)OYp8NjsJn)aIDi0D60lEO+ zUt(r~8@r3=iv~|2TucG{LTU=bZDDP0X624n%=$VCEHOJWM*7tooR*ioVKDu1bo(Q?>Hx@q&+GP(AA5&) zXDe$?b>M1l1i)~bcs4e%;dCcv`zF%whw!-EWJ;wv0Bk^?#;}?i@E<({K>SjeXk#Yp7uEqW^LZ-5|E1)5lTj@kXlJxvSm!hUq`CLwgTuyOog&g>}9I&!tKMTxN8rXmn$R?8jYzYK#)z_n3j>6(1HNdJs0D!4vl4@YSl0heE5;PeM zs;uEqNTZG5txeV=>(X^@H|S8XSO`J|~)U zqm&yBpABjvF(64=ux(8w2GoBhsN1zDZlSv-+7B~OddfivTMi;8{IJUd1z4WI + + + + + diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/search.gif b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/search.gif new file mode 100644 index 0000000000000000000000000000000000000000..2a620987e0e1b7e9ad3213c1c0541cc7db5afea0 GIT binary patch literal 550 zcmZ?wbhEHbN5Ue#OE(%(37LBq6V z9n+Td&t5rW;i_4SRxet#bn%j9%U7*mvS!Pg4O(=etw(i)p zW8a(u7dP)YI{(m>`G>D=+jn@?$s4Or-8^vY%$n0T*POm}_~iLRr_OIYcjxG-3rEge zK6d8fwhQ-8oWHv3@`D{$9-h2#Vqg^X to)YGxrtD|QY%Y26QkOZasnngjVb*LG0!~jl%~&`CUUzEyhBY!+0{{*nXwCot literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/search.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/search.png new file mode 100644 index 0000000000000000000000000000000000000000..fba33b8a57d351da68abc3340dd4e589bc55764d GIT binary patch literal 685 zcmV;e0#f~nP)#l3+^+pwak93=7Z|VPQhts0;rO9~&RUt*+FN7~L36 zT)GisL=jOEKtN*@DU?oWX&E}5(#K3^oZtp@;Ysf9{_Z{ZTypLD4RDN|2}L5e!mZIB zPVgYBs>x(x>852`PZ*>4TO0xUJuGWFNZDW5&SL~3w^7#Gh(FVO(dO+!J zkSd|QcRG$9Z!Wq-&8%V5C?k>8AcUf5kHv>AtKMXq7IqfLi;dlc<4~`ap=t(7RSR+h z56vi{nloG5JO3=$yv;<_dHpvJ|UZ~3kek5~Z%{1Ls^2Zt> zpc6CS5?fUh#fpVSpBMWSKMpqg5e-UsHTF5HZRE!Nq5!dhgXrbJhy|9`EkjZE40d+L zsLxHVEfj#_Hhr4?j(hhXRwbwS;`FiZY&hscM3EqQY%rS%vs2UaT1nqJ74{1(pUv4L z&tB%QT)kZh`9)>u+(7?YW_{efYprfO*eaJnyx|y#AcHVI!Z8}FJ7B?}@^y1*E)?%M z@_gj(aBN|AW`2BP@}m3CFS=d;<0J)~-~(kI!*QHtci56&mJO$@Wfs$$?-o<}z6(PG zoua_^CRbA*DwRrR8=@XB2xV?I&UQkgD8bZouqdBdRM+4BOsKt=&JT7Odg1KqYHIQy z$k_qa;DOgCXMZgxKaNe!_vr;aEl~RrhyRGUf8lx0^xWLSWuMc&5^oKpehV-FA-Vn? Tug%)J00000NkvXXu0mjfX&yMP literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/shadow.gif b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/shadow.gif new file mode 100644 index 0000000000000000000000000000000000000000..af7f537e391f08327e417c7be6323c917d5d3788 GIT binary patch literal 4364 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 mNRx4)$-Se2KGVRJG=-nEko^8U73WMVE8{ literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/shadow2.gif b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/shadow2.gif new file mode 100644 index 0000000000000000000000000000000000000000..099cbf35d455e13d49010e736c40bab22c3d1a23 GIT binary patch literal 3093 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 literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/shadowAlpha.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/shadowAlpha.png new file mode 100644 index 0000000000000000000000000000000000000000..a2561df971728d988424100c74c817916eca1979 GIT binary patch literal 3403 zcmeAS@N?(olHy`uVBq!ia0y~yV738bR}L1Sh{z?w93Z7#;u=xnT$Gwvl9`{U5R#dj z$`F!Ks$i<%mYSqsWME*TU}$J%1Vly(x&~$j21QvmX+Ul4C7!;n>{pmr1x4l8+mz-4 zg*Xd5B8wRqxP?HN@zUM8KR`j2bVpxD28NCO+HqZdXMAQjaPeGm)a##I4DP>8^|Q}*osX?x zu(w4E^8SQ>2<4nWJ;;$Ch1?$dLgm)?6;Yr9_CdHMW*W(@x+ip*R06EH_T4pml(Y0_%+Z_b^VZki z+Ig-L)GH{z-FHJSJv;l^O{dMW8|Geryoiy(edpWebG3Q>oX-o7q}^hCpz*y@X6IS? ZpGWQ1{0Pup3+%oyc)I$ztaD0e0swh%>OlYi literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/sprite.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..d117e123ff41a807615546f28a7857e39aa0e2cf GIT binary patch literal 7464 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 a{D})e%Wl^R;ogP-0000FG&0bMoX# z7A74X9iKC2&LsT$^Yil=E-o$xMy*-Q!VC!lY)xXbRPWUDyI-z%bP0l+XkKH>q2T literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tabHoverRight.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tabHoverRight.png new file mode 100644 index 0000000000000000000000000000000000000000..9f02130d8044313e28ef38faae5f10e0819e8355 GIT binary patch literal 432 zcmV;h0Z;ykP)f@56eF=0CGSk0+mBJAWdv+Y(Nf310y5I z1Rx8@fB*hHOMibq0}KEJAbJdL00vcGj4@hkIp^4W a4=4R=Oxw=|N2T-t0000N?d|OX`1$t%0RaH&>guARq5@DT#s&ZY5DcUE|0EA} z>u5oi42l0><|F~+%v{T=iikX3-7RSa5W}`@+dhE7r%#_)fM);t_3Qut|6pBzK)QfR zfgGkkfBrDQ01F2PC(ve~aUjk`Fo4Ja1fYQmasY-wP?jy(!JGeof^V}g&6UuAw-~b-r)S#-WyLGcW5%{i*MW2BPvgz3d6TU1*H~=-QDHOAL8!!VW{@_`x{XB&C!)=NRK2 i0{Y1E&8)SWzw-j{`jbXdjdrR40000%mq!^2X+?^QKos)S9l5Y=V1NPK>@SUgxxb#j0)Hj=K%#H@hrp<0(ziY;Cn$qB$lOko9uweeR$HkHl1f*xW@hE+`)>M8>*Knp@$Fl1{s~J39 L{an^LB{Ts5ttLz; literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tabMenuPin.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tabMenuPin.png new file mode 100644 index 0000000000000000000000000000000000000000..eb4b11efe5ee01103c2d5fa2f0f6b8921e640cce GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^Ahr?*6Oeql{{BWF#aJBV?!>U}oXkrghb_t5-G$*l z2rk&Wd@@jkv%n*=n1O*?7=#%aX3dcR3MP5FIEGl9PX6=%zddu_fg=s#0eWXoobYfk z*AwM9ym6JoM(JSIE|W9~gNGBHJsxveA7kVT`LtA$cXJ=#lFR3Ow<;}=p3c?sFd}rp wjoy_^uD3LPOZa8_Shkpi?Q|4a@x+^%p~OOFcBy}4KhQP?Pgg&ebxsLQ0DvV!;s5{u literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tabMenuRadio.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tabMenuRadio.png new file mode 100644 index 0000000000000000000000000000000000000000..55b982d7c8e69c12497a020b798010f570d5cdaa GIT binary patch literal 192 zcmeAS@N?(olHy`uVBq!ia0vp^96+qZ!2~4VM)CImDaPU;cPEB*=VV?2Ic!PZ?k)`f zL2$v|<&%LToCO|{#S9GG!XV7ZFl&wkP%zlj#W6(VeDa_F|LvL04jgG<4hU>wbuu(E zI@G%0+`(6?{{R0Ud^0rTn!}DBW=RzbRSDkBeS9S@b7yCW4qd@!}UDqW~jjJ h3p(-_6b@=KGECU6@Nto2r904g22WQ%mvv4FO#l_>J;wk5 literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tabMenuTarget.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tabMenuTarget.png new file mode 100644 index 0000000000000000000000000000000000000000..957bd9f2adabb791aee25df923efebc85e86c0da GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^+(695!2~4VPBOj%q*&4&eI0=`L$_*zFOXs@3GxeO z_zz_L?>wMC0Z1Erx;TbNOiliC{=FVdQ&MBb@07%~_*#H0l literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tabMenuTargetHover.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tabMenuTargetHover.png new file mode 100644 index 0000000000000000000000000000000000000000..200a37083d6d9f325c493ffe490dde115521f2bd GIT binary patch literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^+(695!2~4VPBOj%q*&4&eI0=`L$_*zFOXs@3GxeO z_zz_L?>wMC0Z3bVx;TbNOij+o$VfQAJ>!G7@X{t$r>obmC!aDkGgCU#P++h$Fvl^h q<&0Y)y9?7jud)elI-@2xs|;J^W<5T->9Rt_Qo#vM#E*_Sj#Ib8Yw|Nq2_ i0IpS^uCI@G;9^*7tlx2HqG2x3WelFKelF{r5}E+f)mDE1 literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tabRight.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tabRight.png new file mode 100644 index 0000000000000000000000000000000000000000..b43c352d7f2d4e8bf3740a79d54a50b49d4c53a2 GIT binary patch literal 433 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 L`)q75=;;3dF|oR- literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/textEditorCorners.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/textEditorCorners.png new file mode 100644 index 0000000000000000000000000000000000000000..a0f839dc598edd80d093e1cf954134a916db5af0 GIT binary patch literal 3960 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 literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/titlebarMid.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/titlebarMid.png new file mode 100644 index 0000000000000000000000000000000000000000..5fc63e793f09fb9eb0da6306132efa2344aa4d2d GIT binary patch literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^EI=&H!NkD8xLBm~BakCm;u=vBoS#-wo>-L1;Fyx1 zl&avFo0y&&l$w}QS$Hzl2B^r_)5S5Q;#N{dMn*!#_jj_w%*@Oj%q#*%(h3a{7oJQo zbYL)KI+}Q@V-W*WhhT~XGxNz`9m^S*dOrUD|DVU;K+(51krwP(nq99LpD-|Nc9Z%d T{!QKsXfT7PtDnm{r-UW|(LOd6 literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/toolbarMid.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/toolbarMid.png new file mode 100644 index 0000000000000000000000000000000000000000..8520aab2c1dfb5ad62ed829875fa68f3862c7c3b GIT binary patch literal 256 zcmeAS@N?(olHy`uVBq!ia0vp^EI=&I!NkD8c;%XB7my=a;u=vBoS#-wo>-L1;Fyx1 zl&avFo0y&&l$w}QS$Hzl2B>I}r;B4q#jPX{Z|~$CrLV<=)z#G<7!2?1shr%|+S=MV zeY&_pgM`B)1v_PBWnp7uV_|7&X<=(?YoMZgJB!;J8yla#zrSCBOM`h)L}a9+NC5AI zB(^O3>Tfzg6-_<~2@Y2e9ARM7aR_!45f&B};^&yave2f3_spF;cb5ClXX7w97HeH@ zcz~gMPm|4@!$%re0xSYPa}+6vB|dhDX>#RfsOXf>3!Qt)2k2S`Pgg&ebxsLQ0JH^D AR{#J2 literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tree_close.gif b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tree_close.gif new file mode 100644 index 0000000000000000000000000000000000000000..e26728ab36b9d612af0edb49ea297da5d6c4b96a GIT binary patch literal 300 zcmZ?wbhEHbnIzhYznme}4D*^ZPGfK7RlH z`Nxm1KYo1s@#Fj7zrX+f{qvv3K=GfTb5UwyNotBhd1gt5g1e`00E6OB7Dg@xdj=hl z_dp(HU^6-3oZ!L3;dnwN<42~M?d-(mhgZg_IrAp$ZsjqS@NN|<J`-rmugEauac+Ic? literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tree_open.gif b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/tree_open.gif new file mode 100644 index 0000000000000000000000000000000000000000..edf662f36f32f39352a4033cde8c43baef3611e5 GIT binary patch literal 202 zcmV;*05$(dNk%w1VF>^U0E8X@0001qrohU=v&+M@%fq$I#J11Ky1dKU*U`n<)XCY@ z%H7z{-rCXO-PGdV*W}^Z=;hz&=HKb&;O_0{@bK&N^X~KW@AUNX_xJPo`1Sbs_W1bs z{r&s>{rvy`|NsC0A^s6Va%Ew3Wn>_CX>@2HM@dak03rDV0SW*g04x9i000R92><{E zGT;%6WFUHI>Wy6sbX+!Wn+9l=G-5#CKckC<0+>J=qlkk6SSS#qgn=*^2nwbW=@0?{ EJ89T&G5`Po literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/twistyClosed.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/twistyClosed.png new file mode 100644 index 0000000000000000000000000000000000000000..f80319b0a4e21532f5139acd618ce6782117b2d2 GIT binary patch literal 334 zcmV-U0kQsxP)1EtgQQRS5LtMzbrwA?yc}HH6?GB;baT0Ow3G2}Uok zHZ&NcAq(C>m59+ZoP+%k$L{2MaLq1=`W8Dud*c$1alVL@3 g)*%1<;7x!50Gzmo@IIg>jQ{`u07*qoM6N<$f_#RHXaE2J literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/twistyOpen.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/twistyOpen.png new file mode 100644 index 0000000000000000000000000000000000000000..868012434599b589e3d75190202fe6b4a16270cd GIT binary patch literal 309 zcmV-50m}Y~P)j*YPNxz}~_W*jQMJ*jNY_HW3qJ$j|;{+%Yjh7DXTI z56m}@x3hwX@T)q!Emk{P?@u40(V&mXcqqWm)7g@~sjgSfEMqi;Xx*xG1SO027%Zja z3u|B{GbFdrh09XI_j^v><6-N<#u!A=#hwaOl5I99vJ`oGci}h;klUiRafr(2!})Hs za^Y)mMiPh6(!xz{g6A>fw=mCfzTr7{>*dawCI0!rhX4Zrv(|{FCa*++00000NkvXX Hu0mjfk~@O2 literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/up.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/up.png new file mode 100644 index 0000000000000000000000000000000000000000..2174d03a9c91a29a40ce8e9cfd715e9b9320f178 GIT binary patch literal 619 zcmV-x0+juUP)vmZ_X00GBIL_t(I zjir-4h!a5+$A3Hfp&N7OLOAf6gQOHW4z;rpP76^GI}1A@mL|kbk8Dso#aMc^{UIn8 zDjZ1ALaoH=xD=v=aAe(F-0vBSP4t!v8uV2&%=`c5z5mS9lv4ap7?Z`v3zuBrI^g_8 z;{gwkJ>75tG^G^p&R=W`+jc8w&N6@e1j4qbDrFGhe|XQ%%NNKXa8Eva(lG!cB^#CH z6|99t!p~p-c)hi-NNIV6owvOPkOM*`ozhYb8O1a8U0SN~<;`mc#vX)9AvA$X(wP84 z6NF>)bAXhnG$|ydSw^*f1%UqgV+>s{oQG2G0VoNhA4PGq&gQMV0Gz&alm3JC0wh#9 zKuk8uAENvr$-tx9tkY|)VaEw}oX~5nQEk>q2Hvl{3E+1HzE3JMYWF$-oVtH|U+=Yc zi|re2453d042jc(&C6H$9!Ho$V2ZrtL}nyXa@ab+k@6gdVeSV+-T)JgN-CL0fCOZ= z*L%!VV(yNJP(^?OZ#($r96eOVvZg=X*j^yw(`Xl!f9V`h)vmZ_X00DzZL_t(I zjir-KOB+!XhM(h1jFXHIQ$%-J1iF$LXcdG~;$P^Z3pcLaRr&`q`2&*fT)XL_i~fa_ zQYiJK%;2ghsGzuMn}svAHkZ>yZX~0T2K&P0ex3I@=W;oss{D`K!D3q^0$u@?e|WmU zn>E!4Kvb12k)~5BNAoXUQhnaQDV0Y$O_uWG;|DI@zr$o{w659`Rb^A;=lt?Y<GJe9t4ZPjvxOfU{G~SoXeBI}a+r9Otte;PK85 z0N<9DaBcyz+W_bKcitQ)d*;HjO5Rf`kO!vOa_fB}*);1Y1`8NeTV=L55&DoAZW377+_cXIbt0H!Q3 z_X`w@-LFos(r^skJ?3G3F%B5Fdjs&Mr`sLTs5qIi=w9K;=mz_x!ftPh&UFb-r46vmZ_X00C-AL_t(I zjir;ZOF~f;#((GaRIvBdAc=w+8=8cmDH4u%Lb(A(07#^Mkopg(g^U z)IR}}kT13HoER*}AZiUazP>~C1xk&M2h3jp*b&JBdyMv(@&~H9KEPk~0rA~|dRYjc QCIA2c07*qoM6N<$f>7|)4gdfE literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/warningIcon.gif b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/warningIcon.gif new file mode 100644 index 0000000000000000000000000000000000000000..84972788620159cbf2bfc443acbdea47350e69de GIT binary patch literal 357 zcmZ?wbhEHbE&KGfouIlu9-6#HcaB$ zG?i=146bdnIajS>*t>-D$U2T4+ZlK7W;nHt{p>EbO9$C5A7VRmhT+CZ)|;nUZ(U}7 zaE0aZ4VEXjnD5?Ycy^ch`90=WkCD>#a_b-_~zF~Uzj^Wc=rqAz~zJ6r< z@s;uCcg9~o82|rg_)j8G{3qyKl$uzQnxasiS(2gP?&%xAp!k!8k&D5eK?meLkVhTZ zau3W8h|mygJ8~u4lObW+>2n{Mco{e@gr`I#q?iebooI6SC$mJn?L%ahn2UG`Lq&?~ z@grF)Ic%m^c(92os;bHgx;wM0dxu2?y0fZ~Y@8+83$Y2csYTc*2 literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/warningIcon.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/light/warningIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..de51084e8489f498b89dd9a59d82eb9564b7d050 GIT binary patch literal 516 zcmV+f0{i`mP)X+Z1;#G+8)`#`)nwDij+1|+};(+Jd*z{tojUrGNrgOti&26irp z_}33i3=gldFg&}%ydKD%4m4mlSOTPRRTp>8w%MHj-#%jkasQt=!|=bOgW><(yI^TB zesYWX|At9i|AA_qz?K0SLTh@t|9^bL1XtwZ!T_=ktQjT-!jEsTfHbZKahQM#GSy9g zGw=!jV;}@%)c=6I5d!peNPt)%qXt$R0@A3+&Ho=o(%2Y6D=A@WxvV2T-}@x_m?j12e;Kn75?FIa%Y*5~(_)p>;wfs>Yo>SSa9R12cEf^3|A z?HDV=w@(OLSFdJZ*t3U$;p|ydO|Ks_Gd#G$auApZ7BB&cJHLN2R-V|*!SL$`L^DVe z48y>e_e>0@wy}el)6tV$3kUcAYBiJJ3`|`A816m!$KYVc!0_$`6T_P)%nWzVvoQSm z#aIlqs1HRWRI?%|K>)EC$csSy9f(f>@eyb`{RmSF5MTfvB)oWs%O|`50000we@P7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-pp~bKV+hCf(36II4Gug<9Mb>)4|i}V@624c zaHEOQ-P127%)EC~hDl(;irH2!_0HWPp3B55=Xc+Eevp069PP;+tLL2nn!@1e>gTe~ HDWM4fu+KD3 literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/buttonBgHover.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/buttonBgHover.png new file mode 100644 index 0000000000000000000000000000000000000000..cd37a0d52de85c54f3e502c9a4fb6c93c4ebcc46 GIT binary patch literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^j6f{R!3HD)xzi;<0>we@P7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-pq;0SV+hA}+fy5P8w^B_1ROu*f8^ifi%MaN z?t+e)KMUj2=R7_T$DElU6!ZEZgVO|-$@brW6qqs2=3ULdX4am+55(@39-C|hG>O5} L)z4*}Q$iB}Zf-R* literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/debugger.css b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/debugger.css new file mode 100644 index 00000000000..ba55c7ea8c8 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/debugger.css @@ -0,0 +1,331 @@ +/* See license.txt for terms of usage */ + +.panelNode-script { + overflow: hidden; + font-family: monospace; +} + +/************************************************************************************************/ + +.scriptTooltip { + position: fixed; + z-index: 2147483647; + padding: 2px 3px; + border: 1px solid #CBE087; + background: LightYellow; + font-family: monospace; + color: #000000; +} + +/************************************************************************************************/ + +.sourceBox { + /* TODO: xxxpedro problem with sourceBox and scrolling elements */ + /*overflow: scroll; /* see issue 1479 */ + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; +} + +.sourceRow { + white-space: nowrap; + -moz-user-select: text; +} + +.sourceRow.hovered { + background-color: #EEEEEE; +} + +/************************************************************************************************/ + +.sourceLine { + -moz-user-select: none; + margin-right: 10px; + border-right: 1px solid #CCCCCC; + padding: 0px 4px 0 20px; + background: #EEEEEE no-repeat 2px 0px; + color: #888888; + white-space: pre; + font-family: monospace; /* see issue 2953 */ +} + +.noteInToolTip { /* below sourceLine, so it overrides it */ + background-color: #FFD472; +} + +.useA11y .sourceBox .sourceViewport:focus .sourceLine { + background-color: #FFFFC0; + color: navy; + border-right: 1px solid black; +} + +.useA11y .sourceBox .sourceViewport:focus { + outline: none; +} + +.a11y1emSize { + width: 1em; + height: 1em; + position: absolute; +} + +.useA11y .panelStatusLabel:focus { + outline-offset: -2px !important; + } + +.sourceBox > .sourceRow > .sourceLine { + cursor: pointer; +} + +.sourceLine:hover { + text-decoration: none; +} + +.sourceRowText { + white-space: pre; +} + +.sourceRow[exe_line="true"] { + outline: 1px solid #D9D9B6; + margin-right: 1px; + background-color: lightgoldenrodyellow; +} + +.sourceRow[executable="true"] > .sourceLine { + content: "-"; + color: #4AA02C; /* Spring Green */ + font-weight: bold; +} + +.sourceRow[exe_line="true"] > .sourceLine { + background-image: url(chrome://firebug/skin/exe.png); + color: #000000; +} + +.sourceRow[breakpoint="true"] > .sourceLine { + background-image: url(chrome://firebug/skin/breakpoint.png); +} + +.sourceRow[breakpoint="true"][condition="true"] > .sourceLine { + background-image: url(chrome://firebug/skin/breakpointCondition.png); +} + +.sourceRow[breakpoint="true"][disabledBreakpoint="true"] > .sourceLine { + background-image: url(chrome://firebug/skin/breakpointDisabled.png); +} + +.sourceRow[breakpoint="true"][exe_line="true"] > .sourceLine { + background-image: url(chrome://firebug/skin/breakpointExe.png); +} + +.sourceRow[breakpoint="true"][exe_line="true"][disabledBreakpoint="true"] > .sourceLine { + background-image: url(chrome://firebug/skin/breakpointDisabledExe.png); +} + +.sourceLine.editing { + background-image: url(chrome://firebug/skin/breakpoint.png); +} + +/************************************************************************************************/ + +.conditionEditor { + z-index: 2147483647; + position: absolute; + margin-top: 0; + left: 2px; + width: 90%; +} + +.conditionEditorInner { + position: relative; + top: -26px; + height: 0; +} + +.conditionCaption { + margin-bottom: 2px; + font-family: Lucida Grande, sans-serif; + font-weight: bold; + font-size: 11px; + color: #226679; +} + +.conditionInput { + width: 100%; + border: 1px solid #0096C0; + font-family: monospace; + font-size: inherit; +} + +.conditionEditorInner1 { + padding-left: 37px; + background: url(condBorders.png) repeat-y; +} + +.conditionEditorInner2 { + padding-right: 25px; + background: url(condBorders.png) repeat-y 100% 0; +} + +.conditionEditorTop1 { + background: url(condCorners.png) no-repeat 100% 0; + margin-left: 37px; + height: 35px; +} + +.conditionEditorTop2 { + position: relative; + left: -37px; + width: 37px; + height: 35px; + background: url(condCorners.png) no-repeat; +} + +.conditionEditorBottom1 { + background: url(condCorners.png) no-repeat 100% 100%; + margin-left: 37px; + height: 33px; +} + +.conditionEditorBottom2 { + position: relative; left: -37px; + width: 37px; + height: 33px; + background: url(condCorners.png) no-repeat 0 100%; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +.upsideDown { + margin-top: 2px; +} + +.upsideDown .conditionEditorInner { + top: -8px; +} + +.upsideDown .conditionEditorInner1 { + padding-left: 33px; + background: url(condBordersUps.png) repeat-y; +} + +.upsideDown .conditionEditorInner2 { + padding-right: 25px; + background: url(condBordersUps.png) repeat-y 100% 0; +} + +.upsideDown .conditionEditorTop1 { + background: url(condCornersUps.png) no-repeat 100% 0; + margin-left: 33px; + height: 25px; +} + +.upsideDown .conditionEditorTop2 { + position: relative; + left: -33px; + width: 33px; + height: 25px; + background: url(condCornersUps.png) no-repeat; +} + +.upsideDown .conditionEditorBottom1 { + background: url(condCornersUps.png) no-repeat 100% 100%; + margin-left: 33px; + height: 43px; +} + +.upsideDown .conditionEditorBottom2 { + position: relative; + left: -33px; + width: 33px; + height: 43px; + background: url(condCornersUps.png) no-repeat 0 100%; +} + +/************************************************************************************************/ + +.breakpointsGroupListBox { + overflow: hidden; +} + +.breakpointBlockHead { + position: relative; + padding-top: 4px; +} + +.breakpointBlockHead > .checkbox { + margin-right: 4px; +} + +.breakpointBlockHead > .objectLink-sourceLink { + top: 4px; + right: 20px; + background-color: #FFFFFF; /* issue 3308 */ +} + +.breakpointBlockHead > .closeButton { + position: absolute; + top: 2px; + right: 2px; +} + +.breakpointCheckbox { + margin-top: 0; + vertical-align: top; +} + +.breakpointName { + margin-left: 4px; + font-weight: bold; +} + +.breakpointRow[aria-checked="false"] > .breakpointBlockHead > *, +.breakpointRow[aria-checked="false"] > .breakpointCode { + opacity: 0.5; +} + +.breakpointRow[aria-checked="false"] .breakpointCheckbox, +.breakpointRow[aria-checked="false"] .objectLink-sourceLink, +.breakpointRow[aria-checked="false"] .closeButton, +.breakpointRow[aria-checked="false"] .breakpointMutationType { + opacity: 1.0 !important; +} + +.breakpointCode { + overflow: hidden; + white-space: nowrap; + padding-left: 24px; + padding-bottom: 2px; + border-bottom: 1px solid #D7D7D7; + font-family: monospace; + color: DarkGreen; +} + +.breakpointCondition { + white-space: nowrap; + padding-left: 24px; + padding-bottom: 2px; + border-bottom: 1px solid #D7D7D7; + font-family: monospace; + color: Gray; +} + +.breakpointBlock-breakpoints > .groupHeader { + display: none; +} + +.breakpointBlock-monitors > .breakpointCode { + padding: 0; +} + +.breakpointBlock-errorBreakpoints .breakpointCheckbox, +.breakpointBlock-monitors .breakpointCheckbox { + display: none; +} + +.breakpointHeader { + margin: 0 !important; + border-top: none !important; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/detach.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/detach.png new file mode 100644 index 0000000000000000000000000000000000000000..0ddb9a1764a7244e13fb3ae0ed1ae7a286e9e138 GIT binary patch literal 655 zcmV;A0&x9_P)vmZ_X00HYsL_t(I zjiuASixWW@g>ab5{?6{qvzRs9VNlU&_RX;G^Jd=ee{7lWMJ%eR z3{AF20Ep)y!mj|M5oBktri!{UFOVt#7H?iRbJqo>rvWZx)o?vXGay^Lw{)KBp1m~6 z`yibH#KZ5%*nGxgcWzCZ*UX-Er8%I%2}0r^*bN8_KZM_Ehl)0XcAG?Nik4;0p2ZEv zp<>5C%zNKM%r9+#a^70sjNEQv#^&Ju9OMMhlU>*rIK>E&n2*DR%_ydvx7H!M3jnuU pr&fUue|MSIFK;|s+XejV_yNX*_HvmZ_X00E{+L_t(I zjir;nOIuMC$3G|U#kBgKiL^m1)>#S;QgEwd9Wr!^UE86Xp#Oo-|3IOegHA##f`vL% zHz^%l{n0?s!A_+^L*7foyk|~_+#8-6sOW{uIh=dG-}C)m?iE$#A-oX+cONLulyE)2Co+jb{(Rfv*ZL|+6b2>LB~evAiToXV{iZNH zHGL=9zYq2~-~Cd1t2*QYgiy$PK1ubsGpXI?#pku2;FH<+$gzq>+rq?PUsUDL6FQc$Ktz0?m=3D&(09>5@hnaP5s*8v+9YvBLK{>@_+VFn)YR16+}zUA(%RbE(b3V_+1b_A)!p6Q z+uPgM*EeCpgozU;PMS1n^5n@=rc9YSb?S^6GiJ`5IeYf(`Sa&5Sg>HxqD4!VELpZ} z+4AMfSFBjEe*OAQn>PKYF;M&`=v}?EMTFVmhmRH-h=@!%H(`U1mWjL~(r(9$jZjy>BwLW0Bd-< AumAu6 literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/disable.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/disable.png new file mode 100644 index 0000000000000000000000000000000000000000..c28bcdf24a88d4d1266486af283b3557011e916f GIT binary patch literal 543 zcmV+)0^t3LP)x3Se~ z6`Rdw>Ucah*6THwB#AIg5(ME2(GQ@(Ktm}Oiyw-jOuF4}$mMdq0C<3425O0ZzyB?w zG!F)YEE0)iG)?PM7Ep{MxC7835;9bI9SjCUm5V5UB+D}KZ98BrZv^)Fd<+#H0nARP zQ)U>(v8{m|K_IKw>w7Q>#(lF;D3rirvolE&A?Rx~8nO9&p2b7wKRBPy-|iA#kVa_f zNy%i=1n?4ep5s9#8zHu-s;UjH)oO9r-65TzcW3vZTrNK$vxY`l(P*>{?$@ZuCX

zSS&c+6eN1i<#IPJ%7UN@%1Hq6;c$2c$9~94N=7cBH!TRR>^toYUDxfe0SXBMg4!q6 hR;g6le~mu@1^}m-%vu#A_1FLa002ovPDHLkV1iC4;#>d# literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/disableHover.gif b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/disableHover.gif new file mode 100644 index 0000000000000000000000000000000000000000..70565a83cce61a6ce84ced32713fe11dfe32ad32 GIT binary patch literal 344 zcmb8qy-Gr100!XKJeKL_&p{0{mG9UuD279lD4bHr&LBv10SQS(TL?8ow74`xPC-j8 z&2q0GiEI6k05_T4}da2s#{eI_YvzRq652>!r`fK!Cv@Lm_G!BN0ZU zjK!EpFqvd3#dMmP40WA_0_W%Xe_BV)t(8la@}gW{sVvL9Q7A%dD<&Is#PI7citdH8 z!{(A&o4Y7AUW+m;uj}%BNE_SVs~Pd|!PQB3-vKr2s6vs%_Gnj+LH>~wJ-A1;nr&k!$NdEx3Rg!1` literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/disableHover.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/disableHover.png new file mode 100644 index 0000000000000000000000000000000000000000..26fe37542f865a5fc668ceaaa597261351416abf GIT binary patch literal 512 zcmV+b0{{JqP)B9UvD<_Rt@Fa9A3cn2&8 zsB&(OLveLQ9g(&fjgs5jRpxS*W_>#78#q)z2})fFv@41YM6bY}(`dWTB8p3#fBpflR0K9xPy7!y|#6zbl^UQ?6C> ziLs8A6~MOL#(GM{<*3a92_qDO&+k9_0E*B0XQ#8__5i~GMk5TTVbcWs{xXKcgCD>d zPss3n0XJwgfR~q|ccusdH{^Eisu~qG{#@uF){aM55v@S-*L}h!u=!w0000vmZ_X00G%aL_t(I zjir-6Xj4%XhritS^4b@Z=1IwrrO=KdrKp>WpbkMn+#K8l16@p^xL9l&?2^Se*4bSI zZ3h(s5_C`}$I=d>gHQ~KukZgo4ljuYOAUIadoTC*oqNykoQ#O@KVc3RpRQi719t%D zFPbj!==Afab%2bB@czoRb!FT2*-Mw1Idc|e+ea$3=h6H4frD2s(Vka7_u|=x2@r^` z%`PrsmCE>^zaE?3DwWACE^+X#Qv*_fFWSk?Eue#NqJQV+7Wne^jRS)k_#&u`LZWyg zfXXQRLGe?7)<_%?CkgYnZyqb&fBXc~Fz~hh4ImoaL&7kiy|&4P2lv>yd!MY4niM55 zm1cwX+9qY^B&Ic$Y5+9^NUu-U^{~T;?d4S}%?5=;Q%E$GW`phJRqQY#>v~A9KLY%E zL9d4il(b+egHCmY^IH!A=u}rIXDy0aFkP3CW*pET9Tc^OAf$cc768SmX^NsS_CY+V%VO=|af7lf^PJM_L#r!hSbm*AK`Wss)2t0NAQrTnB1QHcYMR&g+daz`w>% X_aN9B#@k{#00000NkvXXu0mjfMjaKM literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/downActive.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/downActive.png new file mode 100644 index 0000000000000000000000000000000000000000..f4312b2ffbc485366e5b3eb2d52fac976597b256 GIT binary patch literal 543 zcmV+)0^t3LP)vmZ_X00DbRL_t(I zjir;lN&`UU}0fnZKwDGo-ZJ=v$nCY@Ck$jQ3OS~ z!%8ev5NyplSR@yfwM_ljM z8jB*`Hb4wcNo$%HXKe{eS`(X6ZGZ^i>XM`_{4FB0rx}o(pOF9q2M0fbrz0a+hWRA0 zo}YLDc0HG|AY|Kf-&@oKDnZDu=h6%0TLc}cAO~om1k^p3N)Y1kR%j&%se3LZb0?RT zL9S(KAoN_kAOv&nH}W*AOaU#Ddjn#?atr)T5CMsK8B=2(NWW9(7x;lMU7%2C99vCi z!un`rT1r;zB^D%h<6WT3xz>HE$zyj?J hQ*}dR`IF$U@d_-*f~iPPaE<@~002ovPDHLkV1gf_)cF7a literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/downHover.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/downHover.png new file mode 100644 index 0000000000000000000000000000000000000000..8144e63787d3015e5ab2219bf24fab87b9fe1141 GIT binary patch literal 526 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf4nJ za0`Jja>QWe}Xi&D$;i?WOTH_Q7mFfe9$x;Tbd^e&xj@9h*QajbrQoamc4Q>{6x z_ytW`lXX-V5t7R4YFksyd&xV$`T4iwda7R! zJhXjYP{)71@w;f~Q~OPae7%pbmNneb_u;>xynx1mHSr=7#+7eGwA%h*Z*MZ+XTsH-c1$v(;2R~YOE~MaXMrp z#grQQO6f^sMM#s10JG77PL9;jC?y7w5KF;Cwi!kjwzI7CKh1VaNyKOJR@VrYO*JNd zDNH`T4E=0J8X}A3Pf43g%&J)E`RTHyE!+3wyh#^!drZ_;wU=v+?+hwt*eG80o^5kL zHecaeo;4{7vfXU+;}`yAIs31J(U_azwvuSV^pkBXx2=!*oAe=kFC#Z!&8|0*agxB8 OVeoYIb6Mw<&;$T_rpeI& literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/errorIcon-sm.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/errorIcon-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..0c377e307e54c7d1ac78b316b6b949085aa368a6 GIT binary patch literal 447 zcmV;w0YLtVP)z^Q>-8KIssI20AY({UO#lFGm;eBCjsO7aNB{ta0001Y z?*IVM@BjcZ_W%GKbhgrL3jhECHAzH4RCwBKl08eqP!xurR1gFQcfld}1BAN@f~4SF z@*4vFk1iRU6beo*g41nrsg!_|n{jZexJXq{gcLysKj`al6LV8~;J`hX^Kjnt5lF(f zeh};dF|Y-E06B2nfxG`CNl3!Nj)k);&;w`+dIQ~qMj#6Z4ama!0Q3mb0{;c&4m|Xs z?ii#fk|ZffYA8u0NwX-@r31IIu+#^AffR;PQPf}ws3@c`)WkujSlGDmC5>cn7<1bWUJj$ZS+iPe7jBcSDR!8x$w6_L3u)yphaIGl zNwmvu6p_Y-3q=&oV#+9g^BMelzQE&f+IxEaa^$28Y{53{z%Ha=5BA{z4j~Iia0=&e z30H6pH*g2{@BokS1kdmSd3c2ayumvZ;R8OQ1YhtCLOG2_Fd7A`RR{)!cwES2gnVB3 zAN7yI5()UDfpJxQA{tUToNf>5QiVv0nQqGdMh7IZ?3$-qFHTs`LebF;-)7Dmi7pLa z1ac;?Oq5u(71vFY<5qEca;3d;EHtvv=W?ASZ#z>3?OfaJkVw{`RMtx!7IAYp>@(A( p)p5Ui~H0X8YDC6$Gxpb|xtYf@N==`2Jc z7Ah8ji(kR7VtwakC$}D$g(o{ZGjC>QZ;f+~bR8H|#%4hcOnLVm*j;w6MZq#Egs5(a zc4lEugK?iQ0QcYtDcH902T2xS;XcvY8O)TA|L_Qo0dkkJVlXBT;dmV(QXWLO$HEed zt}ftbg3DK{l45N>4BPBOtRiE?7^^l0JFaL_w@cLT6E&N;kZtyH3~NT_jk(q5@35sP zaxP8XaIwukAMZ)K?GhDNr$f|e@AO4;e+3u-uo^Lr*!;%I00000NkvXXu0mjfj3mDh literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/firebug-1.3a2.css b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/firebug-1.3a2.css new file mode 100644 index 00000000000..42f9faf5d58 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/firebug-1.3a2.css @@ -0,0 +1,817 @@ +.fbBtnPressed { + background: #ECEBE3; + padding: 3px 6px 2px 7px !important; + margin: 1px 0 0 1px; + _margin: 1px -1px 0 1px; + border: 1px solid #ACA899 !important; + border-color: #ACA899 #ECEBE3 #ECEBE3 #ACA899 !important; +} + +.fbToolbarButtons { + display: none; +} + +#fbStatusBarBox { + display: none; +} + +/************************************************************************************************ + Error Popup +*************************************************************************************************/ +#fbErrorPopup { + position: absolute; + right: 0; + bottom: 0; + height: 19px; + width: 75px; + background: url(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; +} + +/************************************************************************************************ + General +*************************************************************************************************/ +html, body { + margin: 0; + padding: 0; + overflow: hidden; +} + +body { + font-family: Lucida Grande, Tahoma, sans-serif; + font-size: 11px; + background: #fff; +} + +.clear { + clear: both; +} + +/************************************************************************************************ + Mini Chrome +*************************************************************************************************/ +#fbMiniChrome { + display: none; + right: 0; + height: 27px; + background: url(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(search.png) 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(errorIcon.png) 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(sprite.png) 0 -135px; + cursor: pointer; +} + + +/************************************************************************************************ + Master Layout +*************************************************************************************************/ +#fbChrome { + position: fixed; + overflow: hidden; + height: 100%; + width: 100%; + border-collapse: collapse; + background: #fff; +} + +#fbTop { + height: 49px; +} + +#fbToolbar { + position: absolute; + z-index: 5; + width: 100%; + top: 0; + background: url(sprite.png) #f1f2ee 0 0; + height: 27px; + font-size: 11px; + overflow: hidden; +} + +#fbPanelBarBox { + top: 27px; + position: absolute; + z-index: 8; + width: 100%; + background: url(sprite.png) #dbd9c9 0 -27px; + height: 22px; +} + +#fbContent { + height: 100%; + vertical-align: top; +} + +#fbBottom { + height: 18px; + background: #fff; +} + +/************************************************************************************************ + Sub-Layout +*************************************************************************************************/ + +/* fbToolbar +*************************************************************************************************/ +#fbToolbarIcon { + float: left; + padding: 4px 5px 0; +} + +#fbToolbarIcon a { + display: block; + height: 20px; + width: 20px; + background: url(sprite.png) 0 -135px; + text-decoration: none; + cursor: default; +} + +#fbToolbarButtons { + float: left; + padding: 4px 2px 0 5px; +} + +#fbToolbarButtons a { + text-decoration: none; + display: block; + float: left; + color: #000; + padding: 4px 8px 4px; + cursor: default; +} + +#fbToolbarButtons a:hover { + color: #333; + padding: 3px 7px 3px; + border: 1px solid #fff; + border-bottom: 1px solid #bbb; + border-right: 1px solid #bbb; +} + +#fbStatusBarBox { + position: relative; + top: 5px; + line-height: 19px; + cursor: default; +} + +.fbToolbarSeparator{ + overflow: hidden; + border: 1px solid; + border-color: transparent #fff transparent #777; + _border-color: #eee #fff #eee #777; + height: 7px; + margin: 10px 6px 0 0; + float: left; +} + +.fbStatusBar span { + color: #808080; + padding: 0 4px 0 0; +} + +.fbStatusBar span a { + text-decoration: none; + color: black; +} + +.fbStatusBar span a:hover { + color: blue; + cursor: pointer; +} + + +#fbWindowButtons { + position: absolute; + white-space: nowrap; + right: 0; + top: 0; + height: 17px; + _width: 50px; + padding: 5px 0 5px 5px; + z-index: 6; + background: url(sprite.png) #f1f2ee 0 0; +} + +/* fbPanelBarBox +*************************************************************************************************/ + +#fbPanelBar1 { + width: 255px; /* fixed width to avoid tabs breaking line */ + z-index: 8; + left: 0; + white-space: nowrap; + background: url(sprite.png) #dbd9c9 0 -27px; + position: absolute; + left: 4px; +} + +#fbPanelBar2Box { + background: url(sprite.png) #dbd9c9 0 -27px; + position: absolute; + height: 22px; + width: 300px; /* fixed width to avoid tabs breaking line */ + z-index: 9; + right: 0; +} + +#fbPanelBar2 { + position: absolute; + width: 290px; /* fixed width to avoid tabs breaking line */ + height: 22px; + padding-left: 10px; +} + +/* body +*************************************************************************************************/ +.fbPanel { + display: none; +} + +#fbPanelBox1, #fbPanelBox2 { + max-height: inherit; + height: 100%; + font-size: 11px; +} + +#fbPanelBox2 { + background: #fff; +} + +#fbPanelBox2 { + width: 300px; + background: #fff; +} + +#fbPanel2 { + padding-left: 6px; + background: #fff; +} + +.hide { + overflow: hidden !important; + position: fixed !important; + display: none !important; + visibility: hidden !important; +} + +/* fbBottom +*************************************************************************************************/ + +#fbCommand { + height: 18px; +} + +#fbCommandBox { + 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: 7px; + 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; +} + +div.fbFitHeight { + overflow: auto; + _position: absolute; +} + + +/************************************************************************************************ + Layout Controls +*************************************************************************************************/ + +/* fbToolbar buttons +*************************************************************************************************/ +#fbWindowButtons a { + font-size: 1px; + width: 16px; + height: 16px; + display: block; + float: right; + margin-right: 4px; + text-decoration: none; + cursor: default; +} + +#fbWindow_btClose { + background: url(sprite.png) 0 -119px; +} + +#fbWindow_btClose:hover { + background: url(sprite.png) -16px -119px; +} + +#fbWindow_btDetach { + background: url(sprite.png) -32px -119px; +} + +#fbWindow_btDetach:hover { + background: url(sprite.png) -48px -119px; +} + +/* fbPanelBarBox tabs +*************************************************************************************************/ +.fbTab { + text-decoration: none; + display: none; + float: left; + width: auto; + float: left; + cursor: default; + font-family: Lucida Grande, Tahoma, sans-serif; + font-size: 11px; + font-weight: bold; + height: 22px; + color: #565656; +} + +.fbPanelBar span { + display: block; + float: left; +} + +.fbPanelBar .fbTabL,.fbPanelBar .fbTabR { + height: 22px; + width: 8px; +} + +.fbPanelBar .fbTabText { + padding: 4px 1px 0; +} + +a.fbTab:hover { + background: url(sprite.png) 0 -73px; +} + +a.fbTab:hover .fbTabL { + background: url(sprite.png) -16px -96px; +} + +a.fbTab:hover .fbTabR { + background: url(sprite.png) -24px -96px; +} + +.fbSelectedTab { + background: url(sprite.png) #f1f2ee 0 -50px !important; + color: #000; +} + +.fbSelectedTab .fbTabL { + background: url(sprite.png) 0 -96px !important; +} + +.fbSelectedTab .fbTabR { + background: url(sprite.png) -8px -96px !important; +} + +/* splitters +*************************************************************************************************/ +#fbHSplitter { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 5px; + overflow: hidden; + cursor: n-resize !important; + background: url(pixel_transparent.gif); + z-index: 9; +} + +#fbHSplitter.fbOnMovingHSplitter { + height: 100%; + z-index: 100; +} + +.fbVSplitter { + background: #ece9d8; + color: #000; + border: 1px solid #716f64; + border-width: 0 1px; + border-left-color: #aca899; + width: 4px; + cursor: e-resize; + overflow: hidden; + right: 294px; + text-decoration: none; + z-index: 9; + position: absolute; + height: 100%; + top: 27px; + _width: 6px; +} + +/************************************************************************************************/ +div.lineNo { + font: 11px Monaco, monospace; + float: left; + display: inline; + position: relative; + margin: 0; + padding: 0 5px 0 20px; + background: #eee; + color: #888; + border-right: 1px solid #ccc; + text-align: right; +} + +pre.nodeCode { + font: 11px Monaco, monospace; + margin: 0; + padding-left: 10px; + overflow: hidden; + /* + _width: 100%; + /**/ +} + +/************************************************************************************************/ +.nodeControl { + margin-top: 3px; + margin-left: -14px; + float: left; + width: 9px; + height: 9px; + overflow: hidden; + cursor: default; + background: url(tree_open.gif); + _float: none; + _display: inline; + _position: absolute; +} + +div.nodeMaximized { + background: url(tree_close.gif); +} + +div.objectBox-element { + padding: 1px 3px; +} +.objectBox-selector{ + cursor: default; +} + +.selectedElement{ + background: highlight; + /* background: url(roundCorner.svg); Opera */ + color: #fff !important; +} +.selectedElement span{ + color: #fff !important; +} + +/* Webkit CSS Hack - bug in "highlight" named color */ +@media screen and (-webkit-min-device-pixel-ratio:0) { + .selectedElement{ + background: #316AC5; + color: #fff !important; + } +} + +/************************************************************************************************/ +/************************************************************************************************/ +.logRow * { + font-size: 11px; +} + +.logRow { + position: relative; + border-bottom: 1px solid #D7D7D7; + padding: 2px 4px 1px 6px; + background-color: #FFFFFF; +} + +.logRow-command { + font-family: Monaco, monospace; + color: blue; +} + +.objectBox-string, +.objectBox-text, +.objectBox-number, +.objectBox-function, +.objectLink-element, +.objectLink-textNode, +.objectLink-function, +.objectBox-stackTrace, +.objectLink-profile { + font-family: Monaco, monospace; +} + +.objectBox-null { + padding: 0 2px; + border: 1px solid #666666; + background-color: #888888; + color: #FFFFFF; +} + +.objectBox-string { + color: red; + white-space: pre; +} + +.objectBox-number { + color: #000088; +} + +.objectBox-function { + color: DarkGreen; +} + +.objectBox-object { + color: DarkGreen; + font-weight: bold; + font-family: Lucida Grande, sans-serif; +} + +.objectBox-array { + color: #000; +} + +/************************************************************************************************/ +.logRow-info,.logRow-error,.logRow-warning { + background: #fff no-repeat 2px 2px; + padding-left: 20px; + padding-bottom: 3px; +} + +.logRow-info { + background-image: url(infoIcon.png); +} + +.logRow-warning { + background-color: cyan; + background-image: url(warningIcon.png); +} + +.logRow-error { + background-color: LightYellow; + background-image: url(errorIcon.png); + color: #f00; +} + +.errorMessage { + vertical-align: top; + color: #f00; +} + +.objectBox-sourceLink { + position: absolute; + right: 4px; + top: 2px; + padding-left: 8px; + font-family: Lucida Grande, sans-serif; + font-weight: bold; + color: #0000FF; +} + +/************************************************************************************************/ +.logRow-group { + background: #EEEEEE; + border-bottom: none; +} + +.logGroup { + background: #EEEEEE; +} + +.logGroupBox { + margin-left: 24px; + border-top: 1px solid #D7D7D7; + border-left: 1px solid #D7D7D7; +} + +/************************************************************************************************/ +.selectorTag,.selectorId,.selectorClass { + font-family: Monaco, monospace; + font-weight: normal; +} + +.selectorTag { + color: #0000FF; +} + +.selectorId { + color: DarkBlue; +} + +.selectorClass { + color: red; +} + +/************************************************************************************************/ +.objectBox-element { + font-family: Monaco, monospace; + color: #000088; +} + +.nodeChildren { + padding-left: 26px; +} + +.nodeTag { + color: blue; + cursor: pointer; +} + +.nodeValue { + color: #FF0000; + font-weight: normal; +} + +.nodeText,.nodeComment { + margin: 0 2px; + vertical-align: top; +} + +.nodeText { + color: #333333; + font-family: Monaco, monospace; +} + +.nodeComment { + color: DarkGreen; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +.nodeHidden, .nodeHidden * { + color: #888888; +} + +.nodeHidden .nodeTag { + color: #5F82D9; +} + +.nodeHidden .nodeValue { + color: #D86060; +} + +.selectedElement .nodeHidden, .selectedElement .nodeHidden * { + color: SkyBlue !important; +} + + +/************************************************************************************************/ +.log-object { + /* + _position: relative; + _height: 100%; + /**/ +} + +.property { + position: relative; + clear: both; + height: 15px; +} + +.propertyNameCell { + vertical-align: top; + float: left; + width: 28%; + position: absolute; + left: 0; + z-index: 0; +} + +.propertyValueCell { + float: right; + width: 68%; + background: #fff; + position: absolute; + padding-left: 5px; + display: table-cell; + right: 0; + z-index: 1; + /* + _position: relative; + /**/ +} + +.propertyName { + font-weight: bold; +} + +.FirebugPopup { + height: 100% !important; +} + +.FirebugPopup #fbWindowButtons { + display: none !important; +} + +.FirebugPopup #fbHSplitter { + display: none !important; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/firebug.IE6.css b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/firebug.IE6.css new file mode 100644 index 00000000000..13a41d284b8 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/firebug.IE6.css @@ -0,0 +1,20 @@ +/************************************************************************************************/ +#fbToolbarSearch { + background-image: url(search.gif) !important; +} +/************************************************************************************************/ +.fbErrors { + background-image: url(errorIcon.gif) !important; +} +/************************************************************************************************/ +.logRow-info { + background-image: url(infoIcon.gif) !important; +} + +.logRow-warning { + background-image: url(warningIcon.gif) !important; +} + +.logRow-error { + background-image: url(errorIcon.gif) !important; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/firebug.css b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/firebug.css new file mode 100644 index 00000000000..a1465ec5f35 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/firebug.css @@ -0,0 +1,3147 @@ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/* Loose */ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/* +.netInfoResponseHeadersTitle, netInfoResponseHeadersBody { + display: none; +} +/**/ + +.obscured { + left: -999999px !important; +} + +/* IE6 need a separated rule, otherwise it will not recognize it */ +.collapsed { + display: none; +} + +[collapsed="true"] { + display: none; +} + +#fbCSS { + padding: 0 !important; +} + +.cssPropDisable { + float: left; + display: block; + width: 2em; + cursor: default; +} + +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/* panelBase */ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ + +/************************************************************************************************/ + +.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(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(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; + /* + _margin-left: -7px; + _margin-top: -5px; + /**/ +} + +.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; + + /* + _border: 1px solid #999 !important; + _padding: 1px !important; + _filter:progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color="#55404040"); + /**/ +} + +.textEditorInner1 { + padding-left: 11px; + background: url(textEditorBorders.png) repeat-y; + _background: url(textEditorBorders.gif) repeat-y; + _overflow: hidden; +} + +.textEditorInner2 { + position: relative; + padding-right: 2px; + background: url(textEditorBorders.png) repeat-y 100% 0; + _background: url(textEditorBorders.gif) repeat-y 100% 0; + _position: fixed; +} + +.textEditorTop1 { + background: url(textEditorCorners.png) no-repeat 100% 0; + margin-left: 11px; + height: 10px; + _background: url(textEditorCorners.gif) no-repeat 100% 0; + _overflow: hidden; +} + +.textEditorTop2 { + position: relative; + left: -11px; + width: 11px; + height: 10px; + background: url(textEditorCorners.png) no-repeat; + _background: url(textEditorCorners.gif) no-repeat; +} + +.textEditorBottom1 { + position: relative; + background: url(textEditorCorners.png) no-repeat 100% 100%; + margin-left: 11px; + height: 12px; + _background: url(textEditorCorners.gif) no-repeat 100% 100%; +} + +.textEditorBottom2 { + position: relative; + left: -11px; + width: 11px; + height: 12px; + background: url(textEditorCorners.png) no-repeat 0 100%; + _background: url(textEditorCorners.gif) no-repeat 0 100%; +} + + +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/* CSS */ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ + +/* See license.txt for terms of usage */ + +.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 { + /*padding-left: 2em;*/ +} + +.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(disable.png) no-repeat 2px 1px; + _background: url(disable.gif) no-repeat 2px 1px; +} + +.cssProp.editGroup.editing { + background: none; +} + +.cssProp.disabledStyle { + background: url(disableHover.png) no-repeat 2px 1px; + _background: url(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%; +} +/* +.useA11y .a11yCSSView .focusRow:focus { + outline: none; + background-color: transparent + } + + .useA11y .a11yCSSView .focusRow:focus .cssSelector, + .useA11y .a11yCSSView .focusRow:focus .cssPropName, + .useA11y .a11yCSSView .focusRow:focus .cssPropValue, + .useA11y .a11yCSSView .computedStyleRow:focus, + .useA11y .a11yCSSView .groupHeader:focus { + outline: 2px solid #FF9933; + outline-offset: -2px; + background-color: #FFFFD6; + } + + .useA11y .a11yCSSView .groupHeader:focus { + outline-offset: -2px; + } +/**/ + + +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/* Net */ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ + +/* See license.txt for terms of usage */ + +.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(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; +} + +/************************************************************************************************/ +/* Header for Net panel table */ + +.netHeaderRow { + height: 16px; +} + +.netHeaderCell { + cursor: pointer; + -moz-user-select: none; + border-bottom: 1px solid #9C9C9C; + padding: 0 !important; + font-weight: bold; + background: #BBBBBB url(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(chrome://firebug/skin/tableHeaderActive.gif) repeat-x; +} + +.netHeaderSorted { + background: #7D93B2 url(chrome://firebug/skin/tableHeaderSorted.gif) repeat-x; +} + +.netHeaderSorted > .netHeaderCellBox { + border-right-color: #6B7C93; + background: url(chrome://firebug/skin/arrowDown.png) no-repeat right; +} + +.netHeaderSorted.sortedAscending > .netHeaderCellBox { + background-image: url(chrome://firebug/skin/arrowUp.png); +} + +.netHeaderSorted:hover:active { + background: #536B90 url(chrome://firebug/skin/tableHeaderSortedActive.gif) repeat-x; +} + +/************************************************************************************************/ +/* Breakpoints */ + +.panelNode-net .netRowHeader { + display: block; +} + +.netRowHeader { + cursor: pointer; + display: none; + height: 15px; + margin-right: 0 !important; +} + +/* Display brekpoint disc */ +.netRow .netRowHeader { + background-position: 5px 1px; +} + +.netRow[breakpoint="true"] .netRowHeader { + background-image: url(chrome://firebug/skin/breakpoint.png); +} + +.netRow[breakpoint="true"][disabledBreakpoint="true"] .netRowHeader { + background-image: url(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; +} + +/************************************************************************************************/ +/* Column visibility */ + +.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(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(chrome://firebug/skin/netBarResolving.gif) repeat-x; + z-index:60; +} + +.netConnectingBar { + position: absolute; + left: 0; + top: 0; + bottom: 0; + background: #FFFFFF url(chrome://firebug/skin/netBarConnecting.gif) repeat-x; + z-index:50; +} + +.netBlockingBar { + position: absolute; + left: 0; + top: 0; + bottom: 0; + background: #FFFFFF url(chrome://firebug/skin/netBarWaiting.gif) repeat-x; + z-index:40; +} + +.netSendingBar { + position: absolute; + left: 0; + top: 0; + bottom: 0; + background: #FFFFFF url(chrome://firebug/skin/netBarSending.gif) repeat-x; + z-index:30; +} + +.netWaitingBar { + position: absolute; + left: 0; + top: 0; + bottom: 0; + background: #FFFFFF url(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(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; +} + +/* + * Timing info tip is reusing net timeline styles to display the same + * colors for individual request phases. Notice that the info tip must + * respect also loaded and fromCache styles that also modify the + * actual color. These are used both on the same element in case + * of the tooltip. + */ +.loaded .netReceivingBar, +.loaded.netReceivingBar { + background: #B6B6B6 url(chrome://firebug/skin/netBarLoaded.gif) repeat-x; + border-color: #B6B6B6; +} + +.fromCache .netReceivingBar, +.fromCache.netReceivingBar { + background: #D6D6D6 url(chrome://firebug/skin/netBarCached.gif) repeat-x; + border-color: #D6D6D6; +} + +.netSummaryRow .netTimeLabel, +.loaded .netTimeLabel { + background: transparent; +} + +/************************************************************************************************/ +/* Time Info tip */ + +.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; +} + +/************************************************************************************************/ +/* Size Info tip */ + +.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; +} + +/************************************************************************************************/ +/* Summary */ + +.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(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; +} + +/*.netInfoTab:hover { + cursor: pointer; +}*/ + +/* replaced by .netInfoTabSelected for IE6 support +.netInfoTab[selected="true"] { + cursor: default !important; + border: 1px solid #D7D7D7 !important; + border-bottom: none !important; + -moz-border-radius: 4px 4px 0 0; + background-color: #FFFFFF; +} +/**/ +.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; + /*overflow-x: auto; HTML is damaged in case of big (2-3MB) responses */ +} + +/* replaced by .netInfoTextSelected for IE6 support +.netInfoText[selected="true"] { + display: block; +} +/**/ +.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; /* Google Chrome need this otherwise the first column of + the post variables table will be larger than expected */ +} + +.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%; +} + +/************************************************************************************************/ +/* Request & Response Headers */ + +.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(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; +} +/* +.useA11y .panelNode-net .a11yFocus:focus, +.useA11y .panelNode-net .focusRow:focus { + outline-offset: -2px; + background-color: #FFFFD6 !important; +} + +.useA11y .panelNode-net .netHeaderCell:focus, +.useA11y .panelNode-net :focus .netHeaderCell, +.useA11y .panelNode-net :focus .netReceivingBar, +.useA11y .netSummaryRow :focus .netBar, +.useA11y .netSummaryRow:focus .netBar { + background-color: #FFFFD6; + background-image: none; + border-color: #FFFFD6; +} +/**/ + +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/* Windows */ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ + + +/************************************************************************************************/ +/* Twisties */ + +.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(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(tree_close.gif); +} + +.twisty { + background-position: 4px 4px; +} + + + +/************************************************************************************************/ +/* Twisties IE6 */ + +/* IE6 has problems with > operator, and multiple classes */ + +* html .logRow-spy .spyHead .spyTitle, +* html .logGroup .logGroupLabel, +* html .hasChildren .memberLabelCell .memberLabel, +* html .hasHeaders .netHrefLabel { + background-image: url(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(tree_close.gif); + background-repeat: no-repeat; + background-position: 2px 2px; +} + + + +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/* Console */ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ + + +/* See license.txt for terms of usage */ + +.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; /* IE need this to avoid disappearing bug with collapsed logs */ +} + +.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(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 { + /*background-image: url(chrome://firebug/skin/infoIcon.png);*/ +} + +.logRow-warn, +.logRow-warningMessage { + /*background-image: url(chrome://firebug/skin/warningIcon.png);*/ +} + +.logRow-error, +.logRow-assert, +.logRow-errorMessage { + /*background-image: url(chrome://firebug/skin/errorIcon.png);*/ +} + +/*****************************************************************************************/ + +.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; + /*background: url(chrome://firebug/skin/errorIcon-sm.png) no-repeat 0 0;*/ + 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; + /*background: url(chrome://firebug/skin/breakpoint.png) no-repeat;*/ + 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 { + /*background: transparent url(chrome://firebug/skin/loading_16.gif) no-repeat 2px 0 !important;*/ + 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; + /*background: #BBBBBB url(chrome://firebug/skin/tableHeader.gif) repeat-x;*/ +} + +.headerCellBox { + padding: 2px 4px; + border-left: 1px solid #D9D9D9; + border-right: 1px solid #9C9C9C; +} + +.headerCell:hover:active { + /*background: #959595 url(chrome://firebug/skin/tableHeaderActive.gif) repeat-x;*/ +} + +.headerSorted { + /*background: #7D93B2 url(chrome://firebug/skin/tableHeaderSorted.gif) repeat-x;*/ +} + +.headerSorted > .headerCellBox { + border-right-color: #6B7C93; + /*background: url(chrome://firebug/skin/arrowDown.png) no-repeat right;*/ +} + +.headerSorted.sortedAscending > .headerCellBox { + /*background-image: url(chrome://firebug/skin/arrowUp.png);*/ +} + +.headerSorted:hover:active { + /*background: #536B90 url(chrome://firebug/skin/tableHeaderSortedActive.gif) repeat-x;*/ +} + +.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; +} + +/* xxxpedro reps object representation .................................... */ +.objectProp-object { + color: DarkGreen; +} + +.objectProps { + color: #000; + font-weight: normal; +} + +.objectPropName { + /*font-style: italic;*/ + color: #777; +} + +/* +.objectProps .objectProp-string, +.objectProps .objectProp-number, +.objectProps .objectProp-object +{ + font-style: italic; +} +/**/ + +.objectProps .objectProp-string +{ + /*font-family: Monaco, monospace;*/ + color: #f55; +} +.objectProps .objectProp-number +{ + /*font-family: Monaco, monospace;*/ + color: #55a; +} +.objectProps .objectProp-object +{ + /*font-family: Lucida Grande,sans-serif;*/ + color: #585; +} +/* xxxpedro reps object representation .................................... */ + +/************************************************************************************************/ + +.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 +*/ +.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(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(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(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; +} + + + + +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/* DOM */ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ + + +/* See license.txt for terms of usage */ + +.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; + /*position: absolute;*/ + padding-left: 18px; + /*max-width: 30%;*/ + /*white-space: nowrap;*/ + 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; +} + + +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/* FROM ORIGINAL FIREBUG */ + + + + +/************************************************************************************************ + CSS Not organized +*************************************************************************************************/ +#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; } + + +/************************************************************************************************ + Not organized +*************************************************************************************************/ + +#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(tabMenuTarget.png); +} + +.fbTabMenuTarget:hover { + background: url(tabMenuTargetHover.png); +} + +.fbShadow { + float: left; + background: url(shadowAlpha.png) no-repeat bottom right !important; + background: url(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(tabMenuPin.png) no-repeat right 0; +} + +.fbMenuGroup:hover { + background: #316AC5 url(tabMenuPin.png) no-repeat right -17px; +} + +.fbMenuGroupSelected { + color: #fff; + background: #316AC5 url(tabMenuPin.png) no-repeat right -17px; +} + +.fbMenuChecked { + background: transparent url(tabMenuCheckbox.png) no-repeat 4px 0; +} + +.fbMenuChecked:hover { + background: #316AC5 url(tabMenuCheckbox.png) no-repeat 4px -17px; +} + +.fbMenuRadioSelected { + background: transparent url(tabMenuRadio.png) no-repeat 4px 0; +} + +.fbMenuRadioSelected:hover { + background: #316AC5 url(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; +} + + + +/************************************************************************************************ + Error Popup +*************************************************************************************************/ +#fbErrorPopup { + position: absolute; + right: 0; + bottom: 0; + height: 19px; + width: 75px; + background: url(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; +} + +/************************************************************************************************ + General +*************************************************************************************************/ +.fbBody { + margin: 0; + padding: 0; + overflow: hidden; + + font-family: Lucida Grande, Tahoma, sans-serif; + font-size: 11px; + background: #fff; +} + +.clear { + clear: both; +} + +/************************************************************************************************ + Mini Chrome +*************************************************************************************************/ +#fbMiniChrome { + display: none; + right: 0; + height: 27px; + background: url(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(search.png) no-repeat 4px 2px !important; + background: #fff url(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(errorIcon.png) no-repeat !important; + background: url(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(sprite.png) 0 -135px; + cursor: pointer; +} + + +/************************************************************************************************ + Master Layout +*************************************************************************************************/ +#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(sprite.png) #f1f2ee 0 0; + height: 27px; + font-size: 11px; + line-height: 13px; +} + +#fbPanelBarBox { + background: url(sprite.png) #dbd9c9 0 -27px; + height: 22px; +} + +#fbContent { + height: 100%; + vertical-align: top; +} + +#fbBottom { + height: 18px; + background: #fff; +} + +/************************************************************************************************ + Sub-Layout +*************************************************************************************************/ + +/* fbToolbar +*************************************************************************************************/ +#fbToolbarIcon { + float: left; + padding: 0 5px 0; +} + +#fbToolbarIcon a { + background: url(sprite.png) 0 -135px; +} + +#fbToolbarButtons { + padding: 0 2px 0 5px; +} + +#fbToolbarButtons { + padding: 0 2px 0 5px; +} +/* +#fbStatusBarBox a { + text-decoration: none; + display: block; + float: left; + color: #000; + padding: 4px 5px; + margin: 0 0 0 1px; + cursor: default; +} + +#fbStatusBarBox a:hover { + color: #333; + padding: 3px 4px; + border: 1px solid #fff; + border-bottom: 1px solid #bbb; + border-right: 1px solid #bbb; +} +/**/ + +.fbButton { + text-decoration: none; + display: block; + float: left; + color: #000; + padding: 4px 6px 4px 7px; + cursor: default; +} + +.fbButton:hover { + color: #333; + background: #f5f5ef url(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(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(sprite.png) #f1f2ee 0 0; +} + +/* fbPanelBarBox +*************************************************************************************************/ + +#fbPanelBar1 { + width: 1024px; /* fixed width to avoid tabs breaking line */ + z-index: 8; + left: 0; + white-space: nowrap; + background: url(sprite.png) #dbd9c9 0 -27px; + position: absolute; + left: 4px; +} + +#fbPanelBar2Box { + background: url(sprite.png) #dbd9c9 0 -27px; + position: absolute; + height: 22px; + width: 300px; /* fixed width to avoid tabs breaking line */ + z-index: 9; + right: 0; +} + +#fbPanelBar2 { + position: absolute; + width: 290px; /* fixed width to avoid tabs breaking line */ + height: 22px; + padding-left: 4px; +} + +/* body +*************************************************************************************************/ +.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(down.png) no-repeat; + position: absolute; + right: 2px; + bottom: 3px; + + z-index: 99; +} + +#fbSmallCommandLineIcon:hover { + background: url(downHover.png) no-repeat; +} + +.hide { + overflow: hidden !important; + position: fixed !important; + display: none !important; + visibility: hidden !important; +} + +/* fbBottom +*************************************************************************************************/ + +#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(up.png) no-repeat; + position: absolute; + right: 1px; + bottom: 1px; + z-index: 10; +} + +#fbLargeCommandLineIcon:hover { + background: url(upHover.png) no-repeat; +} + +div.fbFitHeight { + overflow: auto; + position: relative; +} + + +/************************************************************************************************ + Layout Controls +*************************************************************************************************/ + +/* fbToolbar buttons +*************************************************************************************************/ +.fbSmallButton { + overflow: hidden; + width: 16px; + height: 16px; + display: block; + text-decoration: none; + cursor: default; +} + +#fbWindowButtons .fbSmallButton { + float: right; +} + +#fbWindow_btClose { + background: url(min.png); +} + +#fbWindow_btClose:hover { + background: url(minHover.png); +} + +#fbWindow_btDetach { + background: url(detach.png); +} + +#fbWindow_btDetach:hover { + background: url(detachHover.png); +} + +#fbWindow_btDeactivate { + background: url(off.png); +} + +#fbWindow_btDeactivate:hover { + background: url(offHover.png); +} + + +/* fbPanelBarBox tabs +*************************************************************************************************/ +.fbTab { + text-decoration: none; + display: none; + float: left; + width: auto; + float: left; + cursor: default; + font-family: Lucida Grande, Tahoma, sans-serif; + font-size: 11px; + line-height: 13px; + font-weight: bold; + height: 22px; + color: #565656; +} + +.fbPanelBar span { + /*display: block; TODO: safe to remove this? */ + float: left; +} + +.fbPanelBar .fbTabL,.fbPanelBar .fbTabR { + height: 22px; + width: 8px; +} + +.fbPanelBar .fbTabText { + padding: 4px 1px 0; +} + +a.fbTab:hover { + background: url(sprite.png) 0 -73px; +} + +a.fbTab:hover .fbTabL { + background: url(sprite.png) -16px -96px; +} + +a.fbTab:hover .fbTabR { + background: url(sprite.png) -24px -96px; +} + +.fbSelectedTab { + background: url(sprite.png) #f1f2ee 0 -50px !important; + color: #000; +} + +.fbSelectedTab .fbTabL { + background: url(sprite.png) 0 -96px !important; +} + +.fbSelectedTab .fbTabR { + background: url(sprite.png) -8px -96px !important; +} + +/* splitters +*************************************************************************************************/ +#fbHSplitter { + position: fixed; + _position: absolute; + left: 0; + top: 0; + width: 100%; + height: 5px; + overflow: hidden; + cursor: n-resize !important; + background: url(pixel_transparent.gif); + z-index: 9; +} + +#fbHSplitter.fbOnMovingHSplitter { + height: 100%; + z-index: 100; +} + +.fbVSplitter { + background: #ece9d8; + color: #000; + border: 1px solid #716f64; + border-width: 0 1px; + border-left-color: #aca899; + width: 4px; + cursor: e-resize; + overflow: hidden; + right: 294px; + text-decoration: none; + z-index: 10; + position: absolute; + height: 100%; + top: 27px; +} + +/************************************************************************************************/ +div.lineNo { + font: 1em/1.4545em Monaco, monospace; + position: relative; + float: left; + top: 0; + left: 0; + margin: 0 5px 0 0; + padding: 0 5px 0 10px; + background: #eee; + color: #888; + border-right: 1px solid #ccc; + text-align: right; +} + +.sourceBox { + position: absolute; +} + +.sourceCode { + font: 1em Monaco, monospace; + overflow: hidden; + white-space: pre; + display: inline; +} + +/************************************************************************************************/ +.nodeControl { + margin-top: 3px; + margin-left: -14px; + float: left; + width: 9px; + height: 9px; + overflow: hidden; + cursor: default; + background: url(tree_open.gif); + _float: none; + _display: inline; + _position: absolute; +} + +div.nodeMaximized { + background: url(tree_close.gif); +} + +div.objectBox-element { + padding: 1px 3px; +} +.objectBox-selector{ + cursor: default; +} + +.selectedElement{ + background: highlight; + /* background: url(roundCorner.svg); Opera */ + color: #fff !important; +} +.selectedElement span{ + color: #fff !important; +} + +/* IE6 need this hack */ +* html .selectedElement { + position: relative; +} + +/* Webkit CSS Hack - bug in "highlight" named color */ +@media screen and (-webkit-min-device-pixel-ratio:0) { + .selectedElement{ + background: #316AC5; + color: #fff !important; + } +} + +/************************************************************************************************/ +/************************************************************************************************/ +.logRow * { + font-size: 1em; +} + +/* TODO: remove this? */ +/* TODO: xxxpedro - IE need this in windowless mode (cnn.com) check if the issue is related to +position. if so, override it at chrome.js initialization when creating the div */ +.logRow { + position: relative; + border-bottom: 1px solid #D7D7D7; + padding: 2px 4px 1px 6px; + zbackground-color: #FFFFFF; +} +/**/ + +.logRow-command { + font-family: Monaco, monospace; + color: blue; +} + +.objectBox-string, +.objectBox-text, +.objectBox-number, +.objectBox-function, +.objectLink-element, +.objectLink-textNode, +.objectLink-function, +.objectBox-stackTrace, +.objectLink-profile { + font-family: Monaco, monospace; +} + +.objectBox-null { + padding: 0 2px; + border: 1px solid #666666; + background-color: #888888; + color: #FFFFFF; +} + +.objectBox-string { + color: red; + + /* TODO: xxxpedro make long strings break line */ + /*white-space: pre; */ +} + +.objectBox-number { + color: #000088; +} + +.objectBox-function { + color: DarkGreen; +} + +.objectBox-object { + color: DarkGreen; + font-weight: bold; + font-family: Lucida Grande, sans-serif; +} + +.objectBox-array { + color: #000; +} + +/************************************************************************************************/ +.logRow-info,.logRow-error,.logRow-warn { + background: #fff no-repeat 2px 2px; + padding-left: 20px; + padding-bottom: 3px; +} + +.logRow-info { + background-image: url(infoIcon.png) !important; + background-image: url(infoIcon.gif); +} + +.logRow-warn { + background-color: cyan; + background-image: url(warningIcon.png) !important; + background-image: url(warningIcon.gif); +} + +.logRow-error { + background-color: LightYellow; + background-image: url(errorIcon.png) !important; + background-image: url(errorIcon.gif); + color: #f00; +} + +.errorMessage { + vertical-align: top; + color: #f00; +} + +.objectBox-sourceLink { + position: absolute; + right: 4px; + top: 2px; + padding-left: 8px; + font-family: Lucida Grande, sans-serif; + font-weight: bold; + color: #0000FF; +} + +/************************************************************************************************/ +/* +//TODO: remove this when console2 is finished +*/ +/* +.logRow-group { + background: #EEEEEE; + border-bottom: none; +} + +.logGroup { + background: #EEEEEE; +} + +.logGroupBox { + margin-left: 24px; + border-top: 1px solid #D7D7D7; + border-left: 1px solid #D7D7D7; +}/**/ + +/************************************************************************************************/ +.selectorTag,.selectorId,.selectorClass { + font-family: Monaco, monospace; + font-weight: normal; +} + +.selectorTag { + color: #0000FF; +} + +.selectorId { + color: DarkBlue; +} + +.selectorClass { + color: red; +} + +/************************************************************************************************/ +.objectBox-element { + font-family: Monaco, monospace; + color: #000088; +} + +.nodeChildren { + padding-left: 26px; +} + +.nodeTag { + color: blue; + cursor: pointer; +} + +.nodeValue { + color: #FF0000; + font-weight: normal; +} + +.nodeText,.nodeComment { + margin: 0 2px; + vertical-align: top; +} + +.nodeText { + color: #333333; + font-family: Monaco, monospace; +} + +.nodeComment { + color: DarkGreen; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +.nodeHidden, .nodeHidden * { + color: #888888; +} + +.nodeHidden .nodeTag { + color: #5F82D9; +} + +.nodeHidden .nodeValue { + color: #D86060; +} + +.selectedElement .nodeHidden, .selectedElement .nodeHidden * { + color: SkyBlue !important; +} + + +/************************************************************************************************/ +.log-object { + /* + _position: relative; + _height: 100%; + /**/ +} + +.property { + position: relative; + clear: both; + height: 15px; +} + +.propertyNameCell { + vertical-align: top; + float: left; + width: 28%; + position: absolute; + left: 0; + z-index: 0; +} + +.propertyValueCell { + float: right; + width: 68%; + background: #fff; + position: absolute; + padding-left: 5px; + display: table-cell; + right: 0; + z-index: 1; + /* + _position: relative; + /**/ +} + +.propertyName { + font-weight: bold; +} + +.FirebugPopup { + height: 100% !important; +} + +.FirebugPopup #fbWindowButtons { + display: none !important; +} + +.FirebugPopup #fbHSplitter { + display: none !important; +} diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/firebug.html b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/firebug.html new file mode 100644 index 00000000000..aa078099fb4 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/firebug.html @@ -0,0 +1,215 @@ + + + + +Firebug Lite + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+   +   +   +
+ + +
+
+ + + +   + + + + + + + + + Inspect + + + + + Clear + + + + + + + + + + + + + +
+ +
+ + + + + +
 
+ +
+
+
+
+
+
+ + +
 
+ + +
+ + +
+
+
+ +
+ + + + + +
+ Run + Clear + + +
+ +
+
+
>>>
+ + +
+
+ + + + + + + + + \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/firebug.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/firebug.png new file mode 100644 index 0000000000000000000000000000000000000000..e10affebb48dc2aa7a70c575b87b901d91de1aca GIT binary patch literal 1167 zcmV;A1aSL_P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iXP% z1vMe5=_CX>@2HM@dakSAh-}000B(Nkl7?fcTwQeNIxiXejg>Qttn`vK11&PA8F>~71F-R#aSS$46%VwcNq zmUy$PU6|;Ganl8yG1G0R6SPVzR7DKMg8faQ?fc{G0<0lue3B<8IXQXG=Q-c+c|>7x zSt29=tS;3MP{?Pgb1T>`FX?oKQn^gAkio+eiL`~|I1CI7pt)-RPc-)&28u#yHGWiYuEn5w(aV9rAh}N#A>e4Az|mPJuCLE*$qkR9}Pxv=>pbEkG*ch>B zlsu}sa$qg5*^57#CScCvx%wkob_Qd|9zGrHVLCp^(}fg?M1sA0_aP-HQd&69 zN=nD%_UJ|CZk(pHyhwC1#>mJpotc~XM^8~k#kL$|rNZYYzv9cITbX+t=fJ@O?AqPO zrUnrC#k`cVDk`~LinG7`icxP6@@oWRLxc^5oDx8(t!G2?Ce%&cP~QTYi|FtfT2Fk9 zX<0FScQiax_kFKp@gsT=B+7NX*rdh^nAH*~* zV$s;EMNzMwVt(N%kwPumOpeZgN^6sknfL>0y$v+j0#7o6`QAwcps6Z>fPsp%dET;F zsc`n(1-i{C!ufG7XPU{RQ@q_I+1(N3?xSa9i#A(Z1WeEJq~{}wGf#LpGfQu{olvN8 zt;&B4U#6inN6%7}k)_Qa(O@v+I-R?%>H@)1Loae((hQ9VDu1_Ypm3GtFV$f;8<7|ao_s4v8 z_zPtOvrH`(51aCu^Ze~L}K(;eby zeG*S&7xL&gBrjazct^`i#Z;uU5sm}4jVR^NT_xIEbVjFA+{*|)*`{&O$TBY5aUK5_ zp}Db;EJV&D%LSxkAsq`=bB!o2Z$19DFj{GuknZP;5BdlVoZt#?GNbRrkt;qu_Wl9p zOr7jvc^#ohJxjcphY0Lq8oQWBY94H@j^Bo_Q0Mh<@uJ~-!0+cum_DYZ5wA-1(jY43wJMoAe$u-1C-Fd;ES zgb)|JqErZh%MxMyL5NgUj1m4MrvJ-D=k5uE+2y(~&iUh3oM8GsrsLOSlx0u4o$rRQ F`U22=Vrl>Y literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/html.css b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/html.css new file mode 100644 index 00000000000..5b7c5f4baf7 --- /dev/null +++ b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/html.css @@ -0,0 +1,272 @@ +/* See license.txt for terms of usage */ + +.panelNode-html { + -moz-box-sizing: padding-box; + padding: 4px 0 0 2px; +} + +.nodeBox { + position: relative; + font-family: Monaco, monospace; + padding-left: 13px; + -moz-user-select: -moz-none; +} +.nodeBox.search-selection { + -moz-user-select: text; +} +.twisty { + position: absolute; + left: 0px; + top: 0px; + width: 14px; + height: 14px; +} + +.nodeChildBox { + margin-left: 12px; + display: none; +} + +.nodeLabel, +.nodeCloseLabel { + margin: -2px 2px 0 2px; + border: 2px solid transparent; + -moz-border-radius: 3px; + padding: 0 2px; + color: #000088; +} + +.nodeCloseLabel { + display: none; +} + +.nodeTag { + cursor: pointer; + color: blue; +} + +.nodeValue { + color: #FF0000; + font-weight: normal; +} + +.nodeText, +.nodeComment { + margin: 0 2px; + vertical-align: top; +} + +.nodeText { + color: #333333; +} + +.nodeWhiteSpace { + border: 1px solid LightGray; + white-space: pre; /* otherwise the border will be collapsed around zero pixels */ + margin-left: 1px; + color: gray; +} + + +.nodeWhiteSpace_Space { + border: 1px solid #ddd; +} + +.nodeTextEntity { + border: 1px solid gray; + white-space: pre; /* otherwise the border will be collapsed around zero pixels */ + margin-left: 1px; +} + +.nodeComment { + color: DarkGreen; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +.nodeBox.highlightOpen > .nodeLabel { + background-color: #EEEEEE; +} + +.nodeBox.highlightOpen > .nodeCloseLabel, +.nodeBox.highlightOpen > .nodeChildBox, +.nodeBox.open > .nodeCloseLabel, +.nodeBox.open > .nodeChildBox { + display: block; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +.nodeBox.selected > .nodeLabel > .nodeLabelBox, +.nodeBox.selected > .nodeLabel { + border-color: Highlight; + background-color: Highlight; + color: HighlightText !important; +} + +.nodeBox.selected > .nodeLabel > .nodeLabelBox, +.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeTag, +.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue, +.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeText { + color: inherit !important; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +.nodeBox.highlighted > .nodeLabel { + border-color: Highlight !important; + background-color: cyan !important; + color: #000000 !important; +} + +.nodeBox.highlighted > .nodeLabel > .nodeLabelBox, +.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeTag, +.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue, +.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeText { + color: #000000 !important; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox, +.nodeBox.nodeHidden .nodeCloseLabel, +.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeText, +.nodeBox.nodeHidden .nodeText { + color: #888888; +} + +.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeTag, +.nodeBox.nodeHidden .nodeCloseLabel > .nodeCloseLabelBox > .nodeTag { + color: #5F82D9; +} + +.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue { + color: #D86060; +} + +.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox, +.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeTag, +.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue, +.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeText { + color: SkyBlue !important; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +.nodeBox.mutated > .nodeLabel, +.nodeAttr.mutated, +.nodeValue.mutated, +.nodeText.mutated, +.nodeBox.mutated > .nodeText { + background-color: #EFFF79; + color: #FF0000 !important; +} + +.nodeBox.selected.mutated > .nodeLabel, +.nodeBox.selected.mutated > .nodeLabel > .nodeLabelBox, +.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr.mutated > .nodeValue, +.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue.mutated, +.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeText.mutated { + background-color: #EFFF79; + border-color: #EFFF79; + color: #FF0000 !important; +} + +/************************************************************************************************/ + +.logRow-dirxml { + padding-left: 0; +} + +.soloElement > .nodeBox { + padding-left: 0; +} + +.useA11y .nodeLabel.focused { + outline: 2px solid #FF9933; + -moz-outline-radius: 3px; + outline-offset: -2px; +} + +.useA11y .nodeLabelBox:focus { + outline: none; +} + +/************************************************************************************************/ + +.breakpointCode .twisty { + display: none; +} + +.breakpointCode .nodeBox.containerNodeBox, +.breakpointCode .nodeLabel { + padding-left: 0px; + margin-left: 0px; + font-family: Monaco, monospace !important; +} + +.breakpointCode .nodeTag, +.breakpointCode .nodeAttr, +.breakpointCode .nodeText, +.breakpointCode .nodeValue, +.breakpointCode .nodeLabel { + color: DarkGreen !important; +} + +.breakpointMutationType { + position: absolute; + top: 4px; + right: 20px; + color: gray; +} + + + + + + +/************************************************************************************************/ +/************************************************************************************************/ +/************************************************************************************************/ +/************************************************************************************************/ +/************************************************************************************************/ +/************************************************************************************************/ +/************************************************************************************************/ +/************************************************************************************************/ +/************************************************************************************************/ +/************************************************************************************************/ + + + +/************************************************************************************************/ +/* Twisties */ + +.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(twistyClosed.png); + 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(twistyOpen.png); +} + +.twisty { + background-position: 4px 4px; +} \ No newline at end of file diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/infoIcon.gif b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/infoIcon.gif new file mode 100644 index 0000000000000000000000000000000000000000..0618e208c3488f9d332eff840219c4b37806a396 GIT binary patch literal 359 zcmZ?wbhEHbMdn4SjS?t zoyB-Jv&kW5)5FYWr^BHcuFBo-x|KV6=V7X!nNE z?k%I;dq(?@3=Urz9KJI+{9thW#o+W`(Eq=2#($TR|K+p(uR8F5_u2oH1I2%W&PAz- zC8;S2<(VZJ3hti10St;iSs1w(>=|?zfB@uC2e$kJ^8+|EnA%*k!W#MOQK{ljl)GVz=%0?7rtE9wY7Lo;JgN;%aBBhkF zup$d#AvGJB@i#x7d!6%U9&aT1>bvKh+xgD9@4TZarC_79XA_3Y)u z4jj;IA&G`4T$SEtNOwJyD9b09DTwq1MCN*%!X+xO|0N{Rs4^;&b|i*sHEGPq;n|zOEfbH<6(;%L`k^mT)7z~ywlRx3h4?$ zl>}*o?-02Jb-IWCddBfMi57}>wIB`^Hlv*vh?pjx5|0aenzD001sDKWl9*QR=`djc O0000nb99Af5rT)t{mCEg5urg=A(g z{C|6SPb~9Xage|wB`SrZk2FOMYM!buln2sX?5Y+T78iB(Zu9cS7|LZyZ++}u$^oi1 z_j@S}bW9OzU2R+RMy&~OT>X-oZ98$jq#ogNfJ!BM-42wHGZk*6s2KD}U*IA%epmxb zm}|6BK9YoIF;*xSL!+z@<64lB7->LTW2Vi4ostCA(z&2XniwNIv}fFo-`MbG;)u4G z^p@F!)|9HhZprHd_vXjDoxs6WkK-6P0@lfxnGT>*p(QHoUV=u1FAqb@b%*W=a3{`LsH5k^AvQNL>6fPpy#oU(&MuH(*aEX4b35*} zn4n7)`I2U%=+Z=?BVZQ?vjQFW4gD@~XSOO6b{qu81`4&LFuU2(ilxW+1|ZkNMnWe79C$gs zWT?Ele|HR{JGPe)5BTW>0Ey?-Ls6S#GoV0tbt6ku7B&*0 z;i9QM$W1Rj*rRIdceL)rAOSl+sDe3LkB87<%){;ZdHp6|SNlopDXRx< zxBDF9-lTo&v`8$humFygUij@qgT=Qzhj8{ym2-{Xciwqq_Xwk%=O3B-MNAL_6e`3U zyxwmXex4`g0^1RYw~Dth3av3Dl^AAlpO3mG!nLr#&ZZ7c_wUboI+deC+&%TFjK2Lm z!Y&f1h|T_On%RCV&=4bx`!>(YezqGVhl&QpED?N6GV)HmzJ9&rh$x*i?*@o9#6QI< z5ZI_MRX;0+pY8$`j)eF#TlUyG(eE%E7S!rj;mj^M5vhUicPm zVWQ2z+imFyg}SRABmOBY_@osR!>7Ov!ioK`NB6_Rv}7Ud?35ed5Sb@?yND?kv~RCa wqs^a3Sh>&&L4)!LKI?D2&k@))k(LESaga|C278ChSzn3NWVkcuNoY&{0f?~U_5c6? literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/min.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/min.png new file mode 100644 index 0000000000000000000000000000000000000000..1034d66fb4405598401302e3e624b1674d2bf1e4 GIT binary patch literal 552 zcmV+@0@wYCP)vmZ_X00D$aL_t(I zjiuAUOB+EH$MNsZCL1?R8&!4bS6fS<)tz`g=*viD*Jl^CK z`t%GY-@^kYv5587_1khrGe5s5z@kn#$OJ&Z!eFXD1Sm(L2g^?Y zYmr`er0{)dYkvX6!fog80Qn7&_6-2NexGu6D>c-py(Qzi=>Y9E03D+rytQ-Lq?j9f z2uM00HtcO|a&62|cs!S*R1Cm$(*e`E!c#83wM^skESnnwvbgx22+@Yv_J;w1RwKFy zozi=wY0ONJ#dDq19mIX%q}AnE8w#$f!{9Ff q>@2^m0u@I4O!e0v_iIDIzt$ZPov@8OQ*!|T00004nJ za0`Jja>QWe}Xi&D$;i?WOTH_Q7mFfclLx;Tbd^e&ye){i+*pmo2d_v|Tm-%WA| zXmI?Fy){a=&u=f4TRr{YyjOcz1)84U;wyZtH?bkx zx+N`yTY>4zLPu-Cz0D_%tZP1UcQ?mxR;7exlD+Hw9x3Ds8E&w9mVc-F%e}wTn|nOB zsFnO>dbZ5cgE>_2UfT)14Y$J0A1JWga=XiV?aW^J%?{U&Jlo*F)ij&up5HFxF55(& zhFj`OqF8JjSv9WT`ccMbRy@JCSFNt*@K@_Avt;>Z#4=cjXfhpFiC*?;WmcxcgY`cc YmzC#;_!)WW0t1}E)78&qol`;+0Lys1;s5{u literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/off.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/off.png new file mode 100644 index 0000000000000000000000000000000000000000..b70b1d24d881014f43bbc8f6ac6e5d84921c0ece GIT binary patch literal 742 zcmVPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FZT01FZU(%pXi0007cNklqH)0mG!ByR2T(Q_4JHo86*cHY zh~fooLU0lPU?Oy!fyZLq%=)}Z(j3lpdV?PzJq7_g47OL4;4Cdfcc&3D43;LRvAT0esjMcVWGjFG2rKDI*|i%PS;bLS zOj^x8?AdMrgjL6pn?>%C8nl8ug2ocIJP%

yFlpb(nCwj+ns@?rq|_a5+Sz>mY} zr1X%NW9QG3U*lzXY6iI&#FUa>3Zz8EqS%W(06f3b&D#M#ZMSc7>DpDCfv>#leGEWO zRXKAD^Q^?;4+{R z*+y2$wpbIZSBe$Gz!q6u%R;fVxJXEDRS*mknw|xqwB`U-O+&?E#A9&?hjA3<128}S z8BCLil3M}G82%vuYA?5-7kT*D(ni<03miUKkNb2303$sQNtKG|np%Aw5HY@^{4e<8 zPN(2ZBUQ~!(A>nHO@}mm_der&PbqPwGre}hdcqaPq`BZKOL4H$-NnmK@5!yJW2e_k z)HInN8)KxWhw=V?3Y<=&!bE7Au>sg-5uFp^WuMKtN`AVIJ~PC`^=AyOm>A(GLW9&~ zD|Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FZT01FZU(%pXi0006zNklLBO?ccg<(Vi96RihU3|k%V;awJqJeI@l%)iVo_6hv)OYp8NjsJn)aIDi0D60lEO+ zUt(r~8@r3=iv~|2TucG{LTU=bZDDP0X624n%=$VCEHOJWM*7tooR*ioVKDu1bo(Q?>Hx@q&+GP(AA5&) zXDe$?b>M1l1i)~bcs4e%;dCcv`zF%whw!-EWJ;wv0Bk^?#;}?i@E<({K>SjeXk#Yp7uEqW^LZ-5|E1)5lTj@kXlJxvSm!hUq`CLwgTuyOog&g>}9I&!tKMTxN8rXmn$R?8jYzYK#)z_n3j>6(1HNdJs0D!4vl4@YSl0heE5;PeM zs;uEqNTZG5txeV=>(X^@H|S8XSO`J|~)U zqm&yBpABjvF(64=ux(8w2GoBhsN1zDZlSv-+7B~OddfivTMi;8{IJUd1z4WI + + + + + diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/search.gif b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/search.gif new file mode 100644 index 0000000000000000000000000000000000000000..2a620987e0e1b7e9ad3213c1c0541cc7db5afea0 GIT binary patch literal 550 zcmZ?wbhEHbN5Ue#OE(%(37LBq6V z9n+Td&t5rW;i_4SRxet#bn%j9%U7*mvS!Pg4O(=etw(i)p zW8a(u7dP)YI{(m>`G>D=+jn@?$s4Or-8^vY%$n0T*POm}_~iLRr_OIYcjxG-3rEge zK6d8fwhQ-8oWHv3@`D{$9-h2#Vqg^X to)YGxrtD|QY%Y26QkOZasnngjVb*LG0!~jl%~&`CUUzEyhBY!+0{{*nXwCot literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/search.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/search.png new file mode 100644 index 0000000000000000000000000000000000000000..fba33b8a57d351da68abc3340dd4e589bc55764d GIT binary patch literal 685 zcmV;e0#f~nP)#l3+^+pwak93=7Z|VPQhts0;rO9~&RUt*+FN7~L36 zT)GisL=jOEKtN*@DU?oWX&E}5(#K3^oZtp@;Ysf9{_Z{ZTypLD4RDN|2}L5e!mZIB zPVgYBs>x(x>852`PZ*>4TO0xUJuGWFNZDW5&SL~3w^7#Gh(FVO(dO+!J zkSd|QcRG$9Z!Wq-&8%V5C?k>8AcUf5kHv>AtKMXq7IqfLi;dlc<4~`ap=t(7RSR+h z56vi{nloG5JO3=$yv;<_dHpvJ|UZ~3kek5~Z%{1Ls^2Zt> zpc6CS5?fUh#fpVSpBMWSKMpqg5e-UsHTF5HZRE!Nq5!dhgXrbJhy|9`EkjZE40d+L zsLxHVEfj#_Hhr4?j(hhXRwbwS;`FiZY&hscM3EqQY%rS%vs2UaT1nqJ74{1(pUv4L z&tB%QT)kZh`9)>u+(7?YW_{efYprfO*eaJnyx|y#AcHVI!Z8}FJ7B?}@^y1*E)?%M z@_gj(aBN|AW`2BP@}m3CFS=d;<0J)~-~(kI!*QHtci56&mJO$@Wfs$$?-o<}z6(PG zoua_^CRbA*DwRrR8=@XB2xV?I&UQkgD8bZouqdBdRM+4BOsKt=&JT7Odg1KqYHIQy z$k_qa;DOgCXMZgxKaNe!_vr;aEl~RrhyRGUf8lx0^xWLSWuMc&5^oKpehV-FA-Vn? Tug%)J00000NkvXXu0mjfX&yMP literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/shadow.gif b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/shadow.gif new file mode 100644 index 0000000000000000000000000000000000000000..af7f537e391f08327e417c7be6323c917d5d3788 GIT binary patch literal 4364 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 mNRx4)$-Se2KGVRJG=-nEko^8U73WMVE8{ literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/shadow2.gif b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/shadow2.gif new file mode 100644 index 0000000000000000000000000000000000000000..099cbf35d455e13d49010e736c40bab22c3d1a23 GIT binary patch literal 3093 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 literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/shadowAlpha.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/shadowAlpha.png new file mode 100644 index 0000000000000000000000000000000000000000..a2561df971728d988424100c74c817916eca1979 GIT binary patch literal 3403 zcmeAS@N?(olHy`uVBq!ia0y~yV738bR}L1Sh{z?w93Z7#;u=xnT$Gwvl9`{U5R#dj z$`F!Ks$i<%mYSqsWME*TU}$J%1Vly(x&~$j21QvmX+Ul4C7!;n>{pmr1x4l8+mz-4 zg*Xd5B8wRqxP?HN@zUM8KR`j2bVpxD28NCO+HqZdXMAQjaPeGm)a##I4DP>8^|Q}*osX?x zu(w4E^8SQ>2<4nWJ;;$Ch1?$dLgm)?6;Yr9_CdHMW*W(@x+ip*R06EH_T4pml(Y0_%+Z_b^VZki z+Ig-L)GH{z-FHJSJv;l^O{dMW8|Geryoiy(edpWebG3Q>oX-o7q}^hCpz*y@X6IS? ZpGWQ1{0Pup3+%oyc)I$ztaD0e0swh%>OlYi literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/sprite.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..33d2c4d4649ec35b7771213977d7c83180907ccd GIT binary patch literal 40027 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 literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabHoverMid.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabHoverMid.png new file mode 100644 index 0000000000000000000000000000000000000000..fbccab54d050bb7d2f503df9fb040d6328cda5ea GIT binary patch literal 261 zcmeAS@N?(olHy`uVBq!ia0vp^Oh7Eg!3HE>ee_)kq!^2X+?^QKos)S9lS| zxv6<249-QVi6yBi3gww484B*6z5(HleBwYw37#&FAsp9Z`wnt8IPkEj?~G{Df4iTh zUTFpEiAG(HZx0IX^c+8!zj<@$l###afwqn82Tlb`aXeaJq9ByTdv(stQpRt=O8dMf yu2?qz()u?OCY5`Aw6~OJI8i(I?dNUp820>T70JFbhpioG7lWs(pUXO@geCwfnO58Y literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabHoverRight.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabHoverRight.png new file mode 100644 index 0000000000000000000000000000000000000000..3db0f361799c5fd3c8d44453c0e74eed59fe203e GIT binary patch literal 436 zcmeAS@N?(olHy`uVBq!ia0vp^96&6_!3HG%UcQ?Eq!^2X+?^QKos)S9lS| zxv6<249-QVi6yBi3gww484B*6z5(HleBwZ>_&r@5Lp09UPBip)Hsoosf4=iA3(pD; z&MOQ5{@0dvVya_Ub%g0mfZ3I@nv;eW`n7KZ+$YNXJXc=!=H*AnNfR767*w8_Z?CDX zdr^Pfl*Iy{f+nQKHhnLiYs8rq9;!GzpE(ovEA@kR#xggRnuT|SWierz+*$L z?K+CB9g!yH*+yE2beElS| zxv6<249-QVi6yBi3gww484B*6z5(HleBwZ>WISCQLp09UPPFx7HWX;xFL_&9#6_4> zv5;FUL;0O2qxnPikR_*CCv+^}lieuaDw{t^Y1*~y>UsBnn`~Qtoc-+c?@Oi};9lv)z3{>08%V(x%&Y={0ohZWh?Hcy?s7>7ombZ$Ca?6_Wft=M8hi<>IyH zWiRzacpYq*^IvLCa>H(OHco>(hvUjh3(J$Tg%w*2ugm5?@~G~9!1&hqOGnz%cW)2w z;xRscetG(u>+?A#2Bk=-@f>#W>J(u5`0iWV_M_}-JNE2STUv6V==Z-U&V-NqQa1m5 oT5;oim8xIQk57N9R-LoIqLa7d%*7w4fPu;2>FVdQ&MBb@0HlJn00000 literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabMenuCheckbox.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabMenuCheckbox.png new file mode 100644 index 0000000000000000000000000000000000000000..4726e62208e024a017a7c5325e160e202976d7d9 GIT binary patch literal 220 zcmeAS@N?(olHy`uVBq!ia0vp^oItF^!3HFIe|>%mq!^2X+?^QKos)S9l5Y=V1NPK>@SUgxxb#j0)Hj=K%#H@hrp<0(ziY;Cn$qB$lOko9uweeR$HkHl1f*xW@hE+`)>M8>*Knp@$Fl1{s~J39 L{an^LB{Ts5ttLz; literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabMenuPin.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabMenuPin.png new file mode 100644 index 0000000000000000000000000000000000000000..eb4b11efe5ee01103c2d5fa2f0f6b8921e640cce GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^Ahr?*6Oeql{{BWF#aJBV?!>U}oXkrghb_t5-G$*l z2rk&Wd@@jkv%n*=n1O*?7=#%aX3dcR3MP5FIEGl9PX6=%zddu_fg=s#0eWXoobYfk z*AwM9ym6JoM(JSIE|W9~gNGBHJsxveA7kVT`LtA$cXJ=#lFR3Ow<;}=p3c?sFd}rp wjoy_^uD3LPOZa8_Shkpi?Q|4a@x+^%p~OOFcBy}4KhQP?Pgg&ebxsLQ0DvV!;s5{u literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabMenuRadio.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabMenuRadio.png new file mode 100644 index 0000000000000000000000000000000000000000..55b982d7c8e69c12497a020b798010f570d5cdaa GIT binary patch literal 192 zcmeAS@N?(olHy`uVBq!ia0vp^96+qZ!2~4VM)CImDaPU;cPEB*=VV?2Ic!PZ?k)`f zL2$v|<&%LToCO|{#S9GG!XV7ZFl&wkP%zlj#W6(VeDa_F|LvL04jgG<4hU>wbuu(E zI@G%0+`(6?{{R0Ud^0rTn!}DBW=RzbRSDkBeS9S@b7yCW4qd@!}UDqW~jjJ h3p(-_6b@=KGECU6@Nto2r904g22WQ%mvv4FO#l_>J;wk5 literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabMenuTarget.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabMenuTarget.png new file mode 100644 index 0000000000000000000000000000000000000000..957bd9f2adabb791aee25df923efebc85e86c0da GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^+(695!2~4VPBOj%q*&4&eI0=`L$_*zFOXs@3GxeO z_zz_L?>wMC0Z1Erx;TbNOiliC{=FVdQ&MBb@07%~_*#H0l literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabMenuTargetHover.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabMenuTargetHover.png new file mode 100644 index 0000000000000000000000000000000000000000..200a37083d6d9f325c493ffe490dde115521f2bd GIT binary patch literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^+(695!2~4VPBOj%q*&4&eI0=`L$_*zFOXs@3GxeO z_zz_L?>wMC0Z3bVx;TbNOij+o$VfQAJ>!G7@X{t$r>obmC!aDkGgCU#P++h$Fvl^h q<&0Y)y9?7ee_)kq!^2X+?^QKos)S9lS| zxv6<249-QVi6yBi3gww484B*6z5(HleBwYwiJmTwAsp9J&u!#wFyL{y`2L2+8+&%4 zGYo4Ea4j%!auMQE=QX)@`L5_R>p0N^#|jw^6rJk}>SBJS{xf{lH9>|C+!9KCv*g_a yas}qkY?A&t1opP!-NXCf1kI#W7yNzsv!Jk1CJ%pG6qjqKbLh*2~7agCR0=Z literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabRight.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tabRight.png new file mode 100644 index 0000000000000000000000000000000000000000..501130796a5fa80c352b87defde9def6510f91fc GIT binary patch literal 448 zcmeAS@N?(olHy`uVBq!ia0vp^96&6_!3HG%UcQ?Eq!^2X+?^QKos)S9lS| zxv6<249-QVi6yBi3gww484B*6z5(HleBwZ>q&;06Lp09UPK@Ho;O zx^+9}gqbCCH{D$GF^DTyKw)O&sg(}|4b6+$R&YpmI?oIA&q-r3G`^Dd`jpF0eFfvf z@ay1Lxm|3g&V^n{DDfM`+31cr$fOL+ubRRmc= z*UoY&Fg|=n%#&?-(2L*x>(+<;_*fBhM1kk_FwOXRu3klbVJI*x89ZJ6T-G@yGywoy-Kj7D literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/textEditorBorders.gif b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/textEditorBorders.gif new file mode 100644 index 0000000000000000000000000000000000000000..0ee5497874cec4a5599e562dd7c00b8c57bc5a44 GIT binary patch literal 117 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 L`)q75=;;3dF|oR- literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/textEditorCorners.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/textEditorCorners.png new file mode 100644 index 0000000000000000000000000000000000000000..a0f839dc598edd80d093e1cf954134a916db5af0 GIT binary patch literal 3960 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 literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/titlebarMid.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/titlebarMid.png new file mode 100644 index 0000000000000000000000000000000000000000..10998ae7b37f7462d6d8780c092b2c42f2b87249 GIT binary patch literal 273 zcmeAS@N?(olHy`uVBq!ia0vp^EI=&H!3HFw3-t_u6k~CayA#8@b22Z19JVBHcNd2L zAh=-f^2tCE&H|6fVg?3oVGw3ym^DWND9B#o>FdgVlZ};CPx{!U2mgRVk|nMYCC>S| zxv6<249-QVi6yBi3gww484B*6z5(HleBwYwIi4<#ArhBcCv4FxtmpF^vf0ZtmW3wW?R6r@!BMzW0`(AIn1J}M@~KJ_Bfp%=6Xf@ zz*W^<8$T2>{TEPd+2($FN}ccfdoNwrRMcl3+}ZqT`{}$MCAqmNTD=YHw5@>lGI+ZB KxvXlS| zxv6<249-QVi6yBi3gww484B*6z5(HleBwYwzMd|QArhC9@9eDoThFF)V9^SVlMPBA zzMqd5VN_!?IdJI2iH3MqGu;(c5fT?zB{(?~q)xT0Ywhgpba6J^YG9l^!|_IdNxQ6F d35zQOLvk9Y)x(dMYJdhac)I$ztaD0e0sz`NNu~e* literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tree_close.gif b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tree_close.gif new file mode 100644 index 0000000000000000000000000000000000000000..e26728ab36b9d612af0edb49ea297da5d6c4b96a GIT binary patch literal 300 zcmZ?wbhEHbnIzhYznme}4D*^ZPGfK7RlH z`Nxm1KYo1s@#Fj7zrX+f{qvv3K=GfTb5UwyNotBhd1gt5g1e`00E6OB7Dg@xdj=hl z_dp(HU^6-3oZ!L3;dnwN<42~M?d-(mhgZg_IrAp$ZsjqS@NN|<J`-rmugEauac+Ic? literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tree_open.gif b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/tree_open.gif new file mode 100644 index 0000000000000000000000000000000000000000..edf662f36f32f39352a4033cde8c43baef3611e5 GIT binary patch literal 202 zcmV;*05$(dNk%w1VF>^U0E8X@0001qrohU=v&+M@%fq$I#J11Ky1dKU*U`n<)XCY@ z%H7z{-rCXO-PGdV*W}^Z=;hz&=HKb&;O_0{@bK&N^X~KW@AUNX_xJPo`1Sbs_W1bs z{r&s>{rvy`|NsC0A^s6Va%Ew3Wn>_CX>@2HM@dak03rDV0SW*g04x9i000R92><{E zGT;%6WFUHI>Wy6sbX+!Wn+9l=G-5#CKckC<0+>J=qlkk6SSS#qgn=*^2nwbW=@0?{ EJ89T&G5`Po literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/twistyClosed.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/twistyClosed.png new file mode 100644 index 0000000000000000000000000000000000000000..f80319b0a4e21532f5139acd618ce6782117b2d2 GIT binary patch literal 334 zcmV-U0kQsxP)1EtgQQRS5LtMzbrwA?yc}HH6?GB;baT0Ow3G2}Uok zHZ&NcAq(C>m59+ZoP+%k$L{2MaLq1=`W8Dud*c$1alVL@3 g)*%1<;7x!50Gzmo@IIg>jQ{`u07*qoM6N<$f_#RHXaE2J literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/twistyOpen.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/twistyOpen.png new file mode 100644 index 0000000000000000000000000000000000000000..868012434599b589e3d75190202fe6b4a16270cd GIT binary patch literal 309 zcmV-50m}Y~P)j*YPNxz}~_W*jQMJ*jNY_HW3qJ$j|;{+%Yjh7DXTI z56m}@x3hwX@T)q!Emk{P?@u40(V&mXcqqWm)7g@~sjgSfEMqi;Xx*xG1SO027%Zja z3u|B{GbFdrh09XI_j^v><6-N<#u!A=#hwaOl5I99vJ`oGci}h;klUiRafr(2!})Hs za^Y)mMiPh6(!xz{g6A>fw=mCfzTr7{>*dawCI0!rhX4Zrv(|{FCa*++00000NkvXX Hu0mjfk~@O2 literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/up.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/up.png new file mode 100644 index 0000000000000000000000000000000000000000..2174d03a9c91a29a40ce8e9cfd715e9b9320f178 GIT binary patch literal 619 zcmV-x0+juUP)vmZ_X00GBIL_t(I zjir-4h!a5+$A3Hfp&N7OLOAf6gQOHW4z;rpP76^GI}1A@mL|kbk8Dso#aMc^{UIn8 zDjZ1ALaoH=xD=v=aAe(F-0vBSP4t!v8uV2&%=`c5z5mS9lv4ap7?Z`v3zuBrI^g_8 z;{gwkJ>75tG^G^p&R=W`+jc8w&N6@e1j4qbDrFGhe|XQ%%NNKXa8Eva(lG!cB^#CH z6|99t!p~p-c)hi-NNIV6owvOPkOM*`ozhYb8O1a8U0SN~<;`mc#vX)9AvA$X(wP84 z6NF>)bAXhnG$|ydSw^*f1%UqgV+>s{oQG2G0VoNhA4PGq&gQMV0Gz&alm3JC0wh#9 zKuk8uAENvr$-tx9tkY|)VaEw}oX~5nQEk>q2Hvl{3E+1HzE3JMYWF$-oVtH|U+=Yc zi|re2453d042jc(&C6H$9!Ho$V2ZrtL}nyXa@ab+k@6gdVeSV+-T)JgN-CL0fCOZ= z*L%!VV(yNJP(^?OZ#($r96eOVvZg=X*j^yw(`Xl!f9V`h)vmZ_X00DzZL_t(I zjir-KOB+!XhM(h1jFXHIQ$%-J1iF$LXcdG~;$P^Z3pcLaRr&`q`2&*fT)XL_i~fa_ zQYiJK%;2ghsGzuMn}svAHkZ>yZX~0T2K&P0ex3I@=W;oss{D`K!D3q^0$u@?e|WmU zn>E!4Kvb12k)~5BNAoXUQhnaQDV0Y$O_uWG;|DI@zr$o{w659`Rb^A;=lt?Y<GJe9t4ZPjvxOfU{G~SoXeBI}a+r9Otte;PK85 z0N<9DaBcyz+W_bKcitQ)d*;HjO5Rf`kO!vOa_fB}*);1Y1`8NeTV=L55&DoAZW377+_cXIbt0H!Q3 z_X`w@-LFos(r^skJ?3G3F%B5Fdjs&Mr`sLTs5qIi=w9K;=mz_x!ftPh&UFb-r46vmZ_X00C-AL_t(I zjir;ZOF~f;#((GaRIvBdAc=w+8=8cmDH4u%Lb(A(07#^Mkopg(g^U z)IR}}kT13HoER*}AZiUazP>~C1xk&M2h3jp*b&JBdyMv(@&~H9KEPk~0rA~|dRYjc QCIA2c07*qoM6N<$f>7|)4gdfE literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/warningIcon.gif b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/warningIcon.gif new file mode 100644 index 0000000000000000000000000000000000000000..84972788620159cbf2bfc443acbdea47350e69de GIT binary patch literal 357 zcmZ?wbhEHbE&KGfouIlu9-6#HcaB$ zG?i=146bdnIajS>*t>-D$U2T4+ZlK7W;nHt{p>EbO9$C5A7VRmhT+CZ)|;nUZ(U}7 zaE0aZ4VEXjnD5?Ycy^ch`90=WkCD>#a_b-_~zF~Uzj^Wc=rqAz~zJ6r< z@s;uCcg9~o82|rg_)j8G{3qyKl$uzQnxasiS(2gP?&%xAp!k!8k&D5eK?meLkVhTZ zau3W8h|mygJ8~u4lObW+>2n{Mco{e@gr`I#q?iebooI6SC$mJn?L%ahn2UG`Lq&?~ z@grF)Ic%m^c(92os;bHgx;wM0dxu2?y0fZ~Y@8+83$Y2csYTc*2 literal 0 HcmV?d00001 diff --git a/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/warningIcon.png b/Frameworks/Misc/ERFirebug/WebServerResources/skin/xp/warningIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..de51084e8489f498b89dd9a59d82eb9564b7d050 GIT binary patch literal 516 zcmV+f0{i`mP)X+Z1;#G+8)`#`)nwDij+1|+};(+Jd*z{tojUrGNrgOti&26irp z_}33i3=gldFg&}%ydKD%4m4mlSOTPRRTp>8w%MHj-#%jkasQt=!|=bOgW><(yI^TB zesYWX|At9i|AA_qz?K0SLTh@t|9^bL1XtwZ!T_=ktQjT-!jEsTfHbZKahQM#GSy9g zGw=!jV;}@%)c=6I5d!peNPt)%qXt$R0@A3+&Ho=o(%2Y6D=A@WxvV2T-}@x_m?j12e;Kn75?FIa%Y*5~(_)p>;wfs>Yo>SSa9R12cEf^3|A z?HDV=w@(OLSFdJZ*t3U$;p|ydO|Ks_Gd#G$auApZ7BB&cJHLN2R-V|*!SL$`L^DVe z48y>e_e>0@wy}el)6tV$3kUcAYBiJJ3`|`A816m!$KYVc!0_$`6T_P)%nWzVvoQSm z#aIlqs1HRWRI?%|K>)EC$csSy9f(f>@eyb`{RmSF5MTfvB)oWs%O|`50000