From 39eb47a2175ae998b0616bc4b5989cac23c2fc70 Mon Sep 17 00:00:00 2001 From: zouzz Date: Mon, 25 Jul 2016 17:36:51 +0800 Subject: [PATCH] =?UTF-8?q?kindeditor=E5=AF=8C=E6=96=87=E6=9C=AC=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=99=A8demo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- php/kindeditor_demo/css/article.css | 125 + php/kindeditor_demo/demo_action.php | 7 + php/kindeditor_demo/demo_add_article.html | 171 + php/kindeditor_demo/images/back.jpg | Bin 0 -> 115446 bytes php/kindeditor_demo/js/jquery-1.7.2.min.js | 4 + php/kindeditor_demo/kindeditor/.gitignore | 15 + php/kindeditor_demo/kindeditor/Gruntfile.js | 119 + php/kindeditor_demo/kindeditor/README.md | 14 + php/kindeditor_demo/kindeditor/changelog.txt | 663 + php/kindeditor_demo/kindeditor/docs/Makefile | 130 + .../kindeditor/docs/_static/file.png | Bin 0 -> 392 bytes .../docs/_static/firebug_upload_json.gif | Bin 0 -> 7494 bytes .../docs/_templates/classy/layout.html | 6 + .../_templates/classy/static/classy.css_t | 288 + .../docs/_templates/classy/theme.conf | 4 + php/kindeditor_demo/kindeditor/docs/ajax.rst | 75 + .../kindeditor/docs/changelog.rst | 699 + .../kindeditor/docs/classyext.py | 86 + .../kindeditor/docs/classyext.pyc | Bin 0 -> 2376 bytes php/kindeditor_demo/kindeditor/docs/cmd.rst | 579 + .../kindeditor/docs/colorpicker.rst | 32 + php/kindeditor_demo/kindeditor/docs/conf.py | 216 + php/kindeditor_demo/kindeditor/docs/core.rst | 511 + .../kindeditor/docs/dialog.rst | 47 + .../kindeditor/docs/editor.rst | 743 + php/kindeditor_demo/kindeditor/docs/event.rst | 53 + php/kindeditor_demo/kindeditor/docs/index.rst | 30 + php/kindeditor_demo/kindeditor/docs/make.bat | 170 + php/kindeditor_demo/kindeditor/docs/menu.rst | 41 + php/kindeditor_demo/kindeditor/docs/node.rst | 984 + .../kindeditor/docs/option.rst | 870 + .../kindeditor/docs/plugin.rst | 80 + php/kindeditor_demo/kindeditor/docs/qna.rst | 39 + php/kindeditor_demo/kindeditor/docs/range.rst | 643 + .../kindeditor/docs/selector.rst | 59 + php/kindeditor_demo/kindeditor/docs/tabs.rst | 42 + php/kindeditor_demo/kindeditor/docs/theme.rst | 40 + .../kindeditor/docs/upgrade.rst | 68 + .../kindeditor/docs/upload.rst | 59 + .../kindeditor/docs/uploadbutton.rst | 37 + php/kindeditor_demo/kindeditor/docs/usage.rst | 97 + .../kindeditor/docs/widget.rst | 33 + .../kindeditor/kindeditor-all-min.js | 7 + .../kindeditor/kindeditor-all.js | 9849 +++++ php/kindeditor_demo/kindeditor/lang/ar.js | 242 + php/kindeditor_demo/kindeditor/lang/en.js | 241 + php/kindeditor_demo/kindeditor/lang/ko.js | 246 + php/kindeditor_demo/kindeditor/lang/ru.js | 242 + php/kindeditor_demo/kindeditor/lang/zh-CN.js | 238 + php/kindeditor_demo/kindeditor/lang/zh-TW.js | 243 + .../lib/firebug-lite/build/.htaccess | 15 + .../lib/firebug-lite/build/build.bat | 21 + .../chrome-extension-beta/background.html | 187 + .../chrome-extension-beta/contentScript.js | 378 + .../firebug-lite-beta.js | 29624 ++++++++++++++++ .../build/chrome-extension-beta/firebug.jpg | Bin 0 -> 34998 bytes .../chrome-extension-beta/firebug128.png | Bin 0 -> 19240 bytes .../build/chrome-extension-beta/firebug16.png | Bin 0 -> 1053 bytes .../build/chrome-extension-beta/firebug24.png | Bin 0 -> 1949 bytes .../firebug24_disabled.png | Bin 0 -> 1015 bytes .../build/chrome-extension-beta/firebug32.png | Bin 0 -> 3575 bytes .../build/chrome-extension-beta/firebug48.png | Bin 0 -> 4096 bytes .../chrome-extension-beta/googleChrome.js | 106 + .../build/chrome-extension-beta/license.txt | 30 + .../build/chrome-extension-beta/manifest.json | 36 + .../chrome-extension-beta/skin/xp/blank.gif | Bin 0 -> 43 bytes .../skin/xp/buttonBg.png | Bin 0 -> 167 bytes .../skin/xp/buttonBgHover.png | Bin 0 -> 171 bytes .../chrome-extension-beta/skin/xp/detach.png | Bin 0 -> 655 bytes .../skin/xp/detachHover.png | Bin 0 -> 586 bytes .../chrome-extension-beta/skin/xp/disable.gif | Bin 0 -> 340 bytes .../chrome-extension-beta/skin/xp/disable.png | Bin 0 -> 543 bytes .../skin/xp/disableHover.gif | Bin 0 -> 344 bytes .../skin/xp/disableHover.png | Bin 0 -> 512 bytes .../chrome-extension-beta/skin/xp/down.png | Bin 0 -> 637 bytes .../skin/xp/downActive.png | Bin 0 -> 543 bytes .../skin/xp/downHover.png | Bin 0 -> 526 bytes .../skin/xp/errorIcon-sm.png | Bin 0 -> 447 bytes .../skin/xp/errorIcon.gif | Bin 0 -> 365 bytes .../skin/xp/errorIcon.png | Bin 0 -> 457 bytes .../skin/xp/firebug-1.3a2.css | 817 + .../skin/xp/firebug.IE6.css | 20 + .../chrome-extension-beta/skin/xp/firebug.css | 3056 ++ .../skin/xp/firebug.html | 213 + .../chrome-extension-beta/skin/xp/firebug.png | Bin 0 -> 1167 bytes .../chrome-extension-beta/skin/xp/group.gif | Bin 0 -> 158 bytes .../skin/xp/infoIcon.gif | Bin 0 -> 359 bytes .../skin/xp/infoIcon.png | Bin 0 -> 524 bytes .../skin/xp/loading_16.gif | Bin 0 -> 1553 bytes .../chrome-extension-beta/skin/xp/min.png | Bin 0 -> 552 bytes .../skin/xp/minHover.png | Bin 0 -> 485 bytes .../chrome-extension-beta/skin/xp/off.png | Bin 0 -> 742 bytes .../skin/xp/offHover.png | Bin 0 -> 680 bytes .../skin/xp/pixel_transparent.gif | Bin 0 -> 43 bytes .../skin/xp/roundCorner.svg | 6 + .../chrome-extension-beta/skin/xp/search.gif | Bin 0 -> 550 bytes .../chrome-extension-beta/skin/xp/search.png | Bin 0 -> 685 bytes .../chrome-extension-beta/skin/xp/shadow.gif | Bin 0 -> 4364 bytes .../chrome-extension-beta/skin/xp/shadow2.gif | Bin 0 -> 3093 bytes .../skin/xp/shadowAlpha.png | Bin 0 -> 3403 bytes .../chrome-extension-beta/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 .../chrome-extension-beta/skin/xp/tabLeft.png | Bin 0 -> 449 bytes .../skin/xp/tabMenuCheckbox.png | Bin 0 -> 220 bytes .../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 .../chrome-extension-beta/skin/xp/tabMid.png | Bin 0 -> 262 bytes .../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 .../skin/xp/toolbarMid.png | Bin 0 -> 242 bytes .../skin/xp/tree_close.gif | Bin 0 -> 300 bytes .../skin/xp/tree_open.gif | Bin 0 -> 202 bytes .../chrome-extension-beta/skin/xp/up.png | Bin 0 -> 619 bytes .../skin/xp/upActive.png | Bin 0 -> 551 bytes .../chrome-extension-beta/skin/xp/upHover.png | Bin 0 -> 526 bytes .../skin/xp/warningIcon.gif | Bin 0 -> 357 bytes .../skin/xp/warningIcon.png | Bin 0 -> 516 bytes .../build/chrome-extension/background.html | 187 + .../build/chrome-extension/contentScript.js | 378 + .../build/chrome-extension/firebug-lite.js | 29624 ++++++++++++++++ .../build/chrome-extension/firebug.jpg | Bin 0 -> 34998 bytes .../build/chrome-extension/firebug128.png | Bin 0 -> 19240 bytes .../build/chrome-extension/firebug16.png | Bin 0 -> 1053 bytes .../build/chrome-extension/firebug24.png | Bin 0 -> 1949 bytes .../chrome-extension/firebug24_disabled.png | Bin 0 -> 1015 bytes .../build/chrome-extension/firebug32.png | Bin 0 -> 3575 bytes .../build/chrome-extension/firebug48.png | Bin 0 -> 4096 bytes .../build/chrome-extension/googleChrome.js | 106 + .../build/chrome-extension/license.txt | 30 + .../build/chrome-extension/manifest.json | 34 + .../build/chrome-extension/skin/xp/blank.gif | Bin 0 -> 43 bytes .../chrome-extension/skin/xp/buttonBg.png | Bin 0 -> 167 bytes .../skin/xp/buttonBgHover.png | Bin 0 -> 171 bytes .../build/chrome-extension/skin/xp/detach.png | Bin 0 -> 655 bytes .../chrome-extension/skin/xp/detachHover.png | Bin 0 -> 586 bytes .../chrome-extension/skin/xp/disable.gif | Bin 0 -> 340 bytes .../chrome-extension/skin/xp/disable.png | Bin 0 -> 543 bytes .../chrome-extension/skin/xp/disableHover.gif | Bin 0 -> 344 bytes .../chrome-extension/skin/xp/disableHover.png | Bin 0 -> 512 bytes .../build/chrome-extension/skin/xp/down.png | Bin 0 -> 637 bytes .../chrome-extension/skin/xp/downActive.png | Bin 0 -> 543 bytes .../chrome-extension/skin/xp/downHover.png | Bin 0 -> 526 bytes .../chrome-extension/skin/xp/errorIcon-sm.png | Bin 0 -> 447 bytes .../chrome-extension/skin/xp/errorIcon.gif | Bin 0 -> 365 bytes .../chrome-extension/skin/xp/errorIcon.png | Bin 0 -> 457 bytes .../skin/xp/firebug-1.3a2.css | 817 + .../chrome-extension/skin/xp/firebug.IE6.css | 20 + .../chrome-extension/skin/xp/firebug.css | 3056 ++ .../chrome-extension/skin/xp/firebug.html | 213 + .../chrome-extension/skin/xp/firebug.png | Bin 0 -> 1167 bytes .../build/chrome-extension/skin/xp/group.gif | Bin 0 -> 158 bytes .../chrome-extension/skin/xp/infoIcon.gif | Bin 0 -> 359 bytes .../chrome-extension/skin/xp/infoIcon.png | Bin 0 -> 524 bytes .../chrome-extension/skin/xp/loading_16.gif | Bin 0 -> 1553 bytes .../build/chrome-extension/skin/xp/min.png | Bin 0 -> 552 bytes .../chrome-extension/skin/xp/minHover.png | Bin 0 -> 485 bytes .../build/chrome-extension/skin/xp/off.png | Bin 0 -> 742 bytes .../chrome-extension/skin/xp/offHover.png | Bin 0 -> 680 bytes .../skin/xp/pixel_transparent.gif | Bin 0 -> 43 bytes .../chrome-extension/skin/xp/roundCorner.svg | 6 + .../build/chrome-extension/skin/xp/search.gif | Bin 0 -> 550 bytes .../build/chrome-extension/skin/xp/search.png | Bin 0 -> 685 bytes .../build/chrome-extension/skin/xp/shadow.gif | Bin 0 -> 4364 bytes .../chrome-extension/skin/xp/shadow2.gif | Bin 0 -> 3093 bytes .../chrome-extension/skin/xp/shadowAlpha.png | Bin 0 -> 3403 bytes .../build/chrome-extension/skin/xp/sprite.png | Bin 0 -> 40027 bytes .../chrome-extension/skin/xp/tabHoverLeft.png | Bin 0 -> 438 bytes .../chrome-extension/skin/xp/tabHoverMid.png | Bin 0 -> 261 bytes .../skin/xp/tabHoverRight.png | Bin 0 -> 436 bytes .../chrome-extension/skin/xp/tabLeft.png | Bin 0 -> 449 bytes .../skin/xp/tabMenuCheckbox.png | Bin 0 -> 220 bytes .../chrome-extension/skin/xp/tabMenuPin.png | Bin 0 -> 207 bytes .../chrome-extension/skin/xp/tabMenuRadio.png | Bin 0 -> 192 bytes .../skin/xp/tabMenuTarget.png | Bin 0 -> 142 bytes .../skin/xp/tabMenuTargetHover.png | Bin 0 -> 148 bytes .../build/chrome-extension/skin/xp/tabMid.png | Bin 0 -> 262 bytes .../chrome-extension/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 .../chrome-extension/skin/xp/titlebarMid.png | Bin 0 -> 273 bytes .../chrome-extension/skin/xp/toolbarMid.png | Bin 0 -> 242 bytes .../chrome-extension/skin/xp/tree_close.gif | Bin 0 -> 300 bytes .../chrome-extension/skin/xp/tree_open.gif | Bin 0 -> 202 bytes .../build/chrome-extension/skin/xp/up.png | Bin 0 -> 619 bytes .../chrome-extension/skin/xp/upActive.png | Bin 0 -> 551 bytes .../chrome-extension/skin/xp/upHover.png | Bin 0 -> 526 bytes .../chrome-extension/skin/xp/warningIcon.gif | Bin 0 -> 357 bytes .../chrome-extension/skin/xp/warningIcon.png | Bin 0 -> 516 bytes .../lib/firebug-lite/build/compress.bat | 3 + .../firebug-lite/build/firebug-lite-beta.js | 29624 ++++++++++++++++ .../firebug-lite/build/firebug-lite-debug.js | 29624 ++++++++++++++++ .../lib/firebug-lite/build/firebug-lite.js | 7886 ++++ .../kindeditor/lib/firebug-lite/license.txt | 30 + .../lib/firebug-lite/plugin/proxy/proxy.php | 258 + .../lib/firebug-lite/skin/classic/blank.gif | Bin 0 -> 43 bytes .../firebug-lite/skin/classic/buttonBg.png | Bin 0 -> 167 bytes .../skin/classic/buttonBgHover.png | Bin 0 -> 171 bytes .../lib/firebug-lite/skin/classic/detach.png | Bin 0 -> 655 bytes .../firebug-lite/skin/classic/detachHover.png | Bin 0 -> 586 bytes .../lib/firebug-lite/skin/classic/disable.gif | Bin 0 -> 340 bytes .../lib/firebug-lite/skin/classic/disable.png | Bin 0 -> 543 bytes .../skin/classic/disableHover.gif | Bin 0 -> 344 bytes .../skin/classic/disableHover.png | Bin 0 -> 512 bytes .../lib/firebug-lite/skin/classic/down.png | Bin 0 -> 637 bytes .../firebug-lite/skin/classic/downActive.png | Bin 0 -> 543 bytes .../firebug-lite/skin/classic/downHover.png | Bin 0 -> 526 bytes .../skin/classic/errorIcon-sm.png | Bin 0 -> 447 bytes .../firebug-lite/skin/classic/errorIcon.gif | Bin 0 -> 365 bytes .../firebug-lite/skin/classic/errorIcon.png | Bin 0 -> 457 bytes .../lib/firebug-lite/skin/classic/firebug.css | 3063 ++ .../firebug-lite/skin/classic/firebug.html | 213 + .../lib/firebug-lite/skin/classic/firebug.png | Bin 0 -> 1059 bytes .../lib/firebug-lite/skin/classic/group.gif | Bin 0 -> 158 bytes .../firebug-lite/skin/classic/infoIcon.gif | Bin 0 -> 359 bytes .../firebug-lite/skin/classic/infoIcon.png | Bin 0 -> 524 bytes .../firebug-lite/skin/classic/loading_16.gif | Bin 0 -> 1553 bytes .../lib/firebug-lite/skin/classic/min.png | Bin 0 -> 552 bytes .../firebug-lite/skin/classic/minHover.png | Bin 0 -> 485 bytes .../lib/firebug-lite/skin/classic/off.png | Bin 0 -> 742 bytes .../firebug-lite/skin/classic/offHover.png | Bin 0 -> 680 bytes .../skin/classic/pixel_transparent.gif | Bin 0 -> 43 bytes .../firebug-lite/skin/classic/roundCorner.svg | 6 + .../lib/firebug-lite/skin/classic/search.gif | Bin 0 -> 550 bytes .../lib/firebug-lite/skin/classic/search.png | Bin 0 -> 685 bytes .../lib/firebug-lite/skin/classic/shadow.gif | Bin 0 -> 4364 bytes .../lib/firebug-lite/skin/classic/shadow2.gif | Bin 0 -> 3093 bytes .../firebug-lite/skin/classic/shadowAlpha.png | Bin 0 -> 3403 bytes .../lib/firebug-lite/skin/classic/sprite.png | Bin 0 -> 40027 bytes .../skin/classic/tabHoverLeft.png | Bin 0 -> 433 bytes .../firebug-lite/skin/classic/tabHoverMid.png | Bin 0 -> 263 bytes .../skin/classic/tabHoverRight.png | Bin 0 -> 441 bytes .../lib/firebug-lite/skin/classic/tabLeft.png | Bin 0 -> 458 bytes .../skin/classic/tabMenuCheckbox.png | Bin 0 -> 220 bytes .../firebug-lite/skin/classic/tabMenuPin.png | Bin 0 -> 207 bytes .../skin/classic/tabMenuRadio.png | Bin 0 -> 192 bytes .../skin/classic/tabMenuTarget.png | Bin 0 -> 142 bytes .../skin/classic/tabMenuTargetHover.png | Bin 0 -> 148 bytes .../lib/firebug-lite/skin/classic/tabMid.png | Bin 0 -> 268 bytes .../firebug-lite/skin/classic/tabRight.png | Bin 0 -> 459 bytes .../skin/classic/textEditorBorders.gif | Bin 0 -> 117 bytes .../skin/classic/textEditorBorders.png | Bin 0 -> 3144 bytes .../skin/classic/textEditorCorners.gif | Bin 0 -> 1821 bytes .../skin/classic/textEditorCorners.png | Bin 0 -> 3960 bytes .../firebug-lite/skin/classic/titlebarMid.png | Bin 0 -> 215 bytes .../firebug-lite/skin/classic/toolbarMid.png | Bin 0 -> 242 bytes .../firebug-lite/skin/classic/tree_close.gif | Bin 0 -> 300 bytes .../firebug-lite/skin/classic/tree_open.gif | Bin 0 -> 202 bytes .../skin/classic/twistyClosed.png | Bin 0 -> 334 bytes .../firebug-lite/skin/classic/twistyOpen.png | Bin 0 -> 309 bytes .../lib/firebug-lite/skin/classic/up.png | Bin 0 -> 619 bytes .../firebug-lite/skin/classic/upActive.png | Bin 0 -> 551 bytes .../lib/firebug-lite/skin/classic/upHover.png | Bin 0 -> 526 bytes .../firebug-lite/skin/classic/warningIcon.gif | Bin 0 -> 357 bytes .../firebug-lite/skin/classic/warningIcon.png | Bin 0 -> 516 bytes .../lib/firebug-lite/skin/light/blank.gif | Bin 0 -> 43 bytes .../lib/firebug-lite/skin/light/buttonBg.png | Bin 0 -> 167 bytes .../firebug-lite/skin/light/buttonBgHover.png | Bin 0 -> 171 bytes .../lib/firebug-lite/skin/light/close.png | Bin 0 -> 3490 bytes .../firebug-lite/skin/light/closeHover.png | Bin 0 -> 3480 bytes .../lib/firebug-lite/skin/light/detach.png | Bin 0 -> 3466 bytes .../firebug-lite/skin/light/detachHover.png | Bin 0 -> 3473 bytes .../lib/firebug-lite/skin/light/disable.gif | Bin 0 -> 340 bytes .../lib/firebug-lite/skin/light/disable.png | Bin 0 -> 543 bytes .../firebug-lite/skin/light/disableHover.gif | Bin 0 -> 344 bytes .../firebug-lite/skin/light/disableHover.png | Bin 0 -> 512 bytes .../lib/firebug-lite/skin/light/down.png | Bin 0 -> 637 bytes .../firebug-lite/skin/light/downActive.png | Bin 0 -> 543 bytes .../lib/firebug-lite/skin/light/downHover.png | Bin 0 -> 526 bytes .../firebug-lite/skin/light/errorIcon-sm.png | Bin 0 -> 447 bytes .../lib/firebug-lite/skin/light/errorIcon.gif | Bin 0 -> 365 bytes .../lib/firebug-lite/skin/light/errorIcon.png | Bin 0 -> 457 bytes .../lib/firebug-lite/skin/light/firebug.css | 3063 ++ .../lib/firebug-lite/skin/light/firebug.html | 213 + .../lib/firebug-lite/skin/light/firebug.png | Bin 0 -> 1037 bytes .../lib/firebug-lite/skin/light/group.gif | Bin 0 -> 158 bytes .../lib/firebug-lite/skin/light/infoIcon.gif | Bin 0 -> 359 bytes .../lib/firebug-lite/skin/light/infoIcon.png | Bin 0 -> 524 bytes .../firebug-lite/skin/light/loading_16.gif | Bin 0 -> 1553 bytes .../lib/firebug-lite/skin/light/min.png | Bin 0 -> 552 bytes .../lib/firebug-lite/skin/light/minHover.png | Bin 0 -> 485 bytes .../lib/firebug-lite/skin/light/off.png | Bin 0 -> 742 bytes .../lib/firebug-lite/skin/light/offHover.png | Bin 0 -> 680 bytes .../skin/light/pixel_transparent.gif | Bin 0 -> 43 bytes .../firebug-lite/skin/light/roundCorner.svg | 6 + .../lib/firebug-lite/skin/light/search.gif | Bin 0 -> 550 bytes .../lib/firebug-lite/skin/light/search.png | Bin 0 -> 685 bytes .../lib/firebug-lite/skin/light/shadow.gif | Bin 0 -> 4364 bytes .../lib/firebug-lite/skin/light/shadow2.gif | Bin 0 -> 3093 bytes .../firebug-lite/skin/light/shadowAlpha.png | Bin 0 -> 3403 bytes .../lib/firebug-lite/skin/light/sprite.png | Bin 0 -> 7464 bytes .../firebug-lite/skin/light/tabHoverLeft.png | Bin 0 -> 432 bytes .../firebug-lite/skin/light/tabHoverMid.png | Bin 0 -> 239 bytes .../firebug-lite/skin/light/tabHoverRight.png | Bin 0 -> 432 bytes .../lib/firebug-lite/skin/light/tabLeft.png | Bin 0 -> 440 bytes .../skin/light/tabMenuCheckbox.png | Bin 0 -> 220 bytes .../firebug-lite/skin/light/tabMenuPin.png | Bin 0 -> 207 bytes .../firebug-lite/skin/light/tabMenuRadio.png | Bin 0 -> 192 bytes .../firebug-lite/skin/light/tabMenuTarget.png | Bin 0 -> 142 bytes .../skin/light/tabMenuTargetHover.png | Bin 0 -> 148 bytes .../lib/firebug-lite/skin/light/tabMid.png | Bin 0 -> 236 bytes .../lib/firebug-lite/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 .../firebug-lite/skin/light/titlebarMid.png | Bin 0 -> 171 bytes .../firebug-lite/skin/light/toolbarMid.png | Bin 0 -> 256 bytes .../firebug-lite/skin/light/tree_close.gif | Bin 0 -> 300 bytes .../lib/firebug-lite/skin/light/tree_open.gif | Bin 0 -> 202 bytes .../firebug-lite/skin/light/twistyClosed.png | Bin 0 -> 334 bytes .../firebug-lite/skin/light/twistyOpen.png | Bin 0 -> 309 bytes .../lib/firebug-lite/skin/light/up.png | Bin 0 -> 619 bytes .../lib/firebug-lite/skin/light/upActive.png | Bin 0 -> 551 bytes .../lib/firebug-lite/skin/light/upHover.png | Bin 0 -> 526 bytes .../firebug-lite/skin/light/warningIcon.gif | Bin 0 -> 357 bytes .../firebug-lite/skin/light/warningIcon.png | Bin 0 -> 516 bytes .../lib/firebug-lite/skin/xp/blank.gif | Bin 0 -> 43 bytes .../lib/firebug-lite/skin/xp/buttonBg.png | Bin 0 -> 167 bytes .../firebug-lite/skin/xp/buttonBgHover.png | Bin 0 -> 171 bytes .../lib/firebug-lite/skin/xp/detach.png | Bin 0 -> 655 bytes .../lib/firebug-lite/skin/xp/detachHover.png | Bin 0 -> 586 bytes .../lib/firebug-lite/skin/xp/disable.gif | Bin 0 -> 340 bytes .../lib/firebug-lite/skin/xp/disable.png | Bin 0 -> 543 bytes .../lib/firebug-lite/skin/xp/disableHover.gif | Bin 0 -> 344 bytes .../lib/firebug-lite/skin/xp/disableHover.png | Bin 0 -> 512 bytes .../lib/firebug-lite/skin/xp/down.png | Bin 0 -> 637 bytes .../lib/firebug-lite/skin/xp/downActive.png | Bin 0 -> 543 bytes .../lib/firebug-lite/skin/xp/downHover.png | Bin 0 -> 526 bytes .../lib/firebug-lite/skin/xp/errorIcon-sm.png | Bin 0 -> 447 bytes .../lib/firebug-lite/skin/xp/errorIcon.gif | Bin 0 -> 365 bytes .../lib/firebug-lite/skin/xp/errorIcon.png | Bin 0 -> 457 bytes .../firebug-lite/skin/xp/firebug-1.3a2.css | 817 + .../lib/firebug-lite/skin/xp/firebug.IE6.css | 20 + .../lib/firebug-lite/skin/xp/firebug.css | 3140 ++ .../lib/firebug-lite/skin/xp/firebug.html | 213 + .../lib/firebug-lite/skin/xp/firebug.png | Bin 0 -> 1167 bytes .../lib/firebug-lite/skin/xp/group.gif | Bin 0 -> 158 bytes .../lib/firebug-lite/skin/xp/infoIcon.gif | Bin 0 -> 359 bytes .../lib/firebug-lite/skin/xp/infoIcon.png | Bin 0 -> 524 bytes .../lib/firebug-lite/skin/xp/loading_16.gif | Bin 0 -> 1553 bytes .../lib/firebug-lite/skin/xp/min.png | Bin 0 -> 552 bytes .../lib/firebug-lite/skin/xp/minHover.png | Bin 0 -> 485 bytes .../lib/firebug-lite/skin/xp/off.png | Bin 0 -> 742 bytes .../lib/firebug-lite/skin/xp/offHover.png | Bin 0 -> 680 bytes .../skin/xp/pixel_transparent.gif | Bin 0 -> 43 bytes .../lib/firebug-lite/skin/xp/roundCorner.svg | 6 + .../lib/firebug-lite/skin/xp/search.gif | Bin 0 -> 550 bytes .../lib/firebug-lite/skin/xp/search.png | Bin 0 -> 685 bytes .../lib/firebug-lite/skin/xp/shadow.gif | Bin 0 -> 4364 bytes .../lib/firebug-lite/skin/xp/shadow2.gif | Bin 0 -> 3093 bytes .../lib/firebug-lite/skin/xp/shadowAlpha.png | Bin 0 -> 3403 bytes .../lib/firebug-lite/skin/xp/sprite.png | Bin 0 -> 40027 bytes .../lib/firebug-lite/skin/xp/tabHoverLeft.png | Bin 0 -> 438 bytes .../lib/firebug-lite/skin/xp/tabHoverMid.png | Bin 0 -> 261 bytes .../firebug-lite/skin/xp/tabHoverRight.png | Bin 0 -> 436 bytes .../lib/firebug-lite/skin/xp/tabLeft.png | Bin 0 -> 449 bytes .../firebug-lite/skin/xp/tabMenuCheckbox.png | Bin 0 -> 220 bytes .../lib/firebug-lite/skin/xp/tabMenuPin.png | Bin 0 -> 207 bytes .../lib/firebug-lite/skin/xp/tabMenuRadio.png | Bin 0 -> 192 bytes .../firebug-lite/skin/xp/tabMenuTarget.png | Bin 0 -> 142 bytes .../skin/xp/tabMenuTargetHover.png | Bin 0 -> 148 bytes .../lib/firebug-lite/skin/xp/tabMid.png | Bin 0 -> 262 bytes .../lib/firebug-lite/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 .../lib/firebug-lite/skin/xp/titlebarMid.png | Bin 0 -> 273 bytes .../lib/firebug-lite/skin/xp/toolbarMid.png | Bin 0 -> 242 bytes .../lib/firebug-lite/skin/xp/tree_close.gif | Bin 0 -> 300 bytes .../lib/firebug-lite/skin/xp/tree_open.gif | Bin 0 -> 202 bytes .../lib/firebug-lite/skin/xp/up.png | Bin 0 -> 619 bytes .../lib/firebug-lite/skin/xp/upActive.png | Bin 0 -> 551 bytes .../lib/firebug-lite/skin/xp/upHover.png | Bin 0 -> 526 bytes .../lib/firebug-lite/skin/xp/warningIcon.gif | Bin 0 -> 357 bytes .../lib/firebug-lite/skin/xp/warningIcon.png | Bin 0 -> 516 bytes .../kindeditor/lib/jquery.min.js | 4 + .../kindeditor/lib/qunit/qunit.css | 225 + .../kindeditor/lib/qunit/qunit.js | 1448 + php/kindeditor_demo/kindeditor/license.txt | 502 + php/kindeditor_demo/kindeditor/package.json | 11 + php/kindeditor_demo/kindeditor/php/JSON.php | 806 + php/kindeditor_demo/kindeditor/php/demo.php | 53 + .../kindeditor/php/file_manager_json.php | 137 + .../kindeditor/php/upload_json.php | 140 + .../kindeditor/plugins/anchor/anchor.js | 46 + .../plugins/autoheight/autoheight.js | 54 + .../kindeditor/plugins/baidumap/baidumap.js | 93 + .../kindeditor/plugins/baidumap/index.html | 83 + .../kindeditor/plugins/baidumap/map.html | 43 + .../kindeditor/plugins/clearhtml/clearhtml.js | 29 + .../kindeditor/plugins/code/code.js | 62 + .../kindeditor/plugins/code/prettify.css | 13 + .../kindeditor/plugins/code/prettify.js | 28 + .../kindeditor/plugins/emoticons/emoticons.js | 129 + .../kindeditor/plugins/emoticons/images/0.gif | Bin 0 -> 1810 bytes .../kindeditor/plugins/emoticons/images/1.gif | Bin 0 -> 1582 bytes .../plugins/emoticons/images/10.gif | Bin 0 -> 3716 bytes .../plugins/emoticons/images/100.gif | Bin 0 -> 1780 bytes .../plugins/emoticons/images/101.gif | Bin 0 -> 2443 bytes .../plugins/emoticons/images/102.gif | Bin 0 -> 1446 bytes .../plugins/emoticons/images/103.gif | Bin 0 -> 2166 bytes .../plugins/emoticons/images/104.gif | Bin 0 -> 2169 bytes .../plugins/emoticons/images/105.gif | Bin 0 -> 1277 bytes .../plugins/emoticons/images/106.gif | Bin 0 -> 1041 bytes .../plugins/emoticons/images/107.gif | Bin 0 -> 1058 bytes .../plugins/emoticons/images/108.gif | Bin 0 -> 1046 bytes .../plugins/emoticons/images/109.gif | Bin 0 -> 1081 bytes .../plugins/emoticons/images/11.gif | Bin 0 -> 8033 bytes .../plugins/emoticons/images/110.gif | Bin 0 -> 1082 bytes .../plugins/emoticons/images/111.gif | Bin 0 -> 1039 bytes .../plugins/emoticons/images/112.gif | Bin 0 -> 1111 bytes .../plugins/emoticons/images/113.gif | Bin 0 -> 1015 bytes .../plugins/emoticons/images/114.gif | Bin 0 -> 1003 bytes .../plugins/emoticons/images/115.gif | Bin 0 -> 1061 bytes .../plugins/emoticons/images/116.gif | Bin 0 -> 996 bytes .../plugins/emoticons/images/117.gif | Bin 0 -> 1041 bytes .../plugins/emoticons/images/118.gif | Bin 0 -> 1012 bytes .../plugins/emoticons/images/119.gif | Bin 0 -> 1101 bytes .../plugins/emoticons/images/12.gif | Bin 0 -> 2247 bytes .../plugins/emoticons/images/120.gif | Bin 0 -> 1008 bytes .../plugins/emoticons/images/121.gif | Bin 0 -> 1060 bytes .../plugins/emoticons/images/122.gif | Bin 0 -> 999 bytes .../plugins/emoticons/images/123.gif | Bin 0 -> 1055 bytes .../plugins/emoticons/images/124.gif | Bin 0 -> 1022 bytes .../plugins/emoticons/images/125.gif | Bin 0 -> 1013 bytes .../plugins/emoticons/images/126.gif | Bin 0 -> 1030 bytes .../plugins/emoticons/images/127.gif | Bin 0 -> 956 bytes .../plugins/emoticons/images/128.gif | Bin 0 -> 1022 bytes .../plugins/emoticons/images/129.gif | Bin 0 -> 972 bytes .../plugins/emoticons/images/13.gif | Bin 0 -> 1736 bytes .../plugins/emoticons/images/130.gif | Bin 0 -> 980 bytes .../plugins/emoticons/images/131.gif | Bin 0 -> 945 bytes .../plugins/emoticons/images/132.gif | Bin 0 -> 936 bytes .../plugins/emoticons/images/133.gif | Bin 0 -> 1012 bytes .../plugins/emoticons/images/134.gif | Bin 0 -> 968 bytes .../plugins/emoticons/images/14.gif | Bin 0 -> 4006 bytes .../plugins/emoticons/images/15.gif | Bin 0 -> 1562 bytes .../plugins/emoticons/images/16.gif | Bin 0 -> 1413 bytes .../plugins/emoticons/images/17.gif | Bin 0 -> 3366 bytes .../plugins/emoticons/images/18.gif | Bin 0 -> 8137 bytes .../plugins/emoticons/images/19.gif | Bin 0 -> 8135 bytes .../kindeditor/plugins/emoticons/images/2.gif | Bin 0 -> 1804 bytes .../plugins/emoticons/images/20.gif | Bin 0 -> 1808 bytes .../plugins/emoticons/images/21.gif | Bin 0 -> 1864 bytes .../plugins/emoticons/images/22.gif | Bin 0 -> 3010 bytes .../plugins/emoticons/images/23.gif | Bin 0 -> 1950 bytes .../plugins/emoticons/images/24.gif | Bin 0 -> 2257 bytes .../plugins/emoticons/images/25.gif | Bin 0 -> 2446 bytes .../plugins/emoticons/images/26.gif | Bin 0 -> 4014 bytes .../plugins/emoticons/images/27.gif | Bin 0 -> 2893 bytes .../plugins/emoticons/images/28.gif | Bin 0 -> 3262 bytes .../plugins/emoticons/images/29.gif | Bin 0 -> 5861 bytes .../kindeditor/plugins/emoticons/images/3.gif | Bin 0 -> 1852 bytes .../plugins/emoticons/images/30.gif | Bin 0 -> 1780 bytes .../plugins/emoticons/images/31.gif | Bin 0 -> 5174 bytes .../plugins/emoticons/images/32.gif | Bin 0 -> 7189 bytes .../plugins/emoticons/images/33.gif | Bin 0 -> 4317 bytes .../plugins/emoticons/images/34.gif | Bin 0 -> 2140 bytes .../plugins/emoticons/images/35.gif | Bin 0 -> 13392 bytes .../plugins/emoticons/images/36.gif | Bin 0 -> 1417 bytes .../plugins/emoticons/images/37.gif | Bin 0 -> 1195 bytes .../plugins/emoticons/images/38.gif | Bin 0 -> 1674 bytes .../plugins/emoticons/images/39.gif | Bin 0 -> 1798 bytes .../kindeditor/plugins/emoticons/images/4.gif | Bin 0 -> 1977 bytes .../plugins/emoticons/images/40.gif | Bin 0 -> 10092 bytes .../plugins/emoticons/images/41.gif | Bin 0 -> 3368 bytes .../plugins/emoticons/images/42.gif | Bin 0 -> 13367 bytes .../plugins/emoticons/images/43.gif | Bin 0 -> 4327 bytes .../plugins/emoticons/images/44.gif | Bin 0 -> 1571 bytes .../plugins/emoticons/images/45.gif | Bin 0 -> 4692 bytes .../plugins/emoticons/images/46.gif | Bin 0 -> 5162 bytes .../plugins/emoticons/images/47.gif | Bin 0 -> 3685 bytes .../plugins/emoticons/images/48.gif | Bin 0 -> 1755 bytes .../plugins/emoticons/images/49.gif | Bin 0 -> 6361 bytes .../kindeditor/plugins/emoticons/images/5.gif | Bin 0 -> 1866 bytes .../plugins/emoticons/images/50.gif | Bin 0 -> 3073 bytes .../plugins/emoticons/images/51.gif | Bin 0 -> 3731 bytes .../plugins/emoticons/images/52.gif | Bin 0 -> 1532 bytes .../plugins/emoticons/images/53.gif | Bin 0 -> 2056 bytes .../plugins/emoticons/images/54.gif | Bin 0 -> 2362 bytes .../plugins/emoticons/images/55.gif | Bin 0 -> 1582 bytes .../plugins/emoticons/images/56.gif | Bin 0 -> 1170 bytes .../plugins/emoticons/images/57.gif | Bin 0 -> 5072 bytes .../plugins/emoticons/images/58.gif | Bin 0 -> 2596 bytes .../plugins/emoticons/images/59.gif | Bin 0 -> 1533 bytes .../kindeditor/plugins/emoticons/images/6.gif | Bin 0 -> 3556 bytes .../plugins/emoticons/images/60.gif | Bin 0 -> 2667 bytes .../plugins/emoticons/images/61.gif | Bin 0 -> 1136 bytes .../plugins/emoticons/images/62.gif | Bin 0 -> 1269 bytes .../plugins/emoticons/images/63.gif | Bin 0 -> 971 bytes .../plugins/emoticons/images/64.gif | Bin 0 -> 988 bytes .../plugins/emoticons/images/65.gif | Bin 0 -> 5285 bytes .../plugins/emoticons/images/66.gif | Bin 0 -> 1159 bytes .../plugins/emoticons/images/67.gif | Bin 0 -> 2746 bytes .../plugins/emoticons/images/68.gif | Bin 0 -> 4148 bytes .../plugins/emoticons/images/69.gif | Bin 0 -> 1015 bytes .../kindeditor/plugins/emoticons/images/7.gif | Bin 0 -> 3929 bytes .../plugins/emoticons/images/70.gif | Bin 0 -> 1162 bytes .../plugins/emoticons/images/71.gif | Bin 0 -> 824 bytes .../plugins/emoticons/images/72.gif | Bin 0 -> 3679 bytes .../plugins/emoticons/images/73.gif | Bin 0 -> 2195 bytes .../plugins/emoticons/images/74.gif | Bin 0 -> 2454 bytes .../plugins/emoticons/images/75.gif | Bin 0 -> 1222 bytes .../plugins/emoticons/images/76.gif | Bin 0 -> 1211 bytes .../plugins/emoticons/images/77.gif | Bin 0 -> 1151 bytes .../plugins/emoticons/images/78.gif | Bin 0 -> 1565 bytes .../plugins/emoticons/images/79.gif | Bin 0 -> 1518 bytes .../kindeditor/plugins/emoticons/images/8.gif | Bin 0 -> 4679 bytes .../plugins/emoticons/images/80.gif | Bin 0 -> 1537 bytes .../plugins/emoticons/images/81.gif | Bin 0 -> 1591 bytes .../plugins/emoticons/images/82.gif | Bin 0 -> 1547 bytes .../plugins/emoticons/images/83.gif | Bin 0 -> 1591 bytes .../plugins/emoticons/images/84.gif | Bin 0 -> 3424 bytes .../plugins/emoticons/images/85.gif | Bin 0 -> 1581 bytes .../plugins/emoticons/images/86.gif | Bin 0 -> 1519 bytes .../plugins/emoticons/images/87.gif | Bin 0 -> 1558 bytes .../plugins/emoticons/images/88.gif | Bin 0 -> 2134 bytes .../plugins/emoticons/images/89.gif | Bin 0 -> 1219 bytes .../kindeditor/plugins/emoticons/images/9.gif | Bin 0 -> 3298 bytes .../plugins/emoticons/images/90.gif | Bin 0 -> 2743 bytes .../plugins/emoticons/images/91.gif | Bin 0 -> 654 bytes .../plugins/emoticons/images/92.gif | Bin 0 -> 1377 bytes .../plugins/emoticons/images/93.gif | Bin 0 -> 1119 bytes .../plugins/emoticons/images/94.gif | Bin 0 -> 3426 bytes .../plugins/emoticons/images/95.gif | Bin 0 -> 3011 bytes .../plugins/emoticons/images/96.gif | Bin 0 -> 1796 bytes .../plugins/emoticons/images/97.gif | Bin 0 -> 5300 bytes .../plugins/emoticons/images/98.gif | Bin 0 -> 1629 bytes .../plugins/emoticons/images/99.gif | Bin 0 -> 2261 bytes .../plugins/emoticons/images/static.gif | Bin 0 -> 35504 bytes .../plugins/filemanager/filemanager.js | 189 + .../plugins/filemanager/images/file-16.gif | Bin 0 -> 170 bytes .../plugins/filemanager/images/file-64.gif | Bin 0 -> 1149 bytes .../plugins/filemanager/images/folder-16.gif | Bin 0 -> 226 bytes .../plugins/filemanager/images/folder-64.gif | Bin 0 -> 1272 bytes .../plugins/filemanager/images/go-up.gif | Bin 0 -> 562 bytes .../plugins/fixtoolbar/fixtoolbar.js | 35 + .../kindeditor/plugins/flash/flash.js | 161 + .../kindeditor/plugins/image/image.js | 328 + .../plugins/image/images/align_left.gif | Bin 0 -> 639 bytes .../plugins/image/images/align_right.gif | Bin 0 -> 636 bytes .../plugins/image/images/align_top.gif | Bin 0 -> 625 bytes .../plugins/image/images/refresh.png | Bin 0 -> 800 bytes .../plugins/insertfile/insertfile.js | 138 + .../plugins/lineheight/lineheight.js | 38 + .../kindeditor/plugins/link/link.js | 66 + .../kindeditor/plugins/map/map.html | 57 + .../kindeditor/plugins/map/map.js | 137 + .../kindeditor/plugins/media/media.js | 170 + .../plugins/multiimage/images/image.png | Bin 0 -> 1862 bytes .../multiimage/images/select-files-en.png | Bin 0 -> 484 bytes .../multiimage/images/select-files-zh-CN.png | Bin 0 -> 481 bytes .../plugins/multiimage/images/swfupload.swf | Bin 0 -> 12787 bytes .../plugins/multiimage/multiimage.js | 1384 + .../kindeditor/plugins/pagebreak/pagebreak.js | 27 + .../plugins/plainpaste/plainpaste.js | 41 + .../kindeditor/plugins/preview/preview.js | 31 + .../plugins/quickformat/quickformat.js | 81 + .../kindeditor/plugins/table/table.js | 712 + .../kindeditor/plugins/template/html/1.html | 14 + .../kindeditor/plugins/template/html/2.html | 42 + .../kindeditor/plugins/template/html/3.html | 36 + .../kindeditor/plugins/template/template.js | 58 + .../kindeditor/plugins/wordpaste/wordpaste.js | 51 + php/kindeditor_demo/kindeditor/src/ajax.js | 72 + php/kindeditor_demo/kindeditor/src/cmd.js | 884 + .../kindeditor/src/colorpicker.js | 79 + php/kindeditor_demo/kindeditor/src/config.js | 97 + php/kindeditor_demo/kindeditor/src/core.js | 231 + php/kindeditor_demo/kindeditor/src/dialog.js | 142 + php/kindeditor_demo/kindeditor/src/edit.js | 371 + php/kindeditor_demo/kindeditor/src/event.js | 389 + php/kindeditor_demo/kindeditor/src/footer.js | 2 + php/kindeditor_demo/kindeditor/src/header.js | 15 + php/kindeditor_demo/kindeditor/src/html.js | 428 + php/kindeditor_demo/kindeditor/src/main.js | 1623 + php/kindeditor_demo/kindeditor/src/menu.js | 85 + php/kindeditor_demo/kindeditor/src/node.js | 628 + php/kindeditor_demo/kindeditor/src/range.js | 780 + .../kindeditor/src/selector.js | 229 + php/kindeditor_demo/kindeditor/src/tabs.js | 60 + php/kindeditor_demo/kindeditor/src/toolbar.js | 136 + .../kindeditor/src/uploadbutton.js | 105 + php/kindeditor_demo/kindeditor/src/widget.js | 237 + php/kindeditor_demo/kindeditor/test/ajax.html | 29 + php/kindeditor_demo/kindeditor/test/cmd.html | 36 + php/kindeditor_demo/kindeditor/test/cmd.js | 570 + php/kindeditor_demo/kindeditor/test/core.html | 19 + php/kindeditor_demo/kindeditor/test/core.js | 196 + .../kindeditor/test/data/logo_180_30.gif | Bin 0 -> 1755 bytes .../kindeditor/test/dialog.html | 80 + php/kindeditor_demo/kindeditor/test/edit.html | 61 + php/kindeditor_demo/kindeditor/test/edit.js | 52 + .../kindeditor/test/editor.html | 59 + php/kindeditor_demo/kindeditor/test/editor.js | 140 + .../kindeditor/test/event.html | 61 + php/kindeditor_demo/kindeditor/test/event.js | 153 + .../kindeditor/test/frame.html | 3 + .../kindeditor/test/hidden.html | 48 + php/kindeditor_demo/kindeditor/test/html.html | 48 + php/kindeditor_demo/kindeditor/test/html.js | 91 + .../kindeditor/test/index.html | 11 + php/kindeditor_demo/kindeditor/test/leak.html | 39 + php/kindeditor_demo/kindeditor/test/main.html | 369 + php/kindeditor_demo/kindeditor/test/menu.html | 33 + php/kindeditor_demo/kindeditor/test/menu.js | 72 + php/kindeditor_demo/kindeditor/test/navi.html | 36 + php/kindeditor_demo/kindeditor/test/node.html | 62 + php/kindeditor_demo/kindeditor/test/node.js | 206 + .../kindeditor/test/quirkmode.html | 25 + .../kindeditor/test/range.html | 52 + php/kindeditor_demo/kindeditor/test/range.js | 812 + .../kindeditor/test/remote.html | 19 + .../kindeditor/test/selector.html | 56 + .../kindeditor/test/selector.js | 55 + php/kindeditor_demo/kindeditor/test/tabs.html | 49 + .../kindeditor/test/toolbar.html | 34 + .../kindeditor/test/toolbar.js | 60 + .../kindeditor/test/total.html | 58 + .../test/webdriver/KindEditorDriver.php | 151 + .../kindeditor/test/webdriver/all-chrome.bat | 2 + .../kindeditor/test/webdriver/all-firefox.bat | 2 + .../kindeditor/test/webdriver/all-ie.bat | 2 + .../kindeditor/test/webdriver/all.php | 27 + .../test/webdriver/php-webdriver/README.md | 167 + .../webdriver/php-webdriver/WebDriver.php | 49 + .../webdriver/php-webdriver/WebDriverBase.php | 236 + .../php-webdriver/WebDriverContainer.php | 60 + .../php-webdriver/WebDriverElement.php | 50 + .../php-webdriver/WebDriverEnvironment.php | 25 + .../php-webdriver/WebDriverExceptions.php | 62 + .../php-webdriver/WebDriverSession.php | 148 + .../php-webdriver/WebDriverSimpleItem.php | 26 + .../test/webdriver/php-webdriver/__init__.php | 23 + .../test/webdriver/test-default.php | 22 + .../kindeditor/test/webdriver/test-dialog.php | 17 + .../test/webdriver/test-unittest.php | 23 + .../kindeditor/test/widget.html | 64 + .../kindeditor/themes/common/anchor.gif | Bin 0 -> 371 bytes .../kindeditor/themes/common/blank.gif | Bin 0 -> 43 bytes .../kindeditor/themes/common/flash.gif | Bin 0 -> 1089 bytes .../kindeditor/themes/common/loading.gif | Bin 0 -> 2608 bytes .../kindeditor/themes/common/media.gif | Bin 0 -> 1036 bytes .../kindeditor/themes/common/rm.gif | Bin 0 -> 989 bytes .../kindeditor/themes/default/background.png | Bin 0 -> 1410 bytes .../kindeditor/themes/default/default.css | 1147 + .../kindeditor/themes/default/default.png | Bin 0 -> 8299 bytes .../kindeditor/themes/qq/editor.gif | Bin 0 -> 1449 bytes .../kindeditor/themes/qq/qq.css | 163 + .../kindeditor/themes/simple/simple.css | 100 + 661 files changed, 186907 insertions(+) create mode 100755 php/kindeditor_demo/css/article.css create mode 100755 php/kindeditor_demo/demo_action.php create mode 100755 php/kindeditor_demo/demo_add_article.html create mode 100755 php/kindeditor_demo/images/back.jpg create mode 100755 php/kindeditor_demo/js/jquery-1.7.2.min.js create mode 100755 php/kindeditor_demo/kindeditor/.gitignore create mode 100755 php/kindeditor_demo/kindeditor/Gruntfile.js create mode 100755 php/kindeditor_demo/kindeditor/README.md create mode 100755 php/kindeditor_demo/kindeditor/changelog.txt create mode 100755 php/kindeditor_demo/kindeditor/docs/Makefile create mode 100755 php/kindeditor_demo/kindeditor/docs/_static/file.png create mode 100755 php/kindeditor_demo/kindeditor/docs/_static/firebug_upload_json.gif create mode 100755 php/kindeditor_demo/kindeditor/docs/_templates/classy/layout.html create mode 100755 php/kindeditor_demo/kindeditor/docs/_templates/classy/static/classy.css_t create mode 100755 php/kindeditor_demo/kindeditor/docs/_templates/classy/theme.conf create mode 100755 php/kindeditor_demo/kindeditor/docs/ajax.rst create mode 100755 php/kindeditor_demo/kindeditor/docs/changelog.rst create mode 100755 php/kindeditor_demo/kindeditor/docs/classyext.py create mode 100755 php/kindeditor_demo/kindeditor/docs/classyext.pyc create mode 100755 php/kindeditor_demo/kindeditor/docs/cmd.rst create mode 100755 php/kindeditor_demo/kindeditor/docs/colorpicker.rst create mode 100755 php/kindeditor_demo/kindeditor/docs/conf.py create mode 100755 php/kindeditor_demo/kindeditor/docs/core.rst create mode 100755 php/kindeditor_demo/kindeditor/docs/dialog.rst create mode 100755 php/kindeditor_demo/kindeditor/docs/editor.rst create mode 100755 php/kindeditor_demo/kindeditor/docs/event.rst create mode 100755 php/kindeditor_demo/kindeditor/docs/index.rst create mode 100755 php/kindeditor_demo/kindeditor/docs/make.bat create mode 100755 php/kindeditor_demo/kindeditor/docs/menu.rst create mode 100755 php/kindeditor_demo/kindeditor/docs/node.rst create mode 100755 php/kindeditor_demo/kindeditor/docs/option.rst create mode 100755 php/kindeditor_demo/kindeditor/docs/plugin.rst create mode 100755 php/kindeditor_demo/kindeditor/docs/qna.rst create mode 100755 php/kindeditor_demo/kindeditor/docs/range.rst create mode 100755 php/kindeditor_demo/kindeditor/docs/selector.rst create mode 100755 php/kindeditor_demo/kindeditor/docs/tabs.rst create mode 100755 php/kindeditor_demo/kindeditor/docs/theme.rst create mode 100755 php/kindeditor_demo/kindeditor/docs/upgrade.rst create mode 100755 php/kindeditor_demo/kindeditor/docs/upload.rst create mode 100755 php/kindeditor_demo/kindeditor/docs/uploadbutton.rst create mode 100755 php/kindeditor_demo/kindeditor/docs/usage.rst create mode 100755 php/kindeditor_demo/kindeditor/docs/widget.rst create mode 100755 php/kindeditor_demo/kindeditor/kindeditor-all-min.js create mode 100755 php/kindeditor_demo/kindeditor/kindeditor-all.js create mode 100755 php/kindeditor_demo/kindeditor/lang/ar.js create mode 100755 php/kindeditor_demo/kindeditor/lang/en.js create mode 100755 php/kindeditor_demo/kindeditor/lang/ko.js create mode 100755 php/kindeditor_demo/kindeditor/lang/ru.js create mode 100755 php/kindeditor_demo/kindeditor/lang/zh-CN.js create mode 100755 php/kindeditor_demo/kindeditor/lang/zh-TW.js create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/.htaccess create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/build.bat create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/background.html create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/contentScript.js create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/firebug-lite-beta.js create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/firebug.jpg create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/firebug128.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/firebug16.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/firebug24.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/firebug24_disabled.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/firebug32.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/firebug48.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/googleChrome.js create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/license.txt create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/manifest.json create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/blank.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/buttonBg.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/buttonBgHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/detach.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/detachHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/disable.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/disable.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/disableHover.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/disableHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/down.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/downActive.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/downHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/errorIcon-sm.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/errorIcon.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/errorIcon.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/firebug-1.3a2.css create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/firebug.IE6.css create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/firebug.css create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/firebug.html create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/firebug.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/group.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/infoIcon.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/infoIcon.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/loading_16.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/min.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/minHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/off.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/offHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/pixel_transparent.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/roundCorner.svg create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/search.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/search.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/shadow.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/shadow2.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/shadowAlpha.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/sprite.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabHoverLeft.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabHoverMid.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabHoverRight.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabLeft.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabMenuCheckbox.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabMenuPin.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabMenuRadio.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabMenuTarget.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabMenuTargetHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabMid.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabRight.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/textEditorBorders.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/textEditorBorders.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/textEditorCorners.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/textEditorCorners.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/titlebarMid.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/toolbarMid.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tree_close.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tree_open.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/up.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/upActive.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/upHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/warningIcon.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/warningIcon.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/background.html create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/contentScript.js create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/firebug-lite.js create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/firebug.jpg create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/firebug128.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/firebug16.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/firebug24.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/firebug24_disabled.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/firebug32.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/firebug48.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/googleChrome.js create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/license.txt create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/manifest.json create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/blank.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/buttonBg.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/buttonBgHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/detach.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/detachHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/disable.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/disable.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/disableHover.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/disableHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/down.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/downActive.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/downHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/errorIcon-sm.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/errorIcon.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/errorIcon.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/firebug-1.3a2.css create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/firebug.IE6.css create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/firebug.css create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/firebug.html create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/firebug.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/group.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/infoIcon.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/infoIcon.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/loading_16.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/min.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/minHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/off.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/offHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/pixel_transparent.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/roundCorner.svg create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/search.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/search.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/shadow.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/shadow2.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/shadowAlpha.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/sprite.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabHoverLeft.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabHoverMid.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabHoverRight.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabLeft.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabMenuCheckbox.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabMenuPin.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabMenuRadio.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabMenuTarget.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabMenuTargetHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabMid.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabRight.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/textEditorBorders.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/textEditorBorders.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/textEditorCorners.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/textEditorCorners.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/titlebarMid.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/toolbarMid.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tree_close.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tree_open.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/up.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/upActive.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/upHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/warningIcon.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/warningIcon.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/compress.bat create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/firebug-lite-beta.js create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/firebug-lite-debug.js create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/build/firebug-lite.js create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/license.txt create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/plugin/proxy/proxy.php create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/blank.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/buttonBg.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/buttonBgHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/detach.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/detachHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/disable.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/disable.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/disableHover.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/disableHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/down.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/downActive.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/downHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/errorIcon-sm.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/errorIcon.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/errorIcon.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/firebug.css create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/firebug.html create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/firebug.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/group.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/infoIcon.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/infoIcon.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/loading_16.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/min.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/minHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/off.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/offHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/pixel_transparent.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/roundCorner.svg create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/search.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/search.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/shadow.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/shadow2.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/shadowAlpha.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/sprite.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabHoverLeft.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabHoverMid.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabHoverRight.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabLeft.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabMenuCheckbox.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabMenuPin.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabMenuRadio.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabMenuTarget.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabMenuTargetHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabMid.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabRight.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/textEditorBorders.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/textEditorBorders.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/textEditorCorners.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/textEditorCorners.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/titlebarMid.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/toolbarMid.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tree_close.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tree_open.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/twistyClosed.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/twistyOpen.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/up.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/upActive.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/upHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/warningIcon.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/warningIcon.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/blank.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/buttonBg.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/buttonBgHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/close.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/closeHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/detach.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/detachHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/disable.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/disable.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/disableHover.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/disableHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/down.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/downActive.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/downHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/errorIcon-sm.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/errorIcon.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/errorIcon.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/firebug.css create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/firebug.html create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/firebug.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/group.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/infoIcon.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/infoIcon.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/loading_16.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/min.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/minHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/off.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/offHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/pixel_transparent.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/roundCorner.svg create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/search.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/search.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/shadow.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/shadow2.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/shadowAlpha.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/sprite.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tabHoverLeft.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tabHoverMid.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tabHoverRight.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tabLeft.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tabMenuCheckbox.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tabMenuPin.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tabMenuRadio.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tabMenuTarget.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tabMenuTargetHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tabMid.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tabRight.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/textEditorBorders.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/textEditorBorders.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/textEditorCorners.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/textEditorCorners.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/titlebarMid.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/toolbarMid.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tree_close.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tree_open.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/twistyClosed.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/twistyOpen.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/up.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/upActive.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/upHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/warningIcon.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/warningIcon.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/blank.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/buttonBg.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/buttonBgHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/detach.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/detachHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/disable.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/disable.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/disableHover.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/disableHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/down.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/downActive.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/downHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/errorIcon-sm.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/errorIcon.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/errorIcon.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/firebug-1.3a2.css create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/firebug.IE6.css create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/firebug.css create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/firebug.html create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/firebug.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/group.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/infoIcon.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/infoIcon.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/loading_16.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/min.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/minHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/off.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/offHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/pixel_transparent.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/roundCorner.svg create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/search.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/search.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/shadow.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/shadow2.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/shadowAlpha.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/sprite.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabHoverLeft.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabHoverMid.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabHoverRight.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabLeft.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabMenuCheckbox.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabMenuPin.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabMenuRadio.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabMenuTarget.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabMenuTargetHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabMid.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabRight.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/textEditorBorders.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/textEditorBorders.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/textEditorCorners.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/textEditorCorners.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/titlebarMid.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/toolbarMid.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tree_close.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tree_open.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/up.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/upActive.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/upHover.png create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/warningIcon.gif create mode 100755 php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/warningIcon.png create mode 100755 php/kindeditor_demo/kindeditor/lib/jquery.min.js create mode 100755 php/kindeditor_demo/kindeditor/lib/qunit/qunit.css create mode 100755 php/kindeditor_demo/kindeditor/lib/qunit/qunit.js create mode 100755 php/kindeditor_demo/kindeditor/license.txt create mode 100755 php/kindeditor_demo/kindeditor/package.json create mode 100755 php/kindeditor_demo/kindeditor/php/JSON.php create mode 100755 php/kindeditor_demo/kindeditor/php/demo.php create mode 100755 php/kindeditor_demo/kindeditor/php/file_manager_json.php create mode 100755 php/kindeditor_demo/kindeditor/php/upload_json.php create mode 100755 php/kindeditor_demo/kindeditor/plugins/anchor/anchor.js create mode 100755 php/kindeditor_demo/kindeditor/plugins/autoheight/autoheight.js create mode 100755 php/kindeditor_demo/kindeditor/plugins/baidumap/baidumap.js create mode 100755 php/kindeditor_demo/kindeditor/plugins/baidumap/index.html create mode 100755 php/kindeditor_demo/kindeditor/plugins/baidumap/map.html create mode 100755 php/kindeditor_demo/kindeditor/plugins/clearhtml/clearhtml.js create mode 100755 php/kindeditor_demo/kindeditor/plugins/code/code.js create mode 100755 php/kindeditor_demo/kindeditor/plugins/code/prettify.css create mode 100755 php/kindeditor_demo/kindeditor/plugins/code/prettify.js create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/emoticons.js create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/0.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/1.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/10.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/100.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/101.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/102.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/103.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/104.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/105.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/106.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/107.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/108.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/109.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/11.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/110.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/111.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/112.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/113.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/114.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/115.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/116.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/117.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/118.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/119.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/12.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/120.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/121.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/122.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/123.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/124.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/125.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/126.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/127.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/128.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/129.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/13.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/130.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/131.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/132.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/133.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/134.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/14.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/15.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/16.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/17.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/18.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/19.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/2.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/20.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/21.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/22.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/23.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/24.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/25.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/26.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/27.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/28.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/29.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/3.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/30.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/31.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/32.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/33.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/34.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/35.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/36.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/37.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/38.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/39.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/4.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/40.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/41.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/42.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/43.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/44.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/45.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/46.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/47.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/48.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/49.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/5.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/50.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/51.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/52.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/53.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/54.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/55.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/56.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/57.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/58.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/59.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/6.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/60.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/61.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/62.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/63.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/64.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/65.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/66.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/67.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/68.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/69.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/7.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/70.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/71.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/72.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/73.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/74.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/75.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/76.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/77.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/78.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/79.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/8.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/80.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/81.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/82.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/83.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/84.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/85.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/86.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/87.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/88.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/89.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/9.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/90.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/91.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/92.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/93.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/94.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/95.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/96.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/97.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/98.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/99.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/emoticons/images/static.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/filemanager/filemanager.js create mode 100755 php/kindeditor_demo/kindeditor/plugins/filemanager/images/file-16.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/filemanager/images/file-64.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/filemanager/images/folder-16.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/filemanager/images/folder-64.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/filemanager/images/go-up.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/fixtoolbar/fixtoolbar.js create mode 100755 php/kindeditor_demo/kindeditor/plugins/flash/flash.js create mode 100755 php/kindeditor_demo/kindeditor/plugins/image/image.js create mode 100755 php/kindeditor_demo/kindeditor/plugins/image/images/align_left.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/image/images/align_right.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/image/images/align_top.gif create mode 100755 php/kindeditor_demo/kindeditor/plugins/image/images/refresh.png create mode 100755 php/kindeditor_demo/kindeditor/plugins/insertfile/insertfile.js create mode 100755 php/kindeditor_demo/kindeditor/plugins/lineheight/lineheight.js create mode 100755 php/kindeditor_demo/kindeditor/plugins/link/link.js create mode 100755 php/kindeditor_demo/kindeditor/plugins/map/map.html create mode 100755 php/kindeditor_demo/kindeditor/plugins/map/map.js create mode 100755 php/kindeditor_demo/kindeditor/plugins/media/media.js create mode 100755 php/kindeditor_demo/kindeditor/plugins/multiimage/images/image.png create mode 100755 php/kindeditor_demo/kindeditor/plugins/multiimage/images/select-files-en.png create mode 100755 php/kindeditor_demo/kindeditor/plugins/multiimage/images/select-files-zh-CN.png create mode 100755 php/kindeditor_demo/kindeditor/plugins/multiimage/images/swfupload.swf create mode 100755 php/kindeditor_demo/kindeditor/plugins/multiimage/multiimage.js create mode 100755 php/kindeditor_demo/kindeditor/plugins/pagebreak/pagebreak.js create mode 100755 php/kindeditor_demo/kindeditor/plugins/plainpaste/plainpaste.js create mode 100755 php/kindeditor_demo/kindeditor/plugins/preview/preview.js create mode 100755 php/kindeditor_demo/kindeditor/plugins/quickformat/quickformat.js create mode 100755 php/kindeditor_demo/kindeditor/plugins/table/table.js create mode 100755 php/kindeditor_demo/kindeditor/plugins/template/html/1.html create mode 100755 php/kindeditor_demo/kindeditor/plugins/template/html/2.html create mode 100755 php/kindeditor_demo/kindeditor/plugins/template/html/3.html create mode 100755 php/kindeditor_demo/kindeditor/plugins/template/template.js create mode 100755 php/kindeditor_demo/kindeditor/plugins/wordpaste/wordpaste.js create mode 100755 php/kindeditor_demo/kindeditor/src/ajax.js create mode 100755 php/kindeditor_demo/kindeditor/src/cmd.js create mode 100755 php/kindeditor_demo/kindeditor/src/colorpicker.js create mode 100755 php/kindeditor_demo/kindeditor/src/config.js create mode 100755 php/kindeditor_demo/kindeditor/src/core.js create mode 100755 php/kindeditor_demo/kindeditor/src/dialog.js create mode 100755 php/kindeditor_demo/kindeditor/src/edit.js create mode 100755 php/kindeditor_demo/kindeditor/src/event.js create mode 100755 php/kindeditor_demo/kindeditor/src/footer.js create mode 100755 php/kindeditor_demo/kindeditor/src/header.js create mode 100755 php/kindeditor_demo/kindeditor/src/html.js create mode 100755 php/kindeditor_demo/kindeditor/src/main.js create mode 100755 php/kindeditor_demo/kindeditor/src/menu.js create mode 100755 php/kindeditor_demo/kindeditor/src/node.js create mode 100755 php/kindeditor_demo/kindeditor/src/range.js create mode 100755 php/kindeditor_demo/kindeditor/src/selector.js create mode 100755 php/kindeditor_demo/kindeditor/src/tabs.js create mode 100755 php/kindeditor_demo/kindeditor/src/toolbar.js create mode 100755 php/kindeditor_demo/kindeditor/src/uploadbutton.js create mode 100755 php/kindeditor_demo/kindeditor/src/widget.js create mode 100755 php/kindeditor_demo/kindeditor/test/ajax.html create mode 100755 php/kindeditor_demo/kindeditor/test/cmd.html create mode 100755 php/kindeditor_demo/kindeditor/test/cmd.js create mode 100755 php/kindeditor_demo/kindeditor/test/core.html create mode 100755 php/kindeditor_demo/kindeditor/test/core.js create mode 100755 php/kindeditor_demo/kindeditor/test/data/logo_180_30.gif create mode 100755 php/kindeditor_demo/kindeditor/test/dialog.html create mode 100755 php/kindeditor_demo/kindeditor/test/edit.html create mode 100755 php/kindeditor_demo/kindeditor/test/edit.js create mode 100755 php/kindeditor_demo/kindeditor/test/editor.html create mode 100755 php/kindeditor_demo/kindeditor/test/editor.js create mode 100755 php/kindeditor_demo/kindeditor/test/event.html create mode 100755 php/kindeditor_demo/kindeditor/test/event.js create mode 100755 php/kindeditor_demo/kindeditor/test/frame.html create mode 100755 php/kindeditor_demo/kindeditor/test/hidden.html create mode 100755 php/kindeditor_demo/kindeditor/test/html.html create mode 100755 php/kindeditor_demo/kindeditor/test/html.js create mode 100755 php/kindeditor_demo/kindeditor/test/index.html create mode 100755 php/kindeditor_demo/kindeditor/test/leak.html create mode 100755 php/kindeditor_demo/kindeditor/test/main.html create mode 100755 php/kindeditor_demo/kindeditor/test/menu.html create mode 100755 php/kindeditor_demo/kindeditor/test/menu.js create mode 100755 php/kindeditor_demo/kindeditor/test/navi.html create mode 100755 php/kindeditor_demo/kindeditor/test/node.html create mode 100755 php/kindeditor_demo/kindeditor/test/node.js create mode 100755 php/kindeditor_demo/kindeditor/test/quirkmode.html create mode 100755 php/kindeditor_demo/kindeditor/test/range.html create mode 100755 php/kindeditor_demo/kindeditor/test/range.js create mode 100755 php/kindeditor_demo/kindeditor/test/remote.html create mode 100755 php/kindeditor_demo/kindeditor/test/selector.html create mode 100755 php/kindeditor_demo/kindeditor/test/selector.js create mode 100755 php/kindeditor_demo/kindeditor/test/tabs.html create mode 100755 php/kindeditor_demo/kindeditor/test/toolbar.html create mode 100755 php/kindeditor_demo/kindeditor/test/toolbar.js create mode 100755 php/kindeditor_demo/kindeditor/test/total.html create mode 100755 php/kindeditor_demo/kindeditor/test/webdriver/KindEditorDriver.php create mode 100755 php/kindeditor_demo/kindeditor/test/webdriver/all-chrome.bat create mode 100755 php/kindeditor_demo/kindeditor/test/webdriver/all-firefox.bat create mode 100755 php/kindeditor_demo/kindeditor/test/webdriver/all-ie.bat create mode 100755 php/kindeditor_demo/kindeditor/test/webdriver/all.php create mode 100755 php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/README.md create mode 100755 php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriver.php create mode 100755 php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriverBase.php create mode 100755 php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriverContainer.php create mode 100755 php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriverElement.php create mode 100755 php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriverEnvironment.php create mode 100755 php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriverExceptions.php create mode 100755 php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriverSession.php create mode 100755 php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriverSimpleItem.php create mode 100755 php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/__init__.php create mode 100755 php/kindeditor_demo/kindeditor/test/webdriver/test-default.php create mode 100755 php/kindeditor_demo/kindeditor/test/webdriver/test-dialog.php create mode 100755 php/kindeditor_demo/kindeditor/test/webdriver/test-unittest.php create mode 100755 php/kindeditor_demo/kindeditor/test/widget.html create mode 100755 php/kindeditor_demo/kindeditor/themes/common/anchor.gif create mode 100755 php/kindeditor_demo/kindeditor/themes/common/blank.gif create mode 100755 php/kindeditor_demo/kindeditor/themes/common/flash.gif create mode 100755 php/kindeditor_demo/kindeditor/themes/common/loading.gif create mode 100755 php/kindeditor_demo/kindeditor/themes/common/media.gif create mode 100755 php/kindeditor_demo/kindeditor/themes/common/rm.gif create mode 100755 php/kindeditor_demo/kindeditor/themes/default/background.png create mode 100755 php/kindeditor_demo/kindeditor/themes/default/default.css create mode 100755 php/kindeditor_demo/kindeditor/themes/default/default.png create mode 100755 php/kindeditor_demo/kindeditor/themes/qq/editor.gif create mode 100755 php/kindeditor_demo/kindeditor/themes/qq/qq.css create mode 100755 php/kindeditor_demo/kindeditor/themes/simple/simple.css diff --git a/php/kindeditor_demo/css/article.css b/php/kindeditor_demo/css/article.css new file mode 100755 index 0000000..d7c1a58 --- /dev/null +++ b/php/kindeditor_demo/css/article.css @@ -0,0 +1,125 @@ +/*** 清楚间距 ***/ +*{ + margin: 0; + padding: 0; +} +/*** 设置字体--更新字体--字体抗锯齿 ***/ +body{ + font-family: 'Avenir Next'; + color: #000; + background: rgba(225,225,225,0.3); + -webkit-font-smoothing:antialiased;/**字体抗锯齿**/ +} + +/*** 链接重新设置 ***/ +a{ + color:#FFF; + text-decoration: none; + display: inline-block; + height: inherit; +} +a:hover{color:#f15a22;} +/****背景图片自适应*****/ +/*.main-code +{ + background: #444 url(../../../static/img/back.jpg); + background-attachment: fixed; + background-repeat: no-repeat; + background-size: cover; + background-position: center center; +}*/ + +.left-nav +{ + background: #444 url(../images/back.jpg); + /*background-attachment: fixed;*/ + background-repeat: no-repeat; + background-size: cover; + background-position: center center; + width: 20%; + height: 100%; + position:fixed; + top:0px; + left:0px; +} +.left-nav .left-summary + { + color: #FFFFFF; + font-size: 18px; + margin-left: 15px; + margin-top: 60%; + } + .left-nav .left-summary h5 + { + padding: 20px 0px; + } +.code-list{ + background: #FFFFFF; + float: right; + width: 80%; + color: #000; +} +.whow-search +{ + color: #fff; + border-color: #49be38;background: #4FC7BD;border-radius: 5px;width: 40px;text-align:center;margin:3px 3px;padding: 2px 3px; + position:fixed; + top:0px; + right:5px; + +} +.whow-search:hover{border-color: #418A84;background: #418A84;} +.code-search +{ + + color: #fff; + border-color: #49be38; + border-bottom: 4px solid; + background:#E7F0F0;border-radius: 3px;width: 80%;height:50px;text-align:center; + position:fixed; + top:0px; + right:0px; +} +.code-search>span{ + display:inline-block; + height: 40px; + line-height: 40px; + margin: 0 auto; + text-align: center; + padding: 0 5px; +} +.input-style{ + padding: 5px 15px; + font-size: 16px; + width: 160px; + border-radius: 10px; + background: #fff; + color: #535d92; + height: 20px; + line-height: 20px; + border: none; + outline:none; +} +.code-search .to-search{ + padding-left: 5px; +} +.code-search .hide-search{ + color: #fff; + height: 20px; + line-height: 20px; + padding: 0; + border-color: #49be38;background: #4FC7BD;border-radius: 5px;width: 40px;text-align:center;margin:3px 3px;padding: 0 3px; + position:fixed; + top:0px; + right:5px; +} +.code-search .hide-search:hover{border-color: #418A84;background: #418A84;} +.code-list-warper{width: 90%;padding-left: 5px;margin-top: 60px;} +.code-list-detail{border-top:1px solid #CCC;padding: 8px 0;clear: both;} +.list-left{width: 60%;float: left;margin: 5px 10px;} +.list-left span{padding-left: 40px;letter-spacing: 1px;font-size: 18px;} +.list-left h5{padding:3px;} +.list-left b{font-size: 16px;color: #ccc;margin: 0px 5px;} +.list-right{width: 30%;float: right;} +.list-right>a{float: right;margin-right: 20px;} +.list-right img{width: 150px;height: 80px;margin: 5px auto;} diff --git a/php/kindeditor_demo/demo_action.php b/php/kindeditor_demo/demo_action.php new file mode 100755 index 0000000..ed2b99f --- /dev/null +++ b/php/kindeditor_demo/demo_action.php @@ -0,0 +1,7 @@ +"; + echo "文章标题是:--------".$_POST['article_title']; + echo "
"; + echo "文章内容是是:-----".$_POST['article_content']; \ No newline at end of file diff --git a/php/kindeditor_demo/demo_add_article.html b/php/kindeditor_demo/demo_add_article.html new file mode 100755 index 0000000..50ee851 --- /dev/null +++ b/php/kindeditor_demo/demo_add_article.html @@ -0,0 +1,171 @@ + + + + + + + + + + + + + +kindeditor在qq风格上做了修改 + + +
+
+
+

Kindeditor

+
+

用法解释

+

官网

+
+
+
+ +
+ 发布文章 +
+
+ 注:这个demo 实在qq风格的基础上做了改造 +
+ 113行可以对图标进行添加或删除,比如不需要百度地图删掉 'baidumap',  即可 +
+
+
TITLE:
+
+ CONTENT:
+ + +
+
+ +
+ +
+
+ + diff --git a/php/kindeditor_demo/images/back.jpg b/php/kindeditor_demo/images/back.jpg new file mode 100755 index 0000000000000000000000000000000000000000..4217295f43a8251d7e1c2a2d0d0d23c8f04cf09c GIT binary patch literal 115446 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

x|8_BvU=40Sm9-t&B>u{T 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Ðu=?|XD%<71^ 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

J5_<7}n$ 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 Ee`n5LMF0Q* literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/js/jquery-1.7.2.min.js b/php/kindeditor_demo/js/jquery-1.7.2.min.js new file mode 100755 index 0000000..16ad06c --- /dev/null +++ b/php/kindeditor_demo/js/jquery-1.7.2.min.js @@ -0,0 +1,4 @@ +/*! jQuery v1.7.2 jquery.com | jquery.org/license */ +(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cu(a){if(!cj[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),b.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write((f.support.boxModel?"":"")+""),cl.close();d=cl.createElement(a),cl.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ck)}cj[a]=e}return cj[a]}function ct(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function cs(){cq=b}function cr(){setTimeout(cs,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;e=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?+d:j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){if(typeof c!="string"||!c)return null;var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
a",d=p.getElementsByTagName("*"),e=p.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=p.getElementsByTagName("input")[0],b={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:p.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,pixelMargin:!0},f.boxModel=b.boxModel=c.compatMode==="CSS1Compat",i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete p.test}catch(r){b.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",function(){b.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),i.setAttribute("name","t"),p.appendChild(i),j=c.createDocumentFragment(),j.appendChild(p.lastChild),b.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,j.removeChild(i),j.appendChild(p);if(p.attachEvent)for(n in{submit:1,change:1,focusin:1})m="on"+n,o=m in p,o||(p.setAttribute(m,"return;"),o=typeof p[m]=="function"),b[n+"Bubbles"]=o;j.removeChild(p),j=g=h=p=i=null,f(function(){var d,e,g,h,i,j,l,m,n,q,r,s,t,u=c.getElementsByTagName("body")[0];!u||(m=1,t="padding:0;margin:0;border:",r="position:absolute;top:0;left:0;width:1px;height:1px;",s=t+"0;visibility:hidden;",n="style='"+r+t+"5px solid #000;",q="

"+""+"
",d=c.createElement("div"),d.style.cssText=s+"width:0;height:0;position:static;top:0;margin-top:"+m+"px",u.insertBefore(d,u.firstChild),p=c.createElement("div"),d.appendChild(p),p.innerHTML="
t
",k=p.getElementsByTagName("td"),o=k[0].offsetHeight===0,k[0].style.display="",k[1].style.display="none",b.reliableHiddenOffsets=o&&k[0].offsetHeight===0,a.getComputedStyle&&(p.innerHTML="",l=c.createElement("div"),l.style.width="0",l.style.marginRight="0",p.style.width="2px",p.appendChild(l),b.reliableMarginRight=(parseInt((a.getComputedStyle(l,null)||{marginRight:0}).marginRight,10)||0)===0),typeof p.style.zoom!="undefined"&&(p.innerHTML="",p.style.width=p.style.padding="1px",p.style.border=0,p.style.overflow="hidden",p.style.display="inline",p.style.zoom=1,b.inlineBlockNeedsLayout=p.offsetWidth===3,p.style.display="block",p.style.overflow="visible",p.innerHTML="
",b.shrinkWrapBlocks=p.offsetWidth!==3),p.style.cssText=r+s,p.innerHTML=q,e=p.firstChild,g=e.firstChild,i=e.nextSibling.firstChild.firstChild,j={doesNotAddBorder:g.offsetTop!==5,doesAddBorderForTableAndCells:i.offsetTop===5},g.style.position="fixed",g.style.top="20px",j.fixedPosition=g.offsetTop===20||g.offsetTop===15,g.style.position=g.style.top="",e.style.overflow="hidden",e.style.position="relative",j.subtractsBorderForOverflowNotVisible=g.offsetTop===-5,j.doesNotIncludeMarginInBodyOffset=u.offsetTop!==m,a.getComputedStyle&&(p.style.marginTop="1%",b.pixelMargin=(a.getComputedStyle(p,null)||{marginTop:0}).marginTop!=="1%"),typeof d.style.zoom!="undefined"&&(d.style.zoom=1),u.removeChild(d),l=p=d=null,f.extend(b,j))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e1,null,!1)},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){var d=2;typeof a!="string"&&(c=a,a="fx",d--);if(arguments.length1)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,f.prop,a,b,arguments.length>1)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.type]||f.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.type]||f.valHooks[g.nodeName.toLowerCase()];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h,i=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;i=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/(?:^|\s)hover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function( +a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler,g=p.selector),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&j.push({elem:this,matches:d.slice(e)});for(k=0;k0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));o.match.globalPOS=p;var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/]","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
","
"]),f.fn.extend({text:function(a){return f.access(this,function(a){return a===b?f.text(this):this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f +.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){return f.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(;d1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||f.isXMLDoc(a)||!bc.test("<"+a.nodeName+">")?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g,h,i,j=[];b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);for(var k=0,l;(l=a[k])!=null;k++){typeof l=="number"&&(l+="");if(!l)continue;if(typeof l=="string")if(!_.test(l))l=b.createTextNode(l);else{l=l.replace(Y,"<$1>");var m=(Z.exec(l)||["",""])[1].toLowerCase(),n=bg[m]||bg._default,o=n[0],p=b.createElement("div"),q=bh.childNodes,r;b===c?bh.appendChild(p):U(b).appendChild(p),p.innerHTML=n[1]+l+n[2];while(o--)p=p.lastChild;if(!f.support.tbody){var s=$.test(l),t=m==="table"&&!s?p.firstChild&&p.firstChild.childNodes:n[1]===""&&!s?p.childNodes:[];for(i=t.length-1;i>=0;--i)f.nodeName(t[i],"tbody")&&!t[i].childNodes.length&&t[i].parentNode.removeChild(t[i])}!f.support.leadingWhitespace&&X.test(l)&&p.insertBefore(b.createTextNode(X.exec(l)[0]),p.firstChild),l=p.childNodes,p&&(p.parentNode.removeChild(p),q.length>0&&(r=q[q.length-1],r&&r.parentNode&&r.parentNode.removeChild(r)))}var u;if(!f.support.appendChecked)if(l[0]&&typeof (u=l.length)=="number")for(i=0;i1)},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=by(a,"opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bu.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(by)return by(a,c)},swap:function(a,b,c){var d={},e,f;for(f in b)d[f]=a.style[f],a.style[f]=b[f];e=c.call(a);for(f in b)a.style[f]=d[f];return e}}),f.curCSS=f.css,c.defaultView&&c.defaultView.getComputedStyle&&(bz=function(a,b){var c,d,e,g,h=a.style;b=b.replace(br,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b))),!f.support.pixelMargin&&e&&bv.test(b)&&bt.test(c)&&(g=h.width,h.width=c,c=e.width,h.width=g);return c}),c.documentElement.currentStyle&&(bA=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f==null&&g&&(e=g[b])&&(f=e),bt.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),by=bz||bA,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0?bB(a,b,d):f.swap(a,bw,function(){return bB(a,b,d)})},set:function(a,b){return bs.test(b)?b+"px":b}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bq.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bp,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bp.test(g)?g.replace(bp,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){return f.swap(a,{display:"inline-block"},function(){return b?by(a,"margin-right"):a.style.marginRight})}})}),f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)}),f.each({margin:"",padding:"",border:"Width"},function(a,b){f.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bx[d]+b]=e[d]||e[d-2]||e[0];return f}}});var bC=/%20/g,bD=/\[\]$/,bE=/\r?\n/g,bF=/#.*$/,bG=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bH=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bI=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bJ=/^(?:GET|HEAD)$/,bK=/^\/\//,bL=/\?/,bM=/)<[^<]*)*<\/script>/gi,bN=/^(?:select|textarea)/i,bO=/\s+/,bP=/([?&])_=[^&]*/,bQ=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bR=f.fn.load,bS={},bT={},bU,bV,bW=["*/"]+["*"];try{bU=e.href}catch(bX){bU=c.createElement("a"),bU.href="",bU=bU.href}bV=bQ.exec(bU.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bR)return bR.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bM,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bN.test(this.nodeName)||bH.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bE,"\r\n")}}):{name:b.name,value:c.replace(bE,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b$(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b$(a,b);return a},ajaxSettings:{url:bU,isLocal:bI.test(bV[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bW},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bY(bS),ajaxTransport:bY(bT),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?ca(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cb(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bF,"").replace(bK,bV[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bO),d.crossDomain==null&&(r=bQ.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bV[1]&&r[2]==bV[2]&&(r[3]||(r[1]==="http:"?80:443))==(bV[3]||(bV[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bZ(bS,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bJ.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bL.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bP,"$1_="+x);d.url=y+(y===d.url?(bL.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bW+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bZ(bT,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)b_(g,a[g],c,e);return d.join("&").replace(bC,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cc=f.now(),cd=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cc++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=typeof b.data=="string"&&/^application\/x\-www\-form\-urlencoded/.test(b.contentType);if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cd.test(b.url)||e&&cd.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cd,l),b.url===j&&(e&&(k=k.replace(cd,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ce=a.ActiveXObject?function(){for(var a in cg)cg[a](0,1)}:!1,cf=0,cg;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ch()||ci()}:ch,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ce&&delete cg[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n);try{m.text=h.responseText}catch(a){}try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cf,ce&&(cg||(cg={},f(a).unload(ce)),cg[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cj={},ck,cl,cm=/^(?:toggle|show|hide)$/,cn=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,co,cp=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cq;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(ct("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);f.fn[a]=function(e){return f.access(this,function(a,e,g){var h=cy(a);if(g===b)return h?c in h?h[c]:f.support.boxModel&&h.document.documentElement[e]||h.document.body[e]:a[e];h?h.scrollTo(d?f(h).scrollLeft():g,d?g:f(h).scrollTop()):a[e]=g},a,e,arguments.length,null)}}),f.each({Height:"height",Width:"width"},function(a,c){var d="client"+a,e="scroll"+a,g="offset"+a;f.fn["inner"+a]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,c,"padding")):this[c]():null},f.fn["outer"+a]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,c,a?"margin":"border")):this[c]():null},f.fn[c]=function(a){return f.access(this,function(a,c,h){var i,j,k,l;if(f.isWindow(a)){i=a.document,j=i.documentElement[d];return f.support.boxModel&&j||i.body&&i.body[d]||j}if(a.nodeType===9){i=a.documentElement;if(i[d]>=i[e])return i[d];return Math.max(a.body[e],i[e],a.body[g],i[g])}if(h===b){k=f.css(a,c),l=parseFloat(k);return f.isNumeric(l)?l:k}f(a).css(c,h)},c,a,arguments.length,null)}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/.gitignore b/php/kindeditor_demo/kindeditor/.gitignore new file mode 100755 index 0000000..6bf256e --- /dev/null +++ b/php/kindeditor_demo/kindeditor/.gitignore @@ -0,0 +1,15 @@ +*~ +~* +*.diff +*.patch +*.bak +.DS_Store +Thumbs.db +.project +.*proj +.svn/ +*.swp +dist/ +node_modules/ +_build/ +attached/* diff --git a/php/kindeditor_demo/kindeditor/Gruntfile.js b/php/kindeditor_demo/kindeditor/Gruntfile.js new file mode 100755 index 0000000..2de20a9 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/Gruntfile.js @@ -0,0 +1,119 @@ + +module.exports = function(grunt) { + +var BANNER = '/* <%= pkg.name %> <%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd") %>), Copyright (C) kindsoft.net, Licence: http://kindeditor.net/license.php */\r\n'; + +var SRC_FILES = [ + 'src/header.js', + 'src/core.js', + 'src/config.js', + 'src/event.js', + 'src/html.js', + 'src/selector.js', + 'src/node.js', + 'src/range.js', + 'src/cmd.js', + 'src/widget.js', + 'src/edit.js', + 'src/toolbar.js', + 'src/menu.js', + 'src/colorpicker.js', + 'src/uploadbutton.js', + 'src/dialog.js', + 'src/tabs.js', + 'src/ajax.js', + 'src/main.js', + 'src/footer.js', +]; + +var PLUGIN_FILES = [ + 'plugins/anchor/anchor.js', + 'plugins/autoheight/autoheight.js', + 'plugins/baidumap/baidumap.js', + 'plugins/map/map.js', + 'plugins/clearhtml/clearhtml.js', + 'plugins/code/code.js', + 'plugins/emoticons/emoticons.js', + 'plugins/filemanager/filemanager.js', + 'plugins/flash/flash.js', + 'plugins/image/image.js', + 'plugins/insertfile/insertfile.js', + 'plugins/lineheight/lineheight.js', + 'plugins/link/link.js', + 'plugins/map/map.js', + 'plugins/media/media.js', + 'plugins/multiimage/multiimage.js', + 'plugins/pagebreak/pagebreak.js', + 'plugins/plainpaste/plainpaste.js', + 'plugins/preview/preview.js', + 'plugins/quickformat/quickformat.js', + 'plugins/table/table.js', + 'plugins/template/template.js', + 'plugins/wordpaste/wordpaste.js', + 'plugins/fixtoolbar/fixtoolbar.js' +]; + +var pkg = grunt.file.readJSON('package.json'); + +var lang = grunt.option('lang') || 'en'; + +grunt.initConfig({ + pkg : pkg, + concat : { + options : { + process : function(src, filepath) { + src = src.replace(/\$\{VERSION\}/g, pkg.version + ' (' + grunt.template.today('yyyy-mm-dd') + ')'); + src = src.replace(/\$\{THISYEAR\}/g, grunt.template.today('yyyy')); + src = src.replace(/\/\*\*(\r\n|\n)[\s\S]*?\*\//g, ''); + src = src.replace(/(^|\s)\/\/.*$/mg, ''); + src = src.replace(/(\r\n|\n)\/\*\*\/.*(\r\n|\n)/g, ''); + src = src.replace(/[ \t]+$/mg, ''); + src = src.replace(/(\r\n|\n){2,}/g, '$1'); + return src; + } + }, + build : { + src : SRC_FILES.concat('lang/' + lang + '.js').concat(PLUGIN_FILES), + dest : 'kindeditor-all.js' + } + }, + uglify : { + options : { + banner : BANNER, + }, + build : { + src : '<%= pkg.filename %>-all.js', + dest : '<%= pkg.filename %>-all-min.js' + } + }, + compress : { + main : { + options: { + archive: 'dist/<%= pkg.filename %>-<%= pkg.version %>-' + lang + '.zip', + }, + files: [ + {src: ['asp/**'], dest: 'kindeditor/'}, + {src: ['asp.net/**'], dest: 'kindeditor/'}, + {src: ['attached'], dest: 'kindeditor/'}, + {src: ['jsp/**'], dest: 'kindeditor/'}, + {src: ['lang/**'], dest: 'kindeditor/'}, + {src: ['php/**'], dest: 'kindeditor/'}, + {src: ['plugins/**'], dest: 'kindeditor/'}, + {src: ['themes/**'], dest: 'kindeditor/'}, + {src: ['kindeditor*.js'], dest: 'kindeditor/'}, + {src: ['license.txt'], dest: 'kindeditor/'}, + ] + } + } +}); + +grunt.loadNpmTasks('grunt-contrib-concat'); +grunt.loadNpmTasks('grunt-contrib-uglify'); +grunt.loadNpmTasks('grunt-contrib-compress'); + +grunt.registerTask('build', ['concat', 'uglify']); +grunt.registerTask('zip', ['build', 'compress']); + +grunt.registerTask('default', 'build'); + +}; diff --git a/php/kindeditor_demo/kindeditor/README.md b/php/kindeditor_demo/kindeditor/README.md new file mode 100755 index 0000000..ae2c630 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/README.md @@ -0,0 +1,14 @@ +## What is KindEditor? + +KindEditor is a lightweight, Open Source(LGPL), cross browser, web based WYSIWYG HTML editor. KindEditor has the ability to convert standard textareas to rich text editing. + +## Official site + +http://kindeditor.org/ + +## Contributors + +* Timon Lin +* daif alotaibi (http://daif.net/) : Arabic Translation +* fisker (https://github.com/fisker) : QQ style theme +* composite (https://github.com/composite) : Korean Translation \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/changelog.txt b/php/kindeditor_demo/kindeditor/changelog.txt new file mode 100755 index 0000000..fc92257 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/changelog.txt @@ -0,0 +1,663 @@ +####################################################################### +# +# KindEditor 变更记录 +# +####################################################################### + +ver 4.1.11 (2016-03-31) +* 新增: 俄语语言包,感谢Valery Votintsev (http://codersclub.org/)。 +* 改善: 语言包文件名标准化,zh_CN -> zh-CN, zh_TW -> zh-TW。 +* Bugfix: [IE6] 当前页面设置了document.domain,销毁编辑器会报错。 +* Bugfix: 行首全角空格被过滤。 +* Bugfix: 修复多语言包的一些小错误。 +* Bugfix: [IE11] 有些设备报错不能显示,对象不支持attachEvent属性或方法。 +* Bugfix: retina屏幕上按钮裂开。 +* Bugfix: 编辑图片后点击插入图片,弹出两个dialog。 + +ver 4.1.10 (2013-11-23) +* Bugfix: 兼容IE11。 +* Bugfix: [IE6-7] 上传按钮界面错乱。 +* Bugfix: 引入kindeditor-all.js后开启自动高度插件会报错。 +* Bugfix: ®来回切换代码模式后变成(R)。 +* Bugfix: 字体、文字大小、颜色等操作有toogle效果。 +* Bugfix: 非IE设置returnValue和cancelBubble。 +* Bugfix: 特定的字符导致浏览器死循环。 + +ver 4.1.9 (2013-10-08) +* Bugfix: 选中后无法添加超级链接。 +* Bugfix: 自动高度插件无法在多个编辑器上使用。 + +ver 4.1.8 (2013-10-06) +* 新增: kindeditor-all.js包含自动高度插件。 +* 新增: K.html(expr, val),K.appendHtml(expr, val),K.insertHtml(expr, val)接口。 +* 改善: IE9+都使用W3C Range。 +* 改善: 页面加载完成后也可以触发KindEditor.ready。 +* 改善: getAttributeNode已不赞成使用,用getAttribute替代。 +* Bugfix: 有些浏览器上点击边缘,可能无法弹出文件选择框。 +* Bugfix: embed宽高无法用百分比设置。 +* Bugfix: [Firefox] 输入几个文字,切换到源代码模式再切换回来,插入图片报错。 +* Bugfix: 自动高度插件高度只增不减,感谢Github用户wyqbailey贡献。 +* Bugfix: editor.html(val)的val参数为null或undefined时报错。 +* Bugfix: [IE10] 单独调用组件-上传图片弹出框,需要点击两次选择图片按钮才能弹出窗体。 +* Bugfix: 代码模式下输入带连续多个空格的标签,有些浏览器无响应。 +* Bugfix: [IE] 当两个A标签并排在一起中间没有别的内容,修改后面的链接地址时,前面的链接地址也被改掉。 +* Bugfix: 页面同时引入SWFUpload,多图上传会失败。 +* Bugfix: 插入分页符,有时候出现复制HTML代码的现象。 +* Bugfix: 编辑图片后丢失class、id等属性。 +* Bugfix: 在编辑器中输入值,页面提交跳转后,按浏览器的后退按钮,就出现__kindeditor_bookmark_start_0。 +* Bugfix: 全屏后和还原后光标没有选中之前光标的位置。 +* Bugfix: 特定环境下有时候出现两个弹出框。 +* Bugfix: [IE] 编辑表格后焦点跳到顶部。 +* Bugfix: [IE] 先选中图片后居中,再左对齐,光标跳到顶部。 + +ver 4.1.7 (2013-04-21) +* Bugfix: 取消全屏后没有恢复到原来大小,调整窗口大小后宽高变成全屏宽高。 +* Bugfix: [IE] 删除图片、Flash、视频后立即点击图片按钮出错。 +* Bugfix: [IE8] 源代码模式下输入会丢失type属性。 +* Bugfix: [IE] 输入几个文字,切换到源代码模式再切换回来,插入图片报错。 +* Bugfix: 插入5x5表格,A1向下合并两次,再点到A2,向下合并报错。 + +ver 4.1.6 (2013-03-24) +* 新增: 韩国语语言包,感谢Github用户composite贡献。 +* 新增: allowImageRemote初始化参数,可隐藏网络图片标签。 +* 改善: 插入程序代码添加是否为空的判断。 +* Bugfix: [IE9] 在frame里调用编辑器,关闭批量上传dialog时浏览器会崩溃。 +* Bugfix: 插入图片后输入文字,文字加粗后取消加粗,图片会被删除。 +* Bugfix: [IE] 工具栏被图片选中标记覆盖时有时候无法操作,比如居中对齐后再左对齐。 +* Bugfix: 全屏ESC快捷键默认未开启,但图标提示还包含ESC。 +* Bugfix: 图片上传后的url包含&时会被转换成&。 +* Bugfix: [IE] 移除编辑器后点击页面出现没有权限错误。 +* Bugfix: [IE] 输入几个文字,调用editor.html(val)后,插入表情报错。 +* Bugfix: 调用editor.resize(),退出全屏后,高度没恢复成原来的大小。 + +ver 4.1.5 (2013-01-20) +* 新增: zIndex初始化参数,可指定弹出层的z-index。 +* Bugfix: 复制粘贴3.x版本生成的文章时,可能会出现多余的空行。 +* Bugfix: 非IE浏览器插入图片或粘贴文本后,可视范围没有自动滚动到光标当前显示的位置。 +* Bugfix: [IE] 工具栏被图片选中标记覆盖时不能操作。 +* Bugfix: [Firefox] 每次按回车都会显示TypeError。 +* Bugfix: [Chrome] 纯文本粘贴1个空行会变成没有空行或者2个空行。 +* Bugfix: [IE9] input标签会丢失checked属性。 +* Bugfix: [IE8-] 未能隐藏display为none的input/select/button。 + +ver 4.1.4 (2012-11-11) +* 改善: 弹出框能够跟随滚动条滚动居中显示。 +* Bugfix: 服务器没有配置默认index.html时,百度动态地图无法加载。 +* Bugfix: 点击图片属性、超级链接属性时,冒号变成%3A。 +* Bugfix: 当页面里面有jQuery的uploadify插件时,无法连续上传。 +* Bugfix: URL包含中文时,就会变成乱码。 +* Bugfix: [Firefox] 编辑链接后回车换行,在新的段落输入内容带上面那个链接。 +* Bugfix: 繁体语言包缺少uploadSuccess属性。 +* Bugfix: [Firefox] 编辑3.x版本生成的文章时,可能会出现多余的空行。 + +ver 4.1.3 (2012-10-14) +* 新增: 百度地图可插入iframe动态地图。 +* 新增: pagebreakHtml初始化参数,可指定分页符HTML。 +* 改善: 重复执行K.create时只创建一次。 +* Bugfix: [IE] 只显示本地上传Tab时,打开图片弹出框报错。 +* Bugfix: 点击全屏后再切换回来,有时候出现JS错误。 +* Bugfix: K.addUnit(val, unit)第二个参数不起作用。 +* Bugfix: &会转义成&这样超链接就不能访问。 +* Bugfix: 表情预览失效。 +* Bugfix: [IE9] 多文件上传时不显示上传按钮。 +* Bugfix: [Chrome] 创建弹出框时,Console提示没有访问权限。 +* Bugfix: URL包含$字符时,生成错误的HTML代码。 + +ver 4.1.2 (2012-07-21) +* 新增: K.remove(expr)函数,可移除多个编辑器,expr为选择器或DOM对象。 +* 新增: K.sync(expr)函数,可同步多个编辑器,expr为选择器或DOM对象。 +* 新增: K.create(expr)、K(expr)等函数可以直接传入jQuery对象。 +* 新增: filePostName初始化参数,可指定上传文件form名称。 +* 新增: fillDescAfterUploadImage初始化参数,true时图片上传成功后切换到图片编辑标签。 +* 新增: afterSelectFile初始化参数,从图片空间选择后执行的回调函数。 +* 新增: K.NodeClass,K.RangeClass,K.CmdClass,K.EditClass,K.MenuClass等接口。 +* 新增: plugin.imageDialog(options)添加showLocal和showRemote参数,值为false时分别隐藏网络图片和本地上传。 +* 新增: afterUpload新增data和name参数,分别为后端返回的JSON数据和插件名称。 +* 变更: fullscreenShortcut默认值改成false,默认不启用ESC快捷键全屏。 +* 改善: 多图上传时,允许用户post自定义参数到服务器。 +* Bugfix: [Firefox] 居中后输入几个文字回车换行,内容被全选。 +* Bugfix: 批量上传无法执行afterUpload这个回调,普通上传可以执行。 +* Bugfix: 页面中存在其它SWFUpload,批量上传出现冲突。 +* Bugfix: IE8怪异模式下先打开弹出框关闭,用滚轮到顶或到底,会出现脚本错误。 +* Bugfix: 图片src为图片数据(base64 data)时,无法正常显示。 +* Bugfix: 在pre标签里无法粘贴内容。 +* Bugfix: KNode.show()和hide(),display都变成block。 +* Bugfix: 版权标识©来回切换代码模式后变成(C)。 +* Bugfix: 重新创建KNode后,data方法无法取得数据。 +* Bugfix: K.create函数未找到目标textarea时报错。 +* Bugfix: 右下角拖动,松开鼠标后还可以继续拖动。 +* Bugfix: 右键编辑表格,插入行和列时有时候错乱。 + +ver 4.1.1 (2012-06-10) +* 新增: extraFileUploadParams初始化参数,文件上传时,支持添加别的参数一并传到服务器。 +* 变更: filterMode默认值改成true,根据htmlTags配置过滤HTML代码。 +* Bugfix: [Chrome] 粘贴内容代码中出现white-space:nowrap导致不换行。 +* Bugfix: [IE6] 本地图片上传按钮错位。 +* Bugfix: 开启过滤模式后,预览内容显示KindEditor。 + +ver 4.1 (2012-05-12) +* 新增: 批量图片上传功能(multiimage)。 +* 新增:地图默认用百度地图(baidumap)。 +* 新增: QQ邮箱风格(贡献者:https://github.com/fisker)。 +* 新增: formatUploadUrl初始化参数,false时不会自动格式化上传后的URL。 +* 新增: fullscreenShortcut初始化参数,false时禁用ESC全屏快捷键。 +* 改善: uploadbutton新增form、target参数,上传图片时可提交其它控件。 +* 改善: K().children()直接返回KNode对象,原来是返回Array。 +* 改善: K.create()支持多个textarea,新增KindEditor.instances。 +* 改善: Opera 最新版本支持BR换行。 +* 改善: 当前页面的语言方向为rtl时,编辑区域也自动设置rtl。 +* 改善: PHP写入临时文件失败,提示详细错误。 +* Bugfix: [IE9] 上传图片的弹出窗口,最下方的“确定”“取消”会错位,跑到跟“图片说明”文本框的后面。 +* Bugfix: FF、Chrome、Opera等行首全角空格被过滤,只有IE没问题。 +* Bugfix: 图片正在上传时,连续点击确定按钮,会重复提交表单。 +* Bugfix: [WEBKIT] 在BR换行模式下,需要两次回车才能换行。 +* Bugfix: [IE9] 在BR换行模式下,在编辑器中回车之后,光标仍然还在本行,不会移动到下一行。 +* Bugfix: noscript里的HTML代码会被转移字符。 +* Bugfix: [ASP] 文件管理对大小写敏感,大写的文件扩展名会识别不出图片。 +* Bugfix: 浏览文件窗口里的目录和文件图标被拉伸,看起来比较模糊。 +* Bugfix: 带有超链接的图片删除以后,源代码里面还有A标签。 +* Bugfix: 通过文件管理器插入本地附件时,URL可能出现连续两个斜线。 + +ver 4.0.6 (2012-03-18) +* 新增: imageTabIndex初始化参数,可设置插入图片弹出层的默认显示标签。 +* 新增: allowFileUpload初始化参数,可设置是否显示插入文件弹出层里的上传按钮。 +* 新增: KNode类增加eq方法。 +* 改善: 改进弹出框样式。 +* 改善: 上传图片不选择文件提交时,在浏览器端验证并提示。 +* 改善: 优化自动排版,块元素的第一个子节点是图片时不加缩进。 +* 改善: 编辑表格时,点击文档会关闭取色器。 +* Bugfix: [IE] 先选中图片,编辑图片后关闭Dialog,有时候会出现脚本错误。 +* Bugfix: 修改plugins目录名,无法显示plugins目录下的图片。 +* Bugfix: [IE] 上传图片后,进度条一直处于加载状态。 +* Bugfix: [IE] 上传文件失败后,进度条一直处于加载状态。 +* Bugfix: form添加onsubmit="return false;",提交表单,编辑器转到代码模式就出错。 +* Bugfix: [FF] 按下全屏按钮,恢复到原来大小后没有滚动条。 +* Bugfix: 自动获取图片尺寸时,有时候得到的尺寸不准确。 +* Bugfix: [IE] 在跨域的frame里调用编辑器,会出现权限错误。 +* Bugfix: 全屏后form失去自动提交,reset功能也失效。 +* Bugfix: 已经引入的default.css带时间戳时会重复加载CSS。 + +ver 4.0.5 (2012-01-15) +* Bugfix: 页面添加 content="IE=EmulateIE7" 后,修改颜色、行距之类的操作全部失效。 +* Bugfix: 后退(Ctrl+Z)时光标错乱。 +* Bugfix: 通过粘贴纯文本框粘贴时,所有空格都变成 。 +* Bugfix: pasteType参数为1时,粘贴内容,多个空格变成一个空格。 +* Bugfix: [FF] 上传图片后,总是出现正在加载的样式。 +* Bugfix: [WEBKIT] event.layerX and event.layerY are broken and deprecated in WebKit. +* Bugfix: pasteType为1(纯文本粘贴模式)时,粘贴的内容会换行。 +* Bugfix: 在iOS5上无法使用编辑器。 +* Bugfix: 单独调用dialog时默认不显示阴影。 +* Bugfix: 初始化编辑器时,在afterChange回调函数里无法得到this.edit对象。 + +ver 4.0.4 (2011-12-11) +* 新增: 阿拉伯语语言包。 +* 改善: 上传文件时显示上传中提示。 +* 改善: JSON解析失败时,通过弹出层显示服务器返回的HTML页面。 +* 改善: [IE] 弹出框支持阴影效果。 +* Bugfix: 浏览器使用有些插件时,上传文件提示不正确。 +* Bugfix: 单独调用图片功能时,点击重置大小图标报错。 +* Bugfix: 设置了参数filterMode:true,分页符就会丢失样式。 +* Bugfix: [FF] 撤销全屏后页面会滚动到顶部。 +* Bugfix: [ASP] demo.asp没有指定编码,导致提交后HTML出现乱码。 +* Bugfix: 单独调用上传按钮时,无法与旁边输入框对齐。 +* Bugfix: [WEBKIT] 在图片、视频、flash等前一个光标处右键,在不选中节点的状态下也能弹出修改属性。 +* Bugfix: [IE] 编辑器无内容,加粗,切换到代码模式,再回到可视化模式,加粗,JS报错。 +* Bugfix: [IE] 插入,会自动变为 。 +* Bugfix: [WEBKIT] 点击粗体后丢失光标。 +* Bugfix: [OPERA] 切换到代码模式后不显示部分工具栏图标。 +* Bugfix: del标签被定义在块级元素里,导致格式化HTML时自动换行。 +* Bugfix: 开启过滤模式,获取HTML时删除线被过滤。 +* Bugfix: [IE] 两张相邻图片添加超级链接,修改其中一个链接,另外一个链接也会被修改。 +* Bugfix: 内嵌脚本的小于号会被转义导致脚本错误。 +* Bugfix: 分页符在不同浏览器下生成的HTML代码不一致。 +* Bugfix: [IE6-7] 插入URL里有大写字符的图片,右键点击选择图片属性,更改图片属性后图片不能显示。 + +ver 4.0.3 (2011-11-04) +* Bugfix: [IE] 残留range.dump()调试代码,导致粘贴时报错。 +* Bugfix: [IE] 存在menu全局变量,可能发生冲突。 +* Bugfix: [IE] 单元格里没有内容时显示不正常。 +* Bugfix: 连续按粗体按钮时会生成很多strong。 +* Bugfix: 初始化编辑器后,按下粗体按钮,焦点不在

标签里。 +* Bugfix: [WEBKIT] 设定图片右对齐后,无法选取图片节点。 +* Bugfix: [IE] 回车,按下tab键,光标在下一行显示。 +* Bugfix: [IE] textarea的高度小于工具栏高度时JS报错。 + +ver 4.0.2 (2011-10-30) +* 新增: 上传按钮新增afterError回调函数,可定制JSON错误。 +* Bugfix: [FF] 在页面上设置iframe {overflow:hidden;} ,编辑区域不出现滚动条。 +* Bugfix: 浏览服务器插件,文件名很长的时候会换行。 +* Bugfix: [IE6-7] 在form里引入js的时候出现JS错误。 +* Bugfix: [IE] 当编辑器为空时,输入任意字符,然后点击表单的重置按钮,再点击页面空白处,出现JS错误。 +* Bugfix: [IE8] 设置X-UA-Compatible=IE7,有时候无法加载编辑器。 +* Bugfix: a标签同时有name和href属性时,丢失name以外的属性。 +* Bugfix: 连续调用多个ready函数时,第4个ready无法执行。 +* Bugfix: 插入多媒体后,右键点击不会弹出菜单。 +* Bugfix: 启用纯文本黏贴后,段落首尾都会出现>符号。 +* Bugfix: [IE] 点击标题、字体、文字大小,编辑区域失去选中状态。 +* Bugfix: [FF,WEBKIT] 连续换行几次,切换到源代码,再切换到可视化模式,没有换行效果。 +* Bugfix: [WEBKIT] 选择几个文字,点击上标或下标功能,上下标格式不会被应用。 +* Bugfix: 加载编辑器后残留多余的div标签。 +* Bugfix: 页面上包含跨域iframe的时候JS报错。 +* Bugfix: 页面刷新后,与第一次访问加载的编译器高度不一致。 +* Bugfix: [IE6] 弹出层无法遮住selectbox。 +* Bugfix: [FF] 提交后退后,编辑器数据不保存。 +* Bugfix: 选择粗体,取消粗体再应用粗体(即点两下粗体),则发现粗体、倾斜、下划线功能失效,无法选择。 +* Bugfix: [WEBKIT] 置入Issue 269中的HTML,全选,点击删除格式,又出现一个图片,图片变为两个。 +* Bugfix: 与MooTools类库有冲突。 +* Bugfix: [IE] 选中粘贴过来的文本,进行格式操作时位置出现偏移。 +* Bugfix: [IE] 后退前进时有时候报错。 + +ver 4.0.1 (2011-10-07) +* 改善: image插件,通过editor.plugin.imageDialog()可以单独调用图片弹出框。 +* 改善: filemanager插件,Ajax请求时显示Loading效果。 +* 改善: 工具栏图标改成png8格式。 +* Bugfix: 不能用style的width和height设置编辑器大小。 +* Bugfix: 从MS WORD里面拷贝过来的表格,表格的颜色会丢掉。 +* Bugfix: [IE] 关闭弹出层后光标自动跳转到顶部。 +* Bugfix: 添加链接时有时候出现__kindeditor_temp_url__。 +* Bugfix: [IE] 点击工具栏后,编辑区域失去选中状态。 +* Bugfix: 网速比较慢的时候,连续点击一个图标,弹出多个弹出框。 +* Bugfix: 删除格式时不能删除段落缩进属性。 +* Bugfix: 拖拉改变Flash大小,点击源代码再点回来,Flash长宽自动恢复成预设值。 + +ver 4.0 (2011-09-26) +* 新增: 锚点功能。 +* 新增: 增加loadStyleMode属性,默认情况下自动加载CSS文件。 +* 新增: 编辑器对象增加isDirty方法,判断编辑器内容是否有修改。 +* 改善: 粘贴MS Word时自动清理Word专用格式代码,生成干净的HTML代码。 +* 改善: 弹出框(dialog)里的输入框添加了基本验证。 +* 改善: 超级链接不允许包含HTML代码。 +* 改善: uploadJson URL支持GET参数。 +* 优化: 后退撤销,粘贴性能。 +* BUG: 修复了allowImageUpload为false时,无法插入网络图片的问题。 +* BUG: [WEBKIT] 修复了粘贴内容时顺序相反的问题。 +* BUG: 修复了进行修改操作,再选择一段带有样式的文字,再进行撤销操作,首先撤销的是选取操作,然后才会撤销修改的问题。 +* BUG: 修复了设置basePath参数后,themesPath、langPath、pluginsPath参数不起作用的问题。 +* BUG: 修复了图片和超级连接URL输入双引号时,HTML代码出现错乱的问题。 +* BUG: [IE] 修复了反复执行后退和前进时有时候出现脚本错误的问题。 +* BUG: [IE] 修复了连续选择相同文件上传时,第二次开始无法上传的问题。 +* BUG: [IE] 修复了textarea在p标签里时,无法创建编辑器的问题。 +* BUG: 修复了filterMode为true时,没有过滤script和style内容的问题。 +* BUG: [WEBKIT] 修复了粘贴内容后光标消失的问题。 +* BUG: [IE7] 修复了上传按钮出现偏移的问题。 +* BUG: [IE] 修复了innerHTML有时候抛出异常的问题。 +* BUG: 修复了清除HTML代码时过滤rowspan和colspan,导致表格被破坏的问题。 +* BUG: 修复了在框架(frameset)下面,点击编辑器的源代码按钮后,再点击其它连接变弹出显示的问题。 +* BUG: 修复了在非IE浏览器上,插入表格后,鼠标无法移到表格下面输入文字的问题。 +* BUG: [WEBKIT] 修复了回车换行后标题属性丢失的问题。 +* BUG: [WEBKIT] 修复了粘贴到单元格时有时候粘贴错位的问题。 +* BUG: 修复了删除格式时有时候丢失文字的问题。 +* BUG: [IE] 修复了在HTML里有inline-block时有时候_getStartEnd报错的问题。 +* BUG: 修复了打开地图后立即关闭窗口时,无法关闭的问题。 +* BUG: 修复了insertHtml插入注释开头的HTML时,注释被过滤的问题。 + +ver 4.0 beta (2011-08-17) +* BUG: 修复了域名包含端口时在IE上发生错误的问题。 +* BUG: 修复了在IE上通过工具栏的undo/redo按钮进行undo/redo时无法后退的问题。 +* BUG: 修复了在FF和IE上加载编辑器后生成一个history的问题。 +* BUG: 修复了在IE上点击右键自动插入 的问题。 +* BUG: 修复了在IE上文本在table标签前时,原生range转换成标准range后出现偏移的问题。 +* BUG: 修复了在WEBKIT系列浏览器上在全屏模式下,弹出的插入图片、超链接等对话框,输入框内无法粘贴内容的问题。 +* BUG: 修复了在pre标签里回车加入空行无效的问题。 +* BUG: 修复了切换到代码模式后,按全屏报错的问题。 +* BUG: 修复了点击工具栏时有时候弹出来几个相同dialog的问题。 +* BUG: 修复了在IE上项目编号无论选在到哪里都是第一行加编号的问题。 +* BUG: 修复了焦点处于被合并的单元格,右键菜单,向上添加一行,表格错乱的问题。 +* BUG: 修复了焦点处于被合并的单元格的上一个单元格,右键菜单,向下合并单元格,表格错乱的问题。 +* BUG: 修复了在IE上点击编辑区域时内存一直增加的问题。 + +ver 4.0 alpha (2011-08-16) +* 初期版本,重新编写所有代码。 +* 新增: 插入程序代码、预览、插入地图、调整行距、一键排版、清理HTML代码、插入分页符、插入附件、插入模板功能。 +* 新增: Flash、多媒体编辑功能,Flash、多媒体上传功能。 +* 新增: 表格单元格的合并和拆分功能。 +* 新增: ESC键切换全屏模式。 +* 改善: 后退/前进(undo/redo)时保持选中状态。 +* 改善: 大部分组件实现模块化,可以单独调用。 +* 改善: 改进了HTML格式化功能。 +* 改善: 粘贴纯文本时按照换行设置(newlineTag)换行。 +* 改善: 滚动页面时dialog自动居中。 +* 改善: 在移动设备上只能使用代码模式。 +* 改善: 修改图片尺寸时自动保持比例。 +* BUG: 修复了在页面上设置document.domain时发生错误的问题。 +* BUG: 修复了跨域调用编辑器时无法使用dialog的问题。 +* BUG: 修复了range的collapsed为true时删除格式不起作用的问题。 +* BUG: [WEBKIT] 修复了range的collapsed为true时字体、颜色等无效的问题。 +* BUG: 修复了在不同浏览器上加粗、斜体、下划线、删除线生成出来的HTML代码不一致的问题。 +* BUG: 修复了全选后有时候不能清除格式的问题。 +* BUG: 修复了工具栏经常受全局CSS影响的问题。(改用DIV布局) +* BUG: 修复了直接拷贝页面自动执行js代码的问题。 +* BUG: 修复了页面底部显示右键菜单被挡住的问题。 +* BUG: 修复了在HTML里存在不规则属性("="")时过滤不掉其它属性的问题。 +* BUG: 修复了处理被合并过的单元格时发生错误的问题。 + +ver 3.5.6 (2011-10-04) +* 增加: 新增afterDrag属性(回调函数),拖动改变编辑器大小后执行。 +* 增加: 新增afterUpload属性(回调函数),上传成功后执行。 +* BUG: 修复了工具栏受全局a:hover的影响的问题。 +* BUG: 修复了在全屏模式下编辑器可以被拖动的问题。 +* BUG: [ASP]不改变文件名并上传中文名文件时文件名出现乱码。 +* BUG: [IE9]删除格式功能有时候不起作用。 +* BUG: [IE9]添加样式时有时候报错。 + +ver 3.5.5 (2011-05-22) +* 增加: 新增单元格编辑功能。 +* 改善: 改进输入框和按钮的外观。 +* 改善: 打开dialog后自动选中第一个输入框。 +* 改善: 用CSS实现dialog的阴影。 +* 改善: 插入图片时不设置border="0"属性。 +* BUG: 修改了在IE9上上传图片后原来的内容全部消失的问题。 +* BUG: 修改了在FF4上有时候无法插入图片的问题。 +* BUG: 修改了在IE6上插入图片后,在图片前出现一个空格的问题。 +* BUG: 修改了在IE上使用清除格式功能来删除一段加粗的文字时发生JS错误的问题。(只有压缩后的min有这个问题) + +ver 3.5.4 (2011-05-01) +* 改善: 直接兼容IE9。 +* BUG: 修改了在源代码模式下输入JS代码后切换到可视化模式时会执行JS代码的问题。 +* BUG: 修改了在IE上编辑区域里的选中select控件时出现JS错误的问题。 +* BUG: 修改了在IE上通过KE.insertHtml函数输入URL时丢失标签的问题。 +* BUG: 修改了在一个页面调用多个编辑器时重复加载相同CSS的问题。 +* BUG: 修改了在一个页面包含多个kindeditor.js时无法打开dialog的问题。 +* BUG: 移除了工具栏里的两对多余的tr标签。 + +ver 3.5.3 (2011-04-09) +* 增加: 新增useContextmenu属性,值为true时使用自定义右键菜单,false时屏蔽自定义右键菜单,默认值为true。 +* 增加: 新增syncType属性,值为"auto"时每次修改时都会同步,"form"时提交form时同步,""时不会自动同步,默认值为"form"。 +* 增加: 新增tabIndex属性,可设置编辑器的tabindex。 +* 增加: 新增afterChange属性(回调函数),编辑器内容发生变化后执行的函数。 +* 增加: 新增afterTab属性(回调函数),按下TAB键后执行的函数,默认情况下插入4个空格。 +* 增加: 新增afterFocus属性(回调函数),编辑器获得焦点(onfocus)时执行的函数。 +* 增加: 新增afterBlur属性(回调函数),编辑器失去焦点(onblur)时执行的函数。 +* 增加: 新增KE.sync函数,将编辑器数据设回到原来的textarea里,与KE.util.setData函数功能相同。 +* 增加: 新增KE.blur函数,让编辑器失去焦点。 +* 改变: 将autoSetDataMode的默认值改成false,默认情况下自动寻找所属form,并将KE.sync绑定到该form的submit事件里。 +* 改善: fileManagerJson支持GET参数。 +* 改善: 动态设置上传图片保存URL(save_url),在不同深度的页面调用编辑器不会出错。 +* 改善: 当编辑器属性newlineTag为p时,粘贴纯文本换行使用p标签。 +* 改善: 编辑器id支持[a-z0-9_]以外的特殊字符。 +* 改善: 上传图片按日期目录保存。 +* 改善: 在IE6和IE7上浏览器原生菜单包含复制粘贴选项。 +* BUG: 在IE上通过showModalDialog显示编辑器时无法输入内容。 +* BUG: 修改了删除列时单元格错位的问题。 +* BUG: 修改了在Firefox下点击dialog的按钮后没有按下去的效果的问题。 +* BUG: 有些浏览器无法解析[\w-:],需对“-”进行转义[\w\-:]。 +* BUG: 执行KE.html后有时候全选整个编辑区域。 +* BUG: 在Mac OS X的Firefox上无法显示右键菜单。 +* BUG: script标签内的JavaScript代码字符串里包含HTML代码时,该字符串也被格式化。 +* BUG: 修改了ASP浏览图片程序无法进入子目录的问题。 +* BUG: 修改了通过TAB键移动焦点时焦点移动到工具栏图标上的问题。 + +ver 3.5.2 (2010-12-02) +* BUG: 修改了在IE下拖动调整大小不够顺畅的问题。 +* BUG: 修改了在IE下JS的src为"kindeditor.js"时无法加载CSS文件的问题。 +* BUG: 提高上传图片JSON格式兼容性,防止某些时候因服务器输出额外的数据而导致JSON解析失败的问题。 +* BUG: 修改了在IE上某些情况下添加样式偏移的问题。 +* BUG: 修改了在IE下焦点在图片后面时按下TAB键JS报错的问题。 +* BUG: 修改了KE.util.setOpacity的opacity为2和20时结果相同的问题。 +* BUG: 修改了在IE6下高度小于0时出现脚本错误的问题。 + +ver 3.5.1 (2010-07-18) +* BUG: 修改了表格左侧插入列时单元格移位的问题。 +* BUG: 修改了在Firefox上设置全局CSS后高度计算不正确的问题。 +* BUG: 修改了ASP上传程序无法上传大写扩展名文件的问题。 +* BUG: 修改了在Firefox上调用KE.html函数在某些情况下JS报错的问题。 +* BUG: 修改了在IE6、IE7上只读模式下不显示内容的问题。 +* BUG: 修改了JSP演示程序提交中文数据后出现乱码的问题。 +* BUG: 修改了通过insertHtml插入HTML时URL自动变成绝对域名的问题。 +* BUG: 修改了在IE上用BR换行时回车换行自动选中下面内容的问题。 +* BUG: 修改了设置表格背景颜色后不能取消颜色的问题。 + +ver 3.5 (2010-06-20) +* 增加: 增加了表格编辑功能。 +* 增加: 引入了多国语言机制。 +* 增加: 标题、字体、文字大小、颜色可以反映当前状态。 +* 增加: 右键菜单支持图标和分割线。 +* 增加: 表情功能增加分页和预览。 +* 增加: 增加了弹出框阴影效果。 +* 增加: 增加了新接口。(KE.html,KE.text,KE.selectedHtml,KE.insertHtml,KE.appendHtml,KE.isEmpty等) +* 改善: 编辑器底部显示向下拖动指示图标。 +* 改善: 点击编辑器外的页面其它部位时关闭菜单。 +* 改善: 移除编辑器时将编辑器内容设置到原来的textarea。 +* 改善: 从外部粘贴内容时自动将font转换成span标签。 +* 改善: ASP.NET程序改成ashx,使用时不需要编译。 +* BUG: 改善了文章内容比较多时速度比较慢的问题。 +* BUG: 修改了在IE上选中图片或表格后无法用backspace键删除的问题。 +* BUG: 修改了在Firefox上全屏后浏览器一直处于加载状态的问题。 +* BUG: 修改了在非IE上DOMContentLoaded事件不起作用的问题。 +* BUG: 修改了删除编辑器时没有销毁事件的问题。 +* BUG: 修改了设置成无颜色时其它样式也被删除的问题。 +* BUG: 修改了拖动时拖到浏览器外面放开鼠标后会粘住的问题。 +* BUG: 修改了在Firefox上pre标签自动生成br标签的问题。 +* BUG: 修改了在IE6上用KE.cmd.wrap方法设置class属性后没有效果的问题。 +* BUG: 修改了在P标签内没选中内容时无法插入超级链接的问题。 +* BUG: 修改了使用快捷键加粗体、斜体、下划线时没有同步的问题。 + +ver 3.4.4 (2010-06-01) +* BUG: 修改了在IE上焦点自动移动到编辑区域的问题。 +* BUG: 修改了在IE上打开类型无法修改成当前窗口的问题。 +* BUG: 修改了全选后无法取消超级链接的问题。 +* BUG: 修改了切换代码模式时编辑器轻微抖动的问题。 +* BUG: 修改了在IE上切换代码模式时有时候不出现滚动条的问题。 +* BUG: 修改了在Chrome 5.0上反复切换代码模式有时候出现崩溃页面的问题。 +* 改善: 显示菜单后再点将关闭此菜单。 + +ver 3.4.3 (2010-05-26) +* BUG: 修改了重复编辑超级链接时每次都添加&的问题。 +* BUG: 修改了在IE上右键菜单没有复制、剪切项目的问题。 +* BUG: 修改了在IE上没有格式化代码的问题。 +* BUG: 修改了PHP上传程序日期格式不正确的问题。 +* BUG: 修改了在IE上代码模式下全屏本地URL自动变成绝对URL的问题。 +* BUG: 修改了在代码模式下KE.util.setFullHtml函数不显示HTML内容的问题。 +* BUG: 修改了在MARQUEE元素里回车换行出现JS错误的问题。 +* BUG: 修改了通过菜单剪切、粘贴时不触发KE.event.input事件的问题。 +* BUG: 修改了在IE上焦点离开编辑区域后没有记住最后的range位置的问题。 +* BUG: 修改了在源代码模式下undo/redo能看到临时HTML代码的问题。 +* BUG: 修改了在IE上输入的HTML开头是 + + + +.. index:: langType + +.. _langType: + +langType +-------------------------------------------------------- +指定语言,可设置"en"、"zh-CN",需要引入lang/[langType].js。 + +* 数据类型: String +* 默认值: "zh-CN" + +示例: + +.. sourcecode:: html + + + + + + +.. index:: designMode + +.. _designMode: + +designMode +-------------------------------------------------------- +可视化模式或代码模式 + +* 数据类型: Boolean +* 默认值: true + +.. index:: fullscreenMode + +.. _fullscreenMode: + +fullscreenMode +-------------------------------------------------------- +true时加载编辑器后变成全屏模式。 + +* 数据类型: Boolean +* 默认值: false + +.. index:: basePath + +.. _basePath: + +basePath +-------------------------------------------------------- +指定编辑器的根目录路径。 + +* 数据类型: String +* 默认值: 根据kindeditor.js文件名自动获取 + +.. index:: themesPath + +.. _themesPath: + +themesPath +-------------------------------------------------------- +指定编辑器的themes目录路径。 + +* 数据类型: String +* 默认值: basePath + 'themes/' + +.. index:: pluginsPath + +.. _pluginsPath: + +pluginsPath +-------------------------------------------------------- +指定编辑器的plugins目录路径。 + +* 数据类型: String +* 默认值: basePath + 'plugins/' + +.. index:: langPath + +.. _langPath: + +langPath +-------------------------------------------------------- +指定编辑器的lang目录路径。 + +* 数据类型: String +* 默认值: basePath + 'lang/' + +.. index:: minChangeSize + +.. _minChangeSize: + +minChangeSize +-------------------------------------------------------- +undo/redo文字输入最小变化长度,当输入的文字变化小于这个长度时不会添加到undo记录里。 + +* 数据类型: String +* 默认值: 5 + +.. index:: urlType + +.. _urlType: + +urlType +-------------------------------------------------------- +改变站内本地URL,可设置""、"relative"、"absolute"、"domain"。空为不修改URL,relative为相对路径,absolute为绝对路径,domain为带域名的绝对路径。 + +* 数据类型: String +* 默认值: "" + +.. index:: newlineTag + +.. _newlineTag: + +newlineTag +-------------------------------------------------------- +设置回车换行标签,可设置"p"、"br"。 + +* 数据类型: String +* 默认值: "p" + +.. index:: pasteType + +.. _pasteType: + +pasteType +-------------------------------------------------------- +设置粘贴类型,0:禁止粘贴, 1:纯文本粘贴, 2:HTML粘贴 + +* 数据类型: Int +* 默认值: 2 + +.. index:: dialogAlignType + +.. _dialogAlignType: + +dialogAlignType +-------------------------------------------------------- +设置弹出框(dialog)的对齐类型,可设置""、"page",指定page时按当前页面居中,指定空时按编辑器居中。 + +* 数据类型: String +* 默认值: "page" + +.. index:: shadowMode + +.. _shadowMode: + +shadowMode +-------------------------------------------------------- +true时弹出层(dialog)显示阴影。 + +* 数据类型: Boolean +* 默认值: true + +.. index:: zIndex + +.. _zIndex: + +zIndex +-------------------------------------------------------- +指定弹出层的基准z-index。 + +* 数据类型: Int +* 默认值: 811213 + +.. index:: useContextmenu + +.. _useContextmenu: + +useContextmenu +-------------------------------------------------------- +true时使用右键菜单,false时屏蔽右键菜单。 + +* 数据类型: Boolean +* 默认值: true + +.. index:: syncType + +.. _syncType: + +syncType +-------------------------------------------------------- +同步数据的方式,可设置""、"form",值为form时提交form时自动同步,空时不会自动同步。 + +* 数据类型: String +* 默认值: "form" + +.. index:: indentChar + +.. _indentChar: + +indentChar +-------------------------------------------------------- +:ref:`wellFormatMode` 为true时,HTML代码缩进字符。 + +* 数据类型: String +* 默认值: "\\t" + +.. index:: cssPath + +.. _cssPath: + +cssPath +-------------------------------------------------------- +指定编辑器iframe document的CSS文件,用于设置可视化区域的样式。 + +* 数据类型: String或Array +* 默认值: 空 + +.. index:: cssData + +.. _cssData: + +cssData +-------------------------------------------------------- +指定编辑器iframe document的CSS数据,用于设置可视化区域的样式。 + +* 数据类型: String +* 默认值: 空 + +.. index:: bodyClass + +.. _bodyClass: + +bodyClass +-------------------------------------------------------- +指定编辑器iframe document body的className。 + +* 数据类型: String +* 默认值: "ke-content" + +.. index:: colorTable + +.. _colorTable: + +colorTable +-------------------------------------------------------- +指定取色器里的颜色。 + +* 数据类型: Array +* 默认值: + +.. sourcecode:: js + + [ + ['#E53333', '#E56600', '#FF9900', '#64451D', '#DFC5A4', '#FFE500'], + ['#009900', '#006600', '#99BB00', '#B8D100', '#60D978', '#00D5FF'], + ['#337FE5', '#003399', '#4C33E5', '#9933E5', '#CC33E5', '#EE33EE'], + ['#FFFFFF', '#CCCCCC', '#999999', '#666666', '#333333', '#000000'] + ] + +.. index:: afterCreate + +.. _afterCreate: + +afterCreate +-------------------------------------------------------- +设置编辑器创建后执行的回调函数。 + +* 数据类型: Function +* 默认值: 无 + +.. index:: afterChange + +.. _afterChange: + +afterChange +-------------------------------------------------------- +编辑器内容发生变化后执行的回调函数。 + +* 数据类型: Function +* 默认值: 无 + +.. index:: afterTab + +.. _afterTab: + +afterTab +-------------------------------------------------------- +按下TAB键后执行的的回调函数。 + +* 数据类型: Function +* 默认值: 插入4个空格的函数 + +.. index:: afterFocus + +.. _afterFocus: + +afterFocus +-------------------------------------------------------- +编辑器聚焦(focus)时执行的回调函数。 + +* 数据类型: Function +* 默认值: 无 + +.. index:: afterBlur + +.. _afterBlur: + +afterBlur +-------------------------------------------------------- +编辑器失去焦点(blur)时执行的回调函数。 + +* 数据类型: Function +* 默认值: 无 + +.. index:: afterUpload + +.. _afterUpload: + +afterUpload +-------------------------------------------------------- +上传文件后执行的回调函数。 + +* 数据类型: Function +* 默认值: 无 + +.. sourcecode:: js + + KindEditor.ready(function(K) { + K.create('#id', { + afterUpload : function(url) { + alert(url); + } + }); + }); + +.. index:: uploadJson + +.. _uploadJson: + +uploadJson +-------------------------------------------------------- +指定上传文件的服务器端程序。 + +* 数据类型: String +* 默认值: basePath + 'php/upload_json.php' + +.. index:: fileManagerJson + +.. _fileManagerJson: + +fileManagerJson +-------------------------------------------------------- +指定浏览远程图片的服务器端程序。 + +* 数据类型: String +* 默认值: basePath + 'php/file_manager_json.php' + +.. index:: allowPreviewEmoticons + +.. _allowPreviewEmoticons: + +allowPreviewEmoticons +-------------------------------------------------------- +true时鼠标放在表情上可以预览表情。 + +* 数据类型: Boolean +* 默认值: true + +.. index:: allowImageUpload + +.. _allowImageUpload: + +allowImageUpload +-------------------------------------------------------- +true时显示图片上传按钮。 + +* 数据类型: Boolean +* 默认值: true + +.. index:: allowFlashUpload + +.. _allowFlashUpload: + +allowFlashUpload +-------------------------------------------------------- +true时显示Flash上传按钮。 + +* 数据类型: Boolean +* 默认值: true + +.. index:: allowMediaUpload + +.. _allowMediaUpload: + +allowMediaUpload +-------------------------------------------------------- +true时显示视音频上传按钮。 + +* 数据类型: Boolean +* 默认值: true + +.. index:: allowFileUpload + +.. _allowFileUpload: + +allowFileUpload +-------------------------------------------------------- +true时显示文件上传按钮。 + +* 数据类型: Boolean +* 默认值: true + +.. note:: + + 4.0.6版本开始支持。 + +.. index:: allowFileManager + +.. _allowFileManager: + +allowFileManager +-------------------------------------------------------- +true时显示浏览远程服务器按钮。 + +* 数据类型: Boolean +* 默认值: false + +.. index:: fontSizeTable + +.. _fontSizeTable: + +fontSizeTable +-------------------------------------------------------- +指定文字大小。 + +* 数据类型: Array +* 默认值: + +.. sourcecode:: js + + ['9px', '10px', '12px', '14px', '16px', '18px', '24px', '32px'] + +.. index:: imageTabIndex + +.. _imageTabIndex: + +imageTabIndex +-------------------------------------------------------- +图片弹出层的默认显示标签索引。 + +* 数据类型: Int +* 默认值: 0 + +.. note:: + + 4.0.6版本开始支持。 + +.. index:: formatUploadUrl + +.. _formatUploadUrl: + +formatUploadUrl +-------------------------------------------------------- +false时不会自动格式化上传后的URL。 + +* 数据类型: Boolean +* 默认值: true + +.. note:: + + 4.1版本开始支持。 + +.. index:: fullscreenShortcut + +.. _fullscreenShortcut: + +fullscreenShortcut +-------------------------------------------------------- +false时禁用ESC全屏快捷键。 + +* 数据类型: Boolean +* 默认值: false + +.. note:: + + 4.1版本开始支持,从4.1.2版本开始默认值为false。 + +.. index:: extraFileUploadParams + +.. _extraFileUploadParams: + +extraFileUploadParams +-------------------------------------------------------- +上传图片、Flash、视音频、文件时,支持添加别的参数一并传到服务器。 + +* 数据类型: Array +* 默认值: {} + +.. sourcecode:: js + + KindEditor.ready(function(K) { + K.create('#id', { + extraFileUploadParams : { + item_id : 1000, + category_id : 1 + } + }); + }); + +.. note:: + + 4.1.1版本开始支持。 + +.. index:: filePostName + +.. _filePostName: + +filePostName +-------------------------------------------------------- +指定上传文件form名称。 + +* 数据类型: String +* 默认值: imgFile + +.. note:: + + 4.1.2版本开始支持。 + +.. index:: fillDescAfterUploadImage + +.. _fillDescAfterUploadImage: + +fillDescAfterUploadImage +-------------------------------------------------------- +true时图片上传成功后切换到图片编辑标签,false时插入图片后关闭弹出框。 + +* 数据类型: Boolean +* 默认值: false + +.. note:: + + 4.1.2版本开始支持。 + +.. index:: afterSelectFile + +.. _afterSelectFile: + +afterSelectFile +-------------------------------------------------------- +从图片空间选择文件后执行的回调函数。 + +* 数据类型: Function +* 默认值: 无 + +.. note:: + + 4.1.2版本开始支持。 + +.. index:: pagebreakHtml + +.. _pagebreakHtml: + +pagebreakHtml +-------------------------------------------------------- +可指定分页符HTML。 + +* 数据类型: String +* 默认值: `


` + +.. note:: + + 4.1.3版本开始支持。 + +.. index:: allowImageRemote + +.. _allowImageRemote: + +allowImageRemote +-------------------------------------------------------- +true时显示网络图片标签,false时不显示。 + +* 数据类型: Boolean +* 默认值: true + +.. note:: + + 4.1.6版本开始支持。 + +.. index:: autoHeightMode + +.. _autoHeightMode: + +autoHeightMode +-------------------------------------------------------- +值为true,并引入autoheight.js插件时自动调整高度。 + +* 数据类型: Boolean +* 默认值: false + +.. note:: + + 4.1.8版本开始支持。 + +.. index:: fixToolBar + +.. _fixToolBar: + +fixToolBar +-------------------------------------------------------- +值为true,并引入fixtoolbar.js插件时固定工具栏位置。 + +* 数据类型: Boolean +* 默认值: false + diff --git a/php/kindeditor_demo/kindeditor/docs/plugin.rst b/php/kindeditor_demo/kindeditor/docs/plugin.rst new file mode 100755 index 0000000..d67af07 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/docs/plugin.rst @@ -0,0 +1,80 @@ +添加自定义插件 +======================================================== + +1. 添加"hello"插件 +-------------------------------------------------------- + +1) 添加plugins/hello/hello.js文件。 + +.. sourcecode:: js + + KindEditor.plugin('hello', function(K) { + var editor = this, name = 'hello'; + // 点击图标时执行 + editor.clickToolbar(name, function() { + editor.insertHtml('你好'); + }); + }); + +2) 定义语言,在页面的 + + + + + + + \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/docs/qna.rst b/php/kindeditor_demo/kindeditor/docs/qna.rst new file mode 100755 index 0000000..033a2df --- /dev/null +++ b/php/kindeditor_demo/kindeditor/docs/qna.rst @@ -0,0 +1,39 @@ +常见问题 +======================================================== + +.. contents:: + :depth: 2 + +编辑器好像是UTF-8编码的,可以在GB2312页面上使用吗? +-------------------------------------------------------- +可以使用。有两种方法,一种方法是引入kindeditor.js文件时将script的charset属性设置成utf-8。 + +还有一种方法是直接将html/js/css文件编码都转换成GB2312编码(用Notepad++、editPlus等文本编辑器就可以转换编码),不过转换格式后升级比较困难,建议使用第一种方法。 + +.. sourcecode:: html + + + +我取不到编辑器数据,直接取得textarea的value也没用。 +-------------------------------------------------------- +KindEditor的可视化操作在新创建的iframe上执行,代码模式下的textarea框也是新创建的,所以最后提交前需要执行 :ref:`KEditor.sync` 将HTML数据设置到原来的textarea。 + +KindEditor在默认情况下自动寻找textarea所属的form元素,找到form后onsubmit事件里添加editor.sync()函数,所以用form方式提交数据,不需要手动执行editor.sync()函数。 + +.. sourcecode:: js + + // 将编辑器的HTML数据同步到textarea + editor.sync(); + +为什么有些标签被过滤? +-------------------------------------------------------- +KindEditor默认采用白名单过滤方式,可用 :ref:`htmlTags` 参数定义要保留的标签和属性。当然也可以用 :ref:`filterMode` 参数关闭过滤模式,保留所有标签。 + +.. sourcecode:: js + + // 关闭过滤模式,保留所有标签 + KindEditor.options.filterMode = false; + + KindEditor.ready(function(K)) { + K.create('#editor_id'); + } diff --git a/php/kindeditor_demo/kindeditor/docs/range.rst b/php/kindeditor_demo/kindeditor/docs/range.rst new file mode 100755 index 0000000..1ac0500 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/docs/range.rst @@ -0,0 +1,643 @@ +Range API +======================================================== + +.. contents:: + :depth: 2 + +.. index:: K.range + +.. _K.range: + +K.range(mixed) +-------------------------------------------------------- +创建或选取KRange对象,KRange是原生Range的封装,包含大部分W3C Range接口,此外还有包含KRange和原生Range之间的转换功能。 + +* 参数: + * document|range mixed: document或原生range +* 返回: KRange对象 + +示例: + +.. sourcecode:: js + + range = K.range(document); + range = K.range(originalRange); + +.. note:: + + DOM Level 2 Range Reference: http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html + +.. index:: START_TO_START + +.. _START_TO_START: + +K.START_TO_START +-------------------------------------------------------- +调用 :ref:`KRange.compareBoundaryPoints` 时使用。 + +.. index:: START_TO_END + +.. _START_TO_END: + +K.START_TO_END +-------------------------------------------------------- +调用 :ref:`KRange.compareBoundaryPoints` 时使用。 + +.. index:: END_TO_END + +.. _END_TO_END: + +K.END_TO_END +-------------------------------------------------------- +调用 :ref:`KRange.compareBoundaryPoints` 时使用。 + +.. index:: END_TO_START + +.. _END_TO_START: + +K.END_TO_START +-------------------------------------------------------- +调用 :ref:`KRange.compareBoundaryPoints` 时使用。 + +.. index:: startContainer + +.. _KRange.startContainer: + +startContainer +-------------------------------------------------------- +range的开始节点。 + +.. index:: startOffset + +.. _KRange.startOffset: + +startOffset +-------------------------------------------------------- +range的开始节点位置。 + +.. index:: endContainer + +.. _KRange.endContainer: + +endContainer +-------------------------------------------------------- +range的结束节点。 + +.. index:: endOffset + +.. _KRange.endOffset: + +endOffset +-------------------------------------------------------- +range的结束节点的位置。 + +.. index:: collapsed + +.. _KRange.collapsed: + +collapsed +-------------------------------------------------------- +range的折叠状态,当range处于折叠状态时true,否则false。。 + +.. index:: commonAncestor + +.. _KRange.commonAncestor: + +commonAncestor() +-------------------------------------------------------- +取得KRange的共同祖先。 + +* 参数: 无 +* 返回: Element + +示例: + +.. sourcecode:: js + + var range = K.range(document); + var element = range.commonAncestor(); + +.. index:: setStart + +.. _KRange.setStart: + +setStart(node , offset) +-------------------------------------------------------- +设置KRange的开始节点和位置。 + +* 参数: + * Node node: 任意节点 + * Int offset: 位置 +* 返回: KRange + +示例: + +.. sourcecode:: js + + var range = K.range(document); + range.setStart(document.body, 1); + +.. index:: setEnd + +.. _KRange.setEnd: + +setEnd(node , offset) +-------------------------------------------------------- +设置KRange的结束节点和位置。 + +* 参数: + * Node node: 任意节点 + * Int offset: 位置 +* 返回: KRange + +示例: + +.. sourcecode:: js + + var range = K.range(document); + range.setEnd(document.body, 2); + +.. index:: setStartBefore + +.. _KRange.setStartBefore: + +setStartBefore(node) +-------------------------------------------------------- +将Node的开始位置设置成Range的开始位置。 + +* 参数: + * Node node: 任意节点 +* 返回: KRange + +示例: + +.. sourcecode:: js + + var range = K.range(document); + range.setStartBefore(K('div#id')[0]); + +.. index:: setStartAfter + +.. _KRange.setStartAfter: + +setStartAfter(node) +-------------------------------------------------------- +将Node的结束位置设置成Range的开始位置。 + +* 参数: + * Node node: 任意节点 +* 返回: KRange + +示例: + +.. sourcecode:: js + + var range = K.range(document); + range.setStartAfter(K('div#id')[0]); + +.. index:: setEndBefore + +.. _KRange.setEndBefore: + +setEndBefore(node) +-------------------------------------------------------- +将Node的开始位置设置成Range的结束位置。 + +* 参数: + * Node node: 任意节点 +* 返回: KRange + +示例: + +.. sourcecode:: js + + var range = K.range(document); + range.setEndBefore(K('div#id')[0]); + +.. index:: setEndAfter + +.. _KRange.setEndAfter: + +setEndAfter(node) +-------------------------------------------------------- +将Node的结束位置设置成Range的结束位置。 + +* 参数: + * Node node: 任意节点 +* 返回: KRange + +示例: + +.. sourcecode:: js + + var range = K.range(document); + range.setEndAfter(K('div#id')[0]); + +.. index:: selectNode + +.. _KRange.selectNode: + +selectNode(node) +-------------------------------------------------------- +将Node的开始位置和结束位置分别设置成Range的开始位置和结束位置。 + +* 参数: + * Node node: 任意节点 +* 返回: KRange + +示例: + +.. sourcecode:: js + + var range = K.range(document); + range.selectNode(K('div#id')[0]); + +.. index:: selectNodeContents + +.. _KRange.selectNodeContents: + +selectNodeContents(node) +-------------------------------------------------------- +将Node的子节点的开始位置和结束位置分别设置成Range的开始位置和结束位置。对于文本节点和无结束符的元素,相当于使用selectNode。 + +* 参数: + * Node node: 任意节点 +* 返回: KRange + +示例: + +.. sourcecode:: js + + var range = K.range(document); + range.selectNodeContents(K('div#id')[0]); + +.. index:: collapse + +.. _KRange.collapse: + +collapse(toStart) +-------------------------------------------------------- +折叠KRange,当toStart为true时向前折叠,false时向后折叠。 + +* 参数: + * Boolean toStart: 折叠方向 +* 返回: KRange + +示例: + +.. sourcecode:: js + + var range = K.range(document); + range.selectNodeContents(K('div#id')[0]); + range.collapse(true); + +.. index:: compareBoundaryPoints + +.. _KRange.compareBoundaryPoints: + +compareBoundaryPoints(how , range) +-------------------------------------------------------- +根据how参数比较2个range的边界。 + +* 参数: + * Int how: 位置信息,可设置K.START_TO_START、K.START_TO_END、K.END_TO_END、K.END_TO_START。 + * Range range: 目标Range +* 返回: 当this range在目标range的左侧时返回-1,在目标range的右侧时返回1,相同时返回0。 + +how参数的方向规则: + +* K.START_TO_START:比较目标range的开始位置和this range的开始位置。 +* K.START_TO_END:比较目标range的开始位置和this range的结束位置。 +* K.END_TO_END:比较目标range的结束位置和this range的结束位置。 +* K.END_TO_START:比较目标range的结束位置和this range的开始位置。 + +示例: + +.. sourcecode:: js + + var range1 = K.range(document); + range1.selectNode(K('div#id')[0]); + var range2 = K.range(document); + range2.selectNode(K('div#id p')[0]); + var cmp = range1.compareBoundaryPoints(K.START_TO_START, range2); + +.. index:: cloneRange + +.. _KRange.cloneRange: + +cloneRange() +-------------------------------------------------------- +复制KRange。 + +* 参数: 无 +* 返回: KRange + +示例: + +.. sourcecode:: js + + var range = K.range(document); + range.selectNodeContents(K('div#id')[0]); + var newRange = range.cloneRange(); + +.. index:: toString + +.. _KRange.toString: + +toString() +-------------------------------------------------------- +返回KRange的文本内容。 + +* 参数: 无 +* 返回: String + +示例: + +.. sourcecode:: js + + var range = K.range(document); + range.selectNodeContents(K('div#id')[0]); + var text = range.toString(); + +.. index:: cloneContents + +.. _KRange.cloneContents: + +cloneContents() +-------------------------------------------------------- +复制并返回KRange的内容。 + +* 参数: 无 +* 返回: documentFragment + +示例: + +.. sourcecode:: js + + var range = K.range(document); + range.selectNodeContents(K('div#id')[0]); + var fragment = range.cloneContents(); + +.. index:: deleteContents + +.. _KRange.deleteContents: + +deleteContents() +-------------------------------------------------------- +删除KRange的内容。 + +* 参数: 无 +* 返回: KRange + +示例: + +.. sourcecode:: js + + var range = K.range(document); + range.selectNodeContents(K('div#id')[0]); + range.deleteContents(); + +.. index:: extractContents + +.. _KRange.extractContents: + +extractContents() +-------------------------------------------------------- +删除并返回KRange的内容。 + +* 参数: 无 +* 返回: documentFragment + +示例: + +.. sourcecode:: js + + var range = K.range(document); + range.selectNodeContents(K('div#id')[0]); + var fragment = range.extractContents(); + +.. index:: insertNode + +.. _KRange.insertNode: + +insertNode(node) +-------------------------------------------------------- +将指定Node插入到KRange的开始位置。 + +* 参数: + * Node node: 任意Node或documentFragment +* 返回: KRange + +示例: + +.. sourcecode:: js + + var range = K.range(document); + range.selectNodeContents(K('#id1')[0]); + range.insertNode(K('#id2')[0]); + +.. index:: surroundContents + +.. _KRange.surroundContents: + +surroundContents(node) +-------------------------------------------------------- +用指定Node围住KRange的内容。 + +* 参数: + * Element node: 任意节点 +* 返回: KRange + +示例: + +.. sourcecode:: js + + var range = K.range(document); + range.selectNodeContents(K('#id1')[0]); + range.surroundContents(K('#id2')[0]); + +.. index:: isControl + +.. _KRange.isControl: + +isControl() +-------------------------------------------------------- +判断当前KRange是否可选择的Contral Range。 + +* 参数: 无 +* 返回: Boolean + +示例: + +.. sourcecode:: js + + var range = K.range(document); + range.selectNodeContents(K('#id1')[0]); + var bool = range.isControl(); + +.. index:: get + +.. _KRange.get: + +get([hasControlRange]) +-------------------------------------------------------- +将KRange转换成原生Range并返回。 + +* 参数: + * Boolean hasControlRange: 是否包含Contral Range +* 返回: Range + +示例: + +.. sourcecode:: js + + var range = K.range(document); + range.selectNodeContents(K('#id1')[0]); + var originalRange = range.get(); + +.. index:: html + +.. _KRange.html: + +html() +-------------------------------------------------------- +返回KRange内容的HTML。 + +* 参数: 无 +* 返回: HTML string + +示例: + +.. sourcecode:: js + + var range = K.range(document); + range.selectNodeContents(K('#id1')[0]); + var html = range.html(); + +.. index:: down + +.. _KRange.down: + +down() +-------------------------------------------------------- +降低range的位置。 + +* 参数: 无 +* 返回: KRange + +示例: + +.. sourcecode:: js + + //

123abcdef

+ range.setStart(strong, 1); + range.down(); + console.log(range.startContainer, range.startOffset); // print "abc", 0 + +.. index:: up + +.. _KRange.up: + +up() +-------------------------------------------------------- +提高range的位置。 + +* 参数: 无 +* 返回: KRange + +示例: + +.. sourcecode:: js + + //

123abcdef

+ range.setStart("abc", 0); + range.up(); + console.log(range.startContainer, range.startOffset); // print strong, 1 + +.. index:: enlarge + +.. _KRange.enlarge: + +enlarge() +-------------------------------------------------------- +扩大边界。 + +* 参数: 无 +* 返回: KRange + +示例: + +.. sourcecode:: js + + //

123abcdef

+ range.setStart("123", 0); + range.setEnd("abc", 3); + range.enlarge(); + console.log(range.startContainer, range.startOffset); // print p, 0 + console.log(range.endContainer, range.endOffset); // print p, 1 + +.. index:: shrink + +.. _KRange.shrink: + +shrink() +-------------------------------------------------------- +缩小边界。 + +* 参数: 无 +* 返回: KRange + +示例: + +.. sourcecode:: js + + //

123abc

+ range.setStart(p, 0); + range.setEnd(p, 1); + range.shrink(); + console.log(range.startContainer, range.startOffset); // print "123", 0 + console.log(range.endContainer, range.endOffset); // print "abc", 3 + +.. index:: createBookmark + +.. _KRange.createBookmark: + +createBookmark([serialize]) +-------------------------------------------------------- +创建bookmark。(插入临时节点标记位置) + +* 参数: + * Boolean serialize: bookmark类型,默认值为false,true时bookmark包含临时节点的ID,false时bookmark包含临时节点的Element。 +* 返回: bookmark + +示例: + +.. sourcecode:: js + + bookmark = range.createBookmark(); + console.log(bookmark); // print {start: startNode, end: endNode} + + bookmark = range.createBookmark(true); + console.log(bookmark); // print {start: 'start_node_id', end: 'end_node_id'} + +.. index:: moveToBookmark + +.. _KRange.moveToBookmark: + +moveToBookmark(bookmark) +-------------------------------------------------------- +根据bookmark重新设置range。 + +* 参数: + * Object bookmark: 通过 :ref:`KRange.createBookmark` 得到的bookmark +* 返回: KRange + +示例: + +.. sourcecode:: js + + bookmark = range.createBookmark(); + // 在这里执行一些改变DOM的处理 + // ... + range.moveToBookmark(bookmark); + diff --git a/php/kindeditor_demo/kindeditor/docs/selector.rst b/php/kindeditor_demo/kindeditor/docs/selector.rst new file mode 100755 index 0000000..1d6bbb2 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/docs/selector.rst @@ -0,0 +1,59 @@ +选择器(Selector) API +======================================================== + +.. contents:: + :depth: 2 + +.. index:: query + +.. _query: + +K.query(expr [, root]) +-------------------------------------------------------- +根据expr在root范围内查找DOM元素,并返回第一个元素。没找到则返回null。 + +* 参数: + * string expr: 选择器表达式 + * element root: 根元素,默认值为document +* 返回: DOM元素 + +.. sourcecode:: js + + var div = K.query('#id div'); + var span = K.query('span.class', div); + +.. note:: + + 目前仅支持以下表达式: + + * \*: any element + * E: an element of type E + * E[foo]: an E element with a "foo" attribute + * E[foo="bar"]: an E element whose "foo" attribute value is exactly equal to "bar" + * E.warning: an E element whose class is "warning" (the document language specifies how class is determined) + * E#myid: an E element with ID equal to "myid" + * E F: an F element descendant of an E element + * E > F: an F element child of an E element + +参考文档: http://www.w3.org/TR/css3-selectors/ + +.. index:: queryAll + +.. _queryAll: + +K.queryAll(expr [, root]) +-------------------------------------------------------- +根据expr在root范围内查找DOM元素,并返回所有元素,如果没找到则返回空数组。 + +* 参数: + * string expr: 选择器表达式 + * element root: 根元素,默认值为document +* 返回: array + +示例: + +.. sourcecode:: js + + var divArray = K.queryAll('#id div'); + var spanArray = K.queryAll('span.class', div); + diff --git a/php/kindeditor_demo/kindeditor/docs/tabs.rst b/php/kindeditor_demo/kindeditor/docs/tabs.rst new file mode 100755 index 0000000..64f9609 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/docs/tabs.rst @@ -0,0 +1,42 @@ +Tabs API +======================================================== + +.. contents:: + :depth: 2 + +.. index:: tabs + +.. _K.tabs: + +K.tabs(options) +-------------------------------------------------------- +创建Tabs。 + +* 参数: + * object options: 配置信息 +* 返回: KTabs +* 继承: KWidget ( :ref:`K.widget` ) + +示例: + +.. sourcecode:: js + + var tabs = K.tabs({ + parent : '#tabs', + afterSelect : function(i) { + K('#tab' + (i + 1)).html('选中了标签#' + (i + 1)); + } + }); + tabs.add({ + title : '标签#1', + panel : '#tab1' + }); + tabs.add({ + title : '标签#2', + panel : '#tab2' + }); + tabs.add({ + title : '标签#3', + panel : '#tab3' + }); + tabs.select(0); diff --git a/php/kindeditor_demo/kindeditor/docs/theme.rst b/php/kindeditor_demo/kindeditor/docs/theme.rst new file mode 100755 index 0000000..e0a16d1 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/docs/theme.rst @@ -0,0 +1,40 @@ +更改编辑器外观 +======================================================== + +1. 添加"example1"风格 +-------------------------------------------------------- + +1) 添加themes/example1/example1.css,在这个文件里定义覆盖default.css里的CSS。 + +.. sourcecode:: css + + .ke-container-example1 { + display: block; + border: 1px solid #CCC; + background-color: #FFF; + overflow: hidden; + } + .ke-container-example1 .ke-toolbar { + border-bottom: 1px solid #CCC; + background-color: #FFF; + padding: 2px 5px; + overflow: hidden; + } + /* 在这里继续定义其它CSS */ + +2) 调用编辑器时,引入example1.css,并指定themeType。 + +.. sourcecode:: html + + + + + + diff --git a/php/kindeditor_demo/kindeditor/docs/upgrade.rst b/php/kindeditor_demo/kindeditor/docs/upgrade.rst new file mode 100755 index 0000000..9cd14b5 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/docs/upgrade.rst @@ -0,0 +1,68 @@ +3.x升级到4.x版本 +======================================================== + +1. 替换文件 +----------------------------------------------------------------- +移除3.x版本文件。 + +.. sourcecode:: html + + + +添加4.x版本文件。 + +.. sourcecode:: html + + + + +2. 替换javascript代码 +----------------------------------------------------------------- + +移除3.x版本代码。 + +.. sourcecode:: html + + + +添加4.x版本代码。 + +.. sourcecode:: html + + + +.. note :: + + * 4.x修改过一些参数名,所以3.x的初始化参数不一定直接兼容4.x,具体参数请参考 :doc:`option` 。 + * 4.x通过K.create返回的editor对象调用编辑器API,具体方法请参考 :doc:`editor` 。 + * 4.x插件采用js动态加载机制,uploadJson和fileManagerJson是相对于当前页面的路径,使用相对路径时需要注意。 + * 如果需要在其它函数内调用editor对象,可以将editor对象设置成全局变量。 + +.. sourcecode:: html + + + + + diff --git a/php/kindeditor_demo/kindeditor/docs/upload.rst b/php/kindeditor_demo/kindeditor/docs/upload.rst new file mode 100755 index 0000000..304bfa9 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/docs/upload.rst @@ -0,0 +1,59 @@ +上传文件 +======================================================== +KindEditor默认提供ASP、ASP.NET、PHP、JSP上传程序,这些程序是演示程序,建议不要直接在实际项目中使用。 +如果您确定直接使用本程序,使用之前请仔细确认相关安全设置。 + +选择程序语言 +----------------------------------------------------------------- + +.. sourcecode:: js + + // ASP + KindEditor.ready(function(K) { + K.create('#textarea_id', { + uploadJson : '../asp/upload_json.asp', + fileManagerJson : '../asp/file_manager_json.asp', + allowFileManager : true + }); + }); + // ASP.NET + KindEditor.ready(function(K) { + K.create('#textarea_id', { + uploadJson : '../asp.net/upload_json.ashx', + fileManagerJson : '../asp.net/file_manager_json.ashx', + allowFileManager : true + }); + }); + // JSP + KindEditor.ready(function(K) { + K.create('#textarea_id', { + uploadJson : '../jsp/upload_json.jsp', + fileManagerJson : '../jsp/file_manager_json.jsp', + allowFileManager : true + }); + }); + +.. note:: + + 具体使用方法请参见各语言(asp、asp.net、php、jsp)目录下的demo.xxx文件。 + +POST参数 +----------------------------------------------------------------- +* imgFile: 文件form名称 +* dir: 上传类型,分别为image、flash、media、file + +返回格式(JSON) +----------------------------------------------------------------- + +.. sourcecode:: js + + //成功时 + { + "error" : 0, + "url" : "http://www.example.com/path/to/file.ext" + } + //失败时 + { + "error" : 1, + "message" : "错误信息" + } \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/docs/uploadbutton.rst b/php/kindeditor_demo/kindeditor/docs/uploadbutton.rst new file mode 100755 index 0000000..96af5ee --- /dev/null +++ b/php/kindeditor_demo/kindeditor/docs/uploadbutton.rst @@ -0,0 +1,37 @@ +上传按钮(UplaodButton) API +======================================================== + +.. contents:: + :depth: 2 + +.. index:: uploadbutton + +.. _K.uploadbutton: + +K.uploadbutton(options) +-------------------------------------------------------- +创建上传按钮。 + +* 参数: + * object options: 配置信息 +* 返回: KUploadButton + +示例: + +.. sourcecode:: js + + var uploadbutton = K.uploadbutton({ + button : K('#ke-upload-button')[0], + fieldName : 'imgFile', + url : '../php/upload_json.php', + afterUpload : function(data) { + if (data.error === 0) { + alert(data.url); + } else { + alert(data.message); + } + } + }); + uploadbutton.fileBox.change(function(e) { + uploadbutton.submit(); + }); \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/docs/usage.rst b/php/kindeditor_demo/kindeditor/docs/usage.rst new file mode 100755 index 0000000..81fb2bd --- /dev/null +++ b/php/kindeditor_demo/kindeditor/docs/usage.rst @@ -0,0 +1,97 @@ +编辑器使用方法 +======================================================== + +1. 下载编辑器 +----------------------------------------------------------------- +下载 KindEditor 最新版本,下载之后打开 examples/index.html 就可以看到演示。 + +下载页面: http://www.kindsoft.net/down.php + +2. 部署编辑器 +----------------------------------------------------------------- + +解压 kindeditor-x.x.x.zip 文件,将所有文件上传到您的网站程序目录里,例如:http://您的域名/editor/ + +.. note:: + + 您可以根据需求删除以下目录后上传到服务器。 + + * asp - ASP程序 + * asp.net - ASP.NET程序 + * php - PHP程序 + * jsp - JSP程序 + * examples - 演示文件 + +3. 修改HTML页面 +----------------------------------------------------------------- + +1) 在需要显示编辑器的位置添加textarea输入框。 + +.. sourcecode:: html + + + +.. note:: + + * id在当前页面必须是唯一的值。 + * 在textarea里设置HTML内容即可实现编辑,在这里需要注意的是,如果从服务器端程序(ASP、PHP、ASP.NET等)直接显示内容,则必须转换HTML特殊字符(>,<,&,")。具体请参考各语言目录下面的demo.xxx程序,目前支持ASP、ASP.NET、PHP、JSP。 + * 在有些浏览器上不设宽度和高度可能显示有问题,所以最好设一下宽度和高度。宽度和高度可用inline样式设置,也可用 :doc:`option` 设置。 + +2) 在该HTML页面添加以下脚本。 + +.. sourcecode:: html + + + + + +.. note :: + + * 第一个参数可用其它CSS选择器,匹配多个textarea时只在第一个元素上加载编辑器。 + * 通过K.create函数的第二个参数,可以对编辑器进行配置,具体参数请参考 :doc:`option` 。 + +.. sourcecode:: js + + var options = { + cssPath : '/css/index.css', + filterMode : true + }; + var editor = K.create('textarea[name="content"]', options); + +4. 获取HTML数据 +----------------------------------------------------------------- + +.. sourcecode:: js + + // 取得HTML内容 + html = editor.html(); + + // 同步数据后可以直接取得textarea的value + editor.sync(); + html = document.getElementById('editor_id').value; // 原生API + html = K('#editor_id').val(); // KindEditor Node API + html = $('#editor_id').val(); // jQuery + + // 设置HTML内容 + editor.html('HTML内容'); + +.. note :: + + * KindEditor的可视化操作在新创建的iframe上执行,代码模式下的textarea框也是新创建的,所以最后提交前需要执行 :ref:`KEditor.sync` 将HTML数据设置到原来的textarea。 + * KindEditor在默认情况下自动寻找textarea所属的form元素,找到form后onsubmit事件里添加sync函数,所以用form方式提交数据,不需要手动执行sync()函数。 + * KindEditor默认采用白名单过滤方式,可用 :ref:`htmlTags` 参数定义要保留的标签和属性。当然也可以用 :ref:`filterMode` 参数关闭过滤模式,保留所有标签。 + +.. sourcecode:: js + + // 关闭过滤模式,保留所有标签 + KindEditor.options.filterMode = false; + + KindEditor.ready(function(K)) { + K.create('#editor_id'); + } diff --git a/php/kindeditor_demo/kindeditor/docs/widget.rst b/php/kindeditor_demo/kindeditor/docs/widget.rst new file mode 100755 index 0000000..0d88f0f --- /dev/null +++ b/php/kindeditor_demo/kindeditor/docs/widget.rst @@ -0,0 +1,33 @@ +Widget API +======================================================== + +.. contents:: + :depth: 2 + +.. index:: widget + +.. _K.widget: + +K.widget(options) +-------------------------------------------------------- +创建widget。 + +* 参数: + * object options: 配置信息 +* 返回: KWidget + +示例: + +.. sourcecode:: js + + var widget = K.widget({ + z : 100, + width : 200, + height : 100, + html : 'abc123abcabc', + css : { + border : '1px solid #A0A0A0', + background : '#F0F0F0' + } + }); + diff --git a/php/kindeditor_demo/kindeditor/kindeditor-all-min.js b/php/kindeditor_demo/kindeditor/kindeditor-all-min.js new file mode 100755 index 0000000..9d4aacb --- /dev/null +++ b/php/kindeditor_demo/kindeditor/kindeditor-all-min.js @@ -0,0 +1,7 @@ +/* KindEditor 4.1.11 (2016-03-31), Copyright (C) kindsoft.net, Licence: http://kindeditor.net/license.php */ +!function(window,undefined){function _isArray(a){return a?"[object Array]"===Object.prototype.toString.call(a):!1}function _isFunction(a){return a?"[object Function]"===Object.prototype.toString.call(a):!1}function _inArray(a,b){for(var c=0,d=b.length;d>c;c++)if(a===b[c])return c;return-1}function _each(a,b){if(_isArray(a))for(var c=0,d=a.length;d>c&&b.call(a[c],c,a[c])!==!1;c++);else for(var e in a)if(a.hasOwnProperty(e)&&b.call(a[e],e,a[e])===!1)break}function _trim(a){return a.replace(/(?:^[ \t\n\r]+)|(?:[ \t\n\r]+$)/g,"")}function _inString(a,b,c){return c=c===undefined?",":c,(c+b+c).indexOf(c+a+c)>=0}function _addUnit(a,b){return b=b||"px",a&&/^-?\d+(?:\.\d+)?$/.test(a)?a+b:a}function _removeUnit(a){var b;return a&&(b=/(\d+)/.exec(a))?parseInt(b[1],10):0}function _escape(a){return a.replace(/&/g,"&").replace(//g,">").replace(/"/g,""")}function _unescape(a){return a.replace(/</g,"<").replace(/>/g,">").replace(/"/g,'"').replace(/&/g,"&")}function _toCamel(a){var b=a.split("-");return a="",_each(b,function(b,c){a+=b>0?c.charAt(0).toUpperCase()+c.substr(1):c}),a}function _toHex(a){function b(a){var b=parseInt(a,10).toString(16).toUpperCase();return b.length>1?b:"0"+b}return a.replace(/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/gi,function(a,c,d,e){return"#"+b(c)+b(d)+b(e)})}function _toMap(a,b){b=b===undefined?",":b;var c,d={},e=_isArray(a)?a:a.split(b);return _each(e,function(a,b){if(c=/^(\d+)\.\.(\d+)$/.exec(b))for(var e=parseInt(c[1],10);e<=parseInt(c[2],10);e++)d[e.toString()]=!0;else d[b]=!0}),d}function _toArray(a,b){return Array.prototype.slice.call(a,b||0)}function _undef(a,b){return a===undefined?b:a}function _invalidUrl(a){return!a||/[<>"]/.test(a)}function _addParam(a,b){return a.indexOf("?")>=0?a+"&"+b:a+"?"+b}function _extend(a,b,c){c||(c=b,b=null);var d;if(b){var e=function(){};e.prototype=b.prototype,d=new e,_each(c,function(a,b){d[a]=b})}else d=c;d.constructor=a,a.prototype=d,a.parent=b?b.prototype:null}function _json(text){var match;(match=/\{[\s\S]*\}|\[[\s\S]*\]/.exec(text))&&(text=match[0]);var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;if(cx.lastIndex=0,cx.test(text)&&(text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})),/^[\],:{}\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,"")))return eval("("+text+")");throw"JSON parse error"}function _getBasePath(){for(var a,b=document.getElementsByTagName("script"),c=0,d=b.length;d>c;c++)if(a=b[c].src||"",/kindeditor[\w\-\.]*\.js/.test(a))return a.substring(0,a.lastIndexOf("/")+1);return""}function _bindEvent(a,b,c){a.addEventListener?a.addEventListener(b,c,_useCapture):a.attachEvent&&a.attachEvent("on"+b,c)}function _unbindEvent(a,b,c){a.removeEventListener?a.removeEventListener(b,c,_useCapture):a.detachEvent&&a.detachEvent("on"+b,c)}function KEvent(a,b){this.init(a,b)}function _getId(a){return a[_eventExpendo]||null}function _setId(a){return a[_eventExpendo]=++_eventId,_eventId}function _removeId(a){try{delete a[_eventExpendo]}catch(b){a.removeAttribute&&a.removeAttribute(_eventExpendo)}}function _bind(a,b,c){if(b.indexOf(",")>=0)return void _each(b.split(","),function(){_bind(a,this,c)});var d=_getId(a);d||(d=_setId(a)),_eventData[d]===undefined&&(_eventData[d]={});var e=_eventData[d][b];e&&e.length>0?_unbindEvent(a,b,e[0]):(_eventData[d][b]=[],_eventData[d].el=a),e=_eventData[d][b],0===e.length&&(e[0]=function(b){var c=b?new KEvent(a,b):undefined;_each(e,function(b,d){b>0&&d&&d.call(a,c)})}),_inArray(c,e)<0&&e.push(c),_bindEvent(a,b,e[0])}function _unbind(a,b,c){if(b&&b.indexOf(",")>=0)return void _each(b.split(","),function(){_unbind(a,this,c)});var d=_getId(a);if(d){if(b===undefined)return void(d in _eventData&&(_each(_eventData[d],function(b,c){"el"!=b&&c.length>0&&_unbindEvent(a,b,c[0])}),delete _eventData[d],_removeId(a)));if(_eventData[d]){var e=_eventData[d][b];if(e&&e.length>0){c===undefined?(_unbindEvent(a,b,e[0]),delete _eventData[d][b]):(_each(e,function(a,b){a>0&&b===c&&e.splice(a,1)}),1==e.length&&(_unbindEvent(a,b,e[0]),delete _eventData[d][b]));var f=0;_each(_eventData[d],function(){f++}),2>f&&(delete _eventData[d],_removeId(a))}}}}function _fire(a,b){if(b.indexOf(",")>=0)return void _each(b.split(","),function(){_fire(a,this)});var c=_getId(a);if(c){var d=_eventData[c][b];_eventData[c]&&d&&d.length>0&&d[0]()}}function _ctrl(a,b,c){b=/^\d{2,}$/.test(b)?b:b.toUpperCase().charCodeAt(0),_bind(a,"keydown",function(d){!d.ctrlKey||d.which!=b||d.shiftKey||d.altKey||(c.call(a),d.stop())})}function _ready(a){function b(){e||(e=!0,a(KindEditor),_readyFinished=!0)}function c(){if(!e){try{document.documentElement.doScroll("left")}catch(a){return void setTimeout(c,100)}b()}}function d(){"complete"===document.readyState&&b()}if(_readyFinished)return void a(KindEditor);var e=!1;if(document.addEventListener)_bind(document,"DOMContentLoaded",b);else if(document.attachEvent){_bind(document,"readystatechange",d);var f=!1;try{f=null==window.frameElement}catch(g){}document.documentElement.doScroll&&f&&c()}_bind(window,"load",b)}function _getCssList(a){for(var b,c={},d=/\s*([\w\-]+)\s*:([^;]*)(;|$)/g;b=d.exec(a);){var e=_trim(b[1].toLowerCase()),f=_trim(_toHex(b[2]));c[e]=f}return c}function _getAttrList(a){for(var b,c={},d=/\s+(?:([\w\-:]+)|(?:([\w\-:]+)=([^\s"'<>]+))|(?:([\w\-:"]+)="([^"]*)")|(?:([\w\-:"]+)='([^']*)'))(?=(?:\s|\/|>)+)/g;b=d.exec(a);){var e=(b[1]||b[2]||b[4]||b[6]).toLowerCase(),f=(b[2]?b[3]:b[4]?b[5]:b[7])||"";c[e]=f}return c}function _addClassToTag(a,b){return a=/\s+class\s*=/.test(a)?a.replace(/(\s+class=["']?)([^"']*)(["']?[\s>])/,function(a,c,d,e){return(" "+d+" ").indexOf(" "+b+" ")<0?""===d?c+b+e:c+d+" "+b+e:a}):a.substr(0,a.length-1)+' class="'+b+'">'}function _formatCss(a){var b="";return _each(_getCssList(a),function(a,c){b+=a+":"+c+";"}),b}function _formatUrl(a,b,c,d){function e(a){for(var b=a.split("/"),c=[],d=0,e=b.length;e>d;d++){var f=b[d];".."==f?c.length>0&&c.pop():""!==f&&"."!=f&&c.push(f)}return"/"+c.join("/")}function f(b,c){if(a.substr(0,b.length)===b){for(var e=[],g=0;c>g;g++)e.push("..");var i=".";return e.length>0&&(i+="/"+e.join("/")),"/"==d&&(i+="/"),i+a.substr(b.length)}return(h=/^(.*)\//.exec(b))?f(h[1],++c):void 0}if(b=_undef(b,"").toLowerCase(),"data:"!=a.substr(0,5)&&(a=a.replace(/([^:])\/\//g,"$1/")),_inArray(b,["absolute","relative","domain"])<0)return a;if(c=c||location.protocol+"//"+location.host,d===undefined){var g=location.pathname.match(/^(\/.*)\//);d=g?g[1]:""}var h;if(h=/^(\w+:\/\/[^\/]*)/.exec(a)){if(h[1]!==c)return a}else if(/^\w+:/.test(a))return a;return/^\//.test(a)?a=c+e(a.substr(1)):/^\w+:\/\//.test(a)||(a=c+e(d+"/"+a)),"relative"===b?a=f(c+d,0).substr(2):"absolute"===b&&a.substr(0,c.length)===c&&(a=a.substr(c.length)),a}function _formatHtml(a,b,c,d,e){null==a&&(a=""),c=c||"",d=_undef(d,!1),e=_undef(e," ");var f="xx-small,x-small,small,medium,large,x-large,xx-large".split(",");a=a.replace(/(<(?:pre|pre\s[^>]*)>)([\s\S]*?)(<\/pre>)/gi,function(a,b,c,d){return b+c.replace(/<(?:br|br\s[^>]*)>/gi,"\n")+d}),a=a.replace(/<(?:br|br\s[^>]*)\s*\/?>\s*<\/p>/gi,"

"),a=a.replace(/(<(?:p|p\s[^>]*)>)\s*(<\/p>)/gi,"$1
$2"),a=a.replace(/\u200B/g,""),a=a.replace(/\u00A9/g,"©"),a=a.replace(/\u00AE/g,"®"),a=a.replace(/\u2003/g," "),a=a.replace(/\u3000/g," "),a=a.replace(/<[^>]+/g,function(a){return a.replace(/\s+/g," ")});var g={};b&&(_each(b,function(a,b){for(var c=a.split(","),d=0,e=c.length;e>d;d++)g[c[d]]=_toMap(b)}),g.script||(a=a.replace(/(<(?:script|script\s[^>]*)>)([\s\S]*?)(<\/script>)/gi,"")),g.style||(a=a.replace(/(<(?:style|style\s[^>]*)>)([\s\S]*?)(<\/style>)/gi,"")));var h=/(\s*)<(\/)?([\w\-:]+)((?:\s+|(?:\s+[\w\-:]+)|(?:\s+[\w\-:]+=[^\s"'<>]+)|(?:\s+[\w\-:"]+="[^"]*")|(?:\s+[\w\-:"]+='[^']*'))*)(\/)?>(\s*)/g,i=[];return a=a.replace(h,function(a,h,j,k,l,m,n){var o=a,p=h||"",q=j||"",r=k.toLowerCase(),s=l||"",t=m?" "+m:"",u=n||"";if(b&&!g[r])return"";if(""===t&&_SINGLE_TAG_MAP[r]&&(t=" /"),_INLINE_TAG_MAP[r]&&(p&&(p=" "),u&&(u=" ")),_PRE_TAG_MAP[r]&&(q?u="\n":p="\n"),d&&"br"==r&&(u="\n"),_BLOCK_TAG_MAP[r]&&!_PRE_TAG_MAP[r])if(d){q&&i.length>0&&i[i.length-1]===r?i.pop():i.push(r),p="\n",u="\n";for(var v=0,w=q?i.length:i.length-1;w>v;v++)p+=e,q||(u+=e);t?i.pop():q||(u+=e)}else p=u="";if(""!==s){var x=_getAttrList(o);if("font"===r){var y={},z="";_each(x,function(a,b){"color"===a&&(y.color=b,delete x[a]),"size"===a&&(y["font-size"]=f[parseInt(b,10)-1]||"",delete x[a]),"face"===a&&(y["font-family"]=b,delete x[a]),"style"===a&&(z=b)}),z&&!/;$/.test(z)&&(z+=";"),_each(y,function(a,b){""!==b&&(/\s/.test(b)&&(b="'"+b+"'"),z+=a+":"+b+";")}),x.style=z}_each(x,function(a,d){if(_FILL_ATTR_MAP[a]&&(x[a]=a),_inArray(a,["src","href"])>=0&&(x[a]=_formatUrl(d,c)),(b&&"style"!==a&&!g[r]["*"]&&!g[r][a]||"body"===r&&"contenteditable"===a||/^kindeditor_\d+$/.test(a))&&delete x[a],"style"===a&&""!==d){var e=_getCssList(d);_each(e,function(a){!b||g[r].style||g[r]["."+a]||delete e[a]});var f="";_each(e,function(a,b){f+=a+":"+b+";"}),x.style=f}}),s="",_each(x,function(a,b){("style"!==a||""!==b)&&(b=b.replace(/"/g,"""),s+=" "+a+'="'+b+'"')})}return"font"===r&&(r="span"),p+"<"+q+r+s+t+">"+u}),a=a.replace(/(<(?:pre|pre\s[^>]*)>)([\s\S]*?)(<\/pre>)/gi,function(a,b,c,d){return b+c.replace(/\n/g,'\n')+d}),a=a.replace(/\n\s*\n/g,"\n"),a=a.replace(/\n/g,"\n"),_trim(a)}function _clearMsWord(a,b){return a=a.replace(//gi,"").replace(//gi,"").replace(/]*>[\s\S]*?<\/style>/gi,"").replace(/]*>[\s\S]*?<\/script>/gi,"").replace(/]+>[\s\S]*?<\/w:[^>]+>/gi,"").replace(/]+>[\s\S]*?<\/o:[^>]+>/gi,"").replace(/[\s\S]*?<\/xml>/gi,"").replace(/<(?:table|td)[^>]*>/gi,function(a){return a.replace(/border-bottom:([#\w\s]+)/gi,"border:$1")}),_formatHtml(a,b)}function _mediaType(a){return/\.(rm|rmvb)(\?|$)/i.test(a)?"audio/x-pn-realaudio-plugin":/\.(swf|flv)(\?|$)/i.test(a)?"application/x-shockwave-flash":"video/x-ms-asf-plugin"}function _mediaClass(a){return/realaudio/i.test(a)?"ke-rm":/flash/i.test(a)?"ke-flash":"ke-media"}function _mediaAttrs(a){return _getAttrList(unescape(a))}function _mediaEmbed(a){var b="0&&(g+="width:"+c+"px;"),/\D/.test(d)?g+="height:"+d+";":d>0&&(g+="height:"+d+"px;");var h=''}function _tmpl(a,b){var c=new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+a.replace(/[\r\t\n]/g," ").split("<%").join(" ").replace(/((^|%>)[^\t]*)'/g,"$1\r").replace(/\t=(.*?)%>/g,"',$1,'").split(" ").join("');").split("%>").join("p.push('").split("\r").join("\\'")+"');}return p.join('');");return b?c(b):c}function _contains(a,b){if(9==a.nodeType&&9!=b.nodeType)return!0;for(;b=b.parentNode;)if(b==a)return!0;return!1}function _getAttr(a,b){b=b.toLowerCase();var c=null;if(_GET_SET_ATTRIBUTE||"script"==a.nodeName.toLowerCase())try{c=a.getAttribute(b,2)}catch(d){c=a.getAttribute(b,1)}else{var e=a.ownerDocument.createElement("div");e.appendChild(a.cloneNode(!1));var f=_getAttrList(_unescape(e.innerHTML));b in f&&(c=f[b])}return"style"===b&&null!==c&&(c=_formatCss(c)),c}function _queryAll(a,b){function c(a){return"string"!=typeof a?a:a.replace(/([^\w\-])/g,"\\$1")}function d(a){return a.replace(/\\/g,"")}function e(a,b){return"*"===a||a.toLowerCase()===c(b.toLowerCase())}function f(a,b,c){var f=[],g=c.ownerDocument||c,h=g.getElementById(d(a));return h&&e(b,h.nodeName)&&_contains(c,h)&&f.push(h),f}function g(a,b,c){var f,g,h,i,j=c.ownerDocument||c,k=[];if(c.getElementsByClassName)for(f=c.getElementsByClassName(d(a)),g=0,h=f.length;h>g;g++)i=f[g],e(b,i.nodeName)&&k.push(i);else if(j.querySelectorAll)for(f=j.querySelectorAll(("#document"!==c.nodeName?c.nodeName+" ":"")+b+"."+a),g=0,h=f.length;h>g;g++)i=f[g],_contains(c,i)&&k.push(i);else for(f=c.getElementsByTagName(b),a=" "+a+" ",g=0,h=f.length;h>g;g++)if(i=f[g],1==i.nodeType){var l=i.className;l&&(" "+l+" ").indexOf(a)>-1&&k.push(i)}return k}function h(a,b,c){for(var f,g=[],h=c.ownerDocument||c,i=h.getElementsByName(d(a)),j=0,k=i.length;k>j;j++)f=i[j],e(b,f.nodeName)&&_contains(c,f)&&null!==f.getAttribute("name")&&g.push(f);return g}function i(a,b,d,e){for(var f,g=[],h=e.getElementsByTagName(d),i=0,j=h.length;j>i;i++)f=h[i],1==f.nodeType&&(null===b?null!==_getAttr(f,a)&&g.push(f):b===c(_getAttr(f,a))&&g.push(f));return g}function j(a,b){var c,d=[];c=/^((?:\\.|[^.#\s\[<>])+)/.exec(a);var e=c?c[1]:"*";if(c=/#((?:[\w\-]|\\.)+)$/.exec(a))d=f(c[1],e,b);else if(c=/\.((?:[\w\-]|\\.)+)$/.exec(a))d=g(c[1],e,b);else if(c=/\[((?:[\w\-]|\\.)+)\]/.exec(a))d=i(c[1].toLowerCase(),null,e,b);else if(c=/\[((?:[\w\-]|\\.)+)\s*=\s*['"]?((?:\\.|[^'"]+)+)['"]?\]/.exec(a)){var j=c[1].toLowerCase(),k=c[2];d="id"===j?f(k,e,b):"class"===j?g(k,e,b):"name"===j?h(k,e,b):i(j,k,e,b)}else for(var l,m=b.getElementsByTagName(e),n=0,o=m.length;o>n;n++)l=m[n],1==l.nodeType&&d.push(l);return d}var k=a.split(",");if(k.length>1){var l=[];return _each(k,function(){_each(_queryAll(this,b),function(){_inArray(this,l)<0&&l.push(this)})}),l}b=b||document;for(var m,n=[],o=/((?:\\.|[^\s>])+|[\s>])/g;m=o.exec(a);)" "!==m[1]&&n.push(m[1]);var p=[];if(1==n.length)return j(n[0],b);var q,r,s,t,u,v,w,x,y,z,A=!1;for(v=0,lenth=n.length;v"!==q){if(v>0){for(r=[],w=0,y=p.length;y>w;w++)for(t=p[w],s=j(q,t),x=0,z=s.length;z>x;x++)u=s[x],A?t===u.parentNode&&r.push(u):r.push(u);p=r}else p=j(q,b);if(0===p.length)return[]}else A=!0;return p}function _query(a,b){var c=_queryAll(a,b);return c.length>0?c[0]:null}function _get(a){return K(a)[0]}function _getDoc(a){return a?a.ownerDocument||a.document||a:document}function _getWin(a){if(!a)return window;var b=_getDoc(a);return b.parentWindow||b.defaultView}function _setHtml(a,b){if(1==a.nodeType){var c=_getDoc(a);try{a.innerHTML=''+b;var d=c.getElementById("__kindeditor_temp_tag__");d.parentNode.removeChild(d)}catch(e){K(a).empty(),K("@"+b,c).each(function(){a.appendChild(this)})}}}function _hasClass(a,b){return _inString(b,a.className," ")}function _setAttr(a,b,c){_IE&&8>_V&&"class"==b.toLowerCase()&&(b="className"),a.setAttribute(b,""+c)}function _removeAttr(a,b){_IE&&8>_V&&"class"==b.toLowerCase()&&(b="className"),_setAttr(a,b,""),a.removeAttribute(b)}function _getNodeName(a){return a&&a.nodeName?a.nodeName.toLowerCase():""}function _computedCss(a,b){var c=_getWin(a),d=_toCamel(b),e="";if(c.getComputedStyle){var f=c.getComputedStyle(a,null);e=f[d]||f.getPropertyValue(b)||a.style[d]}else a.currentStyle&&(e=a.currentStyle[d]||a.style[d]);return e}function _hasVal(a){return!!_VALUE_TAG_MAP[_getNodeName(a)]}function _docElement(a){return a=a||document,_QUIRKS?a.body:a.documentElement}function _docHeight(a){var b=_docElement(a);return Math.max(b.scrollHeight,b.clientHeight)}function _docWidth(a){var b=_docElement(a);return Math.max(b.scrollWidth,b.clientWidth)}function _getScrollPos(a){a=a||document;var b,c;return _IE||_NEWIE||_OPERA?(b=_docElement(a).scrollLeft,c=_docElement(a).scrollTop):(b=_getWin(a).scrollX,c=_getWin(a).scrollY),{x:b,y:c}}function KNode(a){this.init(a)}function _updateCollapsed(a){return a.collapsed=a.startContainer===a.endContainer&&a.startOffset===a.endOffset,a}function _copyAndDelete(a,b,c){function d(d,e,f){var g,i=d.nodeValue.length;if(b){var j=d.cloneNode(!0);g=e>0?j.splitText(e):j,i>f&&g.splitText(f-e)}if(c){var k=d;if(e>0&&(k=d.splitText(e),a.setStart(d,e)),i>f){var l=k.splitText(f-e);a.setEnd(l,0)}h.push(k)}return g}function e(){c&&a.up().collapse(!0);for(var b=0,d=h.length;d>b;b++){var e=h[b];e.parentNode&&e.parentNode.removeChild(e)}}function f(e,n){for(var o,p=e.firstChild;p;){var q=new KRange(g).selectNode(p);if(j=q.compareBoundaryPoints(_START_TO_END,a),j>=0&&0>=k&&(k=q.compareBoundaryPoints(_START_TO_START,a)),k>=0&&0>=l&&(l=q.compareBoundaryPoints(_END_TO_END,a)),l>=0&&0>=m&&(m=q.compareBoundaryPoints(_END_TO_START,a)),m>=0)return!1;if(o=p.nextSibling,j>0)if(1==p.nodeType)if(k>=0&&0>=l)b&&n.appendChild(p.cloneNode(!0)),c&&h.push(p);else{var r;if(b&&(r=p.cloneNode(!1),n.appendChild(r)),f(p,r)===!1)return!1}else if(3==p.nodeType){var s;if(s=p==i.startContainer?d(p,i.startOffset,p.nodeValue.length):p==i.endContainer?d(p,0,i.endOffset):d(p,0,p.nodeValue.length),b)try{n.appendChild(s)}catch(t){}}p=o}}var g=a.doc,h=[],i=a.cloneRange().down(),j=-1,k=-1,l=-1,m=-1,n=a.commonAncestor(),o=g.createDocumentFragment();if(3==n.nodeType){var p=d(n,a.startOffset,a.endOffset);return b&&o.appendChild(p),e(),b?o:a}f(n,o),c&&a.up().collapse(!0);for(var q=0,r=h.length;r>q;q++){var s=h[q];s.parentNode&&s.parentNode.removeChild(s)}return b?o:a}function _moveToElementText(a,b){for(var c=b;c;){var d=K(c);if("marquee"==d.name||"select"==d.name)return;c=c.parentNode}try{a.moveToElementText(b)}catch(e){}}function _getStartEnd(a,b){var c=a.parentElement().ownerDocument,d=a.duplicate();d.collapse(b);var e=d.parentElement(),f=e.childNodes;if(0===f.length)return{node:e.parentNode,offset:K(e).index()};var g=c,h=0,i=-1,j=a.duplicate();_moveToElementText(j,e);for(var k=0,l=f.length;l>k;k++){var m=f[k];if(i=j.compareEndPoints("StartToStart",d),0===i)return{node:m.parentNode,offset:k};if(1==m.nodeType){var n,o=a.duplicate(),p=K(m),q=m;p.isControl()&&(n=c.createElement("span"),p.after(n),q=n,h+=p.text().replace(/\r\n|\n|\r/g,"").length),_moveToElementText(o,q),j.setEndPoint("StartToEnd",o),i>0?h+=o.text.replace(/\r\n|\n|\r/g,"").length:h=0,n&&K(n).remove()}else 3==m.nodeType&&(j.moveStart("character",m.nodeValue.length),h+=m.nodeValue.length);0>i&&(g=m)}if(0>i&&1==g.nodeType)return{node:e,offset:K(e.lastChild).index()+1};if(i>0)for(;g.nextSibling&&1==g.nodeType;)g=g.nextSibling;if(j=a.duplicate(),_moveToElementText(j,e),j.setEndPoint("StartToEnd",d),h-=j.text.replace(/\r\n|\n|\r/g,"").length,i>0&&3==g.nodeType)for(var r=g.previousSibling;r&&3==r.nodeType;)h-=r.nodeValue.length,r=r.previousSibling;return{node:g,offset:h}}function _getEndRange(a,b){var c=a.ownerDocument||a,d=c.body.createTextRange();if(c==a)return d.collapse(!0),d;if(1==a.nodeType&&a.childNodes.length>0){var e,f,g=a.childNodes;if(0===b?(f=g[0],e=!0):(f=g[b-1],e=!1),!f)return d;if("head"===K(f).name)return 1===b&&(e=!0),2===b&&(e=!1),d.collapse(e),d;if(1==f.nodeType){var h,i=K(f);return i.isControl()&&(h=c.createElement("span"),e?i.before(h):i.after(h),f=h),_moveToElementText(d,f),d.collapse(e),h&&K(h).remove(),d}a=f,b=e?0:f.nodeValue.length}var j=c.createElement("span");return K(a).before(j),_moveToElementText(d,j),d.moveStart("character",b),K(j).remove(),d}function _toRange(a){function b(a){"tr"==K(a.node).name&&(a.node=a.node.cells[a.offset],a.offset=0)}var c,d;if(_IERANGE){if(a.item)return c=_getDoc(a.item(0)),d=new KRange(c),d.selectNode(a.item(0)),d;c=a.parentElement().ownerDocument;var e=_getStartEnd(a,!0),f=_getStartEnd(a,!1);return b(e),b(f),d=new KRange(c),d.setStart(e.node,e.offset),d.setEnd(f.node,f.offset),d}var g=a.startContainer;return c=g.ownerDocument||g,d=new KRange(c),d.setStart(g,a.startOffset),d.setEnd(a.endContainer,a.endOffset),d}function KRange(a){this.init(a)}function _range(a){return a.nodeName?new KRange(a):a.constructor===KRange?a:_toRange(a)}function _nativeCommand(a,b,c){try{a.execCommand(b,!1,c)}catch(d){}}function _nativeCommandValue(a,b){var c="";try{c=a.queryCommandValue(b)}catch(d){}return"string"!=typeof c&&(c=""),c}function _getSel(a){var b=_getWin(a);return _IERANGE?a.selection:b.getSelection()}function _getRng(a){var b,c=_getSel(a);try{b=c.rangeCount>0?c.getRangeAt(0):c.createRange()}catch(d){}return!_IERANGE||b&&(b.item||b.parentElement().ownerDocument===a)?b:null}function _singleKeyMap(a){var b,c,d={};return _each(a,function(a,e){b=a.split(",");for(var f=0,g=b.length;g>f;f++)c=b[f],d[c]=e}),d}function _hasAttrOrCss(a,b){return _hasAttrOrCssByKey(a,b,"*")||_hasAttrOrCssByKey(a,b)}function _hasAttrOrCssByKey(a,b,c){if(c=c||a.name,1!==a.type)return!1;var d=_singleKeyMap(b);if(!d[c])return!1;for(var e=d[c].split(","),f=0,g=e.length;g>f;f++){var h=e[f];if("*"===h)return!0;var i=/^(\.?)([^=]+)(?:=([^=]*))?$/.exec(h),j=i[1]?"css":"attr";h=i[2];var k=i[3]||"";if(""===k&&""!==a[j](h))return!0;if(""!==k&&a[j](h)===k)return!0}return!1}function _removeAttrOrCss(a,b){1==a.type&&(_removeAttrOrCssByKey(a,b,"*"),_removeAttrOrCssByKey(a,b))}function _removeAttrOrCssByKey(a,b,c){if(c=c||a.name,1===a.type){var d=_singleKeyMap(b);if(d[c]){for(var e=d[c].split(","),f=!1,g=0,h=e.length;h>g;g++){var i=e[g];if("*"===i){f=!0;break}var j=/^(\.?)([^=]+)(?:=([^=]*))?$/.exec(i);i=j[2],j[1]?(i=_toCamel(i),a[0].style[i]&&(a[0].style[i]="")):a.removeAttr(i)}f&&a.remove(!0)}}}function _getInnerNode(a){for(var b=a;b.first();)b=b.first();return b}function _isEmptyNode(a){return 1!=a.type||a.isSingle()?!1:""===a.html().replace(/<[^>]+>/g,"")}function _mergeWrapper(a,b){a=a.clone(!0);for(var c=_getInnerNode(a),d=a,e=!1;b;){for(;d;)d.name===b.name&&(_mergeAttrs(d,b.attr(),b.css()),e=!0),d=d.first();e||c.append(b.clone(!1)),e=!1,b=b.first()}return a}function _wrapNode(a,b){if(b=b.clone(!0),3==a.type)return _getInnerNode(b).append(a.clone(!1)),a.replaceWith(b),b;for(var c,d=a;(c=a.first())&&1==c.children().length;)a=c;c=a.first();for(var e=a.doc.createDocumentFragment();c;)e.appendChild(c[0]),c=c.next();return b=_mergeWrapper(d,b),e.firstChild&&_getInnerNode(b).append(e),d.replaceWith(b),b}function _mergeAttrs(a,b,c){_each(b,function(b,c){"style"!==b&&a.attr(b,c)}),_each(c,function(b,c){a.css(b,c)})}function _inPreElement(a){for(;a&&"body"!=a.name;){if(_PRE_TAG_MAP[a.name]||"div"==a.name&&a.hasClass("ke-script"))return!0;a=a.parent()}return!1}function KCmd(a){this.init(a)}function _cmd(a){if(a.nodeName){var b=_getDoc(a);a=_range(b).selectNodeContents(b.body).collapse(!1)}return new KCmd(a)}function _drag(a){var b=a.moveEl,c=a.moveFn,d=a.clickEl||b,e=a.beforeDrag,f=a.iframeFix===undefined?!0:a.iframeFix,g=[document];f&&K("iframe").each(function(){var a=_formatUrl(this.src||"","absolute");if(!/^https?:\/\//.test(a)){var b;try{b=_iframeDoc(this)}catch(c){}if(b){var d=K(this).pos();K(b).data("pos-x",d.x),K(b).data("pos-y",d.y),g.push(b)}}}),d.mousedown(function(a){function f(a){a.preventDefault();var b=K(_getDoc(a.target)),e=_round((b.data("pos-x")||0)+a.pageX-o),f=_round((b.data("pos-y")||0)+a.pageY-p);c.call(d,k,l,m,n,e,f)}function h(a){a.preventDefault()}function i(a){a.preventDefault(),K(g).unbind("mousemove",f).unbind("mouseup",i).unbind("selectstart",h),j.releaseCapture&&j.releaseCapture()}if(0===a.button||1===a.button){a.stopPropagation();var j=d.get(),k=_removeUnit(b.css("left")),l=_removeUnit(b.css("top")),m=b.width(),n=b.height(),o=a.pageX,p=a.pageY;e&&e(),K(g).mousemove(f).mouseup(i).bind("selectstart",h),j.setCapture&&j.setCapture()}})}function KWidget(a){this.init(a)}function _widget(a){return new KWidget(a)}function _iframeDoc(a){return a=_get(a),a.contentDocument||a.contentWindow.document}function _getInitHtml(a,b,c,d){var e=[""===_direction?"":'','',""];return _isArray(c)||(c=[c]),_each(c,function(a,b){b&&e.push('')}),d&&e.push(""),e.push(""),e.join("\n")}function _elementVal(a,b){if(a.hasVal()){if(b===undefined){var c=a.val();return c=c.replace(/(<(?:p|p\s[^>]*)>) *(<\/p>)/gi,"")}return a.val(b)}return a.html(b)}function KEdit(a){this.init(a)}function _edit(a){return new KEdit(a)}function _selectToolbar(a,b){var c=this,d=c.get(a);if(d){if(d.hasClass("ke-disabled"))return;b(d)}}function KToolbar(a){this.init(a)}function _toolbar(a){return new KToolbar(a)}function KMenu(a){this.init(a)}function _menu(a){return new KMenu(a)}function KColorPicker(a){this.init(a)}function _colorpicker(a){return new KColorPicker(a)}function KUploadButton(a){this.init(a)}function _uploadbutton(a){return new KUploadButton(a)}function _createButton(a){a=a||{};var b=a.name||"",c=K(''),d=K('');return a.click&&d.click(a.click),c.append(d),c}function KDialog(a){this.init(a)}function _dialog(a){return new KDialog(a)}function _tabs(a){var b=_widget(a),c=b.remove,d=a.afterSelect,e=b.div,f=[];e.addClass("ke-tabs").bind("contextmenu,mousedown,mousemove",function(a){a.preventDefault()});var g=K('
    ');return e.append(g),b.add=function(a){var b=K('
  • '+a.title+"
  • ");b.data("tab",a),f.push(b),g.append(b)},b.selectedIndex=0,b.select=function(a){b.selectedIndex=a,_each(f,function(c,d){d.unbind(),c===a?(d.addClass("ke-tabs-li-selected"),K(d.data("tab").panel).show("")):(d.removeClass("ke-tabs-li-selected").removeClass("ke-tabs-li-on").mouseover(function(){K(this).addClass("ke-tabs-li-on")}).mouseout(function(){K(this).removeClass("ke-tabs-li-on")}).click(function(){b.select(c)}),K(d.data("tab").panel).hide())}),d&&d.call(b,a)},b.remove=function(){_each(f,function(){this.remove()}),g.remove(),c.call(b)},b}function _loadScript(a,b){var c=document.getElementsByTagName("head")[0]||(_QUIRKS?document.body:document.documentElement),d=document.createElement("script");c.appendChild(d),d.src=a,d.charset="utf-8",d.onload=d.onreadystatechange=function(){this.readyState&&"loaded"!==this.readyState||(b&&b(),d.onload=d.onreadystatechange=null,c.removeChild(d))}}function _chopQuery(a){var b=a.indexOf("?");return b>0?a.substr(0,b):a}function _loadStyle(a){for(var b=document.getElementsByTagName("head")[0]||(_QUIRKS?document.body:document.documentElement),c=document.createElement("link"),d=_chopQuery(_formatUrl(a,"absolute")),e=K('link[rel="stylesheet"]',b),f=0,g=e.length;g>f;f++)if(_chopQuery(_formatUrl(e[f].href,"absolute"))===d)return;b.appendChild(c),c.href=a,c.rel="stylesheet"}function _ajax(a,b,c,d,e){c=c||"GET",e=e||"json";var f=window.XMLHttpRequest?new window.XMLHttpRequest:new ActiveXObject("Microsoft.XMLHTTP");if(f.open(c,a,!0),f.onreadystatechange=function(){if(4==f.readyState&&200==f.status&&b){var a=_trim(f.responseText);"json"==e&&(a=_json(a)),b(a)}},"POST"==c){var g=[];_each(d,function(a,b){g.push(encodeURIComponent(a)+"="+encodeURIComponent(b))});try{f.setRequestHeader("Content-Type","application/x-www-form-urlencoded")}catch(h){}f.send(g.join("&"))}else f.send(null)}function _plugin(a,b){return a===undefined?_plugins:b?void(_plugins[a]=b):_plugins[a]}function _parseLangKey(a){var b,c="core";return(b=/^(\w+)\.(\w+)$/.exec(a))&&(c=b[1],a=b[2]),{ns:c,key:a}}function _lang(a,b){if(b=b===undefined?K.options.langType:b,"string"==typeof a){if(!_language[b])return"no language";var c=a.length-1;if("."===a.substr(c))return _language[b][a.substr(0,c)];var d=_parseLangKey(a);return _language[b][d.ns][d.key]}_each(a,function(a,c){var d=_parseLangKey(a);_language[b]||(_language[b]={}),_language[b][d.ns]||(_language[b][d.ns]={}),_language[b][d.ns][d.key]=c})}function _getImageFromRange(a,b){if(!a.collapsed){a=a.cloneRange().up();var c=a.startContainer,d=a.startOffset;if(_WEBKIT||a.isControl()){var e=K(c.childNodes[d]);if(e&&"img"==e.name)return b(e)?e:void 0}}}function _bindContextmenuEvent(){var a=this,b=a.edit.doc;K(b).contextmenu(function(b){if(a.menu&&a.hideMenu(),!a.useContextmenu)return void b.preventDefault();if(0!==a._contextmenus.length){var c=0,d=[];for(_each(a._contextmenus,function(){return"-"==this.title?void d.push(this):void(this.cond&&this.cond()&&(d.push(this),this.width&&this.width>c&&(c=this.width)))});d.length>0&&"-"==d[0].title;)d.shift();for(;d.length>0&&"-"==d[d.length-1].title;)d.pop();var e=null;if(_each(d,function(a){"-"==this.title&&"-"==e.title&&delete d[a],e=this}),d.length>0){b.preventDefault();var f=K(a.edit.iframe).pos(),g=_menu({x:f.x+b.clientX,y:f.y+b.clientY,width:c,css:{visibility:"hidden"},shadowMode:a.shadowMode});_each(d,function(){this.title&&g.addItem(this)});var h=_docElement(g.doc),i=g.div.height();b.clientY+i>=h.clientHeight-100&&g.pos(g.x,_removeUnit(g.y)-i),g.div.css("visibility","visible"),a.menu=g}}})}function _bindNewlineEvent(){function a(a){for(var b=K(a.commonAncestor());b&&(1!=b.type||b.isStyle());)b=b.parent();return b.name}var b=this,c=b.edit.doc,d=b.newlineTag;if(!(_IE&&"br"!==d||_GECKO&&3>_V&&"p"!==d||_OPERA&&9>_V)){var e=_toMap("h1,h2,h3,h4,h5,h6,pre,li"),f=_toMap("p,h1,h2,h3,h4,h5,h6,pre,li,blockquote");K(c).keydown(function(g){if(!(13!=g.which||g.shiftKey||g.ctrlKey||g.altKey)){b.cmd.selection();var h=a(b.cmd.range);if("marquee"!=h&&"select"!=h)return"br"!==d||e[h]?void(f[h]||_nativeCommand(c,"formatblock","

    ")):(g.preventDefault(),void b.insertHtml("
    "+(_IE&&9>_V?"":"​")))}}),K(c).keyup(function(e){if(!(13!=e.which||e.shiftKey||e.ctrlKey||e.altKey)&&"br"!=d){if(_GECKO){var g=b.cmd.commonAncestor("p"),h=b.cmd.commonAncestor("a");return void(h&&""==h.text()&&(h.remove(!0),b.cmd.range.selectNodeContents(g[0]).collapse(!0),b.cmd.select()))}b.cmd.selection();var i=a(b.cmd.range);if("marquee"!=i&&"select"!=i){f[i]||_nativeCommand(c,"formatblock","

    ");var j=b.cmd.commonAncestor("div");if(j){for(var k=K("

    "),l=j[0].firstChild;l;){var m=l.nextSibling;k.append(l),l=m}j.before(k),j.remove(),b.cmd.range.selectNodeContents(k[0]),b.cmd.select()}}}})}}function _bindTabEvent(){var a=this,b=a.edit.doc;K(b).keydown(function(c){if(9==c.which){if(c.preventDefault(),a.afterTab)return void a.afterTab.call(a,c);var d=a.cmd,e=d.range;e.shrink(),e.collapsed&&1==e.startContainer.nodeType&&(e.insertNode(K("@ ",b)[0]),d.select()),a.insertHtml("    ")}})}function _bindFocusEvent(){var a=this;K(a.edit.textarea[0],a.edit.win).focus(function(b){a.afterFocus&&a.afterFocus.call(a,b)}).blur(function(b){a.afterBlur&&a.afterBlur.call(a,b)})}function _removeBookmarkTag(a){return _trim(a.replace(/]*id="?__kindeditor_bookmark_\w+_\d+__"?[^>]*><\/span>/gi,""))}function _removeTempTag(a){return a.replace(/]+class="?__kindeditor_paste__"?[^>]*>[\s\S]*?<\/div>/gi,"")}function _addBookmarkToStack(a,b){if(0===a.length)return void a.push(b);var c=a[a.length-1];_removeBookmarkTag(b.html)!==_removeBookmarkTag(c.html)&&a.push(b)}function _undoToRedo(a,b){var c,d,e=this,f=e.edit,g=f.doc.body;if(0===a.length)return e;f.designMode?(c=e.cmd.range,d=c.createBookmark(!0),d.html=g.innerHTML):d={html:g.innerHTML},_addBookmarkToStack(b,d); +var h=a.pop();return _removeBookmarkTag(d.html)===_removeBookmarkTag(h.html)&&a.length>0&&(h=a.pop()),f.designMode?(f.html(h.html),h.start&&(c.moveToBookmark(h),e.select())):K(g).html(_removeBookmarkTag(h.html)),e}function KEditor(a){function b(a,b){KEditor.prototype[a]===undefined&&(c[a]=b),c.options[a]=b}var c=this;c.options={},_each(a,function(c){b(c,a[c])}),_each(K.options,function(a,d){c[a]===undefined&&b(a,d)});var d=K(c.srcElement||"').css("width","100%"),c.tabIndex=isNaN(parseInt(a.tabIndex,10))?c.srcElement.attr("tabindex"):parseInt(a.tabIndex,10),c.iframe.attr("tabindex",c.tabIndex),c.textarea.attr("tabindex",c.tabIndex),c.width&&c.setWidth(c.width),c.height&&c.setHeight(c.height),c.designMode?c.textarea.hide():c.iframe.hide(),h&&c.iframe.bind("load",function(){c.iframe.unbind("load"),_IE?b():setTimeout(b,0)}),c.div.append(c.iframe),c.div.append(c.textarea),c.srcElement.hide(),!h&&b()},setWidth:function(a){var b=this;return a=_addUnit(a),b.width=a,b.div.css("width",a),b},setHeight:function(a){var b=this;return a=_addUnit(a),b.height=a,b.div.css("height",a),b.iframe.css("height",a),(_IE&&8>_V||_QUIRKS)&&(a=_addUnit(_removeUnit(a)-2)),b.textarea.css("height",a),b},remove:function(){var a=this,b=a.doc;K(b.body).unbind(),K(b).unbind(),K(a.win).unbind(),a._mousedownHandler&&K(document).unbind("mousedown",a._mousedownHandler),_elementVal(a.srcElement,a.html()),a.srcElement.show(),a.iframe.unbind(),a.textarea.unbind(),KEdit.parent.remove.call(a)},html:function(a,b){var c=this,d=c.doc;if(c.designMode){var e=d.body;return a===undefined?(a=b?""+e.parentNode.innerHTML+"":e.innerHTML,c.beforeGetHtml&&(a=c.beforeGetHtml(a)),_GECKO&&"
    "==a&&(a=""),a):(c.beforeSetHtml&&(a=c.beforeSetHtml(a)),_IE&&_V>=9&&(a=a.replace(/(<.*?checked=")checked(".*>)/gi,"$1$2")),K(e).html(a),c.afterSetHtml&&c.afterSetHtml(),c)}return a===undefined?c.textarea.val():(c.textarea.val(a),c)},design:function(a){var b,c=this;if(a===undefined?!c.designMode:a){if(!c.designMode){b=c.html(),c.designMode=!0,c.textarea.hide(),c.html(b);var d=c.iframe,e=_removeUnit(c.height);d.height(e-2),d.show(),setTimeout(function(){d.height(e)},0)}}else c.designMode&&(b=c.html(),c.designMode=!1,c.html(b),c.iframe.hide(),c.textarea.show());return c.focus()},focus:function(){var a=this;return a.designMode?a.win.focus():a.textarea[0].focus(),a},blur:function(){var a=this;if(_IE){var b=K('',a.div);a.div.append(b),b[0].focus(),b.remove()}else a.designMode?a.win.blur():a.textarea[0].blur();return a},afterChange:function(a){function b(b){setTimeout(function(){a(b)},1)}var c=this,d=c.doc,e=d.body;return K(d).keyup(function(b){b.ctrlKey||b.altKey||!_CHANGE_KEY_MAP[b.which]||a(b)}),K(d).mouseup(a).contextmenu(a),K(c.win).blur(a),K(e).bind("paste",b),K(e).bind("cut",b),c}}),K.EditClass=KEdit,K.edit=_edit,K.iframeDoc=_iframeDoc,_extend(KToolbar,KWidget,{init:function(a){function b(a){var b=K(a);return b.hasClass("ke-outline")?b:b.hasClass("ke-toolbar-icon")?b.parent():void 0}function c(a,c){var d=b(a.target);if(d){if(d.hasClass("ke-disabled"))return;if(d.hasClass("ke-selected"))return;d[c]("ke-on")}}var d=this;KToolbar.parent.init.call(d,a),d.disableMode=_undef(a.disableMode,!1),d.noDisableItemMap=_toMap(_undef(a.noDisableItems,[])),d._itemMap={},d.div.addClass("ke-toolbar").bind("contextmenu,mousedown,mousemove",function(a){a.preventDefault()}).attr("unselectable","on"),d.div.mouseover(function(a){c(a,"addClass")}).mouseout(function(a){c(a,"removeClass")}).click(function(a){var c=b(a.target);if(c){if(c.hasClass("ke-disabled"))return;d.options.click.call(this,a,c.attr("data-name"))}})},get:function(a){return this._itemMap[a]?this._itemMap[a]:this._itemMap[a]=K("span.ke-icon-"+a,this.div).parent()},select:function(a){return _selectToolbar.call(this,a,function(a){a.addClass("ke-selected")}),self},unselect:function(a){return _selectToolbar.call(this,a,function(a){a.removeClass("ke-selected").removeClass("ke-on")}),self},enable:function(a){var b=this,c=a.get?a:b.get(a);return c&&(c.removeClass("ke-disabled"),c.opacity(1)),b},disable:function(a){var b=this,c=a.get?a:b.get(a);return c&&(c.removeClass("ke-selected").addClass("ke-disabled"),c.opacity(.5)),b},disableAll:function(a,b){var c=this,d=c.noDisableItemMap;return b&&(d=_toMap(b)),(a===undefined?!c.disableMode:a)?(K("span.ke-outline",c.div).each(function(){var a=K(this),b=a[0].getAttribute("data-name",2);d[b]||c.disable(a)}),c.disableMode=!0):(K("span.ke-outline",c.div).each(function(){var a=K(this),b=a[0].getAttribute("data-name",2);d[b]||c.enable(a)}),c.disableMode=!1),c}}),K.ToolbarClass=KToolbar,K.toolbar=_toolbar,_extend(KMenu,KWidget,{init:function(a){var b=this;a.z=a.z||811213,KMenu.parent.init.call(b,a),b.centerLineMode=_undef(a.centerLineMode,!0),b.div.addClass("ke-menu").bind("click,mousedown",function(a){a.stopPropagation()}).attr("unselectable","on")},addItem:function(a){var b=this;if("-"===a.title)return void b.div.append(K('
    '));var c=K('
    '),d=K('
    '),e=K('
    '),f=_addUnit(a.height),g=_undef(a.iconClass,"");b.div.append(c),f&&(c.css("height",f),e.css("line-height",f));var h;return b.centerLineMode&&(h=K('
    '),f&&h.css("height",f)),c.mouseover(function(){K(this).addClass("ke-menu-item-on"),h&&h.addClass("ke-menu-item-center-on")}).mouseout(function(){K(this).removeClass("ke-menu-item-on"),h&&h.removeClass("ke-menu-item-center-on")}).click(function(b){a.click.call(K(this)),b.stopPropagation()}).append(d),h&&c.append(h),c.append(e),a.checked&&(g="ke-icon-checked"),""!==g&&d.html(''),e.html(a.title),b},remove:function(){var a=this;return a.options.beforeRemove&&a.options.beforeRemove.call(a),K(".ke-menu-item",a.div[0]).unbind(),KMenu.parent.remove.call(a),a}}),K.MenuClass=KMenu,K.menu=_menu,_extend(KColorPicker,KWidget,{init:function(a){var b=this;a.z=a.z||811213,KColorPicker.parent.init.call(b,a);var c=a.colors||[["#E53333","#E56600","#FF9900","#64451D","#DFC5A4","#FFE500"],["#009900","#006600","#99BB00","#B8D100","#60D978","#00D5FF"],["#337FE5","#003399","#4C33E5","#9933E5","#CC33E5","#EE33EE"],["#FFFFFF","#CCCCCC","#999999","#666666","#333333","#000000"]];b.selectedColor=(a.selectedColor||"").toLowerCase(),b._cells=[],b.div.addClass("ke-colorpicker").bind("click,mousedown",function(a){a.stopPropagation()}).attr("unselectable","on");var d=b.doc.createElement("table");b.div.append(d),d.className="ke-colorpicker-table",d.cellPadding=0,d.cellSpacing=0,d.border=0;var e=d.insertRow(0),f=e.insertCell(0);f.colSpan=c[0].length,b._addAttr(f,"","ke-colorpicker-cell-top");for(var g=0;g
    ').css("background-color",b)):a.html(d.options.noColor),K(a).attr("unselectable","on"),d._cells.push(a)},remove:function(){var a=this;return _each(a._cells,function(){this.unbind()}),KColorPicker.parent.remove.call(a),a}}),K.ColorPickerClass=KColorPicker,K.colorpicker=_colorpicker,_extend(KUploadButton,{init:function(a){var b=this,c=K(a.button),d=a.fieldName||"file",e=a.url||"",f=c.val(),g=a.extraParams||{},h=c[0].className||"",i=a.target||"kindeditor_upload_iframe_"+(new Date).getTime();a.afterError=a.afterError||function(a){alert(a)};var j=[];for(var k in g)j.push('');var l=['
    ',a.target?"":'',a.form?'
    ':'
    ','',j.join(""),'',"",'',a.form?"
    ":"","
    "].join(""),m=K(l,c.doc);c.hide(),c.before(m),b.div=m,b.button=c,b.iframe=a.target?K('iframe[name="'+i+'"]'):K("iframe",m),b.form=a.form?K(a.form):K("form",m),b.fileBox=K(".ke-upload-file",m);var n=a.width||K(".ke-button-common",m).width();K(".ke-upload-area",m).width(n),b.options=a},submit:function(){var a=this,b=a.iframe;return b.bind("load",function(){b.unbind();var c=document.createElement("form");a.fileBox.before(c),K(c).append(a.fileBox),c.reset(),K(c).remove(!0);var d,e=K.iframeDoc(b),f=e.getElementsByTagName("pre")[0],g="";g=f?f.innerHTML:e.body.innerHTML,g=_unescape(g),b[0].src="javascript:false";try{d=K.json(g)}catch(h){a.options.afterError.call(a,""+e.body.parentNode.innerHTML+"")}d&&a.options.afterUpload.call(a,d)}),a.form[0].submit(),a},remove:function(){var a=this;return a.fileBox&&a.fileBox.unbind(),a.iframe.remove(),a.div.remove(),a.button.show(),a}}),K.UploadButtonClass=KUploadButton,K.uploadbutton=_uploadbutton,_extend(KDialog,KWidget,{init:function(a){var b=this,c=_undef(a.shadowMode,!0);a.z=a.z||811213,a.shadowMode=!1,a.autoScroll=_undef(a.autoScroll,!0),KDialog.parent.init.call(b,a);var d=a.title,e=K(a.body,b.doc),f=a.previewBtn,g=a.yesBtn,h=a.noBtn,i=a.closeBtn,j=_undef(a.showMask,!0);b.div.addClass("ke-dialog").bind("click,mousedown",function(a){a.stopPropagation()});var k=K('
    ').appendTo(b.div);_IE&&7>_V?b.iframeMask=K('').appendTo(b.div):c&&K('
    ').appendTo(b.div);var l=K('
    ');k.append(l),l.html(d),b.closeIcon=K('').click(i.click),l.append(b.closeIcon),b.draggable({clickEl:l,beforeDrag:a.beforeDrag});var m=K('
    ');k.append(m),m.append(e);var n=K('');if((f||g||h)&&k.append(n),_each([{btn:f,name:"preview"},{btn:g,name:"yes"},{btn:h,name:"no"}],function(){if(this.btn){var a=_createButton(this.btn);a.addClass("ke-dialog-"+this.name),n.append(a)}}),b.height&&m.height(_removeUnit(b.height)-l.height()-n.height()),b.div.width(b.div.width()),b.div.height(b.div.height()),b.mask=null,j){var o=_docElement(b.doc),p=Math.max(o.scrollWidth,o.clientWidth),q=Math.max(o.scrollHeight,o.clientHeight);b.mask=_widget({x:0,y:0,z:b.z-1,cls:"ke-dialog-mask",width:p,height:q})}b.autoPos(b.div.width(),b.div.height()),b.footerDiv=n,b.bodyDiv=m,b.headerDiv=l,b.isLoading=!1},setMaskIndex:function(a){var b=this;b.mask.div.css("z-index",a)},showLoading:function(a){a=_undef(a,"");var b=this,c=b.bodyDiv;return b.loading=K('
    '+a+"
    ").width(c.width()).height(c.height()).css("top",b.headerDiv.height()+"px"),c.css("visibility","hidden").after(b.loading),b.isLoading=!0,b},hideLoading:function(){return this.loading&&this.loading.remove(),this.bodyDiv.css("visibility","visible"),this.isLoading=!1,this},remove:function(){var a=this;return a.options.beforeRemove&&a.options.beforeRemove.call(a),a.mask&&a.mask.remove(),a.iframeMask&&a.iframeMask.remove(),a.closeIcon.unbind(),K("input",a.div).unbind(),K("button",a.div).unbind(),a.footerDiv.unbind(),a.bodyDiv.unbind(),a.headerDiv.unbind(),K("iframe",a.div).each(function(){K(this).remove()}),KDialog.parent.remove.call(a),a}}),K.DialogClass=KDialog,K.dialog=_dialog,K.tabs=_tabs,K.loadScript=_loadScript,K.loadStyle=_loadStyle,K.ajax=_ajax;var _plugins={},_language={};KEditor.prototype={lang:function(a){return _lang(a,this.langType)},loadPlugin:function(a,b){var c=this,d=this._pluginStatus;return d||(d=this._pluginStatus={}),_plugins[a]?_isFunction(_plugins[a])?(d[a]||(_plugins[a].call(c,KindEditor),d[a]="inited"),b&&b.call(c),c):(setTimeout(function(){c.loadPlugin(a,b)},100),c):(_plugins[a]="loading",_loadScript(c.pluginsPath+a+"/"+a+".js?ver="+encodeURIComponent(K.DEBUG?_TIME:_VERSION),function(){setTimeout(function(){_plugins[a]&&c.loadPlugin(a,b)},0)}),c)},handler:function(a,b){var c=this;return c._handlers[a]||(c._handlers[a]=[]),_isFunction(b)?(c._handlers[a].push(b),c):(_each(c._handlers[a],function(){b=this.call(c,b)}),b)},clickToolbar:function(a,b){var c=this,d="clickToolbar"+a;return b===undefined?c._handlers[d]?c.handler(d):(c.loadPlugin(a,function(){c.handler(d)}),c):c.handler(d,b)},updateState:function(){var a=this;return _each("justifyleft,justifycenter,justifyright,justifyfull,insertorderedlist,insertunorderedlist,subscript,superscript,bold,italic,underline,strikethrough".split(","),function(b,c){a.cmd.state(c)?a.toolbar.select(c):a.toolbar.unselect(c)}),a},addContextmenu:function(a){return this._contextmenus.push(a),this},afterCreate:function(a){return this.handler("afterCreate",a)},beforeRemove:function(a){return this.handler("beforeRemove",a)},beforeGetHtml:function(a){return this.handler("beforeGetHtml",a)},beforeSetHtml:function(a){return this.handler("beforeSetHtml",a)},afterSetHtml:function(a){return this.handler("afterSetHtml",a)},create:function(){function a(){return 0===i.height()?void setTimeout(a,100):void b.resize(d,e,!1)}var b=this,c=b.fullscreenMode;if(b.isCreated)return b;if(b.srcElement.data("kindeditor"))return b;b.srcElement.data("kindeditor","true"),_docElement().style.overflow=c?"hidden":"";var d=c?_docElement().clientWidth+"px":b.width,e=c?_docElement().clientHeight+"px":b.height;(_IE&&8>_V||_QUIRKS)&&(e=_addUnit(_removeUnit(e)+2));var f=b.container=K(b.layout);c?K(document.body).append(f):b.srcElement.before(f);var g=K(".toolbar",f),h=K(".edit",f),i=b.statusbar=K(".statusbar",f);f.removeClass("container").addClass("ke-container ke-container-"+b.themeType).css("width",d),c?(f.css({position:"absolute",left:0,top:0,"z-index":811211}),_GECKO||(b._scrollPos=_getScrollPos()),window.scrollTo(0,0),K(document.body).css({height:"1px",overflow:"hidden"}),K(document.body.parentNode).css("overflow","hidden"),b._fullscreenExecuted=!0):(b._fullscreenExecuted&&(K(document.body).css({height:"",overflow:""}),K(document.body.parentNode).css("overflow","")),b._scrollPos&&window.scrollTo(b._scrollPos.x,b._scrollPos.y));var j=[];K.each(b.items,function(a,c){"|"==c?j.push(''):"/"==c?j.push('
    '):(j.push(''),j.push(''))});var k=b.toolbar=_toolbar({src:g,html:j.join(""),noDisableItems:b.noDisableItems,click:function(a,c){if(a.stop(),b.menu){var d=b.menu.name;if(b.hideMenu(),d===c)return}b.clickToolbar(c)}}),l=_removeUnit(e)-k.div.height(),m=b.edit=_edit({height:l>0&&_removeUnit(e)>b.minHeight?l:b.minHeight,src:h,srcElement:b.srcElement,designMode:b.designMode,themesPath:b.themesPath,bodyClass:b.bodyClass,cssPath:b.cssPath,cssData:b.cssData,beforeGetHtml:function(a){return a=b.beforeGetHtml(a),a=_removeBookmarkTag(_removeTempTag(a)),_formatHtml(a,b.filterMode?b.htmlTags:null,b.urlType,b.wellFormatMode,b.indentChar)},beforeSetHtml:function(a){return a=_formatHtml(a,b.filterMode?b.htmlTags:null,"",!1),b.beforeSetHtml(a)},afterSetHtml:function(){b.edit=m=this,b.afterSetHtml()},afterCreate:function(){if(b.edit=m=this,b.cmd=m.cmd,b._docMousedownFn=function(){b.menu&&b.hideMenu()},K(m.doc,document).mousedown(b._docMousedownFn),_bindContextmenuEvent.call(b),_bindNewlineEvent.call(b),_bindTabEvent.call(b),_bindFocusEvent.call(b),m.afterChange(function(){m.designMode&&(b.updateState(),b.addBookmark(),b.options.afterChange&&b.options.afterChange.call(b))}),m.textarea.keyup(function(a){a.ctrlKey||a.altKey||!_INPUT_KEY_MAP[a.which]||b.options.afterChange&&b.options.afterChange.call(b)}),b.readonlyMode&&b.readonly(),b.isCreated=!0,""===b.initContent&&(b.initContent=b.html()),b._undoStack.length>0){var a=b._undoStack.pop();a.start&&(b.html(a.html),m.cmd.range.moveToBookmark(a),b.select())}b.afterCreate(),b.options.afterCreate&&b.options.afterCreate.call(b)}});return i.removeClass("statusbar").addClass("ke-statusbar").append('').append(''),b._fullscreenResizeHandler&&(K(window).unbind("resize",b._fullscreenResizeHandler),b._fullscreenResizeHandler=null),a(),c?(b._fullscreenResizeHandler=function(){b.isCreated&&b.resize(_docElement().clientWidth,_docElement().clientHeight,!1)},K(window).bind("resize",b._fullscreenResizeHandler),k.select("fullscreen"),i.first().css("visibility","hidden"),i.last().css("visibility","hidden")):(_GECKO&&K(window).bind("scroll",function(){b._scrollPos=_getScrollPos()}),b.resizeType>0?_drag({moveEl:f,clickEl:i,moveFn:function(a,c,d,e,f,g){e+=g,b.resize(null,e)}}):i.first().css("visibility","hidden"),2===b.resizeType?_drag({moveEl:f,clickEl:i.last(),moveFn:function(a,c,d,e,f,g){d+=f,e+=g,b.resize(d,e)}}):i.last().css("visibility","hidden")),b},remove:function(){var a=this;return a.isCreated?(a.beforeRemove(),a.srcElement.data("kindeditor",""),a.menu&&a.hideMenu(),_each(a.dialogs,function(){a.hideDialog()}),K(document).unbind("mousedown",a._docMousedownFn),a.toolbar.remove(),a.edit.remove(),a.statusbar.last().unbind(),a.statusbar.unbind(),a.container.remove(),a.container=a.toolbar=a.edit=a.menu=null,a.dialogs=[],a.isCreated=!1,a):a},resize:function(a,b,c){var d=this;return c=_undef(c,!0),a&&(/%/.test(a)||(a=_removeUnit(a),a=a/gi,"").replace(/ /gi," ")):b.html(_escape(a))},isEmpty:function(){return""===_trim(this.text().replace(/\r\n|\n|\r/,""))},isDirty:function(){return _trim(this.initContent.replace(/\r\n|\n|\r|t/g,""))!==_trim(this.html().replace(/\r\n|\n|\r|t/g,""))},selectedHtml:function(){var a=this.isCreated?this.cmd.range.html():"";return a=_removeBookmarkTag(_removeTempTag(a))},count:function(a){var b=this;return a=(a||"html").toLowerCase(),"html"===a?b.html().length:"text"===a?b.text().replace(/<(?:img|embed).*?>/gi,"K").replace(/\r\n|\n|\r/g,"").length:0},exec:function(a){a=a.toLowerCase();var b=this,c=b.cmd,d=_inArray(a,"selectall,copy,paste,print".split(","))<0;return d&&b.addBookmark(!1),c[a].apply(c,_toArray(arguments,1)),d&&(b.updateState(),b.addBookmark(!1),b.options.afterChange&&b.options.afterChange.call(b)),b},insertHtml:function(a,b){return this.isCreated?(a=this.beforeSetHtml(a),this.exec("inserthtml",a,b),this):this},appendHtml:function(a){if(this.html(this.html()+a),this.isCreated){var b=this.cmd;b.range.selectNodeContents(b.doc.body).collapse(!1),b.select()}return this},sync:function(){return _elementVal(this.srcElement,this.html()),this},focus:function(){return this.isCreated?this.edit.focus():this.srcElement[0].focus(),this},blur:function(){return this.isCreated?this.edit.blur():this.srcElement[0].blur(),this},addBookmark:function(a){a=_undef(a,!0);var b,c=this,d=c.edit,e=d.doc.body,f=_removeTempTag(e.innerHTML);if(a&&c._undoStack.length>0){var g=c._undoStack[c._undoStack.length-1];if(Math.abs(f.length-_removeBookmarkTag(g.html).length)0){var c=b.dialogs[0],d=b.dialogs[b.dialogs.length-1];c.setMaskIndex(d.z+2),a.z=d.z+3,a.showMask=!1}var e=_dialog(a);return b.dialogs.push(e),e},hideDialog:function(){var a=this;if(a.dialogs.length>0&&a.dialogs.pop().remove(),a.dialogs.length>0){var b=a.dialogs[0],c=a.dialogs[a.dialogs.length-1];b.setMaskIndex(c.z-1)}return a},errorDialog:function(a){var b=this,c=b.createDialog({width:750,title:b.lang("uploadError"),body:'
    '}),d=K("iframe",c.div),e=K.iframeDoc(d);return e.open(),e.write(a),e.close(),K(e.body).css("background-color","#FFF"),d[0].contentWindow.focus(),b}},_instances=[],K.remove=function(a){_eachEditor(a,function(a){this.remove(),_instances.splice(a,1)})},K.sync=function(a){_eachEditor(a,function(){this.sync()})},K.html=function(a,b){_eachEditor(a,function(){this.html(b)})},K.insertHtml=function(a,b){_eachEditor(a,function(){this.insertHtml(b)})},K.appendHtml=function(a,b){_eachEditor(a,function(){this.appendHtml(b)})},_IE&&7>_V&&_nativeCommand(document,"BackgroundImageCache",!0),K.EditorClass=KEditor,K.editor=_editor,K.create=_create,K.instances=_instances,K.plugin=_plugin,K.lang=_lang,_plugin("core",function(a){var b=this,c={undo:"Z",redo:"Y",bold:"B",italic:"I",underline:"U",print:"P",selectall:"A"};if(b.afterSetHtml(function(){b.options.afterChange&&b.options.afterChange.call(b)}),b.afterCreate(function(){if("form"==b.syncType){for(var c=a(b.srcElement),d=!1;c=c.parent();)if("form"==c.name){d=!0;break}if(d){c.bind("submit",function(){b.sync(),a(window).bind("unload",function(){b.edit.textarea.remove()})});var e=a('[type="reset"]',c);e.click(function(){b.html(b.initContent),b.cmd.selection()}),b.beforeRemove(function(){c.unbind(),e.unbind()})}}}),b.clickToolbar("source",function(){b.edit.designMode?(b.toolbar.disableAll(!0),b.edit.design(!1),b.toolbar.select("source")):(b.toolbar.disableAll(!1),b.edit.design(!0),b.toolbar.unselect("source"),_GECKO?setTimeout(function(){b.cmd.selection()},0):b.cmd.selection()),b.designMode=b.edit.designMode}),b.afterCreate(function(){b.designMode||b.toolbar.disableAll(!0).select("source")}),b.clickToolbar("fullscreen",function(){b.fullscreen()}),b.fullscreenShortcut){var d=!1;b.afterCreate(function(){if(a(b.edit.doc,b.edit.textarea).keyup(function(a){27==a.which&&setTimeout(function(){b.fullscreen()},0)}),d){if(_IE&&!b.designMode)return;b.focus()}d||(d=!0)})}_each("undo,redo".split(","),function(a,d){c[d]&&b.afterCreate(function(){_ctrl(this.edit.doc,c[d],function(){b.clickToolbar(d)})}),b.clickToolbar(d,function(){b[d]()})}),b.clickToolbar("formatblock",function(){var a=b.lang("formatblock.formatBlock"),c={h1:28,h2:24,h3:18,H4:14,p:12},d=b.cmd.val("formatblock"),e=b.createMenu({name:"formatblock",width:"en"==b.langType?200:150});_each(a,function(a,f){var g="font-size:"+c[a]+"px;";"h"===a.charAt(0)&&(g+="font-weight:bold;"),e.addItem({title:''+f+"",height:c[a]+12,checked:d===a||d===f,click:function(){b.select().exec("formatblock","<"+a+">").hideMenu()}})})}),b.clickToolbar("fontname",function(){var a=b.cmd.val("fontname"),c=b.createMenu({name:"fontname",width:150});_each(b.lang("fontname.fontName"),function(d,e){c.addItem({title:''+e+"",checked:a===d.toLowerCase()||a===e.toLowerCase(),click:function(){b.exec("fontname",d).hideMenu()}})})}),b.clickToolbar("fontsize",function(){var a=b.cmd.val("fontsize"),c=b.createMenu({name:"fontsize",width:150});_each(b.fontSizeTable,function(d,e){c.addItem({title:''+e+"",height:_removeUnit(e)+12,checked:a===e,click:function(){b.exec("fontsize",e).hideMenu()}})})}),_each("forecolor,hilitecolor".split(","),function(a,c){b.clickToolbar(c,function(){b.createMenu({name:c,selectedColor:b.cmd.val(c)||"default",colors:b.colorTable,click:function(a){b.exec(c,a).hideMenu()}})})}),_each("cut,copy,paste".split(","),function(a,c){b.clickToolbar(c,function(){b.focus();try{b.exec(c,null)}catch(a){alert(b.lang(c+"Error"))}})}),b.clickToolbar("about",function(){var a='
    KindEditor '+_VERSION+'
    Copyright © kindsoft.net All rights reserved.
    ';b.createDialog({name:"about",width:350,title:b.lang("about"),body:a})}),b.plugin.getSelectedLink=function(){return b.cmd.commonAncestor("a")},b.plugin.getSelectedImage=function(){return _getImageFromRange(b.edit.cmd.range,function(a){return!/^ke-\w+$/i.test(a[0].className)})},b.plugin.getSelectedFlash=function(){return _getImageFromRange(b.edit.cmd.range,function(a){return"ke-flash"==a[0].className})},b.plugin.getSelectedMedia=function(){return _getImageFromRange(b.edit.cmd.range,function(a){return"ke-media"==a[0].className||"ke-rm"==a[0].className})},b.plugin.getSelectedAnchor=function(){return _getImageFromRange(b.edit.cmd.range,function(a){return"ke-anchor"==a[0].className})},_each("link,image,flash,media,anchor".split(","),function(a,c){var d=c.charAt(0).toUpperCase()+c.substr(1);_each("edit,delete".split(","),function(a,e){b.addContextmenu({title:b.lang(e+d),click:function(){b.loadPlugin(c,function(){b.plugin[c][e](),b.hideMenu()})},cond:b.plugin["getSelected"+d],width:150,iconClass:"edit"==e?"ke-icon-"+c:undefined}) +}),b.addContextmenu({title:"-"})}),b.plugin.getSelectedTable=function(){return b.cmd.commonAncestor("table")},b.plugin.getSelectedRow=function(){return b.cmd.commonAncestor("tr")},b.plugin.getSelectedCell=function(){return b.cmd.commonAncestor("td")},_each("prop,cellprop,colinsertleft,colinsertright,rowinsertabove,rowinsertbelow,rowmerge,colmerge,rowsplit,colsplit,coldelete,rowdelete,insert,delete".split(","),function(a,c){var d=_inArray(c,["prop","delete"])<0?b.plugin.getSelectedCell:b.plugin.getSelectedTable;b.addContextmenu({title:b.lang("table"+c),click:function(){b.loadPlugin("table",function(){b.plugin.table[c](),b.hideMenu()})},cond:d,width:170,iconClass:"ke-icon-table"+c})}),b.addContextmenu({title:"-"}),_each("selectall,justifyleft,justifycenter,justifyright,justifyfull,insertorderedlist,insertunorderedlist,indent,outdent,subscript,superscript,hr,print,bold,italic,underline,strikethrough,removeformat,unlink".split(","),function(a,d){c[d]&&b.afterCreate(function(){_ctrl(this.edit.doc,c[d],function(){b.cmd.selection(),b.clickToolbar(d)})}),b.clickToolbar(d,function(){b.focus().exec(d,null)})}),b.afterCreate(function(){function c(){d.range.moveToBookmark(e),d.select(),_WEBKIT&&(a("div."+h,f).each(function(){a(this).after("
    ").remove(!0)}),a("span.Apple-style-span",f).remove(!0),a("span.Apple-tab-span",f).remove(!0),a("span[style]",f).each(function(){"nowrap"==a(this).css("white-space")&&a(this).remove(!0)}),a("meta",f).remove());var c=f[0].innerHTML;f.remove(),""!==c&&(_WEBKIT&&(c=c.replace(/(
    )\1/gi,"$1")),2===b.pasteType&&(c=c.replace(/(<(?:p|p\s[^>]*)>) *(<\/p>)/gi,""),/schemas-microsoft-com|worddocument|mso-\w+/i.test(c)?c=_clearMsWord(c,b.filterMode?b.htmlTags:a.options.htmlTags):(c=_formatHtml(c,b.filterMode?b.htmlTags:null),c=b.beforeSetHtml(c))),1===b.pasteType&&(c=c.replace(/ /gi," "),c=c.replace(/\n\s*\n/g,"\n"),c=c.replace(/]*>/gi,"\n"),c=c.replace(/<\/p>]*>/gi,"\n"),c=c.replace(/<[^>]+>/g,""),c=c.replace(/ {2}/g,"  "),"p"==b.newlineTag?/\n/.test(c)&&(c=c.replace(/^/,"

    ").replace(/$/,"

    ").replace(/\n/g,"

    ")):c=c.replace(/\n/g,"
    $&")),b.insertHtml(c,!0))}var d,e,f,g=b.edit.doc,h="__kindeditor_paste__",i=!1;a(g.body).bind("paste",function(j){if(0===b.pasteType)return void j.stop();if(!i){if(i=!0,a("div."+h,g).remove(),d=b.cmd.selection(),e=d.range.createBookmark(),f=a('

    ',g).css({position:"absolute",width:"1px",height:"1px",overflow:"hidden",left:"-1981px",top:a(e.start).pos().y+"px","white-space":"nowrap"}),a(g.body).append(f),_IE){var k=d.range.get(!0);k.moveToElementText(f[0]),k.select(),k.execCommand("paste"),j.preventDefault()}else d.range.selectNodeContents(f[0]),d.select(),f[0].tabIndex=-1,f[0].focus();setTimeout(function(){c(),i=!1},0)}})}),b.beforeGetHtml(function(a){return _IE&&8>=_V&&(a=a.replace(/]*data-ke-input-tag="([^"]*)"[^>]*>([\s\S]*?)<\/div>/gi,function(a,b){return unescape(b)}),a=a.replace(/(]*)?>)/gi,function(a,b,c){return/\s+type="[^"]+"/i.test(a)?a:b+' type="text"'+c})),a.replace(/(<(?:noscript|noscript\s[^>]*)>)([\s\S]*?)(<\/noscript>)/gi,function(a,b,c,d){return b+_unescape(c).replace(/\s+/g," ")+d}).replace(/]*class="?ke-(flash|rm|media)"?[^>]*>/gi,function(a){var b=_getAttrList(a),c=_getCssList(b.style||""),d=_mediaAttrs(b["data-ke-tag"]),e=_undef(c.width,""),f=_undef(c.height,"");return/px/i.test(e)&&(e=_removeUnit(e)),/px/i.test(f)&&(f=_removeUnit(f)),d.width=_undef(b.width,e),d.height=_undef(b.height,f),_mediaEmbed(d)}).replace(/]*class="?ke-anchor"?[^>]*>/gi,function(a){var b=_getAttrList(a);return''}).replace(/]*data-ke-script-attr="([^"]*)"[^>]*>([\s\S]*?)<\/div>/gi,function(a,b,c){return""+unescape(c)+""}).replace(/]*data-ke-noscript-attr="([^"]*)"[^>]*>([\s\S]*?)<\/div>/gi,function(a,b,c){return""+unescape(c)+""}).replace(/(<[^>]*)data-ke-src="([^"]*)"([^>]*>)/gi,function(a,b,c){return a=a.replace(/(\s+(?:href|src)=")[^"]*(")/i,function(a,b,d){return b+_unescape(c)+d}),a=a.replace(/\s+data-ke-src="[^"]*"/i,"")}).replace(/(<[^>]+\s)data-ke-(on\w+="[^"]*"[^>]*>)/gi,function(a,b,c){return b+c})}),b.beforeSetHtml(function(a){return _IE&&8>=_V&&(a=a.replace(/]*>|<(select|button)[^>]*>[\s\S]*?<\/\1>/gi,function(a){var b=_getAttrList(a),c=_getCssList(b.style||"");return"none"==c.display?'
    ':a})),a.replace(/]*type="([^"]+)"[^>]*>(?:<\/embed>)?/gi,function(a){var c=_getAttrList(a);return c.src=_undef(c.src,""),c.width=_undef(c.width,0),c.height=_undef(c.height,0),_mediaImg(b.themesPath+"common/blank.gif",c)}).replace(/]*name="([^"]+)"[^>]*>(?:<\/a>)?/gi,function(a){var c=_getAttrList(a);return c.href!==undefined?a:''}).replace(/]*)>([\s\S]*?)<\/script>/gi,function(a,b,c){return'
    '+escape(c)+"
    "}).replace(/]*)>([\s\S]*?)<\/noscript>/gi,function(a,b,c){return'
    '+escape(c)+"
    "}).replace(/(<[^>]*)(href|src)="([^"]*)"([^>]*>)/gi,function(a,b,c,d,e){return a.match(/\sdata-ke-src="[^"]*"/i)?a:a=b+c+'="'+d+'" data-ke-src="'+_escape(d)+'"'+e}).replace(/(<[^>]+\s)(on\w+="[^"]*"[^>]*>)/gi,function(a,b,c){return b+"data-ke-"+c}).replace(/]*\s+border="0"[^>]*>/gi,function(a){return a.indexOf("ke-zeroborder")>=0?a:_addClassToTag(a,"ke-zeroborder")})})})}}(window),KindEditor.lang({source:"HTML代码",preview:"预览",undo:"后退(Ctrl+Z)",redo:"前进(Ctrl+Y)",cut:"剪切(Ctrl+X)",copy:"复制(Ctrl+C)",paste:"粘贴(Ctrl+V)",plainpaste:"粘贴为无格式文本",wordpaste:"从Word粘贴",selectall:"全选(Ctrl+A)",justifyleft:"左对齐",justifycenter:"居中",justifyright:"右对齐",justifyfull:"两端对齐",insertorderedlist:"编号",insertunorderedlist:"项目符号",indent:"增加缩进",outdent:"减少缩进",subscript:"下标",superscript:"上标",formatblock:"段落",fontname:"字体",fontsize:"文字大小",forecolor:"文字颜色",hilitecolor:"文字背景",bold:"粗体(Ctrl+B)",italic:"斜体(Ctrl+I)",underline:"下划线(Ctrl+U)",strikethrough:"删除线",removeformat:"删除格式",image:"图片",multiimage:"批量图片上传",flash:"Flash",media:"视音频",table:"表格",tablecell:"单元格",hr:"插入横线",emoticons:"插入表情",link:"超级链接",unlink:"取消超级链接",fullscreen:"全屏显示",about:"关于",print:"打印(Ctrl+P)",filemanager:"文件空间",code:"插入程序代码",map:"Google地图",baidumap:"百度地图",lineheight:"行距",clearhtml:"清理HTML代码",pagebreak:"插入分页符",quickformat:"一键排版",insertfile:"插入文件",template:"插入模板",anchor:"锚点",yes:"确定",no:"取消",close:"关闭",editImage:"图片属性",deleteImage:"删除图片",editFlash:"Flash属性",deleteFlash:"删除Flash",editMedia:"视音频属性",deleteMedia:"删除视音频",editLink:"超级链接属性",deleteLink:"取消超级链接",editAnchor:"锚点属性",deleteAnchor:"删除锚点",tableprop:"表格属性",tablecellprop:"单元格属性",tableinsert:"插入表格",tabledelete:"删除表格",tablecolinsertleft:"左侧插入列",tablecolinsertright:"右侧插入列",tablerowinsertabove:"上方插入行",tablerowinsertbelow:"下方插入行",tablerowmerge:"向下合并单元格",tablecolmerge:"向右合并单元格",tablerowsplit:"拆分行",tablecolsplit:"拆分列",tablecoldelete:"删除列",tablerowdelete:"删除行",noColor:"无颜色",pleaseSelectFile:"请选择文件。",invalidImg:"请输入有效的URL地址。\n只允许jpg,gif,bmp,png格式。",invalidMedia:"请输入有效的URL地址。\n只允许swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb格式。",invalidWidth:"宽度必须为数字。",invalidHeight:"高度必须为数字。",invalidBorder:"边框必须为数字。",invalidUrl:"请输入有效的URL地址。",invalidRows:"行数为必选项,只允许输入大于0的数字。",invalidCols:"列数为必选项,只允许输入大于0的数字。",invalidPadding:"边距必须为数字。",invalidSpacing:"间距必须为数字。",invalidJson:"服务器发生故障。",uploadSuccess:"上传成功。",cutError:"您的浏览器安全设置不允许使用剪切操作,请使用快捷键(Ctrl+X)来完成。",copyError:"您的浏览器安全设置不允许使用复制操作,请使用快捷键(Ctrl+C)来完成。",pasteError:"您的浏览器安全设置不允许使用粘贴操作,请使用快捷键(Ctrl+V)来完成。",ajaxLoading:"加载中,请稍候 ...",uploadLoading:"上传中,请稍候 ...",uploadError:"上传错误","plainpaste.comment":"请使用快捷键(Ctrl+V)把内容粘贴到下面的方框里。","wordpaste.comment":"请使用快捷键(Ctrl+V)把内容粘贴到下面的方框里。","code.pleaseInput":"请输入程序代码。","link.url":"URL","link.linkType":"打开类型","link.newWindow":"新窗口","link.selfWindow":"当前窗口","flash.url":"URL","flash.width":"宽度","flash.height":"高度","flash.upload":"上传","flash.viewServer":"文件空间","media.url":"URL","media.width":"宽度","media.height":"高度","media.autostart":"自动播放","media.upload":"上传","media.viewServer":"文件空间","image.remoteImage":"网络图片","image.localImage":"本地上传","image.remoteUrl":"图片地址","image.localUrl":"上传文件","image.size":"图片大小","image.width":"宽","image.height":"高","image.resetSize":"重置大小","image.align":"对齐方式","image.defaultAlign":"默认方式","image.leftAlign":"左对齐","image.rightAlign":"右对齐","image.imgTitle":"图片说明","image.upload":"浏览...","image.viewServer":"图片空间","multiimage.uploadDesc":"允许用户同时上传<%=uploadLimit%>张图片,单张图片容量不超过<%=sizeLimit%>","multiimage.startUpload":"开始上传","multiimage.clearAll":"全部清空","multiimage.insertAll":"全部插入","multiimage.queueLimitExceeded":"文件数量超过限制。","multiimage.fileExceedsSizeLimit":"文件大小超过限制。","multiimage.zeroByteFile":"无法上传空文件。","multiimage.invalidFiletype":"文件类型不正确。","multiimage.unknownError":"发生异常,无法上传。","multiimage.pending":"等待上传","multiimage.uploadError":"上传失败","filemanager.emptyFolder":"空文件夹","filemanager.moveup":"移到上一级文件夹","filemanager.viewType":"显示方式:","filemanager.viewImage":"缩略图","filemanager.listImage":"详细信息","filemanager.orderType":"排序方式:","filemanager.fileName":"名称","filemanager.fileSize":"大小","filemanager.fileType":"类型","insertfile.url":"URL","insertfile.title":"文件说明","insertfile.upload":"上传","insertfile.viewServer":"文件空间","table.cells":"单元格数","table.rows":"行数","table.cols":"列数","table.size":"大小","table.width":"宽度","table.height":"高度","table.percent":"%","table.px":"px","table.space":"边距间距","table.padding":"边距","table.spacing":"间距","table.align":"对齐方式","table.textAlign":"水平对齐","table.verticalAlign":"垂直对齐","table.alignDefault":"默认","table.alignLeft":"左对齐","table.alignCenter":"居中","table.alignRight":"右对齐","table.alignTop":"顶部","table.alignMiddle":"中部","table.alignBottom":"底部","table.alignBaseline":"基线","table.border":"边框","table.borderWidth":"边框","table.borderColor":"颜色","table.backgroundColor":"背景颜色","map.address":"地址: ","map.search":"搜索","baidumap.address":"地址: ","baidumap.search":"搜索","baidumap.insertDynamicMap":"插入动态地图","anchor.name":"锚点名称","formatblock.formatBlock":{h1:"标题 1",h2:"标题 2",h3:"标题 3",h4:"标题 4",p:"正 文"},"fontname.fontName":{SimSun:"宋体",NSimSun:"新宋体",FangSong_GB2312:"仿宋_GB2312",KaiTi_GB2312:"楷体_GB2312",SimHei:"黑体","Microsoft YaHei":"微软雅黑",Arial:"Arial","Arial Black":"Arial Black","Times New Roman":"Times New Roman","Courier New":"Courier New",Tahoma:"Tahoma",Verdana:"Verdana"},"lineheight.lineHeight":[{1:"单倍行距"},{1.5:"1.5倍行距"},{2:"2倍行距"},{2.5:"2.5倍行距"},{3:"3倍行距"}],"template.selectTemplate":"可选模板","template.replaceContent":"替换当前内容","template.fileList":{"1.html":"图片和文字","2.html":"表格","3.html":"项目编号"}},"zh-CN"),KindEditor.options.langType="zh-CN",KindEditor.plugin("anchor",function(a){var b=this,c="anchor",d=b.lang(c+".");b.plugin.anchor={edit:function(){var e=['
    ','
    ','",'',"
    ","
    "].join(""),f=b.createDialog({name:c,width:300,title:b.lang(c),body:e,yesBtn:{name:b.lang("yes"),click:function(){b.insertHtml('').hideDialog().focus()}}}),g=f.div,h=a('input[name="name"]',g),i=b.plugin.getSelectedAnchor();i&&h.val(unescape(i.attr("data-ke-name"))),h[0].focus(),h[0].select()},"delete":function(){b.plugin.getSelectedAnchor().remove()}},b.clickToolbar(c,b.plugin.anchor.edit)}),KindEditor.plugin("autoheight",function(a){function b(){var a=e.edit,b=a.doc.body;a.iframe[0].scroll="no",b.style.overflowY="hidden"}function c(){var b=e.edit,c=b.doc.body;b.iframe.height(f),e.resize(null,Math.max((a.IE?c.scrollHeight:c.offsetHeight)+76,f))}function d(){f=a.removeUnit(e.height),e.edit.afterChange(c),b(),c()}var e=this;if(e.autoHeightMode){var f;e.isCreated?d():e.afterCreate(d)}}),KindEditor.plugin("baidumap",function(a){var b=this,c="baidumap",d=b.lang(c+"."),e=a.undef(b.mapWidth,558),f=a.undef(b.mapHeight,360);b.clickToolbar(c,function(){function g(){h=p[0].contentWindow,i=a.iframeDoc(p)}var h,i,j=['
    ','
    ','
    ',d.address+' ','','',"","
    ",'
    ',' ","
    ",'
    ',"
    ",'
    ',"
    "].join(""),k=b.createDialog({name:c,width:e+42,title:b.lang(c),body:j,yesBtn:{name:b.lang("yes"),click:function(){var a=h.map,c=a.getCenter(),d=c.lng+","+c.lat,g=a.getZoom(),i=[o[0].checked?b.pluginsPath+"baidumap/index.html":"http://api.map.baidu.com/staticimage","?center="+encodeURIComponent(d),"&zoom="+encodeURIComponent(g),"&width="+e,"&height="+f,"&markers="+encodeURIComponent(d),"&markerStyles="+encodeURIComponent("l,A")].join("");o[0].checked?b.insertHtml(''):b.exec("insertimage",i),b.hideDialog().focus()}},beforeRemove:function(){n.remove(),i&&i.write(""),p.remove()}}),l=k.div,m=a('[name="address"]',l),n=a('[name="searchBtn"]',l),o=a('[name="insertDynamicMap"]',k.div),p=a('');p.bind("load",function(){p.unbind("load"),a.IE?g():setTimeout(g,0)}),a(".ke-map",l).replaceWith(p),n.click(function(){h.search(m.val())})})}),KindEditor.plugin("map",function(a){var b=this,c="map",d=b.lang(c+".");b.clickToolbar(c,function(){function e(){f=m[0].contentWindow,g=a.iframeDoc(m)}var f,g,h=['
    ','
    ',d.address+' ','','',"","
    ",'
    ',"
    "].join(""),i=b.createDialog({name:c,width:600,title:b.lang(c),body:h,yesBtn:{name:b.lang("yes"),click:function(){var a=(f.geocoder,f.map),c=a.getCenter().lat()+","+a.getCenter().lng(),d=a.getZoom(),e=a.getMapTypeId(),g="http://maps.googleapis.com/maps/api/staticmap";g+="?center="+encodeURIComponent(c),g+="&zoom="+encodeURIComponent(d),g+="&size=558x360",g+="&maptype="+encodeURIComponent(e),g+="&markers="+encodeURIComponent(c),g+="&language="+b.langType,g+="&sensor=false",b.exec("insertimage",g).hideDialog().focus()}},beforeRemove:function(){l.remove(),g&&g.write(""),m.remove()}}),j=i.div,k=a('[name="address"]',j),l=a('[name="searchBtn"]',j),m=(["",'',"",'',"","",'','
    ',""].join("\n"),a(''));m.bind("load",function(){m.unbind("load"),a.IE?e():setTimeout(e,0)}),a(".ke-map",j).replaceWith(m),l.click(function(){f.search(k.val())})})}),KindEditor.plugin("clearhtml",function(a){var b=this,c="clearhtml";b.clickToolbar(c,function(){b.focus();var c=b.html();c=c.replace(/(]*>)([\s\S]*?)(<\/script>)/gi,""),c=c.replace(/(]*>)([\s\S]*?)(<\/style>)/gi,""),c=a.formatHtml(c,{a:["href","target"],embed:["src","width","height","type","loop","autostart","quality",".width",".height","align","allowscriptaccess"],img:["src","width","height","border","alt","title",".width",".height"],table:["border"],"td,th":["rowspan","colspan"],"div,hr,br,tbody,tr,p,ol,ul,li,blockquote,h1,h2,h3,h4,h5,h6":[]}),b.html(c),b.cmd.selection(!0),b.addBookmark()})}),KindEditor.plugin("code",function(a){var b=this,c="code";b.clickToolbar(c,function(){var d=b.lang(c+"."),e=['
    ','
    ','","
    ",'',"
    "].join(""),f=b.createDialog({name:c,width:450,title:b.lang(c),body:e,yesBtn:{name:b.lang("yes"),click:function(){var c=a(".ke-code-type",f.div).val(),e=g.val(),h=""===c?"":" lang-"+c,i='
    \n'+a.escape(e)+"
    ";return""===a.trim(e)?(alert(d.pleaseInput),void g[0].focus()):void b.insertHtml(i).hideDialog().focus()}}}),g=a("textarea",f.div);g[0].focus()})}),KindEditor.plugin("emoticons",function(a){var b=this,c="emoticons",d=b.emoticonsPath||b.pluginsPath+"emoticons/images/",e=void 0===b.allowPreviewEmoticons?!0:b.allowPreviewEmoticons,f=1;b.clickToolbar(c,function(){function g(c,e,f){c.mouseover(v?function(){e>r?(v.css("left",0),v.css("right","")):(v.css("left",""),v.css("right",0)),w.attr("src",d+f+".gif"),a(this).addClass("ke-on")}:function(){a(this).addClass("ke-on")}),c.mouseout(function(){a(this).removeClass("ke-on")}),c.click(function(a){b.insertHtml('').hideMenu().focus(),a.stop()})}function h(b,c){var e=document.createElement("table");c.append(e),v&&(a(e).mouseover(function(){v.show("block")}),a(e).mouseout(function(){v.hide()}),t.push(a(e))),e.className="ke-table",e.cellPadding=0,e.cellSpacing=0,e.border=0;for(var f=(b-1)*p+o,h=0;l>h;h++)for(var i=e.insertRow(h),j=0;m>j;j++){var k=a(i.insertCell(j));k.addClass("ke-cell"),g(k,j,f);var n=a('').css("background-position","-"+24*f+"px 0px").css("background-image","url("+d+"static.gif)");k.append(n),t.push(k),f++}return e}function i(){a.each(t,function(){this.unbind()})}function j(a,b){a.click(function(a){i(),y.parentNode.removeChild(y),x.remove(),y=h(b,s),k(b),f=b,a.stop()})}function k(b){x=a('
    '),s.append(x);for(var c=1;q>=c;c++){if(b!==c){var d=a('
    ['+c+"]");j(d,c),x.append(d),t.push(d)}else x.append(a("@["+c+"]"));x.append(a("@ "))}}var l=5,m=9,n=135,o=0,p=l*m,q=Math.ceil(n/p),r=Math.floor(m/2),s=a('
    '),t=[],u=b.createMenu({name:c,beforeRemove:function(){i()}});u.div.append(s);var v,w;e&&(v=a('
    ').css("right",0),w=a(''),s.append(v),v.append(w));var x,y=h(f,s);k(f)})}),KindEditor.plugin("filemanager",function(a){function b(a,b,c){return a+" ("+Math.ceil(b/1024)+"KB, "+c+")"}function c(a,c){c.is_dir?a.attr("title",c.filename):a.attr("title",b(c.filename,c.filesize,c.datetime))}var d=this,e="filemanager",f=a.undef(d.fileManagerJson,d.basePath+"php/file_manager_json.php"),g=d.pluginsPath+e+"/images/",h=d.lang(e+".");d.plugin.filemanagerDialog=function(b){function i(b,c,e){var g="path="+b+"&order="+c+"&dir="+p;t.showLoading(d.lang("ajaxLoading")),a.ajax(a.addParam(f,g+"&"+(new Date).getTime()),function(a){t.hideLoading(),e(a)})}function j(b,c,d,e){var f=a.formatUrl(c.current_url+d.filename,"absolute"),g=encodeURIComponent(c.current_dir_path+d.filename+"/");b.click(d.is_dir?function(){i(g,y.val(),e)}:d.is_photo?function(){r.call(this,f,d.filename)}:function(){r.call(this,f,d.filename)}),z.push(b)}function k(b,c){function d(){"VIEW"==x.val()?i(b.current_dir_path,y.val(),m):i(b.current_dir_path,y.val(),l)}a.each(z,function(){this.unbind()}),w.unbind(),x.unbind(),y.unbind(),b.current_dir_path&&w.click(function(){i(b.moveup_dir_path,y.val(),c)}),x.change(d),y.change(d),v.html("")}function l(b){k(b,l);var c=document.createElement("table");c.className="ke-table",c.cellPadding=0,c.cellSpacing=0,c.border=0,v.append(c);for(var d=b.file_list,e=0,f=d.length;f>e;e++){var i=d[e],m=a(c.insertRow(e));m.mouseover(function(){a(this).addClass("ke-on")}).mouseout(function(){a(this).removeClass("ke-on")});var n=g+(i.is_dir?"folder-16.gif":"file-16.gif"),o=a(''+i.filename+''),p=a(m[0].insertCell(0)).addClass("ke-cell ke-name").append(o).append(document.createTextNode(" "+i.filename));!i.is_dir||i.has_file?(m.css("cursor","pointer"),p.attr("title",i.filename),j(p,b,i,l)):p.attr("title",h.emptyFolder),a(m[0].insertCell(1)).addClass("ke-cell ke-size").html(i.is_dir?"-":Math.ceil(i.filesize/1024)+"KB"),a(m[0].insertCell(2)).addClass("ke-cell ke-datetime").html(i.datetime)}}function m(b){k(b,m);for(var d=b.file_list,e=0,f=d.length;f>e;e++){var i=d[e],l=a('
    ');v.append(l);var n=a('
    ').mouseover(function(){a(this).addClass("ke-on")}).mouseout(function(){a(this).removeClass("ke-on")});l.append(n);var o=b.current_url+i.filename,p=i.is_dir?g+"folder-64.gif":i.is_photo?o:g+"file-64.gif",q=a(''+i.filename+'');!i.is_dir||i.has_file?(n.css("cursor","pointer"),c(n,i),j(n,b,i,m)):n.attr("title",h.emptyFolder),n.append(q),l.append('
    '+i.filename+"
    ")}}var n=a.undef(b.width,650),o=a.undef(b.height,510),p=a.undef(b.dirName,""),q=a.undef(b.viewType,"VIEW").toUpperCase(),r=b.clickFn,s=['
    ','
    ','
    ',' ',''+h.moveup+"","
    ",'
    ',h.viewType+' ",h.orderType+' ","
    ",'
    ',"
    ",'
    ',"
    "].join(""),t=d.createDialog({name:e,width:n,height:o,title:d.lang(e),body:s}),u=t.div,v=a(".ke-plugin-filemanager-body",u),w=(a('[name="moveupImg"]',u),a('[name="moveupLink"]',u)),x=(a('[name="viewServer"]',u),a('[name="viewType"]',u)),y=a('[name="orderType"]',u),z=[];return x.val(q),i("",y.val(),"VIEW"==q?m:l),t}}),KindEditor.plugin("flash",function(a){var b=this,c="flash",d=b.lang(c+"."),e=a.undef(b.allowFlashUpload,!0),f=a.undef(b.allowFileManager,!1),g=a.undef(b.formatUploadUrl,!0),h=a.undef(b.extraFileUploadParams,{}),i=a.undef(b.filePostName,"imgFile"),j=a.undef(b.uploadJson,b.basePath+"php/upload_json.php");b.plugin.flash={edit:function(){var k=['
    ','
    ','",'  ','  ','','',"","
    ",'
    ','",' ',"
    ",'
    ','",' ',"
    ","
    "].join(""),l=b.createDialog({name:c,width:450,title:b.lang(c),body:k,yesBtn:{name:b.lang("yes"),click:function(){var c=a.trim(n.val()),d=p.val(),e=q.val();if("http://"==c||a.invalidUrl(c))return alert(b.lang("invalidUrl")),void n[0].focus();if(!/^\d*$/.test(d))return alert(b.lang("invalidWidth")),void p[0].focus();if(!/^\d*$/.test(e))return alert(b.lang("invalidHeight")),void q[0].focus();var f=a.mediaImg(b.themesPath+"common/blank.gif",{src:c,type:a.mediaType(".swf"),width:d,height:e,quality:"high"});b.insertHtml(f).hideDialog().focus()}}}),m=l.div,n=a('[name="url"]',m),o=a('[name="viewServer"]',m),p=a('[name="width"]',m),q=a('[name="height"]',m);if(n.val("http://"),e){var r=a.uploadbutton({button:a(".ke-upload-button",m)[0],fieldName:i,extraParams:h,url:a.addParam(j,"dir=flash"),afterUpload:function(d){if(l.hideLoading(),0===d.error){var e=d.url;g&&(e=a.formatUrl(e,"absolute")),n.val(e),b.afterUpload&&b.afterUpload.call(b,e,d,c),alert(b.lang("uploadSuccess"))}else alert(d.message)},afterError:function(a){l.hideLoading(),b.errorDialog(a)}});r.fileBox.change(function(){l.showLoading(b.lang("uploadLoading")),r.submit()})}else a(".ke-upload-button",m).hide();f?o.click(function(){b.loadPlugin("filemanager",function(){b.plugin.filemanagerDialog({viewType:"LIST",dirName:"flash",clickFn:function(c){b.dialogs.length>1&&(a('[name="url"]',m).val(c),b.afterSelectFile&&b.afterSelectFile.call(b,c),b.hideDialog())}})})}):o.hide();var s=b.plugin.getSelectedFlash();if(s){var t=a.mediaAttrs(s.attr("data-ke-tag"));n.val(t.src),p.val(a.removeUnit(s.css("width"))||t.width||0),q.val(a.removeUnit(s.css("height"))||t.height||0)}n[0].focus(),n[0].select()},"delete":function(){b.plugin.getSelectedFlash().remove(),b.addBookmark()}},b.clickToolbar(c,b.plugin.flash.edit)}),KindEditor.plugin("image",function(a){var b=this,c="image",d=a.undef(b.allowImageUpload,!0),e=a.undef(b.allowImageRemote,!0),f=a.undef(b.formatUploadUrl,!0),g=a.undef(b.allowFileManager,!1),h=a.undef(b.uploadJson,b.basePath+"php/upload_json.php"),i=a.undef(b.imageTabIndex,0),j=b.pluginsPath+"image/images/",k=a.undef(b.extraFileUploadParams,{}),l=a.undef(b.filePostName,"imgFile"),m=a.undef(b.fillDescAfterUploadImage,!1),n=b.lang(c+".");b.plugin.imageDialog=function(d){function e(a,b){D.val(a),E.val(b),J=a,K=b}var i=(d.imageUrl,a.undef(d.imageWidth,""),a.undef(d.imageHeight,""),a.undef(d.imageTitle,""),a.undef(d.imageAlign,""),a.undef(d.showRemote,!0)),o=a.undef(d.showLocal,!0),p=a.undef(d.tabIndex,0),q=d.clickFn,r="kindeditor_upload_iframe_"+(new Date).getTime(),s=[];for(var t in k)s.push('');var u,v=['
    ','
    ','",'","
    "].join(""),w=o||g?450:400,x=o&&i?300:250,y=b.createDialog({name:c,width:w,height:x,title:b.lang(c),body:v,yesBtn:{name:b.lang("yes"),click:function(){if(!y.isLoading){if(o&&i&&u&&1===u.selectedIndex||!i)return""==I.fileBox.val()?void alert(b.lang("pleaseSelectFile")):(y.showLoading(b.lang("uploadLoading")),I.submit(),void B.val(""));var c=a.trim(A.val()),d=D.val(),e=E.val(),f=G.val(),g="";return H.each(function(){return this.checked?(g=this.value,!1):void 0}),"http://"==c||a.invalidUrl(c)?(alert(b.lang("invalidUrl")),void A[0].focus()):/^\d*$/.test(d)?/^\d*$/.test(e)?void q.call(b,c,f,d,e,0,g):(alert(b.lang("invalidHeight")),void E[0].focus()):(alert(b.lang("invalidWidth")),void D[0].focus())}}},beforeRemove:function(){C.unbind(),D.unbind(),E.unbind(),F.unbind()}}),z=y.div,A=a('[name="url"]',z),B=a('[name="localUrl"]',z),C=a('[name="viewServer"]',z),D=a('.tab1 [name="width"]',z),E=a('.tab1 [name="height"]',z),F=a(".ke-refresh-btn",z),G=a('.tab1 [name="title"]',z),H=a('.tab1 [name="align"]',z);i&&o?(u=a.tabs({src:a(".tabs",z),afterSelect:function(){}}),u.add({title:n.remoteImage,panel:a(".tab1",z)}),u.add({title:n.localImage,panel:a(".tab2",z)}),u.select(p)):i?a(".tab1",z).show():o&&a(".tab2",z).show(); +var I=a.uploadbutton({button:a(".ke-upload-button",z)[0],fieldName:l,form:a(".ke-form",z),target:r,width:60,afterUpload:function(d){if(y.hideLoading(),0===d.error){var e=d.url;f&&(e=a.formatUrl(e,"absolute")),b.afterUpload&&b.afterUpload.call(b,e,d,c),m?(a(".ke-dialog-row #remoteUrl",z).val(e),a(".ke-tabs-li",z)[0].click(),a(".ke-refresh-btn",z).click()):q.call(b,e,d.title,d.width,d.height,d.border,d.align)}else alert(d.message)},afterError:function(a){y.hideLoading(),b.errorDialog(a)}});I.fileBox.change(function(){B.val(I.fileBox.val())}),g?C.click(function(){b.loadPlugin("filemanager",function(){b.plugin.filemanagerDialog({viewType:"VIEW",dirName:"image",clickFn:function(c){b.dialogs.length>1&&(a('[name="url"]',z).val(c),b.afterSelectFile&&b.afterSelectFile.call(b,c),b.hideDialog())}})})}):C.hide();var J=0,K=0;return F.click(function(){var b=a('',document).css({position:"absolute",visibility:"hidden",top:0,left:"-1000px"});b.bind("load",function(){e(b.width(),b.height()),b.remove()}),a(document.body).append(b)}),D.change(function(){J>0&&E.val(Math.round(K/J*parseInt(this.value,10)))}),E.change(function(){K>0&&D.val(Math.round(J/K*parseInt(this.value,10)))}),A.val(d.imageUrl),e(d.imageWidth,d.imageHeight),G.val(d.imageTitle),H.each(function(){return this.value===d.imageAlign?(this.checked=!0,!1):void 0}),i&&0===p&&(A[0].focus(),A[0].select()),y},b.plugin.image={edit:function(){var a=b.plugin.getSelectedImage();b.plugin.imageDialog({imageUrl:a?a.attr("data-ke-src"):"http://",imageWidth:a?a.width():"",imageHeight:a?a.height():"",imageTitle:a?a.attr("title"):"",imageAlign:a?a.attr("align"):"",showRemote:e,showLocal:d,tabIndex:a?0:i,clickFn:function(c,d,e,f,g,h){a?(a.attr("src",c),a.attr("data-ke-src",c),a.attr("width",e),a.attr("height",f),a.attr("title",d),a.attr("align",h),a.attr("alt",d)):b.exec("insertimage",c,d,e,f,g,h),setTimeout(function(){b.hideDialog().focus()},0)}})},"delete":function(){var a=b.plugin.getSelectedImage();"a"==a.parent().name&&(a=a.parent()),a.remove(),b.addBookmark()}},b.clickToolbar(c,b.plugin.image.edit)}),KindEditor.plugin("insertfile",function(a){var b=this,c="insertfile",d=a.undef(b.allowFileUpload,!0),e=a.undef(b.allowFileManager,!1),f=a.undef(b.formatUploadUrl,!0),g=a.undef(b.uploadJson,b.basePath+"php/upload_json.php"),h=a.undef(b.extraFileUploadParams,{}),i=a.undef(b.filePostName,"imgFile"),j=b.lang(c+".");b.plugin.fileDialog=function(k){var l=a.undef(k.fileUrl,"http://"),m=a.undef(k.fileTitle,""),n=k.clickFn,o=['
    ','
    ','",'  ','  ','','',"","
    ",'
    ','",'
    ',"
    ","",""].join(""),p=b.createDialog({name:c,width:450,title:b.lang(c),body:o,yesBtn:{name:b.lang("yes"),click:function(){var c=a.trim(r.val()),d=t.val();return"http://"==c||a.invalidUrl(c)?(alert(b.lang("invalidUrl")),void r[0].focus()):(""===a.trim(d)&&(d=c),void n.call(b,c,d))}}}),q=p.div,r=a('[name="url"]',q),s=a('[name="viewServer"]',q),t=a('[name="title"]',q);if(d){var u=a.uploadbutton({button:a(".ke-upload-button",q)[0],fieldName:i,url:a.addParam(g,"dir=file"),extraParams:h,afterUpload:function(d){if(p.hideLoading(),0===d.error){var e=d.url;f&&(e=a.formatUrl(e,"absolute")),r.val(e),b.afterUpload&&b.afterUpload.call(b,e,d,c),alert(b.lang("uploadSuccess"))}else alert(d.message)},afterError:function(a){p.hideLoading(),b.errorDialog(a)}});u.fileBox.change(function(){p.showLoading(b.lang("uploadLoading")),u.submit()})}else a(".ke-upload-button",q).hide();e?s.click(function(){b.loadPlugin("filemanager",function(){b.plugin.filemanagerDialog({viewType:"LIST",dirName:"file",clickFn:function(c){b.dialogs.length>1&&(a('[name="url"]',q).val(c),b.afterSelectFile&&b.afterSelectFile.call(b,c),b.hideDialog())}})})}):s.hide(),r.val(l),t.val(m),r[0].focus(),r[0].select()},b.clickToolbar(c,function(){b.plugin.fileDialog({clickFn:function(a,c){var d=''+c+"";b.insertHtml(d).hideDialog().focus()}})})}),KindEditor.plugin("lineheight",function(a){var b=this,c="lineheight",d=b.lang(c+".");b.clickToolbar(c,function(){var e="",f=b.cmd.commonNode({"*":".line-height"});f&&(e=f.css("line-height"));var g=b.createMenu({name:c,width:150});a.each(d.lineHeight,function(c,d){a.each(d,function(a,c){g.addItem({title:c,checked:e===a,click:function(){b.cmd.toggle('',{span:".line-height="+a}),b.updateState(),b.addBookmark(),b.hideMenu()}})})})})}),KindEditor.plugin("link",function(a){var b=this,c="link";b.plugin.link={edit:function(){var d=b.lang(c+"."),e='
    ',f=b.createDialog({name:c,width:450,title:b.lang(c),body:e,yesBtn:{name:b.lang("yes"),click:function(){var c=a.trim(h.val());return"http://"==c||a.invalidUrl(c)?(alert(b.lang("invalidUrl")),void h[0].focus()):void b.exec("createlink",c,i.val()).hideDialog().focus()}}}),g=f.div,h=a('input[name="url"]',g),i=a('select[name="type"]',g);h.val("http://"),i[0].options[0]=new Option(d.newWindow,"_blank"),i[0].options[1]=new Option(d.selfWindow,""),b.cmd.selection();var j=b.plugin.getSelectedLink();j&&(b.cmd.range.selectNode(j[0]),b.cmd.select(),h.val(j.attr("data-ke-src")),i.val(j.attr("target"))),h[0].focus(),h[0].select()},"delete":function(){b.exec("unlink",null)}},b.clickToolbar(c,b.plugin.link.edit)}),KindEditor.plugin("media",function(a){var b=this,c="media",d=b.lang(c+"."),e=a.undef(b.allowMediaUpload,!0),f=a.undef(b.allowFileManager,!1),g=a.undef(b.formatUploadUrl,!0),h=a.undef(b.extraFileUploadParams,{}),i=a.undef(b.filePostName,"imgFile"),j=a.undef(b.uploadJson,b.basePath+"php/upload_json.php");b.plugin.media={edit:function(){var k=['
    ','
    ','",'  ','  ','','',"","
    ",'
    ','",'',"
    ",'
    ','",'',"
    ",'
    ','",' ',"
    ","
    "].join(""),l=b.createDialog({name:c,width:450,height:230,title:b.lang(c),body:k,yesBtn:{name:b.lang("yes"),click:function(){var c=a.trim(n.val()),d=p.val(),e=q.val();if("http://"==c||a.invalidUrl(c))return alert(b.lang("invalidUrl")),void n[0].focus();if(!/^\d*$/.test(d))return alert(b.lang("invalidWidth")),void p[0].focus();if(!/^\d*$/.test(e))return alert(b.lang("invalidHeight")),void q[0].focus();var f=a.mediaImg(b.themesPath+"common/blank.gif",{src:c,type:a.mediaType(c),width:d,height:e,autostart:r[0].checked?"true":"false",loop:"true"});b.insertHtml(f).hideDialog().focus()}}}),m=l.div,n=a('[name="url"]',m),o=a('[name="viewServer"]',m),p=a('[name="width"]',m),q=a('[name="height"]',m),r=a('[name="autostart"]',m);if(n.val("http://"),e){var s=a.uploadbutton({button:a(".ke-upload-button",m)[0],fieldName:i,extraParams:h,url:a.addParam(j,"dir=media"),afterUpload:function(d){if(l.hideLoading(),0===d.error){var e=d.url;g&&(e=a.formatUrl(e,"absolute")),n.val(e),b.afterUpload&&b.afterUpload.call(b,e,d,c),alert(b.lang("uploadSuccess"))}else alert(d.message)},afterError:function(a){l.hideLoading(),b.errorDialog(a)}});s.fileBox.change(function(){l.showLoading(b.lang("uploadLoading")),s.submit()})}else a(".ke-upload-button",m).hide();f?o.click(function(){b.loadPlugin("filemanager",function(){b.plugin.filemanagerDialog({viewType:"LIST",dirName:"media",clickFn:function(c){b.dialogs.length>1&&(a('[name="url"]',m).val(c),b.afterSelectFile&&b.afterSelectFile.call(b,c),b.hideDialog())}})})}):o.hide();var t=b.plugin.getSelectedMedia();if(t){var u=a.mediaAttrs(t.attr("data-ke-tag"));n.val(u.src),p.val(a.removeUnit(t.css("width"))||u.width||0),q.val(a.removeUnit(t.css("height"))||u.height||0),r[0].checked="true"===u.autostart}n[0].focus(),n[0].select()},"delete":function(){b.plugin.getSelectedMedia().remove(),b.addBookmark()}},b.clickToolbar(c,b.plugin.media.edit)}),function(a){function b(a){this.init(a)}a.extend(b,{init:function(b){function c(b,c){a(".ke-status > div",b).hide(),a(".ke-message",b).addClass("ke-error").show().html(a.escape(c))}var d=this;b.afterError=b.afterError||function(a){alert(a)},d.options=b,d.progressbars={},d.div=a(b.container).html(['
    ','
    ','
    ','',"
    ",'
    '+b.uploadDesc+"
    ",'','',"","
    ",'
    ',"
    "].join("")),d.bodyDiv=a(".ke-swfupload-body",d.div);var e={debug:!1,upload_url:b.uploadUrl,flash_url:b.flashUrl,file_post_name:b.filePostName,button_placeholder:a(".ke-swfupload-button > input",d.div)[0],button_image_url:b.buttonImageUrl,button_width:b.buttonWidth,button_height:b.buttonHeight,button_cursor:SWFUpload.CURSOR.HAND,file_types:b.fileTypes,file_types_description:b.fileTypesDesc,file_upload_limit:b.fileUploadLimit,file_size_limit:b.fileSizeLimit,post_params:b.postParams,file_queued_handler:function(a){a.url=d.options.fileIconUrl,d.appendFile(a)},file_queue_error_handler:function(c,d){var e="";switch(d){case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED:e=b.queueLimitExceeded;break;case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:e=b.fileExceedsSizeLimit;break;case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:e=b.zeroByteFile;break;case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:e=b.invalidFiletype;break;default:e=b.unknownError}a.DEBUG&&alert(e)},upload_start_handler:function(b){var c=this,d=a('div[data-id="'+b.id+'"]',c.bodyDiv);a(".ke-status > div",d).hide(),a(".ke-progressbar",d).show()},upload_progress_handler:function(a,b,c){var e=Math.round(100*b/c),f=d.progressbars[a.id];f.bar.css("width",Math.round(80*e/100)+"px"),f.percent.html(e+"%")},upload_error_handler:function(b){if(b&&b.filestatus==SWFUpload.FILE_STATUS.ERROR){var e=a('div[data-id="'+b.id+'"]',d.bodyDiv).eq(0);c(e,d.options.errorMessage)}},upload_success_handler:function(b,e){var f=a('div[data-id="'+b.id+'"]',d.bodyDiv).eq(0),g={};try{g=a.json(e)}catch(h){d.options.afterError.call(this,""+e+"")}return 0!==g.error?void c(f,a.DEBUG?g.message:d.options.errorMessage):(b.url=g.url,a(".ke-img",f).attr("src",b.url).attr("data-status",b.filestatus).data("data",g),void a(".ke-status > div",f).hide())}};d.swfu=new SWFUpload(e),a(".ke-swfupload-startupload input",d.div).click(function(){d.swfu.startUpload()})},getUrlList:function(){var b=[];return a(".ke-img",self.bodyDiv).each(function(){var c=a(this),d=c.attr("data-status");d==SWFUpload.FILE_STATUS.COMPLETE&&b.push(c.data("data"))}),b},removeFile:function(b){var c=this;c.swfu.cancelUpload(b);var d=a('div[data-id="'+b+'"]',c.bodyDiv);a(".ke-photo",d).unbind(),a(".ke-delete",d).unbind(),d.remove()},removeFiles:function(){var b=this;a(".ke-item",b.bodyDiv).each(function(){b.removeFile(a(this).attr("data-id"))})},appendFile:function(b){var c=this,d=a('
    ');c.bodyDiv.append(d);var e=a('
    ').mouseover(function(){a(this).addClass("ke-on")}).mouseout(function(){a(this).removeClass("ke-on")});d.append(e);var f=a(''+b.name+'');e.append(f),a('').appendTo(e).click(function(){c.removeFile(b.id)});var g=a('
    ').appendTo(e);a(['
    ','
    ','
    0%
    '].join("")).hide().appendTo(g),a('
    '+c.options.pendingMessage+"
    ").appendTo(g),d.append('
    '+b.name+"
    "),c.progressbars[b.id]={bar:a(".ke-progressbar-bar-inner",e),percent:a(".ke-progressbar-percent",e)}},remove:function(){this.removeFiles(),this.swfu.destroy(),this.div.html("")}}),a.swfupload=function(a,c){return new b(a,c)}}(KindEditor),KindEditor.plugin("multiimage",function(a){var b=this,c="multiimage",d=(a.undef(b.formatUploadUrl,!0),a.undef(b.uploadJson,b.basePath+"php/upload_json.php")),e=b.pluginsPath+"multiimage/images/",f=a.undef(b.imageSizeLimit,"1MB"),g=(a.undef(b.imageFileTypes,"*.jpg;*.gif;*.png"),a.undef(b.imageUploadLimit,20)),h=a.undef(b.filePostName,"imgFile"),i=b.lang(c+".");b.plugin.multiImageDialog=function(j){var k=j.clickFn,l=a.tmpl(i.uploadDesc,{uploadLimit:g,sizeLimit:f}),m=['
    ','
    ',"
    ","
    "].join(""),n=b.createDialog({name:c,width:650,height:510,title:b.lang(c),body:m,previewBtn:{name:i.insertAll,click:function(){k.call(b,p.getUrlList())}},yesBtn:{name:i.clearAll,click:function(){p.removeFiles()}},beforeRemove:function(){(!a.IE||a.V<=8)&&p.remove()}}),o=n.div,p=a.swfupload({container:a(".swfupload",o),buttonImageUrl:e+("zh-CN"==b.langType?"select-files-zh-CN.png":"select-files-en.png"),buttonWidth:"zh-CN"==b.langType?72:88,buttonHeight:23,fileIconUrl:e+"image.png",uploadDesc:l,startButtonValue:i.startUpload,uploadUrl:a.addParam(d,"dir=image"),flashUrl:e+"swfupload.swf",filePostName:h,fileTypes:"*.jpg;*.jpeg;*.gif;*.png;*.bmp",fileTypesDesc:"Image Files",fileUploadLimit:g,fileSizeLimit:f,postParams:a.undef(b.extraFileUploadParams,{}),queueLimitExceeded:i.queueLimitExceeded,fileExceedsSizeLimit:i.fileExceedsSizeLimit,zeroByteFile:i.zeroByteFile,invalidFiletype:i.invalidFiletype,unknownError:i.unknownError,pendingMessage:i.pending,errorMessage:i.uploadError,afterError:function(a){b.errorDialog(a)}});return n},b.clickToolbar(c,function(){b.plugin.multiImageDialog({clickFn:function(c){0!==c.length&&(a.each(c,function(a,c){b.afterUpload&&b.afterUpload.call(b,c.url,c,"multiimage"),b.exec("insertimage",c.url,c.title,c.width,c.height,c.border,c.align)}),setTimeout(function(){b.hideDialog().focus()},0))}})})}),function(){window.SWFUpload=function(a){this.initSWFUpload(a)},SWFUpload.prototype.initSWFUpload=function(a){try{this.customSettings={},this.settings=a,this.eventQueue=[],this.movieName="KindEditor_SWFUpload_"+SWFUpload.movieCount++,this.movieElement=null,SWFUpload.instances[this.movieName]=this,this.initSettings(),this.loadFlash(),this.displayDebugInfo()}catch(b){throw delete SWFUpload.instances[this.movieName],b}},SWFUpload.instances={},SWFUpload.movieCount=0,SWFUpload.version="2.2.0 2009-03-25",SWFUpload.QUEUE_ERROR={QUEUE_LIMIT_EXCEEDED:-100,FILE_EXCEEDS_SIZE_LIMIT:-110,ZERO_BYTE_FILE:-120,INVALID_FILETYPE:-130},SWFUpload.UPLOAD_ERROR={HTTP_ERROR:-200,MISSING_UPLOAD_URL:-210,IO_ERROR:-220,SECURITY_ERROR:-230,UPLOAD_LIMIT_EXCEEDED:-240,UPLOAD_FAILED:-250,SPECIFIED_FILE_ID_NOT_FOUND:-260,FILE_VALIDATION_FAILED:-270,FILE_CANCELLED:-280,UPLOAD_STOPPED:-290},SWFUpload.FILE_STATUS={QUEUED:-1,IN_PROGRESS:-2,ERROR:-3,COMPLETE:-4,CANCELLED:-5},SWFUpload.BUTTON_ACTION={SELECT_FILE:-100,SELECT_FILES:-110,START_UPLOAD:-120},SWFUpload.CURSOR={ARROW:-1,HAND:-2},SWFUpload.WINDOW_MODE={WINDOW:"window",TRANSPARENT:"transparent",OPAQUE:"opaque"},SWFUpload.completeURL=function(a){if("string"!=typeof a||a.match(/^https?:\/\//i)||a.match(/^\//))return a;var b=(window.location.protocol+"//"+window.location.hostname+(window.location.port?":"+window.location.port:""),window.location.pathname.lastIndexOf("/"));return path=0>=b?"/":window.location.pathname.substr(0,b)+"/",path+a},SWFUpload.prototype.initSettings=function(){this.ensureDefault=function(a,b){this.settings[a]=void 0==this.settings[a]?b:this.settings[a]},this.ensureDefault("upload_url",""),this.ensureDefault("preserve_relative_urls",!1),this.ensureDefault("file_post_name","Filedata"),this.ensureDefault("post_params",{}),this.ensureDefault("use_query_string",!1),this.ensureDefault("requeue_on_error",!1),this.ensureDefault("http_success",[]),this.ensureDefault("assume_success_timeout",0),this.ensureDefault("file_types","*.*"),this.ensureDefault("file_types_description","All Files"),this.ensureDefault("file_size_limit",0),this.ensureDefault("file_upload_limit",0),this.ensureDefault("file_queue_limit",0),this.ensureDefault("flash_url","swfupload.swf"),this.ensureDefault("prevent_swf_caching",!0),this.ensureDefault("button_image_url",""),this.ensureDefault("button_width",1),this.ensureDefault("button_height",1),this.ensureDefault("button_text",""),this.ensureDefault("button_text_style","color: #000000; font-size: 16pt;"),this.ensureDefault("button_text_top_padding",0),this.ensureDefault("button_text_left_padding",0),this.ensureDefault("button_action",SWFUpload.BUTTON_ACTION.SELECT_FILES),this.ensureDefault("button_disabled",!1),this.ensureDefault("button_placeholder_id",""),this.ensureDefault("button_placeholder",null),this.ensureDefault("button_cursor",SWFUpload.CURSOR.ARROW),this.ensureDefault("button_window_mode",SWFUpload.WINDOW_MODE.WINDOW),this.ensureDefault("debug",!1),this.settings.debug_enabled=this.settings.debug,this.settings.return_upload_start_handler=this.returnUploadStart,this.ensureDefault("swfupload_loaded_handler",null),this.ensureDefault("file_dialog_start_handler",null),this.ensureDefault("file_queued_handler",null),this.ensureDefault("file_queue_error_handler",null),this.ensureDefault("file_dialog_complete_handler",null),this.ensureDefault("upload_start_handler",null),this.ensureDefault("upload_progress_handler",null),this.ensureDefault("upload_error_handler",null),this.ensureDefault("upload_success_handler",null),this.ensureDefault("upload_complete_handler",null),this.ensureDefault("debug_handler",this.debugMessage),this.ensureDefault("custom_settings",{}),this.customSettings=this.settings.custom_settings,this.settings.prevent_swf_caching&&(this.settings.flash_url=this.settings.flash_url+(this.settings.flash_url.indexOf("?")<0?"?":"&")+"preventswfcaching="+(new Date).getTime()),this.settings.preserve_relative_urls||(this.settings.upload_url=SWFUpload.completeURL(this.settings.upload_url),this.settings.button_image_url=SWFUpload.completeURL(this.settings.button_image_url)),delete this.ensureDefault},SWFUpload.prototype.loadFlash=function(){var a,b;if(null!==document.getElementById(this.movieName))throw"ID "+this.movieName+" is already in use. The Flash Object could not be added";if(a=document.getElementById(this.settings.button_placeholder_id)||this.settings.button_placeholder,void 0==a)throw"Could not find the placeholder element: "+this.settings.button_placeholder_id;b=document.createElement("div"),b.innerHTML=this.getFlashHTML(),a.parentNode.replaceChild(b.firstChild,a),void 0==window[this.movieName]&&(window[this.movieName]=this.getMovieElement())},SWFUpload.prototype.getFlashHTML=function(){var a="";return KindEditor.IE&&KindEditor.V>8&&(a=' classid = "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"'),['','','','','','','',""].join("")},SWFUpload.prototype.getFlashVars=function(){var a=this.buildParamString(),b=this.settings.http_success.join(",");return["movieName=",encodeURIComponent(this.movieName),"&uploadURL=",encodeURIComponent(this.settings.upload_url),"&useQueryString=",encodeURIComponent(this.settings.use_query_string),"&requeueOnError=",encodeURIComponent(this.settings.requeue_on_error),"&httpSuccess=",encodeURIComponent(b),"&assumeSuccessTimeout=",encodeURIComponent(this.settings.assume_success_timeout),"&params=",encodeURIComponent(a),"&filePostName=",encodeURIComponent(this.settings.file_post_name),"&fileTypes=",encodeURIComponent(this.settings.file_types),"&fileTypesDescription=",encodeURIComponent(this.settings.file_types_description),"&fileSizeLimit=",encodeURIComponent(this.settings.file_size_limit),"&fileUploadLimit=",encodeURIComponent(this.settings.file_upload_limit),"&fileQueueLimit=",encodeURIComponent(this.settings.file_queue_limit),"&debugEnabled=",encodeURIComponent(this.settings.debug_enabled),"&buttonImageURL=",encodeURIComponent(this.settings.button_image_url),"&buttonWidth=",encodeURIComponent(this.settings.button_width),"&buttonHeight=",encodeURIComponent(this.settings.button_height),"&buttonText=",encodeURIComponent(this.settings.button_text),"&buttonTextTopPadding=",encodeURIComponent(this.settings.button_text_top_padding),"&buttonTextLeftPadding=",encodeURIComponent(this.settings.button_text_left_padding),"&buttonTextStyle=",encodeURIComponent(this.settings.button_text_style),"&buttonAction=",encodeURIComponent(this.settings.button_action),"&buttonDisabled=",encodeURIComponent(this.settings.button_disabled),"&buttonCursor=",encodeURIComponent(this.settings.button_cursor)].join("")},SWFUpload.prototype.getMovieElement=function(){if(void 0==this.movieElement&&(this.movieElement=document.getElementById(this.movieName)),null===this.movieElement)throw"Could not find Flash element";return this.movieElement},SWFUpload.prototype.buildParamString=function(){var a=this.settings.post_params,b=[];if("object"==typeof a)for(var c in a)a.hasOwnProperty(c)&&b.push(encodeURIComponent(c.toString())+"="+encodeURIComponent(a[c].toString()));return b.join("&")},SWFUpload.prototype.destroy=function(){try{this.cancelUpload(null,!1);var a=null;if(a=this.getMovieElement(),a&&"unknown"==typeof a.CallFunction){for(var b in a)try{"function"==typeof a[b]&&(a[b]=null)}catch(c){}try{a.parentNode.removeChild(a)}catch(d){}}return window[this.movieName]=null,SWFUpload.instances[this.movieName]=null,delete SWFUpload.instances[this.movieName],this.movieElement=null,this.settings=null,this.customSettings=null,this.eventQueue=null,this.movieName=null,!0}catch(e){return!1}},SWFUpload.prototype.displayDebugInfo=function(){this.debug(["---SWFUpload Instance Info---\n","Version: ",SWFUpload.version,"\n","Movie Name: ",this.movieName,"\n","Settings:\n"," ","upload_url: ",this.settings.upload_url,"\n"," ","flash_url: ",this.settings.flash_url,"\n"," ","use_query_string: ",this.settings.use_query_string.toString(),"\n"," ","requeue_on_error: ",this.settings.requeue_on_error.toString(),"\n"," ","http_success: ",this.settings.http_success.join(", "),"\n"," ","assume_success_timeout: ",this.settings.assume_success_timeout,"\n"," ","file_post_name: ",this.settings.file_post_name,"\n"," ","post_params: ",this.settings.post_params.toString(),"\n"," ","file_types: ",this.settings.file_types,"\n"," ","file_types_description: ",this.settings.file_types_description,"\n"," ","file_size_limit: ",this.settings.file_size_limit,"\n"," ","file_upload_limit: ",this.settings.file_upload_limit,"\n"," ","file_queue_limit: ",this.settings.file_queue_limit,"\n"," ","debug: ",this.settings.debug.toString(),"\n"," ","prevent_swf_caching: ",this.settings.prevent_swf_caching.toString(),"\n"," ","button_placeholder_id: ",this.settings.button_placeholder_id.toString(),"\n"," ","button_placeholder: ",this.settings.button_placeholder?"Set":"Not Set","\n"," ","button_image_url: ",this.settings.button_image_url.toString(),"\n"," ","button_width: ",this.settings.button_width.toString(),"\n"," ","button_height: ",this.settings.button_height.toString(),"\n"," ","button_text: ",this.settings.button_text.toString(),"\n"," ","button_text_style: ",this.settings.button_text_style.toString(),"\n"," ","button_text_top_padding: ",this.settings.button_text_top_padding.toString(),"\n"," ","button_text_left_padding: ",this.settings.button_text_left_padding.toString(),"\n"," ","button_action: ",this.settings.button_action.toString(),"\n"," ","button_disabled: ",this.settings.button_disabled.toString(),"\n"," ","custom_settings: ",this.settings.custom_settings.toString(),"\n","Event Handlers:\n"," ","swfupload_loaded_handler assigned: ",("function"==typeof this.settings.swfupload_loaded_handler).toString(),"\n"," ","file_dialog_start_handler assigned: ",("function"==typeof this.settings.file_dialog_start_handler).toString(),"\n"," ","file_queued_handler assigned: ",("function"==typeof this.settings.file_queued_handler).toString(),"\n"," ","file_queue_error_handler assigned: ",("function"==typeof this.settings.file_queue_error_handler).toString(),"\n"," ","upload_start_handler assigned: ",("function"==typeof this.settings.upload_start_handler).toString(),"\n"," ","upload_progress_handler assigned: ",("function"==typeof this.settings.upload_progress_handler).toString(),"\n"," ","upload_error_handler assigned: ",("function"==typeof this.settings.upload_error_handler).toString(),"\n"," ","upload_success_handler assigned: ",("function"==typeof this.settings.upload_success_handler).toString(),"\n"," ","upload_complete_handler assigned: ",("function"==typeof this.settings.upload_complete_handler).toString(),"\n"," ","debug_handler assigned: ",("function"==typeof this.settings.debug_handler).toString(),"\n"].join(""))},SWFUpload.prototype.addSetting=function(a,b,c){return this.settings[a]=void 0==b?c:b},SWFUpload.prototype.getSetting=function(a){return void 0!=this.settings[a]?this.settings[a]:""},SWFUpload.prototype.callFlash=function(functionName,argumentArray){argumentArray=argumentArray||[];var movieElement=this.getMovieElement(),returnValue,returnString;try{returnString=movieElement.CallFunction(''+__flash__argumentsToXML(argumentArray,0)+""),returnValue=eval(returnString)}catch(ex){throw"Call to "+functionName+" failed"}return void 0!=returnValue&&"object"==typeof returnValue.post&&(returnValue=this.unescapeFilePostParams(returnValue)),returnValue},SWFUpload.prototype.selectFile=function(){this.callFlash("SelectFile")},SWFUpload.prototype.selectFiles=function(){this.callFlash("SelectFiles")},SWFUpload.prototype.startUpload=function(a){this.callFlash("StartUpload",[a])},SWFUpload.prototype.cancelUpload=function(a,b){b!==!1&&(b=!0),this.callFlash("CancelUpload",[a,b])},SWFUpload.prototype.stopUpload=function(){this.callFlash("StopUpload")},SWFUpload.prototype.getStats=function(){return this.callFlash("GetStats")},SWFUpload.prototype.setStats=function(a){this.callFlash("SetStats",[a])},SWFUpload.prototype.getFile=function(a){return"number"==typeof a?this.callFlash("GetFileByIndex",[a]):this.callFlash("GetFile",[a])},SWFUpload.prototype.addFileParam=function(a,b,c){return this.callFlash("AddFileParam",[a,b,c])},SWFUpload.prototype.removeFileParam=function(a,b){this.callFlash("RemoveFileParam",[a,b])},SWFUpload.prototype.setUploadURL=function(a){this.settings.upload_url=a.toString(),this.callFlash("SetUploadURL",[a])},SWFUpload.prototype.setPostParams=function(a){this.settings.post_params=a,this.callFlash("SetPostParams",[a])},SWFUpload.prototype.addPostParam=function(a,b){this.settings.post_params[a]=b,this.callFlash("SetPostParams",[this.settings.post_params])},SWFUpload.prototype.removePostParam=function(a){delete this.settings.post_params[a],this.callFlash("SetPostParams",[this.settings.post_params])},SWFUpload.prototype.setFileTypes=function(a,b){this.settings.file_types=a,this.settings.file_types_description=b,this.callFlash("SetFileTypes",[a,b])},SWFUpload.prototype.setFileSizeLimit=function(a){this.settings.file_size_limit=a,this.callFlash("SetFileSizeLimit",[a])},SWFUpload.prototype.setFileUploadLimit=function(a){this.settings.file_upload_limit=a,this.callFlash("SetFileUploadLimit",[a])},SWFUpload.prototype.setFileQueueLimit=function(a){this.settings.file_queue_limit=a,this.callFlash("SetFileQueueLimit",[a])},SWFUpload.prototype.setFilePostName=function(a){this.settings.file_post_name=a,this.callFlash("SetFilePostName",[a])},SWFUpload.prototype.setUseQueryString=function(a){this.settings.use_query_string=a,this.callFlash("SetUseQueryString",[a])},SWFUpload.prototype.setRequeueOnError=function(a){this.settings.requeue_on_error=a,this.callFlash("SetRequeueOnError",[a])},SWFUpload.prototype.setHTTPSuccess=function(a){"string"==typeof a&&(a=a.replace(" ","").split(",")),this.settings.http_success=a,this.callFlash("SetHTTPSuccess",[a])},SWFUpload.prototype.setAssumeSuccessTimeout=function(a){this.settings.assume_success_timeout=a,this.callFlash("SetAssumeSuccessTimeout",[a])},SWFUpload.prototype.setDebugEnabled=function(a){this.settings.debug_enabled=a,this.callFlash("SetDebugEnabled",[a])},SWFUpload.prototype.setButtonImageURL=function(a){void 0==a&&(a=""),this.settings.button_image_url=a,this.callFlash("SetButtonImageURL",[a])},SWFUpload.prototype.setButtonDimensions=function(a,b){this.settings.button_width=a,this.settings.button_height=b;var c=this.getMovieElement();void 0!=c&&(c.style.width=a+"px",c.style.height=b+"px"),this.callFlash("SetButtonDimensions",[a,b])},SWFUpload.prototype.setButtonText=function(a){this.settings.button_text=a,this.callFlash("SetButtonText",[a])},SWFUpload.prototype.setButtonTextPadding=function(a,b){this.settings.button_text_top_padding=b,this.settings.button_text_left_padding=a,this.callFlash("SetButtonTextPadding",[a,b])},SWFUpload.prototype.setButtonTextStyle=function(a){this.settings.button_text_style=a,this.callFlash("SetButtonTextStyle",[a])},SWFUpload.prototype.setButtonDisabled=function(a){this.settings.button_disabled=a,this.callFlash("SetButtonDisabled",[a])},SWFUpload.prototype.setButtonAction=function(a){this.settings.button_action=a,this.callFlash("SetButtonAction",[a])},SWFUpload.prototype.setButtonCursor=function(a){this.settings.button_cursor=a,this.callFlash("SetButtonCursor",[a])},SWFUpload.prototype.queueEvent=function(a,b){void 0==b?b=[]:b instanceof Array||(b=[b]);var c=this;if("function"==typeof this.settings[a])this.eventQueue.push(function(){this.settings[a].apply(this,b) +}),setTimeout(function(){c.executeNextEvent()},0);else if(null!==this.settings[a])throw"Event handler "+a+" is unknown or is not a function"},SWFUpload.prototype.executeNextEvent=function(){var a=this.eventQueue?this.eventQueue.shift():null;"function"==typeof a&&a.apply(this)},SWFUpload.prototype.unescapeFilePostParams=function(a){var b,c=/[$]([0-9a-f]{4})/i,d={};if(void 0!=a){for(var e in a.post)if(a.post.hasOwnProperty(e)){b=e;for(var f;null!==(f=c.exec(b));)b=b.replace(f[0],String.fromCharCode(parseInt("0x"+f[1],16)));d[b]=a.post[e]}a.post=d}return a},SWFUpload.prototype.testExternalInterface=function(){try{return this.callFlash("TestExternalInterface")}catch(a){return!1}},SWFUpload.prototype.flashReady=function(){var a=this.getMovieElement();return a?(this.cleanUp(a),void this.queueEvent("swfupload_loaded_handler")):void this.debug("Flash called back ready but the flash movie can't be found.")},SWFUpload.prototype.cleanUp=function(a){try{if(this.movieElement&&"unknown"==typeof a.CallFunction){this.debug("Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)");for(var b in a)try{"function"==typeof a[b]&&(a[b]=null)}catch(c){}}}catch(d){}window.__flash__removeCallback=function(a,b){try{a&&(a[b]=null)}catch(c){}}},SWFUpload.prototype.fileDialogStart=function(){this.queueEvent("file_dialog_start_handler")},SWFUpload.prototype.fileQueued=function(a){a=this.unescapeFilePostParams(a),this.queueEvent("file_queued_handler",a)},SWFUpload.prototype.fileQueueError=function(a,b,c){a=this.unescapeFilePostParams(a),this.queueEvent("file_queue_error_handler",[a,b,c])},SWFUpload.prototype.fileDialogComplete=function(a,b,c){this.queueEvent("file_dialog_complete_handler",[a,b,c])},SWFUpload.prototype.uploadStart=function(a){a=this.unescapeFilePostParams(a),this.queueEvent("return_upload_start_handler",a)},SWFUpload.prototype.returnUploadStart=function(a){var b;if("function"==typeof this.settings.upload_start_handler)a=this.unescapeFilePostParams(a),b=this.settings.upload_start_handler.call(this,a);else if(void 0!=this.settings.upload_start_handler)throw"upload_start_handler must be a function";void 0===b&&(b=!0),b=!!b,this.callFlash("ReturnUploadStart",[b])},SWFUpload.prototype.uploadProgress=function(a,b,c){a=this.unescapeFilePostParams(a),this.queueEvent("upload_progress_handler",[a,b,c])},SWFUpload.prototype.uploadError=function(a,b,c){a=this.unescapeFilePostParams(a),this.queueEvent("upload_error_handler",[a,b,c])},SWFUpload.prototype.uploadSuccess=function(a,b,c){a=this.unescapeFilePostParams(a),this.queueEvent("upload_success_handler",[a,b,c])},SWFUpload.prototype.uploadComplete=function(a){a=this.unescapeFilePostParams(a),this.queueEvent("upload_complete_handler",a)},SWFUpload.prototype.debug=function(a){this.queueEvent("debug_handler",a)},SWFUpload.prototype.debugMessage=function(a){if(this.settings.debug){var b,c=[];if("object"==typeof a&&"string"==typeof a.name&&"string"==typeof a.message){for(var d in a)a.hasOwnProperty(d)&&c.push(d+": "+a[d]);b=c.join("\n")||"",c=b.split("\n"),b="EXCEPTION: "+c.join("\nEXCEPTION: "),SWFUpload.Console.writeLine(b)}else SWFUpload.Console.writeLine(a)}},SWFUpload.Console={},SWFUpload.Console.writeLine=function(a){var b,c;try{b=document.getElementById("SWFUpload_Console"),b||(c=document.createElement("form"),document.getElementsByTagName("body")[0].appendChild(c),b=document.createElement("textarea"),b.id="SWFUpload_Console",b.style.fontFamily="monospace",b.setAttribute("wrap","off"),b.wrap="off",b.style.overflow="auto",b.style.width="700px",b.style.height="350px",b.style.margin="5px",c.appendChild(b)),b.value+=a+"\n",b.scrollTop=b.scrollHeight-b.clientHeight}catch(d){alert("Exception: "+d.name+" Message: "+d.message)}}}(),function(){"function"==typeof SWFUpload&&(SWFUpload.queue={},SWFUpload.prototype.initSettings=function(a){return function(){"function"==typeof a&&a.call(this),this.queueSettings={},this.queueSettings.queue_cancelled_flag=!1,this.queueSettings.queue_upload_count=0,this.queueSettings.user_upload_complete_handler=this.settings.upload_complete_handler,this.queueSettings.user_upload_start_handler=this.settings.upload_start_handler,this.settings.upload_complete_handler=SWFUpload.queue.uploadCompleteHandler,this.settings.upload_start_handler=SWFUpload.queue.uploadStartHandler,this.settings.queue_complete_handler=this.settings.queue_complete_handler||null}}(SWFUpload.prototype.initSettings),SWFUpload.prototype.startUpload=function(a){this.queueSettings.queue_cancelled_flag=!1,this.callFlash("StartUpload",[a])},SWFUpload.prototype.cancelQueue=function(){this.queueSettings.queue_cancelled_flag=!0,this.stopUpload();for(var a=this.getStats();a.files_queued>0;)this.cancelUpload(),a=this.getStats()},SWFUpload.queue.uploadStartHandler=function(a){var b;return"function"==typeof this.queueSettings.user_upload_start_handler&&(b=this.queueSettings.user_upload_start_handler.call(this,a)),b=b===!1?!1:!0,this.queueSettings.queue_cancelled_flag=!b,b},SWFUpload.queue.uploadCompleteHandler=function(a){var b,c=this.queueSettings.user_upload_complete_handler;if(a.filestatus===SWFUpload.FILE_STATUS.COMPLETE&&this.queueSettings.queue_upload_count++,b="function"==typeof c?c.call(this,a)===!1?!1:!0:a.filestatus===SWFUpload.FILE_STATUS.QUEUED?!1:!0){var d=this.getStats();d.files_queued>0&&this.queueSettings.queue_cancelled_flag===!1?this.startUpload():this.queueSettings.queue_cancelled_flag===!1?(this.queueEvent("queue_complete_handler",[this.queueSettings.queue_upload_count]),this.queueSettings.queue_upload_count=0):(this.queueSettings.queue_cancelled_flag=!1,this.queueSettings.queue_upload_count=0)}})}(),KindEditor.plugin("pagebreak",function(a){var b=this,c="pagebreak",d=a.undef(b.pagebreakHtml,'
    ');b.clickToolbar(c,function(){var c=b.cmd,e=c.range;b.focus();var f="br"==b.newlineTag||a.WEBKIT?"":'';if(b.insertHtml(d+f),""!==f){var g=a("#__kindeditor_tail_tag__",b.edit.doc);e.selectNodeContents(g[0]),g.removeAttr("id"),c.select()}})}),KindEditor.plugin("plainpaste",function(a){var b=this,c="plainpaste";b.clickToolbar(c,function(){var d=b.lang(c+"."),e='
    '+d.comment+'
    ',f=b.createDialog({name:c,width:450,title:b.lang(c),body:e,yesBtn:{name:b.lang("yes"),click:function(){var c=g.val();c=a.escape(c),c=c.replace(/ {2}/g,"  "),c="p"==b.newlineTag?c.replace(/^/,"

    ").replace(/$/,"

    ").replace(/\n/g,"

    "):c.replace(/\n/g,"
    $&"),b.insertHtml(c).hideDialog().focus()}}}),g=a("textarea",f.div);g[0].focus()})}),KindEditor.plugin("preview",function(a){var b=this,c="preview";b.clickToolbar(c,function(){var d=(b.lang(c+"."),'

    '),e=b.createDialog({name:c,width:750,title:b.lang(c),body:d}),f=a("iframe",e.div),g=a.iframeDoc(f);g.open(),g.write(b.fullHtml()),g.close(),a(g.body).css("background-color","#FFF"),f[0].contentWindow.focus()})}),KindEditor.plugin("quickformat",function(a){function b(a){for(var b=a.first();b&&b.first();)b=b.first();return b}var c=this,d="quickformat",e=a.toMap("blockquote,center,div,h1,h2,h3,h4,h5,h6,p");c.clickToolbar(d,function(){c.focus();for(var d,f=c.edit.doc,g=c.cmd.range,h=a(f.body).first(),i=[],j=[],k=g.createBookmark(!0);h;){d=h.next();var l=b(h);l&&"img"==l.name||(e[h.name]?(h.html(h.html().replace(/^(\s| | )+/gi,"")),h.css("text-indent","2em")):j.push(h),(!d||e[d.name]||e[h.name]&&!e[d.name])&&(j.length>0&&i.push(j),j=[])),h=d}a.each(i,function(b,c){var d=a('

    ',f);c[0].before(d),a.each(c,function(a,b){d.append(b)})}),g.moveToBookmark(k),c.addBookmark()})}),KindEditor.plugin("table",function(a){function b(a,b){b=b.toUpperCase(),a.css("background-color",b),a.css("color","#000000"===b?"#FFFFFF":"#000000"),a.html(b)}function c(c,d){function f(){a.each(i,function(){this.remove()}),i=[],a(document).unbind("click,mousedown",f),c.unbind("click,mousedown",f)}d.bind("click,mousedown",function(a){a.stopPropagation()}),d.click(function(){f();var d=a(this),g=d.pos(),h=a.colorpicker({x:g.x,y:g.y+d.height(),z:811214,selectedColor:a(this).html(),colors:e.colorTable,noColor:e.lang("noColor"),shadowMode:e.shadowMode,click:function(a){b(d,a),f()}});i.push(h),a(document).bind("click,mousedown",f),c.bind("click,mousedown",f)})}function d(a,b,c){for(var d=0,e=0,f=b.cells.length;f>e&&b.cells[e]!=c;e++)d+=b.cells[e].rowSpan-1;return c.cellIndex-d}var e=this,f="table",g=e.lang(f+"."),h="ke-zeroborder",i=[];e.plugin.table={prop:function(d){var i=['
    ','
    ','",g.rows+'   ',g.cols+' ',"
    ",'
    ','",g.width+'   ','   ",g.height+'   ','","
    ",'
    ','",g.padding+'   ',g.spacing+' ',"
    ",'
    ','",'","
    ",'
    ','",g.borderWidth+'   ',g.borderColor+' ',"
    ",'
    ','",'',"
    ","
    "].join(""),j=e.cmd.range.createBookmark(),k=e.createDialog({name:f,width:500,title:e.lang(f),body:i,beforeRemove:function(){w.unbind()},yesBtn:{name:e.lang("yes"),click:function(){var b=m.val(),c=n.val(),d=o.val(),f=p.val(),g=q.val(),i=r.val(),k=s.val(),l=t.val(),y=u.val(),z=v.val(),A=a(w[0]).html()||"",B=a(w[1]).html()||"";if(0==b||!/^\d+$/.test(b))return alert(e.lang("invalidRows")),void m[0].focus();if(0==c||!/^\d+$/.test(c))return alert(e.lang("invalidRows")),void n[0].focus();if(!/^\d*$/.test(d))return alert(e.lang("invalidWidth")),void o[0].focus();if(!/^\d*$/.test(f))return alert(e.lang("invalidHeight")),void p[0].focus();if(!/^\d*$/.test(k))return alert(e.lang("invalidPadding")),void s[0].focus();if(!/^\d*$/.test(l))return alert(e.lang("invalidSpacing")),void t[0].focus();if(!/^\d*$/.test(z))return alert(e.lang("invalidBorder")),void v[0].focus();if(x)return""!==d?x.width(d+g):x.css("width",""),void 0!==x[0].width&&x.removeAttr("width"),""!==f?x.height(f+i):x.css("height",""),void 0!==x[0].height&&x.removeAttr("height"),x.css("background-color",B),void 0!==x[0].bgColor&&x.removeAttr("bgColor"),""!==k?x[0].cellPadding=k:x.removeAttr("cellPadding"),""!==l?x[0].cellSpacing=l:x.removeAttr("cellSpacing"),""!==y?x[0].align=y:x.removeAttr("align"),""!==z?x.attr("border",z):x.removeAttr("border"),""===z||"0"===z?x.addClass(h):x.removeClass(h),""!==A?x.attr("borderColor",A):x.removeAttr("borderColor"),e.hideDialog().focus(),e.cmd.range.moveToBookmark(j),e.cmd.select(),void e.addBookmark();var C="";""!==d&&(C+="width:"+d+g+";"),""!==f&&(C+="height:"+f+i+";"),""!==B&&(C+="background-color:"+B+";");var D="E;E++){D+="
    ";for(var F=0;c>F;F++)D+="";D+=""}D+="
    "+(a.IE?" ":"
    ")+"
    ",a.IE||(D+="
    "),e.insertHtml(D),e.select().hideDialog().focus(),e.addBookmark()}}}),l=k.div,m=a('[name="rows"]',l).val(3),n=a('[name="cols"]',l).val(2),o=a('[name="width"]',l).val(100),p=a('[name="height"]',l),q=a('[name="widthType"]',l),r=a('[name="heightType"]',l),s=a('[name="padding"]',l).val(2),t=a('[name="spacing"]',l).val(0),u=a('[name="align"]',l),v=a('[name="border"]',l).val(1),w=a(".ke-input-color",l);c(l,w.eq(0)),c(l,w.eq(1)),b(w.eq(0),"#000000"),b(w.eq(1),""),m[0].focus(),m[0].select();var x;if(!d&&(x=e.plugin.getSelectedTable())){m.val(x[0].rows.length),n.val(x[0].rows.length>0?x[0].rows[0].cells.length:0),m.attr("disabled",!0),n.attr("disabled",!0);var y,z=x[0].style.width||x[0].width,A=x[0].style.height||x[0].height;void 0!==z&&(y=/^(\d+)((?:px|%)*)$/.exec(z))?(o.val(y[1]),q.val(y[2])):o.val(""),void 0!==A&&(y=/^(\d+)((?:px|%)*)$/.exec(A))&&(p.val(y[1]),r.val(y[2])),s.val(x[0].cellPadding||""),t.val(x[0].cellSpacing||""),u.val(x[0].align||""),v.val(void 0===x[0].border?"":x[0].border),b(w.eq(0),a.toHex(x.attr("borderColor")||"")),b(w.eq(1),a.toHex(x[0].style.backgroundColor||x[0].bgColor||"")),o[0].focus(),o[0].select()}},cellprop:function(){var d=['
    ','
    ','",g.width+'   ','   ",g.height+'   ','","
    ",'
    ','",g.textAlign+' ",g.verticalAlign+' ","
    ",'
    ','",g.borderWidth+'   ',g.borderColor+' ',"
    ",'
    ','",'',"
    ","
    "].join(""),h=e.cmd.range.createBookmark(),i=e.createDialog({name:f,width:500,title:e.lang("tablecell"),body:d,beforeRemove:function(){t.unbind()},yesBtn:{name:e.lang("yes"),click:function(){var b=k.val(),c=l.val(),d=m.val(),f=n.val(),g=(o.val(),p.val(),q.val()),i=r.val(),j=s.val(),u=a(t[0]).html()||"",w=a(t[1]).html()||"";return/^\d*$/.test(b)?/^\d*$/.test(c)?/^\d*$/.test(j)?(v.css({width:""!==b?b+d:"",height:""!==c?c+f:"","background-color":w,"text-align":g,"vertical-align":i,"border-width":j,"border-style":""!==j?"solid":"","border-color":u}),e.hideDialog().focus(),e.cmd.range.moveToBookmark(h),e.cmd.select(),void e.addBookmark()):(alert(e.lang("invalidBorder")),void s[0].focus()):(alert(e.lang("invalidHeight")),void l[0].focus()):(alert(e.lang("invalidWidth")),void k[0].focus())}}}),j=i.div,k=a('[name="width"]',j).val(100),l=a('[name="height"]',j),m=a('[name="widthType"]',j),n=a('[name="heightType"]',j),o=a('[name="padding"]',j).val(2),p=a('[name="spacing"]',j).val(0),q=a('[name="textAlign"]',j),r=a('[name="verticalAlign"]',j),s=a('[name="border"]',j).val(1),t=a(".ke-input-color",j);c(j,t.eq(0)),c(j,t.eq(1)),b(t.eq(0),"#000000"),b(t.eq(1),""),k[0].focus(),k[0].select();var u,v=e.plugin.getSelectedCell(),w=v[0].style.width||v[0].width||"",x=v[0].style.height||v[0].height||"";(u=/^(\d+)((?:px|%)*)$/.exec(w))?(k.val(u[1]),m.val(u[2])):k.val(""),(u=/^(\d+)((?:px|%)*)$/.exec(x))&&(l.val(u[1]),n.val(u[2])),q.val(v[0].style.textAlign||""),r.val(v[0].style.verticalAlign||"");var y=v[0].style.borderWidth||"";y&&(y=parseInt(y)),s.val(y),b(t.eq(0),a.toHex(v[0].style.borderColor||"")),b(t.eq(1),a.toHex(v[0].style.backgroundColor||"")),k[0].focus(),k[0].select()},insert:function(){this.prop(!0)},"delete":function(){var a=e.plugin.getSelectedTable();e.cmd.range.setStartBefore(a[0]).collapse(!0),e.cmd.select(),a.remove(),e.addBookmark()},colinsert:function(b){var c=e.plugin.getSelectedTable()[0],f=e.plugin.getSelectedRow()[0],g=e.plugin.getSelectedCell()[0],h=g.cellIndex+b;h+=c.rows[0].cells.length-f.cells.length;for(var i=0,j=c.rows.length;j>i;i++){var k=c.rows[i],l=k.insertCell(h);l.innerHTML=a.IE?"":"
    ",h=d(c,k,l)}e.cmd.range.selectNodeContents(g).collapse(!0),e.cmd.select(),e.addBookmark()},colinsertleft:function(){this.colinsert(0)},colinsertright:function(){this.colinsert(1)},rowinsert:function(b){var c=e.plugin.getSelectedTable()[0],d=e.plugin.getSelectedRow()[0],f=e.plugin.getSelectedCell()[0],g=d.rowIndex;1===b&&(g=d.rowIndex+(f.rowSpan-1)+b);for(var h=c.insertRow(g),i=0,j=d.cells.length;j>i;i++){d.cells[i].rowSpan>1&&(j-=d.cells[i].rowSpan-1);var k=h.insertCell(i);1===b&&d.cells[i].colSpan>1&&(k.colSpan=d.cells[i].colSpan),k.innerHTML=a.IE?"":"
    "}for(var l=g;l>=0;l--){var m=c.rows[l].cells;if(m.length>i){for(var n=f.cellIndex;n>=0;n--)m[n].rowSpan>1&&(m[n].rowSpan+=1);break}}e.cmd.range.selectNodeContents(f).collapse(!0),e.cmd.select(),e.addBookmark()},rowinsertabove:function(){this.rowinsert(0)},rowinsertbelow:function(){this.rowinsert(1)},rowmerge:function(){var a=e.plugin.getSelectedTable()[0],b=e.plugin.getSelectedRow()[0],c=e.plugin.getSelectedCell()[0],d=b.rowIndex,f=d+c.rowSpan,g=a.rows[f];if(!(a.rows.length<=f)){var h=c.cellIndex;if(!(g.cells.length<=h)){var i=g.cells[h];c.colSpan===i.colSpan&&(c.rowSpan+=i.rowSpan,g.deleteCell(h),e.cmd.range.selectNodeContents(c).collapse(!0),e.cmd.select(),e.addBookmark())}}},colmerge:function(){var a=(e.plugin.getSelectedTable()[0],e.plugin.getSelectedRow()[0]),b=e.plugin.getSelectedCell()[0],c=(a.rowIndex,b.cellIndex),d=c+1;if(!(a.cells.length<=d)){var f=a.cells[d];b.rowSpan===f.rowSpan&&(b.colSpan+=f.colSpan,a.deleteCell(d),e.cmd.range.selectNodeContents(b).collapse(!0),e.cmd.select(),e.addBookmark())}},rowsplit:function(){var b=e.plugin.getSelectedTable()[0],c=e.plugin.getSelectedRow()[0],f=e.plugin.getSelectedCell()[0],g=c.rowIndex;if(1!==f.rowSpan){for(var h=d(b,c,f),i=1,j=f.rowSpan;j>i;i++){var k=b.rows[g+i],l=k.insertCell(h);f.colSpan>1&&(l.colSpan=f.colSpan),l.innerHTML=a.IE?"":"
    ",h=d(b,k,l)}a(f).removeAttr("rowSpan"),e.cmd.range.selectNodeContents(f).collapse(!0),e.cmd.select(),e.addBookmark()}},colsplit:function(){var b=(e.plugin.getSelectedTable()[0],e.plugin.getSelectedRow()[0]),c=e.plugin.getSelectedCell()[0],d=c.cellIndex;if(1!==c.colSpan){for(var f=1,g=c.colSpan;g>f;f++){var h=b.insertCell(d+f);c.rowSpan>1&&(h.rowSpan=c.rowSpan),h.innerHTML=a.IE?"":"
    "}a(c).removeAttr("colSpan"),e.cmd.range.selectNodeContents(c).collapse(!0),e.cmd.select(),e.addBookmark()}},coldelete:function(){for(var b=e.plugin.getSelectedTable()[0],c=e.plugin.getSelectedRow()[0],d=e.plugin.getSelectedCell()[0],f=d.cellIndex,g=0,h=b.rows.length;h>g;g++){var i=b.rows[g],j=i.cells[f];j.colSpan>1?(j.colSpan-=1,1===j.colSpan&&a(j).removeAttr("colSpan")):i.deleteCell(f),j.rowSpan>1&&(g+=j.rowSpan-1)}0===c.cells.length?(e.cmd.range.setStartBefore(b).collapse(!0),e.cmd.select(),a(b).remove()):e.cmd.selection(!0),e.addBookmark()},rowdelete:function(){for(var b=e.plugin.getSelectedTable()[0],c=e.plugin.getSelectedRow()[0],d=e.plugin.getSelectedCell()[0],f=c.rowIndex,g=d.rowSpan-1;g>=0;g--)b.deleteRow(f+g);0===b.rows.length?(e.cmd.range.setStartBefore(b).collapse(!0),e.cmd.select(),a(b).remove()):e.cmd.selection(!0),e.addBookmark()}},e.clickToolbar(f,e.plugin.table.prop)}),KindEditor.plugin("template",function(a){function b(b){return e+b+"?ver="+encodeURIComponent(a.DEBUG?a.TIME:a.VERSION)}var c=this,d="template",e=(c.lang(d+"."),c.pluginsPath+d+"/html/");c.clickToolbar(d,function(){var e=c.lang(d+"."),f=['
    ','
    ','
    ',e.selectTemplate+"
    ",'
    ',' ","
    ",'
    ',"
    ",'',"
    "].join("");var g=c.createDialog({name:d,width:500,title:c.lang(d),body:html,yesBtn:{name:c.lang("yes"),click:function(){var b=a.iframeDoc(j);c[i[0].checked?"html":"insertHtml"](b.body.innerHTML).hideDialog().focus()}}}),h=a("select",g.div),i=a('[name="replaceFlag"]',g.div),j=a("iframe",g.div);i[0].checked=!0,j.attr("src",b(h.val())),h.change(function(){j.attr("src",b(this.value))})})}),KindEditor.plugin("wordpaste",function(a){var b=this,c="wordpaste";b.clickToolbar(c,function(){var d=b.lang(c+"."),e='
    '+d.comment+'
    ',f=b.createDialog({name:c,width:450,title:b.lang(c),body:e,yesBtn:{name:b.lang("yes"),click:function(){var c=i.body.innerHTML;c=a.clearMsWord(c,b.filterMode?b.htmlTags:a.options.htmlTags),b.insertHtml(c).hideDialog().focus()}}}),g=f.div,h=a("iframe",g),i=a.iframeDoc(h);a.IE||(i.designMode="on"),i.open(),i.write("WordPaste"),i.write(''),a.IE||i.write("
    "),i.write(""),i.close(),a.IE&&(i.body.contentEditable="true"),h[0].contentWindow.focus()})}),KindEditor.plugin("fixtoolbar",function(a){function b(){var b=a(".ke-toolbar"),c=b.pos().y;a(window).bind("scroll",function(){"fixed"==b.css("position")?document.body.scrollTop-c<0&&(b.css("position","static"),b.css("top","auto")):b.pos().y-document.body.scrollTop<0&&(b.css("position","fixed"),b.css("top",0))})}var c=this;c.fixToolBar&&(c.isCreated?b():c.afterCreate(b))}); \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/kindeditor-all.js b/php/kindeditor_demo/kindeditor/kindeditor-all.js new file mode 100755 index 0000000..1fcc08f --- /dev/null +++ b/php/kindeditor_demo/kindeditor/kindeditor-all.js @@ -0,0 +1,9849 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2016 kindsoft.net +* +* @author Roddy +* @website http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +* @version 4.1.11 (2016-03-31) +*******************************************************************************/ +(function (window, undefined) { + if (window.KindEditor) { + return; + } + + +if (!window.console) { + window.console = {}; +} +if (!console.log) { + console.log = function () {}; +} +var _VERSION = '4.1.11 (2016-03-31)', + _ua = navigator.userAgent.toLowerCase(), + _IE = _ua.indexOf('msie') > -1 && _ua.indexOf('opera') == -1, + _NEWIE = _ua.indexOf('msie') == -1 && _ua.indexOf('trident') > -1, + _GECKO = _ua.indexOf('gecko') > -1 && _ua.indexOf('khtml') == -1, + _WEBKIT = _ua.indexOf('applewebkit') > -1, + _OPERA = _ua.indexOf('opera') > -1, + _MOBILE = _ua.indexOf('mobile') > -1, + _IOS = /ipad|iphone|ipod/.test(_ua), + _QUIRKS = document.compatMode != 'CSS1Compat', + _IERANGE = !window.getSelection, + _matches = /(?:msie|firefox|webkit|opera)[\/:\s](\d+)/.exec(_ua), + _V = _matches ? _matches[1] : '0', + _TIME = new Date().getTime(); +function _isArray(val) { + if (!val) { + return false; + } + return Object.prototype.toString.call(val) === '[object Array]'; +} +function _isFunction(val) { + if (!val) { + return false; + } + return Object.prototype.toString.call(val) === '[object Function]'; +} +function _inArray(val, arr) { + for (var i = 0, len = arr.length; i < len; i++) { + if (val === arr[i]) { + return i; + } + } + return -1; +} +function _each(obj, fn) { + if (_isArray(obj)) { + for (var i = 0, len = obj.length; i < len; i++) { + if (fn.call(obj[i], i, obj[i]) === false) { + break; + } + } + } else { + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + if (fn.call(obj[key], key, obj[key]) === false) { + break; + } + } + } + } +} +function _trim(str) { + return str.replace(/(?:^[ \t\n\r]+)|(?:[ \t\n\r]+$)/g, ''); +} +function _inString(val, str, delimiter) { + delimiter = delimiter === undefined ? ',' : delimiter; + return (delimiter + str + delimiter).indexOf(delimiter + val + delimiter) >= 0; +} +function _addUnit(val, unit) { + unit = unit || 'px'; + return val && /^-?\d+(?:\.\d+)?$/.test(val) ? val + unit : val; +} +function _removeUnit(val) { + var match; + return val && (match = /(\d+)/.exec(val)) ? parseInt(match[1], 10) : 0; +} +function _escape(val) { + return val.replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); +} +function _unescape(val) { + return val.replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/&/g, '&'); +} +function _toCamel(str) { + var arr = str.split('-'); + str = ''; + _each(arr, function(key, val) { + str += (key > 0) ? val.charAt(0).toUpperCase() + val.substr(1) : val; + }); + return str; +} +function _toHex(val) { + function hex(d) { + var s = parseInt(d, 10).toString(16).toUpperCase(); + return s.length > 1 ? s : '0' + s; + } + return val.replace(/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/ig, + function($0, $1, $2, $3) { + return '#' + hex($1) + hex($2) + hex($3); + } + ); +} +function _toMap(val, delimiter) { + delimiter = delimiter === undefined ? ',' : delimiter; + var map = {}, arr = _isArray(val) ? val : val.split(delimiter), match; + _each(arr, function(key, val) { + if ((match = /^(\d+)\.\.(\d+)$/.exec(val))) { + for (var i = parseInt(match[1], 10); i <= parseInt(match[2], 10); i++) { + map[i.toString()] = true; + } + } else { + map[val] = true; + } + }); + return map; +} +function _toArray(obj, offset) { + return Array.prototype.slice.call(obj, offset || 0); +} +function _undef(val, defaultVal) { + return val === undefined ? defaultVal : val; +} +function _invalidUrl(url) { + return !url || /[<>"]/.test(url); +} +function _addParam(url, param) { + return url.indexOf('?') >= 0 ? url + '&' + param : url + '?' + param; +} +function _extend(child, parent, proto) { + if (!proto) { + proto = parent; + parent = null; + } + var childProto; + if (parent) { + var fn = function () {}; + fn.prototype = parent.prototype; + childProto = new fn(); + _each(proto, function(key, val) { + childProto[key] = val; + }); + } else { + childProto = proto; + } + childProto.constructor = child; + child.prototype = childProto; + child.parent = parent ? parent.prototype : null; +} + +function _json(text) { + var match; + if ((match = /\{[\s\S]*\}|\[[\s\S]*\]/.exec(text))) { + text = match[0]; + } + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + if (/^[\],:{}\s]*$/. + test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'). + replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'). + replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + return eval('(' + text + ')'); + } + throw 'JSON parse error'; +} +var _round = Math.round; +var K = { + DEBUG : false, + VERSION : _VERSION, + IE : _IE, + GECKO : _GECKO, + WEBKIT : _WEBKIT, + OPERA : _OPERA, + V : _V, + TIME : _TIME, + each : _each, + isArray : _isArray, + isFunction : _isFunction, + inArray : _inArray, + inString : _inString, + trim : _trim, + addUnit : _addUnit, + removeUnit : _removeUnit, + escape : _escape, + unescape : _unescape, + toCamel : _toCamel, + toHex : _toHex, + toMap : _toMap, + toArray : _toArray, + undef : _undef, + invalidUrl : _invalidUrl, + addParam : _addParam, + extend : _extend, + json : _json +}; +var _INLINE_TAG_MAP = _toMap('a,abbr,acronym,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,img,input,ins,kbd,label,map,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'), + _BLOCK_TAG_MAP = _toMap('address,applet,blockquote,body,center,dd,dir,div,dl,dt,fieldset,form,frameset,h1,h2,h3,h4,h5,h6,head,hr,html,iframe,ins,isindex,li,map,menu,meta,noframes,noscript,object,ol,p,pre,script,style,table,tbody,td,tfoot,th,thead,title,tr,ul'), + _SINGLE_TAG_MAP = _toMap('area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed'), + _STYLE_TAG_MAP = _toMap('b,basefont,big,del,em,font,i,s,small,span,strike,strong,sub,sup,u'), + _CONTROL_TAG_MAP = _toMap('img,table,input,textarea,button'), + _PRE_TAG_MAP = _toMap('pre,style,script'), + _NOSPLIT_TAG_MAP = _toMap('html,head,body,td,tr,table,ol,ul,li'), + _AUTOCLOSE_TAG_MAP = _toMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'), + _FILL_ATTR_MAP = _toMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'), + _VALUE_TAG_MAP = _toMap('input,button,textarea,select'); + + +function _getBasePath() { + var els = document.getElementsByTagName('script'), src; + for (var i = 0, len = els.length; i < len; i++) { + src = els[i].src || ''; + if (/kindeditor[\w\-\.]*\.js/.test(src)) { + return src.substring(0, src.lastIndexOf('/') + 1); + } + } + return ''; +} +K.basePath = _getBasePath(); +K.options = { + designMode : true, + fullscreenMode : false, + filterMode : true, + wellFormatMode : true, + shadowMode : true, + loadStyleMode : true, + basePath : K.basePath, + themesPath : K.basePath + 'themes/', + langPath : K.basePath + 'lang/', + pluginsPath : K.basePath + 'plugins/', + themeType : 'default', + langType : 'zh-CN', + urlType : '', + newlineTag : 'p', + resizeType : 2, + syncType : 'form', + pasteType : 2, + dialogAlignType : 'page', + useContextmenu : true, + fullscreenShortcut : false, + bodyClass : 'ke-content', + indentChar : '\t', + cssPath : '', + cssData : '', + minWidth : 650, + minHeight : 100, + minChangeSize : 50, + zIndex : 811213, + items : [ + 'source', '|', 'undo', 'redo', '|', 'preview', 'print', 'template', 'code', 'cut', 'copy', 'paste', + 'plainpaste', 'wordpaste', '|', 'justifyleft', 'justifycenter', 'justifyright', + 'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'subscript', + 'superscript', 'clearhtml', 'quickformat', 'selectall', '|', 'fullscreen', '/', + 'formatblock', 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold', + 'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', '|', 'image', 'multiimage', + 'flash', 'media', 'insertfile', 'table', 'hr', 'emoticons', 'baidumap', 'pagebreak', + 'anchor', 'link', 'unlink', '|', 'about' + ], + noDisableItems : ['source', 'fullscreen'], + colorTable : [ + ['#E53333', '#E56600', '#FF9900', '#64451D', '#DFC5A4', '#FFE500'], + ['#009900', '#006600', '#99BB00', '#B8D100', '#60D978', '#00D5FF'], + ['#337FE5', '#003399', '#4C33E5', '#9933E5', '#CC33E5', '#EE33EE'], + ['#FFFFFF', '#CCCCCC', '#999999', '#666666', '#333333', '#000000'] + ], + fontSizeTable : ['9px', '10px', '12px', '14px', '16px', '18px', '24px', '32px'], + htmlTags : { + font : ['id', 'class', 'color', 'size', 'face', '.background-color'], + span : [ + 'id', 'class', '.color', '.background-color', '.font-size', '.font-family', '.background', + '.font-weight', '.font-style', '.text-decoration', '.vertical-align', '.line-height' + ], + div : [ + 'id', 'class', 'align', '.border', '.margin', '.padding', '.text-align', '.color', + '.background-color', '.font-size', '.font-family', '.font-weight', '.background', + '.font-style', '.text-decoration', '.vertical-align', '.margin-left' + ], + table: [ + 'id', 'class', 'border', 'cellspacing', 'cellpadding', 'width', 'height', 'align', 'bordercolor', + '.padding', '.margin', '.border', 'bgcolor', '.text-align', '.color', '.background-color', + '.font-size', '.font-family', '.font-weight', '.font-style', '.text-decoration', '.background', + '.width', '.height', '.border-collapse' + ], + 'td,th': [ + 'id', 'class', 'align', 'valign', 'width', 'height', 'colspan', 'rowspan', 'bgcolor', + '.text-align', '.color', '.background-color', '.font-size', '.font-family', '.font-weight', + '.font-style', '.text-decoration', '.vertical-align', '.background', '.border' + ], + a : ['id', 'class', 'href', 'target', 'name'], + embed : ['id', 'class', 'src', 'width', 'height', 'type', 'loop', 'autostart', 'quality', '.width', '.height', 'align', 'allowscriptaccess', 'wmode'], + img : ['id', 'class', 'src', 'width', 'height', 'border', 'alt', 'title', 'align', '.width', '.height', '.border'], + 'p,ol,ul,li,blockquote,h1,h2,h3,h4,h5,h6' : [ + 'id', 'class', 'align', '.text-align', '.color', '.background-color', '.font-size', '.font-family', '.background', + '.font-weight', '.font-style', '.text-decoration', '.vertical-align', '.text-indent', '.margin-left' + ], + pre : ['id', 'class'], + hr : ['id', 'class', '.page-break-after'], + 'br,tbody,tr,strong,b,sub,sup,em,i,u,strike,s,del' : ['id', 'class'], + iframe : ['id', 'class', 'src', 'frameborder', 'width', 'height', '.width', '.height'] + }, + layout : '
    ' +}; + + +var _useCapture = false; + +var _INPUT_KEY_MAP = _toMap('8,9,13,32,46,48..57,59,61,65..90,106,109..111,188,190..192,219..222'); +var _CURSORMOVE_KEY_MAP = _toMap('33..40'); +var _CHANGE_KEY_MAP = {}; +_each(_INPUT_KEY_MAP, function(key, val) { + _CHANGE_KEY_MAP[key] = val; +}); +_each(_CURSORMOVE_KEY_MAP, function(key, val) { + _CHANGE_KEY_MAP[key] = val; +}); + +function _bindEvent(el, type, fn) { + if (el.addEventListener){ + el.addEventListener(type, fn, _useCapture); + } else if (el.attachEvent){ + el.attachEvent('on' + type, fn); + } +} +function _unbindEvent(el, type, fn) { + if (el.removeEventListener){ + el.removeEventListener(type, fn, _useCapture); + } else if (el.detachEvent){ + el.detachEvent('on' + type, fn); + } +} +var _EVENT_PROPS = ('altKey,attrChange,attrName,bubbles,button,cancelable,charCode,clientX,clientY,ctrlKey,currentTarget,' + + 'data,detail,eventPhase,fromElement,handler,keyCode,metaKey,newValue,offsetX,offsetY,originalTarget,pageX,' + + 'pageY,prevValue,relatedNode,relatedTarget,screenX,screenY,shiftKey,srcElement,target,toElement,view,wheelDelta,which').split(','); + +function KEvent(el, event) { + this.init(el, event); +} +_extend(KEvent, { + init : function(el, event) { + var self = this, doc = el.ownerDocument || el.document || el; + self.event = event; + _each(_EVENT_PROPS, function(key, val) { + self[val] = event[val]; + }); + if (!self.target) { + self.target = self.srcElement || doc; + } + if (self.target.nodeType === 3) { + self.target = self.target.parentNode; + } + if (!self.relatedTarget && self.fromElement) { + self.relatedTarget = self.fromElement === self.target ? self.toElement : self.fromElement; + } + if (self.pageX == null && self.clientX != null) { + var d = doc.documentElement, body = doc.body; + self.pageX = self.clientX + (d && d.scrollLeft || body && body.scrollLeft || 0) - (d && d.clientLeft || body && body.clientLeft || 0); + self.pageY = self.clientY + (d && d.scrollTop || body && body.scrollTop || 0) - (d && d.clientTop || body && body.clientTop || 0); + } + if (!self.which && ((self.charCode || self.charCode === 0) ? self.charCode : self.keyCode)) { + self.which = self.charCode || self.keyCode; + } + if (!self.metaKey && self.ctrlKey) { + self.metaKey = self.ctrlKey; + } + if (!self.which && self.button !== undefined) { + self.which = (self.button & 1 ? 1 : (self.button & 2 ? 3 : (self.button & 4 ? 2 : 0))); + } + switch (self.which) { + case 186 : + self.which = 59; + break; + case 187 : + case 107 : + case 43 : + self.which = 61; + break; + case 189 : + case 45 : + self.which = 109; + break; + case 42 : + self.which = 106; + break; + case 47 : + self.which = 111; + break; + case 78 : + self.which = 110; + break; + } + if (self.which >= 96 && self.which <= 105) { + self.which -= 48; + } + }, + preventDefault : function() { + var ev = this.event; + if (ev.preventDefault) { + ev.preventDefault(); + } else { + ev.returnValue = false; + } + }, + stopPropagation : function() { + var ev = this.event; + if (ev.stopPropagation) { + ev.stopPropagation(); + } else { + ev.cancelBubble = true; + } + }, + stop : function() { + this.preventDefault(); + this.stopPropagation(); + } +}); +var _eventExpendo = 'kindeditor_' + _TIME, _eventId = 0, _eventData = {}; +function _getId(el) { + return el[_eventExpendo] || null; +} +function _setId(el) { + el[_eventExpendo] = ++_eventId; + return _eventId; +} +function _removeId(el) { + try { + delete el[_eventExpendo]; + } catch(e) { + if (el.removeAttribute) { + el.removeAttribute(_eventExpendo); + } + } +} +function _bind(el, type, fn) { + if (type.indexOf(',') >= 0) { + _each(type.split(','), function() { + _bind(el, this, fn); + }); + return; + } + var id = _getId(el); + if (!id) { + id = _setId(el); + } + if (_eventData[id] === undefined) { + _eventData[id] = {}; + } + var events = _eventData[id][type]; + if (events && events.length > 0) { + _unbindEvent(el, type, events[0]); + } else { + _eventData[id][type] = []; + _eventData[id].el = el; + } + events = _eventData[id][type]; + if (events.length === 0) { + events[0] = function(e) { + var kevent = e ? new KEvent(el, e) : undefined; + _each(events, function(i, event) { + if (i > 0 && event) { + event.call(el, kevent); + } + }); + }; + } + if (_inArray(fn, events) < 0) { + events.push(fn); + } + _bindEvent(el, type, events[0]); +} +function _unbind(el, type, fn) { + if (type && type.indexOf(',') >= 0) { + _each(type.split(','), function() { + _unbind(el, this, fn); + }); + return; + } + var id = _getId(el); + if (!id) { + return; + } + if (type === undefined) { + if (id in _eventData) { + _each(_eventData[id], function(key, events) { + if (key != 'el' && events.length > 0) { + _unbindEvent(el, key, events[0]); + } + }); + delete _eventData[id]; + _removeId(el); + } + return; + } + if (!_eventData[id]) { + return; + } + var events = _eventData[id][type]; + if (events && events.length > 0) { + if (fn === undefined) { + _unbindEvent(el, type, events[0]); + delete _eventData[id][type]; + } else { + _each(events, function(i, event) { + if (i > 0 && event === fn) { + events.splice(i, 1); + } + }); + if (events.length == 1) { + _unbindEvent(el, type, events[0]); + delete _eventData[id][type]; + } + } + var count = 0; + _each(_eventData[id], function() { + count++; + }); + if (count < 2) { + delete _eventData[id]; + _removeId(el); + } + } +} +function _fire(el, type) { + if (type.indexOf(',') >= 0) { + _each(type.split(','), function() { + _fire(el, this); + }); + return; + } + var id = _getId(el); + if (!id) { + return; + } + var events = _eventData[id][type]; + if (_eventData[id] && events && events.length > 0) { + events[0](); + } +} +function _ctrl(el, key, fn) { + var self = this; + key = /^\d{2,}$/.test(key) ? key : key.toUpperCase().charCodeAt(0); + _bind(el, 'keydown', function(e) { + if (e.ctrlKey && e.which == key && !e.shiftKey && !e.altKey) { + fn.call(el); + e.stop(); + } + }); +} +var _readyFinished = false; +function _ready(fn) { + if (_readyFinished) { + fn(KindEditor); + return; + } + var loaded = false; + function readyFunc() { + if (!loaded) { + loaded = true; + fn(KindEditor); + _readyFinished = true; + } + } + function ieReadyFunc() { + if (!loaded) { + try { + document.documentElement.doScroll('left'); + } catch(e) { + setTimeout(ieReadyFunc, 100); + return; + } + readyFunc(); + } + } + function ieReadyStateFunc() { + if (document.readyState === 'complete') { + readyFunc(); + } + } + if (document.addEventListener) { + _bind(document, 'DOMContentLoaded', readyFunc); + } else if (document.attachEvent) { + _bind(document, 'readystatechange', ieReadyStateFunc); + var toplevel = false; + try { + toplevel = window.frameElement == null; + } catch(e) {} + if (document.documentElement.doScroll && toplevel) { + ieReadyFunc(); + } + } + _bind(window, 'load', readyFunc); +} +if (window.attachEvent) { + window.attachEvent('onunload', function() { + _each(_eventData, function(key, events) { + if (events.el) { + _unbind(events.el); + } + }); + }); +} +K.ctrl = _ctrl; +K.ready = _ready; + +function _getCssList(css) { + var list = {}, + reg = /\s*([\w\-]+)\s*:([^;]*)(;|$)/g, + match; + while ((match = reg.exec(css))) { + var key = _trim(match[1].toLowerCase()), + val = _trim(_toHex(match[2])); + list[key] = val; + } + return list; +} +function _getAttrList(tag) { + var list = {}, + reg = /\s+(?:([\w\-:]+)|(?:([\w\-:]+)=([^\s"'<>]+))|(?:([\w\-:"]+)="([^"]*)")|(?:([\w\-:"]+)='([^']*)'))(?=(?:\s|\/|>)+)/g, + match; + while ((match = reg.exec(tag))) { + var key = (match[1] || match[2] || match[4] || match[6]).toLowerCase(), + val = (match[2] ? match[3] : (match[4] ? match[5] : match[7])) || ''; + list[key] = val; + } + return list; +} +function _addClassToTag(tag, className) { + if (/\s+class\s*=/.test(tag)) { + tag = tag.replace(/(\s+class=["']?)([^"']*)(["']?[\s>])/, function($0, $1, $2, $3) { + if ((' ' + $2 + ' ').indexOf(' ' + className + ' ') < 0) { + return $2 === '' ? $1 + className + $3 : $1 + $2 + ' ' + className + $3; + } else { + return $0; + } + }); + } else { + tag = tag.substr(0, tag.length - 1) + ' class="' + className + '">'; + } + return tag; +} +function _formatCss(css) { + var str = ''; + _each(_getCssList(css), function(key, val) { + str += key + ':' + val + ';'; + }); + return str; +} +function _formatUrl(url, mode, host, pathname) { + mode = _undef(mode, '').toLowerCase(); + if (url.substr(0, 5) != 'data:') { + url = url.replace(/([^:])\/\//g, '$1/'); + } + if (_inArray(mode, ['absolute', 'relative', 'domain']) < 0) { + return url; + } + host = host || location.protocol + '//' + location.host; + if (pathname === undefined) { + var m = location.pathname.match(/^(\/.*)\//); + pathname = m ? m[1] : ''; + } + var match; + if ((match = /^(\w+:\/\/[^\/]*)/.exec(url))) { + if (match[1] !== host) { + return url; + } + } else if (/^\w+:/.test(url)) { + return url; + } + function getRealPath(path) { + var parts = path.split('/'), paths = []; + for (var i = 0, len = parts.length; i < len; i++) { + var part = parts[i]; + if (part == '..') { + if (paths.length > 0) { + paths.pop(); + } + } else if (part !== '' && part != '.') { + paths.push(part); + } + } + return '/' + paths.join('/'); + } + if (/^\//.test(url)) { + url = host + getRealPath(url.substr(1)); + } else if (!/^\w+:\/\//.test(url)) { + url = host + getRealPath(pathname + '/' + url); + } + function getRelativePath(path, depth) { + if (url.substr(0, path.length) === path) { + var arr = []; + for (var i = 0; i < depth; i++) { + arr.push('..'); + } + var prefix = '.'; + if (arr.length > 0) { + prefix += '/' + arr.join('/'); + } + if (pathname == '/') { + prefix += '/'; + } + return prefix + url.substr(path.length); + } else { + if ((match = /^(.*)\//.exec(path))) { + return getRelativePath(match[1], ++depth); + } + } + } + if (mode === 'relative') { + url = getRelativePath(host + pathname, 0).substr(2); + } else if (mode === 'absolute') { + if (url.substr(0, host.length) === host) { + url = url.substr(host.length); + } + } + return url; +} +function _formatHtml(html, htmlTags, urlType, wellFormatted, indentChar) { + if (html == null) { + html = ''; + } + urlType = urlType || ''; + wellFormatted = _undef(wellFormatted, false); + indentChar = _undef(indentChar, '\t'); + var fontSizeList = 'xx-small,x-small,small,medium,large,x-large,xx-large'.split(','); + html = html.replace(/(<(?:pre|pre\s[^>]*)>)([\s\S]*?)(<\/pre>)/ig, function($0, $1, $2, $3) { + return $1 + $2.replace(/<(?:br|br\s[^>]*)>/ig, '\n') + $3; + }); + html = html.replace(/<(?:br|br\s[^>]*)\s*\/?>\s*<\/p>/ig, '

    '); + html = html.replace(/(<(?:p|p\s[^>]*)>)\s*(<\/p>)/ig, '$1
    $2'); + html = html.replace(/\u200B/g, ''); + html = html.replace(/\u00A9/g, '©'); + html = html.replace(/\u00AE/g, '®'); + html = html.replace(/\u2003/g, ' '); + html = html.replace(/\u3000/g, ' '); + html = html.replace(/<[^>]+/g, function($0) { + return $0.replace(/\s+/g, ' '); + }); + var htmlTagMap = {}; + if (htmlTags) { + _each(htmlTags, function(key, val) { + var arr = key.split(','); + for (var i = 0, len = arr.length; i < len; i++) { + htmlTagMap[arr[i]] = _toMap(val); + } + }); + if (!htmlTagMap.script) { + html = html.replace(/(<(?:script|script\s[^>]*)>)([\s\S]*?)(<\/script>)/ig, ''); + } + if (!htmlTagMap.style) { + html = html.replace(/(<(?:style|style\s[^>]*)>)([\s\S]*?)(<\/style>)/ig, ''); + } + } + var re = /(\s*)<(\/)?([\w\-:]+)((?:\s+|(?:\s+[\w\-:]+)|(?:\s+[\w\-:]+=[^\s"'<>]+)|(?:\s+[\w\-:"]+="[^"]*")|(?:\s+[\w\-:"]+='[^']*'))*)(\/)?>(\s*)/g; + var tagStack = []; + html = html.replace(re, function($0, $1, $2, $3, $4, $5, $6) { + var full = $0, + startNewline = $1 || '', + startSlash = $2 || '', + tagName = $3.toLowerCase(), + attr = $4 || '', + endSlash = $5 ? ' ' + $5 : '', + endNewline = $6 || ''; + if (htmlTags && !htmlTagMap[tagName]) { + return ''; + } + if (endSlash === '' && _SINGLE_TAG_MAP[tagName]) { + endSlash = ' /'; + } + if (_INLINE_TAG_MAP[tagName]) { + if (startNewline) { + startNewline = ' '; + } + if (endNewline) { + endNewline = ' '; + } + } + if (_PRE_TAG_MAP[tagName]) { + if (startSlash) { + endNewline = '\n'; + } else { + startNewline = '\n'; + } + } + if (wellFormatted && tagName == 'br') { + endNewline = '\n'; + } + if (_BLOCK_TAG_MAP[tagName] && !_PRE_TAG_MAP[tagName]) { + if (wellFormatted) { + if (startSlash && tagStack.length > 0 && tagStack[tagStack.length - 1] === tagName) { + tagStack.pop(); + } else { + tagStack.push(tagName); + } + startNewline = '\n'; + endNewline = '\n'; + for (var i = 0, len = startSlash ? tagStack.length : tagStack.length - 1; i < len; i++) { + startNewline += indentChar; + if (!startSlash) { + endNewline += indentChar; + } + } + if (endSlash) { + tagStack.pop(); + } else if (!startSlash) { + endNewline += indentChar; + } + } else { + startNewline = endNewline = ''; + } + } + if (attr !== '') { + var attrMap = _getAttrList(full); + if (tagName === 'font') { + var fontStyleMap = {}, fontStyle = ''; + _each(attrMap, function(key, val) { + if (key === 'color') { + fontStyleMap.color = val; + delete attrMap[key]; + } + if (key === 'size') { + fontStyleMap['font-size'] = fontSizeList[parseInt(val, 10) - 1] || ''; + delete attrMap[key]; + } + if (key === 'face') { + fontStyleMap['font-family'] = val; + delete attrMap[key]; + } + if (key === 'style') { + fontStyle = val; + } + }); + if (fontStyle && !/;$/.test(fontStyle)) { + fontStyle += ';'; + } + _each(fontStyleMap, function(key, val) { + if (val === '') { + return; + } + if (/\s/.test(val)) { + val = "'" + val + "'"; + } + fontStyle += key + ':' + val + ';'; + }); + attrMap.style = fontStyle; + } + _each(attrMap, function(key, val) { + if (_FILL_ATTR_MAP[key]) { + attrMap[key] = key; + } + if (_inArray(key, ['src', 'href']) >= 0) { + attrMap[key] = _formatUrl(val, urlType); + } + if (htmlTags && key !== 'style' && !htmlTagMap[tagName]['*'] && !htmlTagMap[tagName][key] || + tagName === 'body' && key === 'contenteditable' || + /^kindeditor_\d+$/.test(key)) { + delete attrMap[key]; + } + if (key === 'style' && val !== '') { + var styleMap = _getCssList(val); + _each(styleMap, function(k, v) { + if (htmlTags && !htmlTagMap[tagName].style && !htmlTagMap[tagName]['.' + k]) { + delete styleMap[k]; + } + }); + var style = ''; + _each(styleMap, function(k, v) { + style += k + ':' + v + ';'; + }); + attrMap.style = style; + } + }); + attr = ''; + _each(attrMap, function(key, val) { + if (key === 'style' && val === '') { + return; + } + val = val.replace(/"/g, '"'); + attr += ' ' + key + '="' + val + '"'; + }); + } + if (tagName === 'font') { + tagName = 'span'; + } + return startNewline + '<' + startSlash + tagName + attr + endSlash + '>' + endNewline; + }); + html = html.replace(/(<(?:pre|pre\s[^>]*)>)([\s\S]*?)(<\/pre>)/ig, function($0, $1, $2, $3) { + return $1 + $2.replace(/\n/g, '\n') + $3; + }); + html = html.replace(/\n\s*\n/g, '\n'); + html = html.replace(/\n/g, '\n'); + return _trim(html); +} +function _clearMsWord(html, htmlTags) { + html = html.replace(//ig, '') + .replace(//ig, '') + .replace(/]*>[\s\S]*?<\/style>/ig, '') + .replace(/]*>[\s\S]*?<\/script>/ig, '') + .replace(/]+>[\s\S]*?<\/w:[^>]+>/ig, '') + .replace(/]+>[\s\S]*?<\/o:[^>]+>/ig, '') + .replace(/[\s\S]*?<\/xml>/ig, '') + .replace(/<(?:table|td)[^>]*>/ig, function(full) { + return full.replace(/border-bottom:([#\w\s]+)/ig, 'border:$1'); + }); + return _formatHtml(html, htmlTags); +} +function _mediaType(src) { + if (/\.(rm|rmvb)(\?|$)/i.test(src)) { + return 'audio/x-pn-realaudio-plugin'; + } + if (/\.(swf|flv)(\?|$)/i.test(src)) { + return 'application/x-shockwave-flash'; + } + return 'video/x-ms-asf-plugin'; +} +function _mediaClass(type) { + if (/realaudio/i.test(type)) { + return 'ke-rm'; + } + if (/flash/i.test(type)) { + return 'ke-flash'; + } + return 'ke-media'; +} +function _mediaAttrs(srcTag) { + return _getAttrList(unescape(srcTag)); +} +function _mediaEmbed(attrs) { + var html = ' 0) { + style += 'width:' + width + 'px;'; + } + if (/\D/.test(height)) { + style += 'height:' + height + ';'; + } else if (height > 0) { + style += 'height:' + height + 'px;'; + } + var html = ''; + return html; +} + +function _tmpl(str, data) { + var fn = new Function("obj", + "var p=[],print=function(){p.push.apply(p,arguments);};" + + "with(obj){p.push('" + + str.replace(/[\r\t\n]/g, " ") + .split("<%").join("\t") + .replace(/((^|%>)[^\t]*)'/g, "$1\r") + .replace(/\t=(.*?)%>/g, "',$1,'") + .split("\t").join("');") + .split("%>").join("p.push('") + .split("\r").join("\\'") + "');}return p.join('');"); + return data ? fn(data) : fn; +} +K.formatUrl = _formatUrl; +K.formatHtml = _formatHtml; +K.getCssList = _getCssList; +K.getAttrList = _getAttrList; +K.mediaType = _mediaType; +K.mediaAttrs = _mediaAttrs; +K.mediaEmbed = _mediaEmbed; +K.mediaImg = _mediaImg; +K.clearMsWord = _clearMsWord; +K.tmpl = _tmpl; + + +function _contains(nodeA, nodeB) { + if (nodeA.nodeType == 9 && nodeB.nodeType != 9) { + return true; + } + while ((nodeB = nodeB.parentNode)) { + if (nodeB == nodeA) { + return true; + } + } + return false; +} +var _getSetAttrDiv = document.createElement('div'); +_getSetAttrDiv.setAttribute('className', 't'); +var _GET_SET_ATTRIBUTE = _getSetAttrDiv.className !== 't'; +function _getAttr(el, key) { + key = key.toLowerCase(); + var val = null; + if (!_GET_SET_ATTRIBUTE && el.nodeName.toLowerCase() != 'script') { + var div = el.ownerDocument.createElement('div'); + div.appendChild(el.cloneNode(false)); + var list = _getAttrList(_unescape(div.innerHTML)); + if (key in list) { + val = list[key]; + } + } else { + try { + val = el.getAttribute(key, 2); + } catch(e) { + val = el.getAttribute(key, 1); + } + } + if (key === 'style' && val !== null) { + val = _formatCss(val); + } + return val; +} +function _queryAll(expr, root) { + var exprList = expr.split(','); + if (exprList.length > 1) { + var mergedResults = []; + _each(exprList, function() { + _each(_queryAll(this, root), function() { + if (_inArray(this, mergedResults) < 0) { + mergedResults.push(this); + } + }); + }); + return mergedResults; + } + root = root || document; + function escape(str) { + if (typeof str != 'string') { + return str; + } + return str.replace(/([^\w\-])/g, '\\$1'); + } + function stripslashes(str) { + return str.replace(/\\/g, ''); + } + function cmpTag(tagA, tagB) { + return tagA === '*' || tagA.toLowerCase() === escape(tagB.toLowerCase()); + } + function byId(id, tag, root) { + var arr = [], + doc = root.ownerDocument || root, + el = doc.getElementById(stripslashes(id)); + if (el) { + if (cmpTag(tag, el.nodeName) && _contains(root, el)) { + arr.push(el); + } + } + return arr; + } + function byClass(className, tag, root) { + var doc = root.ownerDocument || root, arr = [], els, i, len, el; + if (root.getElementsByClassName) { + els = root.getElementsByClassName(stripslashes(className)); + for (i = 0, len = els.length; i < len; i++) { + el = els[i]; + if (cmpTag(tag, el.nodeName)) { + arr.push(el); + } + } + } else if (doc.querySelectorAll) { + els = doc.querySelectorAll((root.nodeName !== '#document' ? root.nodeName + ' ' : '') + tag + '.' + className); + for (i = 0, len = els.length; i < len; i++) { + el = els[i]; + if (_contains(root, el)) { + arr.push(el); + } + } + } else { + els = root.getElementsByTagName(tag); + className = ' ' + className + ' '; + for (i = 0, len = els.length; i < len; i++) { + el = els[i]; + if (el.nodeType == 1) { + var cls = el.className; + if (cls && (' ' + cls + ' ').indexOf(className) > -1) { + arr.push(el); + } + } + } + } + return arr; + } + function byName(name, tag, root) { + var arr = [], doc = root.ownerDocument || root, + els = doc.getElementsByName(stripslashes(name)), el; + for (var i = 0, len = els.length; i < len; i++) { + el = els[i]; + if (cmpTag(tag, el.nodeName) && _contains(root, el)) { + if (el.getAttribute('name') !== null) { + arr.push(el); + } + } + } + return arr; + } + function byAttr(key, val, tag, root) { + var arr = [], els = root.getElementsByTagName(tag), el; + for (var i = 0, len = els.length; i < len; i++) { + el = els[i]; + if (el.nodeType == 1) { + if (val === null) { + if (_getAttr(el, key) !== null) { + arr.push(el); + } + } else { + if (val === escape(_getAttr(el, key))) { + arr.push(el); + } + } + } + } + return arr; + } + function select(expr, root) { + var arr = [], matches; + matches = /^((?:\\.|[^.#\s\[<>])+)/.exec(expr); + var tag = matches ? matches[1] : '*'; + if ((matches = /#((?:[\w\-]|\\.)+)$/.exec(expr))) { + arr = byId(matches[1], tag, root); + } else if ((matches = /\.((?:[\w\-]|\\.)+)$/.exec(expr))) { + arr = byClass(matches[1], tag, root); + } else if ((matches = /\[((?:[\w\-]|\\.)+)\]/.exec(expr))) { + arr = byAttr(matches[1].toLowerCase(), null, tag, root); + } else if ((matches = /\[((?:[\w\-]|\\.)+)\s*=\s*['"]?((?:\\.|[^'"]+)+)['"]?\]/.exec(expr))) { + var key = matches[1].toLowerCase(), val = matches[2]; + if (key === 'id') { + arr = byId(val, tag, root); + } else if (key === 'class') { + arr = byClass(val, tag, root); + } else if (key === 'name') { + arr = byName(val, tag, root); + } else { + arr = byAttr(key, val, tag, root); + } + } else { + var els = root.getElementsByTagName(tag), el; + for (var i = 0, len = els.length; i < len; i++) { + el = els[i]; + if (el.nodeType == 1) { + arr.push(el); + } + } + } + return arr; + } + var parts = [], arr, re = /((?:\\.|[^\s>])+|[\s>])/g; + while ((arr = re.exec(expr))) { + if (arr[1] !== ' ') { + parts.push(arr[1]); + } + } + var results = []; + if (parts.length == 1) { + return select(parts[0], root); + } + var isChild = false, part, els, subResults, val, v, i, j, k, length, len, l; + for (i = 0, lenth = parts.length; i < lenth; i++) { + part = parts[i]; + if (part === '>') { + isChild = true; + continue; + } + if (i > 0) { + els = []; + for (j = 0, len = results.length; j < len; j++) { + val = results[j]; + subResults = select(part, val); + for (k = 0, l = subResults.length; k < l; k++) { + v = subResults[k]; + if (isChild) { + if (val === v.parentNode) { + els.push(v); + } + } else { + els.push(v); + } + } + } + results = els; + } else { + results = select(part, root); + } + if (results.length === 0) { + return []; + } + } + return results; +} +function _query(expr, root) { + var arr = _queryAll(expr, root); + return arr.length > 0 ? arr[0] : null; +} +K.query = _query; +K.queryAll = _queryAll; + + +function _get(val) { + return K(val)[0]; +} +function _getDoc(node) { + if (!node) { + return document; + } + return node.ownerDocument || node.document || node; +} +function _getWin(node) { + if (!node) { + return window; + } + var doc = _getDoc(node); + return doc.parentWindow || doc.defaultView; +} +function _setHtml(el, html) { + if (el.nodeType != 1) { + return; + } + var doc = _getDoc(el); + try { + el.innerHTML = '' + html; + var temp = doc.getElementById('__kindeditor_temp_tag__'); + temp.parentNode.removeChild(temp); + } catch(e) { + K(el).empty(); + K('@' + html, doc).each(function() { + el.appendChild(this); + }); + } +} +function _hasClass(el, cls) { + return _inString(cls, el.className, ' '); +} +function _setAttr(el, key, val) { + if (_IE && _V < 8 && key.toLowerCase() == 'class') { + key = 'className'; + } + el.setAttribute(key, '' + val); +} +function _removeAttr(el, key) { + if (_IE && _V < 8 && key.toLowerCase() == 'class') { + key = 'className'; + } + _setAttr(el, key, ''); + el.removeAttribute(key); +} +function _getNodeName(node) { + if (!node || !node.nodeName) { + return ''; + } + return node.nodeName.toLowerCase(); +} +function _computedCss(el, key) { + var self = this, win = _getWin(el), camelKey = _toCamel(key), val = ''; + if (win.getComputedStyle) { + var style = win.getComputedStyle(el, null); + val = style[camelKey] || style.getPropertyValue(key) || el.style[camelKey]; + } else if (el.currentStyle) { + val = el.currentStyle[camelKey] || el.style[camelKey]; + } + return val; +} +function _hasVal(node) { + return !!_VALUE_TAG_MAP[_getNodeName(node)]; +} +function _docElement(doc) { + doc = doc || document; + return _QUIRKS ? doc.body : doc.documentElement; +} +function _docHeight(doc) { + var el = _docElement(doc); + return Math.max(el.scrollHeight, el.clientHeight); +} +function _docWidth(doc) { + var el = _docElement(doc); + return Math.max(el.scrollWidth, el.clientWidth); +} +function _getScrollPos(doc) { + doc = doc || document; + var x, y; + if (_IE || _NEWIE || _OPERA) { + x = _docElement(doc).scrollLeft; + y = _docElement(doc).scrollTop; + } else { + x = _getWin(doc).scrollX; + y = _getWin(doc).scrollY; + } + return {x : x, y : y}; +} + +function KNode(node) { + this.init(node); +} +_extend(KNode, { + init : function(node) { + var self = this; + node = _isArray(node) ? node : [node]; + var length = 0; + for (var i = 0, len = node.length; i < len; i++) { + if (node[i]) { + self[i] = node[i].constructor === KNode ? node[i][0] : node[i]; + length++; + } + } + self.length = length; + self.doc = _getDoc(self[0]); + self.name = _getNodeName(self[0]); + self.type = self.length > 0 ? self[0].nodeType : null; + self.win = _getWin(self[0]); + }, + each : function(fn) { + var self = this; + for (var i = 0; i < self.length; i++) { + if (fn.call(self[i], i, self[i]) === false) { + return self; + } + } + return self; + }, + bind : function(type, fn) { + this.each(function() { + _bind(this, type, fn); + }); + return this; + }, + unbind : function(type, fn) { + this.each(function() { + _unbind(this, type, fn); + }); + return this; + }, + fire : function(type) { + if (this.length < 1) { + return this; + } + _fire(this[0], type); + return this; + }, + hasAttr : function(key) { + if (this.length < 1) { + return false; + } + return !!_getAttr(this[0], key); + }, + attr : function(key, val) { + var self = this; + if (key === undefined) { + return _getAttrList(self.outer()); + } + if (typeof key === 'object') { + _each(key, function(k, v) { + self.attr(k, v); + }); + return self; + } + if (val === undefined) { + val = self.length < 1 ? null : _getAttr(self[0], key); + return val === null ? '' : val; + } + self.each(function() { + _setAttr(this, key, val); + }); + return self; + }, + removeAttr : function(key) { + this.each(function() { + _removeAttr(this, key); + }); + return this; + }, + get : function(i) { + if (this.length < 1) { + return null; + } + return this[i || 0]; + }, + eq : function(i) { + if (this.length < 1) { + return null; + } + return this[i] ? new KNode(this[i]) : null; + }, + hasClass : function(cls) { + if (this.length < 1) { + return false; + } + return _hasClass(this[0], cls); + }, + addClass : function(cls) { + this.each(function() { + if (!_hasClass(this, cls)) { + this.className = _trim(this.className + ' ' + cls); + } + }); + return this; + }, + removeClass : function(cls) { + this.each(function() { + if (_hasClass(this, cls)) { + this.className = _trim(this.className.replace(new RegExp('(^|\\s)' + cls + '(\\s|$)'), ' ')); + } + }); + return this; + }, + html : function(val) { + var self = this; + if (val === undefined) { + if (self.length < 1 || self.type != 1) { + return ''; + } + return _formatHtml(self[0].innerHTML); + } + self.each(function() { + _setHtml(this, val); + }); + return self; + }, + text : function() { + var self = this; + if (self.length < 1) { + return ''; + } + return _IE ? self[0].innerText : self[0].textContent; + }, + hasVal : function() { + if (this.length < 1) { + return false; + } + return _hasVal(this[0]); + }, + val : function(val) { + var self = this; + if (val === undefined) { + if (self.length < 1) { + return ''; + } + return self.hasVal() ? self[0].value : self.attr('value'); + } else { + self.each(function() { + if (_hasVal(this)) { + this.value = val; + } else { + _setAttr(this, 'value' , val); + } + }); + return self; + } + }, + css : function(key, val) { + var self = this; + if (key === undefined) { + return _getCssList(self.attr('style')); + } + if (typeof key === 'object') { + _each(key, function(k, v) { + self.css(k, v); + }); + return self; + } + if (val === undefined) { + if (self.length < 1) { + return ''; + } + return self[0].style[_toCamel(key)] || _computedCss(self[0], key) || ''; + } + self.each(function() { + this.style[_toCamel(key)] = val; + }); + return self; + }, + width : function(val) { + var self = this; + if (val === undefined) { + if (self.length < 1) { + return 0; + } + return self[0].offsetWidth; + } + return self.css('width', _addUnit(val)); + }, + height : function(val) { + var self = this; + if (val === undefined) { + if (self.length < 1) { + return 0; + } + return self[0].offsetHeight; + } + return self.css('height', _addUnit(val)); + }, + opacity : function(val) { + this.each(function() { + if (this.style.opacity === undefined) { + this.style.filter = val == 1 ? '' : 'alpha(opacity=' + (val * 100) + ')'; + } else { + this.style.opacity = val == 1 ? '' : val; + } + }); + return this; + }, + data : function(key, val) { + var self = this; + key = 'kindeditor_data_' + key; + if (val === undefined) { + if (self.length < 1) { + return null; + } + return self[0][key]; + } + this.each(function() { + this[key] = val; + }); + return self; + }, + pos : function() { + var self = this, node = self[0], x = 0, y = 0; + if (node) { + if (node.getBoundingClientRect) { + var box = node.getBoundingClientRect(), + pos = _getScrollPos(self.doc); + x = box.left + pos.x; + y = box.top + pos.y; + } else { + while (node) { + x += node.offsetLeft; + y += node.offsetTop; + node = node.offsetParent; + } + } + } + return {x : _round(x), y : _round(y)}; + }, + clone : function(bool) { + if (this.length < 1) { + return new KNode([]); + } + return new KNode(this[0].cloneNode(bool)); + }, + append : function(expr) { + this.each(function() { + if (this.appendChild) { + this.appendChild(_get(expr)); + } + }); + return this; + }, + appendTo : function(expr) { + this.each(function() { + _get(expr).appendChild(this); + }); + return this; + }, + before : function(expr) { + this.each(function() { + this.parentNode.insertBefore(_get(expr), this); + }); + return this; + }, + after : function(expr) { + this.each(function() { + if (this.nextSibling) { + this.parentNode.insertBefore(_get(expr), this.nextSibling); + } else { + this.parentNode.appendChild(_get(expr)); + } + }); + return this; + }, + replaceWith : function(expr) { + var nodes = []; + this.each(function(i, node) { + _unbind(node); + var newNode = _get(expr); + node.parentNode.replaceChild(newNode, node); + nodes.push(newNode); + }); + return K(nodes); + }, + empty : function() { + var self = this; + self.each(function(i, node) { + var child = node.firstChild; + while (child) { + if (!node.parentNode) { + return; + } + var next = child.nextSibling; + child.parentNode.removeChild(child); + child = next; + } + }); + return self; + }, + remove : function(keepChilds) { + var self = this; + self.each(function(i, node) { + if (!node.parentNode) { + return; + } + _unbind(node); + if (keepChilds) { + var child = node.firstChild; + while (child) { + var next = child.nextSibling; + node.parentNode.insertBefore(child, node); + child = next; + } + } + node.parentNode.removeChild(node); + delete self[i]; + }); + self.length = 0; + return self; + }, + show : function(val) { + var self = this; + if (val === undefined) { + val = self._originDisplay || ''; + } + if (self.css('display') != 'none') { + return self; + } + return self.css('display', val); + }, + hide : function() { + var self = this; + if (self.length < 1) { + return self; + } + self._originDisplay = self[0].style.display; + return self.css('display', 'none'); + }, + outer : function() { + var self = this; + if (self.length < 1) { + return ''; + } + var div = self.doc.createElement('div'), html; + div.appendChild(self[0].cloneNode(true)); + html = _formatHtml(div.innerHTML); + div = null; + return html; + }, + isSingle : function() { + return !!_SINGLE_TAG_MAP[this.name]; + }, + isInline : function() { + return !!_INLINE_TAG_MAP[this.name]; + }, + isBlock : function() { + return !!_BLOCK_TAG_MAP[this.name]; + }, + isStyle : function() { + return !!_STYLE_TAG_MAP[this.name]; + }, + isControl : function() { + return !!_CONTROL_TAG_MAP[this.name]; + }, + contains : function(otherNode) { + if (this.length < 1) { + return false; + } + return _contains(this[0], _get(otherNode)); + }, + parent : function() { + if (this.length < 1) { + return null; + } + var node = this[0].parentNode; + return node ? new KNode(node) : null; + }, + children : function() { + if (this.length < 1) { + return new KNode([]); + } + var list = [], child = this[0].firstChild; + while (child) { + if (child.nodeType != 3 || _trim(child.nodeValue) !== '') { + list.push(child); + } + child = child.nextSibling; + } + return new KNode(list); + }, + first : function() { + var list = this.children(); + return list.length > 0 ? list.eq(0) : null; + }, + last : function() { + var list = this.children(); + return list.length > 0 ? list.eq(list.length - 1) : null; + }, + index : function() { + if (this.length < 1) { + return -1; + } + var i = -1, sibling = this[0]; + while (sibling) { + i++; + sibling = sibling.previousSibling; + } + return i; + }, + prev : function() { + if (this.length < 1) { + return null; + } + var node = this[0].previousSibling; + return node ? new KNode(node) : null; + }, + next : function() { + if (this.length < 1) { + return null; + } + var node = this[0].nextSibling; + return node ? new KNode(node) : null; + }, + scan : function(fn, order) { + if (this.length < 1) { + return; + } + order = (order === undefined) ? true : order; + function walk(node) { + var n = order ? node.firstChild : node.lastChild; + while (n) { + var next = order ? n.nextSibling : n.previousSibling; + if (fn(n) === false) { + return false; + } + if (walk(n) === false) { + return false; + } + n = next; + } + } + walk(this[0]); + return this; + } +}); +_each(('blur,focus,focusin,focusout,load,resize,scroll,unload,click,dblclick,' + + 'mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,' + + 'change,select,submit,keydown,keypress,keyup,error,contextmenu').split(','), function(i, type) { + KNode.prototype[type] = function(fn) { + return fn ? this.bind(type, fn) : this.fire(type); + }; +}); +var _K = K; +K = function(expr, root) { + if (expr === undefined || expr === null) { + return; + } + function newNode(node) { + if (!node[0]) { + node = []; + } + return new KNode(node); + } + if (typeof expr === 'string') { + if (root) { + root = _get(root); + } + var length = expr.length; + if (expr.charAt(0) === '@') { + expr = expr.substr(1); + } + if (expr.length !== length || /<.+>/.test(expr)) { + var doc = root ? root.ownerDocument || root : document, + div = doc.createElement('div'), list = []; + div.innerHTML = '' + expr; + for (var i = 0, len = div.childNodes.length; i < len; i++) { + var child = div.childNodes[i]; + if (child.id == '__kindeditor_temp_tag__') { + continue; + } + list.push(child); + } + return newNode(list); + } + return newNode(_queryAll(expr, root)); + } + if (expr && expr.constructor === KNode) { + return expr; + } + if (expr.toArray) { + expr = expr.toArray(); + } + if (_isArray(expr)) { + return newNode(expr); + } + return newNode(_toArray(arguments)); +}; +_each(_K, function(key, val) { + K[key] = val; +}); +K.NodeClass = KNode; +window.KindEditor = K; + + +var _START_TO_START = 0, + _START_TO_END = 1, + _END_TO_END = 2, + _END_TO_START = 3, + _BOOKMARK_ID = 0; +function _updateCollapsed(range) { + range.collapsed = (range.startContainer === range.endContainer && range.startOffset === range.endOffset); + return range; +} +function _copyAndDelete(range, isCopy, isDelete) { + var doc = range.doc, nodeList = []; + function splitTextNode(node, startOffset, endOffset) { + var length = node.nodeValue.length, centerNode; + if (isCopy) { + var cloneNode = node.cloneNode(true); + if (startOffset > 0) { + centerNode = cloneNode.splitText(startOffset); + } else { + centerNode = cloneNode; + } + if (endOffset < length) { + centerNode.splitText(endOffset - startOffset); + } + } + if (isDelete) { + var center = node; + if (startOffset > 0) { + center = node.splitText(startOffset); + range.setStart(node, startOffset); + } + if (endOffset < length) { + var right = center.splitText(endOffset - startOffset); + range.setEnd(right, 0); + } + nodeList.push(center); + } + return centerNode; + } + function removeNodes() { + if (isDelete) { + range.up().collapse(true); + } + for (var i = 0, len = nodeList.length; i < len; i++) { + var node = nodeList[i]; + if (node.parentNode) { + node.parentNode.removeChild(node); + } + } + } + var copyRange = range.cloneRange().down(); + var start = -1, incStart = -1, incEnd = -1, end = -1, + ancestor = range.commonAncestor(), frag = doc.createDocumentFragment(); + if (ancestor.nodeType == 3) { + var textNode = splitTextNode(ancestor, range.startOffset, range.endOffset); + if (isCopy) { + frag.appendChild(textNode); + } + removeNodes(); + return isCopy ? frag : range; + } + function extractNodes(parent, frag) { + var node = parent.firstChild, nextNode; + while (node) { + var testRange = new KRange(doc).selectNode(node); + start = testRange.compareBoundaryPoints(_START_TO_END, range); + if (start >= 0 && incStart <= 0) { + incStart = testRange.compareBoundaryPoints(_START_TO_START, range); + } + if (incStart >= 0 && incEnd <= 0) { + incEnd = testRange.compareBoundaryPoints(_END_TO_END, range); + } + if (incEnd >= 0 && end <= 0) { + end = testRange.compareBoundaryPoints(_END_TO_START, range); + } + if (end >= 0) { + return false; + } + nextNode = node.nextSibling; + if (start > 0) { + if (node.nodeType == 1) { + if (incStart >= 0 && incEnd <= 0) { + if (isCopy) { + frag.appendChild(node.cloneNode(true)); + } + if (isDelete) { + nodeList.push(node); + } + } else { + var childFlag; + if (isCopy) { + childFlag = node.cloneNode(false); + frag.appendChild(childFlag); + } + if (extractNodes(node, childFlag) === false) { + return false; + } + } + } else if (node.nodeType == 3) { + var textNode; + if (node == copyRange.startContainer) { + textNode = splitTextNode(node, copyRange.startOffset, node.nodeValue.length); + } else if (node == copyRange.endContainer) { + textNode = splitTextNode(node, 0, copyRange.endOffset); + } else { + textNode = splitTextNode(node, 0, node.nodeValue.length); + } + if (isCopy) { + try { + frag.appendChild(textNode); + } catch(e) {} + } + } + } + node = nextNode; + } + } + extractNodes(ancestor, frag); + if (isDelete) { + range.up().collapse(true); + } + for (var i = 0, len = nodeList.length; i < len; i++) { + var node = nodeList[i]; + if (node.parentNode) { + node.parentNode.removeChild(node); + } + } + return isCopy ? frag : range; +} +function _moveToElementText(range, el) { + var node = el; + while (node) { + var knode = K(node); + if (knode.name == 'marquee' || knode.name == 'select') { + return; + } + node = node.parentNode; + } + try { + range.moveToElementText(el); + } catch(e) {} +} +function _getStartEnd(rng, isStart) { + var doc = rng.parentElement().ownerDocument, + pointRange = rng.duplicate(); + pointRange.collapse(isStart); + var parent = pointRange.parentElement(), + nodes = parent.childNodes; + if (nodes.length === 0) { + return {node: parent.parentNode, offset: K(parent).index()}; + } + var startNode = doc, startPos = 0, cmp = -1; + var testRange = rng.duplicate(); + _moveToElementText(testRange, parent); + for (var i = 0, len = nodes.length; i < len; i++) { + var node = nodes[i]; + cmp = testRange.compareEndPoints('StartToStart', pointRange); + if (cmp === 0) { + return {node: node.parentNode, offset: i}; + } + if (node.nodeType == 1) { + var nodeRange = rng.duplicate(), dummy, knode = K(node), newNode = node; + if (knode.isControl()) { + dummy = doc.createElement('span'); + knode.after(dummy); + newNode = dummy; + startPos += knode.text().replace(/\r\n|\n|\r/g, '').length; + } + _moveToElementText(nodeRange, newNode); + testRange.setEndPoint('StartToEnd', nodeRange); + if (cmp > 0) { + startPos += nodeRange.text.replace(/\r\n|\n|\r/g, '').length; + } else { + startPos = 0; + } + if (dummy) { + K(dummy).remove(); + } + } else if (node.nodeType == 3) { + testRange.moveStart('character', node.nodeValue.length); + startPos += node.nodeValue.length; + } + if (cmp < 0) { + startNode = node; + } + } + if (cmp < 0 && startNode.nodeType == 1) { + return {node: parent, offset: K(parent.lastChild).index() + 1}; + } + if (cmp > 0) { + while (startNode.nextSibling && startNode.nodeType == 1) { + startNode = startNode.nextSibling; + } + } + testRange = rng.duplicate(); + _moveToElementText(testRange, parent); + testRange.setEndPoint('StartToEnd', pointRange); + startPos -= testRange.text.replace(/\r\n|\n|\r/g, '').length; + if (cmp > 0 && startNode.nodeType == 3) { + var prevNode = startNode.previousSibling; + while (prevNode && prevNode.nodeType == 3) { + startPos -= prevNode.nodeValue.length; + prevNode = prevNode.previousSibling; + } + } + return {node: startNode, offset: startPos}; +} +function _getEndRange(node, offset) { + var doc = node.ownerDocument || node, + range = doc.body.createTextRange(); + if (doc == node) { + range.collapse(true); + return range; + } + if (node.nodeType == 1 && node.childNodes.length > 0) { + var children = node.childNodes, isStart, child; + if (offset === 0) { + child = children[0]; + isStart = true; + } else { + child = children[offset - 1]; + isStart = false; + } + if (!child) { + return range; + } + if (K(child).name === 'head') { + if (offset === 1) { + isStart = true; + } + if (offset === 2) { + isStart = false; + } + range.collapse(isStart); + return range; + } + if (child.nodeType == 1) { + var kchild = K(child), span; + if (kchild.isControl()) { + span = doc.createElement('span'); + if (isStart) { + kchild.before(span); + } else { + kchild.after(span); + } + child = span; + } + _moveToElementText(range, child); + range.collapse(isStart); + if (span) { + K(span).remove(); + } + return range; + } + node = child; + offset = isStart ? 0 : child.nodeValue.length; + } + var dummy = doc.createElement('span'); + K(node).before(dummy); + _moveToElementText(range, dummy); + range.moveStart('character', offset); + K(dummy).remove(); + return range; +} +function _toRange(rng) { + var doc, range; + function tr2td(start) { + if (K(start.node).name == 'tr') { + start.node = start.node.cells[start.offset]; + start.offset = 0; + } + } + if (_IERANGE) { + if (rng.item) { + doc = _getDoc(rng.item(0)); + range = new KRange(doc); + range.selectNode(rng.item(0)); + return range; + } + doc = rng.parentElement().ownerDocument; + var start = _getStartEnd(rng, true), + end = _getStartEnd(rng, false); + tr2td(start); + tr2td(end); + range = new KRange(doc); + range.setStart(start.node, start.offset); + range.setEnd(end.node, end.offset); + return range; + } + var startContainer = rng.startContainer; + doc = startContainer.ownerDocument || startContainer; + range = new KRange(doc); + range.setStart(startContainer, rng.startOffset); + range.setEnd(rng.endContainer, rng.endOffset); + return range; +} + +function KRange(doc) { + this.init(doc); +} +_extend(KRange, { + init : function(doc) { + var self = this; + self.startContainer = doc; + self.startOffset = 0; + self.endContainer = doc; + self.endOffset = 0; + self.collapsed = true; + self.doc = doc; + }, + commonAncestor : function() { + function getParents(node) { + var parents = []; + while (node) { + parents.push(node); + node = node.parentNode; + } + return parents; + } + var parentsA = getParents(this.startContainer), + parentsB = getParents(this.endContainer), + i = 0, lenA = parentsA.length, lenB = parentsB.length, parentA, parentB; + while (++i) { + parentA = parentsA[lenA - i]; + parentB = parentsB[lenB - i]; + if (!parentA || !parentB || parentA !== parentB) { + break; + } + } + return parentsA[lenA - i + 1]; + }, + setStart : function(node, offset) { + var self = this, doc = self.doc; + self.startContainer = node; + self.startOffset = offset; + if (self.endContainer === doc) { + self.endContainer = node; + self.endOffset = offset; + } + return _updateCollapsed(this); + }, + setEnd : function(node, offset) { + var self = this, doc = self.doc; + self.endContainer = node; + self.endOffset = offset; + if (self.startContainer === doc) { + self.startContainer = node; + self.startOffset = offset; + } + return _updateCollapsed(this); + }, + setStartBefore : function(node) { + return this.setStart(node.parentNode || this.doc, K(node).index()); + }, + setStartAfter : function(node) { + return this.setStart(node.parentNode || this.doc, K(node).index() + 1); + }, + setEndBefore : function(node) { + return this.setEnd(node.parentNode || this.doc, K(node).index()); + }, + setEndAfter : function(node) { + return this.setEnd(node.parentNode || this.doc, K(node).index() + 1); + }, + selectNode : function(node) { + return this.setStartBefore(node).setEndAfter(node); + }, + selectNodeContents : function(node) { + var knode = K(node); + if (knode.type == 3 || knode.isSingle()) { + return this.selectNode(node); + } + var children = knode.children(); + if (children.length > 0) { + return this.setStartBefore(children[0]).setEndAfter(children[children.length - 1]); + } + return this.setStart(node, 0).setEnd(node, 0); + }, + collapse : function(toStart) { + if (toStart) { + return this.setEnd(this.startContainer, this.startOffset); + } + return this.setStart(this.endContainer, this.endOffset); + }, + compareBoundaryPoints : function(how, range) { + var rangeA = this.get(), rangeB = range.get(); + if (_IERANGE) { + var arr = {}; + arr[_START_TO_START] = 'StartToStart'; + arr[_START_TO_END] = 'EndToStart'; + arr[_END_TO_END] = 'EndToEnd'; + arr[_END_TO_START] = 'StartToEnd'; + var cmp = rangeA.compareEndPoints(arr[how], rangeB); + if (cmp !== 0) { + return cmp; + } + var nodeA, nodeB, nodeC, posA, posB; + if (how === _START_TO_START || how === _END_TO_START) { + nodeA = this.startContainer; + posA = this.startOffset; + } + if (how === _START_TO_END || how === _END_TO_END) { + nodeA = this.endContainer; + posA = this.endOffset; + } + if (how === _START_TO_START || how === _START_TO_END) { + nodeB = range.startContainer; + posB = range.startOffset; + } + if (how === _END_TO_END || how === _END_TO_START) { + nodeB = range.endContainer; + posB = range.endOffset; + } + if (nodeA === nodeB) { + var diff = posA - posB; + return diff > 0 ? 1 : (diff < 0 ? -1 : 0); + } + nodeC = nodeB; + while (nodeC && nodeC.parentNode !== nodeA) { + nodeC = nodeC.parentNode; + } + if (nodeC) { + return K(nodeC).index() >= posA ? -1 : 1; + } + nodeC = nodeA; + while (nodeC && nodeC.parentNode !== nodeB) { + nodeC = nodeC.parentNode; + } + if (nodeC) { + return K(nodeC).index() >= posB ? 1 : -1; + } + nodeC = K(nodeB).next(); + if (nodeC && nodeC.contains(nodeA)) { + return 1; + } + nodeC = K(nodeA).next(); + if (nodeC && nodeC.contains(nodeB)) { + return -1; + } + } else { + return rangeA.compareBoundaryPoints(how, rangeB); + } + }, + cloneRange : function() { + return new KRange(this.doc).setStart(this.startContainer, this.startOffset).setEnd(this.endContainer, this.endOffset); + }, + toString : function() { + var rng = this.get(), str = _IERANGE ? rng.text : rng.toString(); + return str.replace(/\r\n|\n|\r/g, ''); + }, + cloneContents : function() { + return _copyAndDelete(this, true, false); + }, + deleteContents : function() { + return _copyAndDelete(this, false, true); + }, + extractContents : function() { + return _copyAndDelete(this, true, true); + }, + insertNode : function(node) { + var self = this, + sc = self.startContainer, so = self.startOffset, + ec = self.endContainer, eo = self.endOffset, + firstChild, lastChild, c, nodeCount = 1; + if (node.nodeName.toLowerCase() === '#document-fragment') { + firstChild = node.firstChild; + lastChild = node.lastChild; + nodeCount = node.childNodes.length; + } + if (sc.nodeType == 1) { + c = sc.childNodes[so]; + if (c) { + sc.insertBefore(node, c); + if (sc === ec) { + eo += nodeCount; + } + } else { + sc.appendChild(node); + } + } else if (sc.nodeType == 3) { + if (so === 0) { + sc.parentNode.insertBefore(node, sc); + if (sc.parentNode === ec) { + eo += nodeCount; + } + } else if (so >= sc.nodeValue.length) { + if (sc.nextSibling) { + sc.parentNode.insertBefore(node, sc.nextSibling); + } else { + sc.parentNode.appendChild(node); + } + } else { + if (so > 0) { + c = sc.splitText(so); + } else { + c = sc; + } + sc.parentNode.insertBefore(node, c); + if (sc === ec) { + ec = c; + eo -= so; + } + } + } + if (firstChild) { + self.setStartBefore(firstChild).setEndAfter(lastChild); + } else { + self.selectNode(node); + } + if (self.compareBoundaryPoints(_END_TO_END, self.cloneRange().setEnd(ec, eo)) >= 1) { + return self; + } + return self.setEnd(ec, eo); + }, + surroundContents : function(node) { + node.appendChild(this.extractContents()); + return this.insertNode(node).selectNode(node); + }, + isControl : function() { + var self = this, + sc = self.startContainer, so = self.startOffset, + ec = self.endContainer, eo = self.endOffset, rng; + return sc.nodeType == 1 && sc === ec && so + 1 === eo && K(sc.childNodes[so]).isControl(); + }, + get : function(hasControlRange) { + var self = this, doc = self.doc, node, rng; + if (!_IERANGE) { + rng = doc.createRange(); + try { + rng.setStart(self.startContainer, self.startOffset); + rng.setEnd(self.endContainer, self.endOffset); + } catch (e) {} + return rng; + } + if (hasControlRange && self.isControl()) { + rng = doc.body.createControlRange(); + rng.addElement(self.startContainer.childNodes[self.startOffset]); + return rng; + } + var range = self.cloneRange().down(); + rng = doc.body.createTextRange(); + rng.setEndPoint('StartToStart', _getEndRange(range.startContainer, range.startOffset)); + rng.setEndPoint('EndToStart', _getEndRange(range.endContainer, range.endOffset)); + return rng; + }, + html : function() { + return K(this.cloneContents()).outer(); + }, + down : function() { + var self = this; + function downPos(node, pos, isStart) { + if (node.nodeType != 1) { + return; + } + var children = K(node).children(); + if (children.length === 0) { + return; + } + var left, right, child, offset; + if (pos > 0) { + left = children.eq(pos - 1); + } + if (pos < children.length) { + right = children.eq(pos); + } + if (left && left.type == 3) { + child = left[0]; + offset = child.nodeValue.length; + } + if (right && right.type == 3) { + child = right[0]; + offset = 0; + } + if (!child) { + return; + } + if (isStart) { + self.setStart(child, offset); + } else { + self.setEnd(child, offset); + } + } + downPos(self.startContainer, self.startOffset, true); + downPos(self.endContainer, self.endOffset, false); + return self; + }, + up : function() { + var self = this; + function upPos(node, pos, isStart) { + if (node.nodeType != 3) { + return; + } + if (pos === 0) { + if (isStart) { + self.setStartBefore(node); + } else { + self.setEndBefore(node); + } + } else if (pos == node.nodeValue.length) { + if (isStart) { + self.setStartAfter(node); + } else { + self.setEndAfter(node); + } + } + } + upPos(self.startContainer, self.startOffset, true); + upPos(self.endContainer, self.endOffset, false); + return self; + }, + enlarge : function(toBlock) { + var self = this; + self.up(); + function enlargePos(node, pos, isStart) { + var knode = K(node), parent; + if (knode.type == 3 || _NOSPLIT_TAG_MAP[knode.name] || !toBlock && knode.isBlock()) { + return; + } + if (pos === 0) { + while (!knode.prev()) { + parent = knode.parent(); + if (!parent || _NOSPLIT_TAG_MAP[parent.name] || !toBlock && parent.isBlock()) { + break; + } + knode = parent; + } + if (isStart) { + self.setStartBefore(knode[0]); + } else { + self.setEndBefore(knode[0]); + } + } else if (pos == knode.children().length) { + while (!knode.next()) { + parent = knode.parent(); + if (!parent || _NOSPLIT_TAG_MAP[parent.name] || !toBlock && parent.isBlock()) { + break; + } + knode = parent; + } + if (isStart) { + self.setStartAfter(knode[0]); + } else { + self.setEndAfter(knode[0]); + } + } + } + enlargePos(self.startContainer, self.startOffset, true); + enlargePos(self.endContainer, self.endOffset, false); + return self; + }, + shrink : function() { + var self = this, child, collapsed = self.collapsed; + while (self.startContainer.nodeType == 1 && (child = self.startContainer.childNodes[self.startOffset]) && child.nodeType == 1 && !K(child).isSingle()) { + self.setStart(child, 0); + } + if (collapsed) { + return self.collapse(collapsed); + } + while (self.endContainer.nodeType == 1 && self.endOffset > 0 && (child = self.endContainer.childNodes[self.endOffset - 1]) && child.nodeType == 1 && !K(child).isSingle()) { + self.setEnd(child, child.childNodes.length); + } + return self; + }, + createBookmark : function(serialize) { + var self = this, doc = self.doc, endNode, + startNode = K('', doc)[0]; + startNode.id = '__kindeditor_bookmark_start_' + (_BOOKMARK_ID++) + '__'; + if (!self.collapsed) { + endNode = startNode.cloneNode(true); + endNode.id = '__kindeditor_bookmark_end_' + (_BOOKMARK_ID++) + '__'; + } + if (endNode) { + self.cloneRange().collapse(false).insertNode(endNode).setEndBefore(endNode); + } + self.insertNode(startNode).setStartAfter(startNode); + return { + start : serialize ? '#' + startNode.id : startNode, + end : endNode ? (serialize ? '#' + endNode.id : endNode) : null + }; + }, + moveToBookmark : function(bookmark) { + var self = this, doc = self.doc, + start = K(bookmark.start, doc), end = bookmark.end ? K(bookmark.end, doc) : null; + if (!start || start.length < 1) { + return self; + } + self.setStartBefore(start[0]); + start.remove(); + if (end && end.length > 0) { + self.setEndBefore(end[0]); + end.remove(); + } else { + self.collapse(true); + } + return self; + }, + dump : function() { + console.log('--------------------'); + console.log(this.startContainer.nodeType == 3 ? this.startContainer.nodeValue : this.startContainer, this.startOffset); + console.log(this.endContainer.nodeType == 3 ? this.endContainer.nodeValue : this.endContainer, this.endOffset); + } +}); +function _range(mixed) { + if (!mixed.nodeName) { + return mixed.constructor === KRange ? mixed : _toRange(mixed); + } + return new KRange(mixed); +} +K.RangeClass = KRange; +K.range = _range; +K.START_TO_START = _START_TO_START; +K.START_TO_END = _START_TO_END; +K.END_TO_END = _END_TO_END; +K.END_TO_START = _END_TO_START; + + +function _nativeCommand(doc, key, val) { + try { + doc.execCommand(key, false, val); + } catch(e) {} +} +function _nativeCommandValue(doc, key) { + var val = ''; + try { + val = doc.queryCommandValue(key); + } catch (e) {} + if (typeof val !== 'string') { + val = ''; + } + return val; +} +function _getSel(doc) { + var win = _getWin(doc); + return _IERANGE ? doc.selection : win.getSelection(); +} +function _getRng(doc) { + var sel = _getSel(doc), rng; + try { + if (sel.rangeCount > 0) { + rng = sel.getRangeAt(0); + } else { + rng = sel.createRange(); + } + } catch(e) {} + if (_IERANGE && (!rng || (!rng.item && rng.parentElement().ownerDocument !== doc))) { + return null; + } + return rng; +} +function _singleKeyMap(map) { + var newMap = {}, arr, v; + _each(map, function(key, val) { + arr = key.split(','); + for (var i = 0, len = arr.length; i < len; i++) { + v = arr[i]; + newMap[v] = val; + } + }); + return newMap; +} +function _hasAttrOrCss(knode, map) { + return _hasAttrOrCssByKey(knode, map, '*') || _hasAttrOrCssByKey(knode, map); +} +function _hasAttrOrCssByKey(knode, map, mapKey) { + mapKey = mapKey || knode.name; + if (knode.type !== 1) { + return false; + } + var newMap = _singleKeyMap(map); + if (!newMap[mapKey]) { + return false; + } + var arr = newMap[mapKey].split(','); + for (var i = 0, len = arr.length; i < len; i++) { + var key = arr[i]; + if (key === '*') { + return true; + } + var match = /^(\.?)([^=]+)(?:=([^=]*))?$/.exec(key); + var method = match[1] ? 'css' : 'attr'; + key = match[2]; + var val = match[3] || ''; + if (val === '' && knode[method](key) !== '') { + return true; + } + if (val !== '' && knode[method](key) === val) { + return true; + } + } + return false; +} +function _removeAttrOrCss(knode, map) { + if (knode.type != 1) { + return; + } + _removeAttrOrCssByKey(knode, map, '*'); + _removeAttrOrCssByKey(knode, map); +} +function _removeAttrOrCssByKey(knode, map, mapKey) { + mapKey = mapKey || knode.name; + if (knode.type !== 1) { + return; + } + var newMap = _singleKeyMap(map); + if (!newMap[mapKey]) { + return; + } + var arr = newMap[mapKey].split(','), allFlag = false; + for (var i = 0, len = arr.length; i < len; i++) { + var key = arr[i]; + if (key === '*') { + allFlag = true; + break; + } + var match = /^(\.?)([^=]+)(?:=([^=]*))?$/.exec(key); + key = match[2]; + if (match[1]) { + key = _toCamel(key); + if (knode[0].style[key]) { + knode[0].style[key] = ''; + } + } else { + knode.removeAttr(key); + } + } + if (allFlag) { + knode.remove(true); + } +} +function _getInnerNode(knode) { + var inner = knode; + while (inner.first()) { + inner = inner.first(); + } + return inner; +} +function _isEmptyNode(knode) { + if (knode.type != 1 || knode.isSingle()) { + return false; + } + return knode.html().replace(/<[^>]+>/g, '') === ''; +} +function _mergeWrapper(a, b) { + a = a.clone(true); + var lastA = _getInnerNode(a), childA = a, merged = false; + while (b) { + while (childA) { + if (childA.name === b.name) { + _mergeAttrs(childA, b.attr(), b.css()); + merged = true; + } + childA = childA.first(); + } + if (!merged) { + lastA.append(b.clone(false)); + } + merged = false; + b = b.first(); + } + return a; +} +function _wrapNode(knode, wrapper) { + wrapper = wrapper.clone(true); + if (knode.type == 3) { + _getInnerNode(wrapper).append(knode.clone(false)); + knode.replaceWith(wrapper); + return wrapper; + } + var nodeWrapper = knode, child; + while ((child = knode.first()) && child.children().length == 1) { + knode = child; + } + child = knode.first(); + var frag = knode.doc.createDocumentFragment(); + while (child) { + frag.appendChild(child[0]); + child = child.next(); + } + wrapper = _mergeWrapper(nodeWrapper, wrapper); + if (frag.firstChild) { + _getInnerNode(wrapper).append(frag); + } + nodeWrapper.replaceWith(wrapper); + return wrapper; +} +function _mergeAttrs(knode, attrs, styles) { + _each(attrs, function(key, val) { + if (key !== 'style') { + knode.attr(key, val); + } + }); + _each(styles, function(key, val) { + knode.css(key, val); + }); +} +function _inPreElement(knode) { + while (knode && knode.name != 'body') { + if (_PRE_TAG_MAP[knode.name] || knode.name == 'div' && knode.hasClass('ke-script')) { + return true; + } + knode = knode.parent(); + } + return false; +} +function KCmd(range) { + this.init(range); +} +_extend(KCmd, { + init : function(range) { + var self = this, doc = range.doc; + self.doc = doc; + self.win = _getWin(doc); + self.sel = _getSel(doc); + self.range = range; + }, + selection : function(forceReset) { + var self = this, doc = self.doc, rng = _getRng(doc); + self.sel = _getSel(doc); + if (rng) { + self.range = _range(rng); + if (K(self.range.startContainer).name == 'html') { + self.range.selectNodeContents(doc.body).collapse(false); + } + return self; + } + if (forceReset) { + self.range.selectNodeContents(doc.body).collapse(false); + } + return self; + }, + select : function(hasDummy) { + hasDummy = _undef(hasDummy, true); + var self = this, sel = self.sel, range = self.range.cloneRange().shrink(), + sc = range.startContainer, so = range.startOffset, + ec = range.endContainer, eo = range.endOffset, + doc = _getDoc(sc), win = self.win, rng, hasU200b = false; + if (hasDummy && sc.nodeType == 1 && range.collapsed) { + if (_IERANGE) { + var dummy = K(' ', doc); + range.insertNode(dummy[0]); + rng = doc.body.createTextRange(); + try { + rng.moveToElementText(dummy[0]); + } catch(ex) {} + rng.collapse(false); + rng.select(); + dummy.remove(); + win.focus(); + return self; + } + if (_WEBKIT) { + var children = sc.childNodes; + if (K(sc).isInline() || so > 0 && K(children[so - 1]).isInline() || children[so] && K(children[so]).isInline()) { + range.insertNode(doc.createTextNode('\u200B')); + hasU200b = true; + } + } + } + if (_IERANGE) { + try { + rng = range.get(true); + rng.select(); + } catch(e) {} + } else { + if (hasU200b) { + range.collapse(false); + } + rng = range.get(true); + sel.removeAllRanges(); + sel.addRange(rng); + if (doc !== document) { + var pos = K(rng.endContainer).pos(); + win.scrollTo(pos.x, pos.y); + } + } + win.focus(); + return self; + }, + wrap : function(val) { + var self = this, doc = self.doc, range = self.range, wrapper; + wrapper = K(val, doc); + if (range.collapsed) { + range.shrink(); + range.insertNode(wrapper[0]).selectNodeContents(wrapper[0]); + return self; + } + if (wrapper.isBlock()) { + var copyWrapper = wrapper.clone(true), child = copyWrapper; + while (child.first()) { + child = child.first(); + } + child.append(range.extractContents()); + range.insertNode(copyWrapper[0]).selectNode(copyWrapper[0]); + return self; + } + range.enlarge(); + var bookmark = range.createBookmark(), ancestor = range.commonAncestor(), isStart = false; + K(ancestor).scan(function(node) { + if (!isStart && node == bookmark.start) { + isStart = true; + return; + } + if (isStart) { + if (node == bookmark.end) { + return false; + } + var knode = K(node); + if (_inPreElement(knode)) { + return; + } + if (knode.type == 3 && _trim(node.nodeValue).length > 0) { + var parent; + while ((parent = knode.parent()) && parent.isStyle() && parent.children().length == 1) { + knode = parent; + } + _wrapNode(knode, wrapper); + } + } + }); + range.moveToBookmark(bookmark); + return self; + }, + split : function(isStart, map) { + var range = this.range, doc = range.doc; + var tempRange = range.cloneRange().collapse(isStart); + var node = tempRange.startContainer, pos = tempRange.startOffset, + parent = node.nodeType == 3 ? node.parentNode : node, + needSplit = false, knode; + while (parent && parent.parentNode) { + knode = K(parent); + if (map) { + if (!knode.isStyle()) { + break; + } + if (!_hasAttrOrCss(knode, map)) { + break; + } + } else { + if (_NOSPLIT_TAG_MAP[knode.name]) { + break; + } + } + needSplit = true; + parent = parent.parentNode; + } + if (needSplit) { + var dummy = doc.createElement('span'); + range.cloneRange().collapse(!isStart).insertNode(dummy); + if (isStart) { + tempRange.setStartBefore(parent.firstChild).setEnd(node, pos); + } else { + tempRange.setStart(node, pos).setEndAfter(parent.lastChild); + } + var frag = tempRange.extractContents(), + first = frag.firstChild, last = frag.lastChild; + if (isStart) { + tempRange.insertNode(frag); + range.setStartAfter(last).setEndBefore(dummy); + } else { + parent.appendChild(frag); + range.setStartBefore(dummy).setEndBefore(first); + } + var dummyParent = dummy.parentNode; + if (dummyParent == range.endContainer) { + var prev = K(dummy).prev(), next = K(dummy).next(); + if (prev && next && prev.type == 3 && next.type == 3) { + range.setEnd(prev[0], prev[0].nodeValue.length); + } else if (!isStart) { + range.setEnd(range.endContainer, range.endOffset - 1); + } + } + dummyParent.removeChild(dummy); + } + return this; + }, + remove : function(map) { + var self = this, doc = self.doc, range = self.range; + range.enlarge(); + if (range.startOffset === 0) { + var ksc = K(range.startContainer), parent; + while ((parent = ksc.parent()) && parent.isStyle() && parent.children().length == 1) { + ksc = parent; + } + range.setStart(ksc[0], 0); + ksc = K(range.startContainer); + if (ksc.isBlock()) { + _removeAttrOrCss(ksc, map); + } + var kscp = ksc.parent(); + if (kscp && kscp.isBlock()) { + _removeAttrOrCss(kscp, map); + } + } + var sc, so; + if (range.collapsed) { + self.split(true, map); + sc = range.startContainer; + so = range.startOffset; + if (so > 0) { + var sb = K(sc.childNodes[so - 1]); + if (sb && _isEmptyNode(sb)) { + sb.remove(); + range.setStart(sc, so - 1); + } + } + var sa = K(sc.childNodes[so]); + if (sa && _isEmptyNode(sa)) { + sa.remove(); + } + if (_isEmptyNode(sc)) { + range.startBefore(sc); + sc.remove(); + } + range.collapse(true); + return self; + } + self.split(true, map); + self.split(false, map); + var startDummy = doc.createElement('span'), endDummy = doc.createElement('span'); + range.cloneRange().collapse(false).insertNode(endDummy); + range.cloneRange().collapse(true).insertNode(startDummy); + var nodeList = [], cmpStart = false; + K(range.commonAncestor()).scan(function(node) { + if (!cmpStart && node == startDummy) { + cmpStart = true; + return; + } + if (node == endDummy) { + return false; + } + if (cmpStart) { + nodeList.push(node); + } + }); + K(startDummy).remove(); + K(endDummy).remove(); + sc = range.startContainer; + so = range.startOffset; + var ec = range.endContainer, eo = range.endOffset; + if (so > 0) { + var startBefore = K(sc.childNodes[so - 1]); + if (startBefore && _isEmptyNode(startBefore)) { + startBefore.remove(); + range.setStart(sc, so - 1); + if (sc == ec) { + range.setEnd(ec, eo - 1); + } + } + var startAfter = K(sc.childNodes[so]); + if (startAfter && _isEmptyNode(startAfter)) { + startAfter.remove(); + if (sc == ec) { + range.setEnd(ec, eo - 1); + } + } + } + var endAfter = K(ec.childNodes[range.endOffset]); + if (endAfter && _isEmptyNode(endAfter)) { + endAfter.remove(); + } + var bookmark = range.createBookmark(true); + _each(nodeList, function(i, node) { + _removeAttrOrCss(K(node), map); + }); + range.moveToBookmark(bookmark); + return self; + }, + commonNode : function(map) { + var range = this.range; + var ec = range.endContainer, eo = range.endOffset, + node = (ec.nodeType == 3 || eo === 0) ? ec : ec.childNodes[eo - 1]; + function find(node) { + var child = node, parent = node; + while (parent) { + if (_hasAttrOrCss(K(parent), map)) { + return K(parent); + } + parent = parent.parentNode; + } + while (child && (child = child.lastChild)) { + if (_hasAttrOrCss(K(child), map)) { + return K(child); + } + } + return null; + } + var cNode = find(node); + if (cNode) { + return cNode; + } + if (node.nodeType == 1 || (ec.nodeType == 3 && eo === 0)) { + var prev = K(node).prev(); + if (prev) { + return find(prev); + } + } + return null; + }, + commonAncestor : function(tagName) { + var range = this.range, + sc = range.startContainer, so = range.startOffset, + ec = range.endContainer, eo = range.endOffset, + startNode = (sc.nodeType == 3 || so === 0) ? sc : sc.childNodes[so - 1], + endNode = (ec.nodeType == 3 || eo === 0) ? ec : ec.childNodes[eo - 1]; + function find(node) { + while (node) { + if (node.nodeType == 1) { + if (node.tagName.toLowerCase() === tagName) { + return node; + } + } + node = node.parentNode; + } + return null; + } + var start = find(startNode), end = find(endNode); + if (start && end && start === end) { + return K(start); + } + return null; + }, + state : function(key) { + var self = this, doc = self.doc, bool = false; + try { + bool = doc.queryCommandState(key); + } catch (e) {} + return bool; + }, + val : function(key) { + var self = this, doc = self.doc, range = self.range; + function lc(val) { + return val.toLowerCase(); + } + key = lc(key); + var val = '', knode; + if (key === 'fontfamily' || key === 'fontname') { + val = _nativeCommandValue(doc, 'fontname'); + val = val.replace(/['"]/g, ''); + return lc(val); + } + if (key === 'formatblock') { + val = _nativeCommandValue(doc, key); + if (val === '') { + knode = self.commonNode({'h1,h2,h3,h4,h5,h6,p,div,pre,address' : '*'}); + if (knode) { + val = knode.name; + } + } + if (val === 'Normal') { + val = 'p'; + } + return lc(val); + } + if (key === 'fontsize') { + knode = self.commonNode({'*' : '.font-size'}); + if (knode) { + val = knode.css('font-size'); + } + return lc(val); + } + if (key === 'forecolor') { + knode = self.commonNode({'*' : '.color'}); + if (knode) { + val = knode.css('color'); + } + val = _toHex(val); + if (val === '') { + val = 'default'; + } + return lc(val); + } + if (key === 'hilitecolor') { + knode = self.commonNode({'*' : '.background-color'}); + if (knode) { + val = knode.css('background-color'); + } + val = _toHex(val); + if (val === '') { + val = 'default'; + } + return lc(val); + } + return val; + }, + toggle : function(wrapper, map) { + var self = this; + if (self.commonNode(map)) { + self.remove(map); + } else { + self.wrap(wrapper); + } + return self.select(); + }, + bold : function() { + return this.toggle('', { + span : '.font-weight=bold', + strong : '*', + b : '*' + }); + }, + italic : function() { + return this.toggle('', { + span : '.font-style=italic', + em : '*', + i : '*' + }); + }, + underline : function() { + return this.toggle('', { + span : '.text-decoration=underline', + u : '*' + }); + }, + strikethrough : function() { + return this.toggle('', { + span : '.text-decoration=line-through', + s : '*' + }); + }, + forecolor : function(val) { + return this.wrap('').select(); + }, + hilitecolor : function(val) { + return this.wrap('').select(); + }, + fontsize : function(val) { + return this.wrap('').select(); + }, + fontname : function(val) { + return this.fontfamily(val); + }, + fontfamily : function(val) { + return this.wrap('').select(); + }, + removeformat : function() { + var map = { + '*' : '.font-weight,.font-style,.text-decoration,.color,.background-color,.font-size,.font-family,.text-indent' + }, + tags = _STYLE_TAG_MAP; + _each(tags, function(key, val) { + map[key] = '*'; + }); + this.remove(map); + return this.select(); + }, + inserthtml : function(val, quickMode) { + var self = this, range = self.range; + if (val === '') { + return self; + } + function pasteHtml(range, val) { + val = '' + val; + var rng = range.get(); + if (rng.item) { + rng.item(0).outerHTML = val; + } else { + rng.pasteHTML(val); + } + var temp = range.doc.getElementById('__kindeditor_temp_tag__'); + temp.parentNode.removeChild(temp); + var newRange = _toRange(rng); + range.setEnd(newRange.endContainer, newRange.endOffset); + range.collapse(false); + self.select(false); + } + function insertHtml(range, val) { + var doc = range.doc, + frag = doc.createDocumentFragment(); + K('@' + val, doc).each(function() { + frag.appendChild(this); + }); + range.deleteContents(); + range.insertNode(frag); + range.collapse(false); + self.select(false); + } + if (_IERANGE && quickMode) { + try { + pasteHtml(range, val); + } catch(e) { + insertHtml(range, val); + } + return self; + } + insertHtml(range, val); + return self; + }, + hr : function() { + return this.inserthtml('
    '); + }, + print : function() { + this.win.print(); + return this; + }, + insertimage : function(url, title, width, height, border, align) { + title = _undef(title, ''); + border = _undef(border, 0); + var html = ''; + return self.inserthtml(html); + } + if (range.isControl()) { + var node = K(range.startContainer.childNodes[range.startOffset]); + html += '>'; + node.after(K(html, doc)); + node.next().append(node); + range.selectNode(node[0]); + return self.select(); + } + function setAttr(node, url, type) { + K(node).attr('href', url).attr('data-ke-src', url); + if (type) { + K(node).attr('target', type); + } else { + K(node).removeAttr('target'); + } + } + var sc = range.startContainer, so = range.startOffset, + ec = range.endContainer, eo = range.endOffset; + if (sc.nodeType == 1 && sc === ec && so + 1 === eo) { + var child = sc.childNodes[so]; + if (child.nodeName.toLowerCase() == 'a') { + setAttr(child, url, type); + return self; + } + } + _nativeCommand(doc, 'createlink', '__kindeditor_temp_url__'); + K('a[href="__kindeditor_temp_url__"]', doc).each(function() { + setAttr(this, url, type); + }); + return self; + }, + unlink : function() { + var self = this, doc = self.doc, range = self.range; + self.select(); + if (range.collapsed) { + var a = self.commonNode({ a : '*' }); + if (a) { + range.selectNode(a.get()); + self.select(); + } + _nativeCommand(doc, 'unlink', null); + if (_WEBKIT && K(range.startContainer).name === 'img') { + var parent = K(range.startContainer).parent(); + if (parent.name === 'a') { + parent.remove(true); + } + } + } else { + _nativeCommand(doc, 'unlink', null); + } + return self; + } +}); +_each(('formatblock,selectall,justifyleft,justifycenter,justifyright,justifyfull,insertorderedlist,' + + 'insertunorderedlist,indent,outdent,subscript,superscript').split(','), function(i, name) { + KCmd.prototype[name] = function(val) { + var self = this; + self.select(); + _nativeCommand(self.doc, name, val); + if (_IERANGE && _inArray(name, 'justifyleft,justifycenter,justifyright,justifyfull'.split(',')) >= 0) { + self.selection(); + } + if (!_IERANGE || _inArray(name, 'formatblock,selectall,insertorderedlist,insertunorderedlist'.split(',')) >= 0) { + self.selection(); + } + return self; + }; +}); +_each('cut,copy,paste'.split(','), function(i, name) { + KCmd.prototype[name] = function() { + var self = this; + if (!self.doc.queryCommandSupported(name)) { + throw 'not supported'; + } + self.select(); + _nativeCommand(self.doc, name, null); + return self; + }; +}); +function _cmd(mixed) { + if (mixed.nodeName) { + var doc = _getDoc(mixed); + mixed = _range(doc).selectNodeContents(doc.body).collapse(false); + } + return new KCmd(mixed); +} +K.CmdClass = KCmd; +K.cmd = _cmd; + + +function _drag(options) { + var moveEl = options.moveEl, + moveFn = options.moveFn, + clickEl = options.clickEl || moveEl, + beforeDrag = options.beforeDrag, + iframeFix = options.iframeFix === undefined ? true : options.iframeFix; + var docs = [document]; + if (iframeFix) { + K('iframe').each(function() { + var src = _formatUrl(this.src || '', 'absolute'); + if (/^https?:\/\//.test(src)) { + return; + } + var doc; + try { + doc = _iframeDoc(this); + } catch(e) {} + if (doc) { + var pos = K(this).pos(); + K(doc).data('pos-x', pos.x); + K(doc).data('pos-y', pos.y); + docs.push(doc); + } + }); + } + clickEl.mousedown(function(e) { + if(e.button !== 0 && e.button !== 1) { + return; + } + e.stopPropagation(); + var self = clickEl.get(), + x = _removeUnit(moveEl.css('left')), + y = _removeUnit(moveEl.css('top')), + width = moveEl.width(), + height = moveEl.height(), + pageX = e.pageX, + pageY = e.pageY; + if (beforeDrag) { + beforeDrag(); + } + function moveListener(e) { + e.preventDefault(); + var kdoc = K(_getDoc(e.target)); + var diffX = _round((kdoc.data('pos-x') || 0) + e.pageX - pageX); + var diffY = _round((kdoc.data('pos-y') || 0) + e.pageY - pageY); + moveFn.call(clickEl, x, y, width, height, diffX, diffY); + } + function selectListener(e) { + e.preventDefault(); + } + function upListener(e) { + e.preventDefault(); + K(docs).unbind('mousemove', moveListener) + .unbind('mouseup', upListener) + .unbind('selectstart', selectListener); + if (self.releaseCapture) { + self.releaseCapture(); + } + } + K(docs).mousemove(moveListener) + .mouseup(upListener) + .bind('selectstart', selectListener); + if (self.setCapture) { + self.setCapture(); + } + }); +} + +function KWidget(options) { + this.init(options); +} +_extend(KWidget, { + init : function(options) { + var self = this; + self.name = options.name || ''; + self.doc = options.doc || document; + self.win = _getWin(self.doc); + self.x = _addUnit(options.x); + self.y = _addUnit(options.y); + self.z = options.z; + self.width = _addUnit(options.width); + self.height = _addUnit(options.height); + self.div = K('
    '); + self.options = options; + self._alignEl = options.alignEl; + if (self.width) { + self.div.css('width', self.width); + } + if (self.height) { + self.div.css('height', self.height); + } + if (self.z) { + self.div.css({ + position : 'absolute', + left : self.x, + top : self.y, + 'z-index' : self.z + }); + } + if (self.z && (self.x === undefined || self.y === undefined)) { + self.autoPos(self.width, self.height); + } + if (options.cls) { + self.div.addClass(options.cls); + } + if (options.shadowMode) { + self.div.addClass('ke-shadow'); + } + if (options.css) { + self.div.css(options.css); + } + if (options.src) { + K(options.src).replaceWith(self.div); + } else { + K(self.doc.body).append(self.div); + } + if (options.html) { + self.div.html(options.html); + } + if (options.autoScroll) { + if (_IE && _V < 7 || _QUIRKS) { + var scrollPos = _getScrollPos(); + K(self.win).bind('scroll', function(e) { + var pos = _getScrollPos(), + diffX = pos.x - scrollPos.x, + diffY = pos.y - scrollPos.y; + self.pos(_removeUnit(self.x) + diffX, _removeUnit(self.y) + diffY, false); + }); + } else { + self.div.css('position', 'fixed'); + } + } + }, + pos : function(x, y, updateProp) { + var self = this; + updateProp = _undef(updateProp, true); + if (x !== null) { + x = x < 0 ? 0 : _addUnit(x); + self.div.css('left', x); + if (updateProp) { + self.x = x; + } + } + if (y !== null) { + y = y < 0 ? 0 : _addUnit(y); + self.div.css('top', y); + if (updateProp) { + self.y = y; + } + } + return self; + }, + autoPos : function(width, height) { + var self = this, + w = _removeUnit(width) || 0, + h = _removeUnit(height) || 0, + scrollPos = _getScrollPos(); + if (self._alignEl) { + var knode = K(self._alignEl), + pos = knode.pos(), + diffX = _round(knode[0].clientWidth / 2 - w / 2), + diffY = _round(knode[0].clientHeight / 2 - h / 2); + x = diffX < 0 ? pos.x : pos.x + diffX; + y = diffY < 0 ? pos.y : pos.y + diffY; + } else { + var docEl = _docElement(self.doc); + x = _round(scrollPos.x + (docEl.clientWidth - w) / 2); + y = _round(scrollPos.y + (docEl.clientHeight - h) / 2); + } + if (!(_IE && _V < 7 || _QUIRKS)) { + x -= scrollPos.x; + y -= scrollPos.y; + } + return self.pos(x, y); + }, + remove : function() { + var self = this; + if (_IE && _V < 7 || _QUIRKS) { + K(self.win).unbind('scroll'); + } + self.div.remove(); + _each(self, function(i) { + self[i] = null; + }); + return this; + }, + show : function() { + this.div.show(); + return this; + }, + hide : function() { + this.div.hide(); + return this; + }, + draggable : function(options) { + var self = this; + options = options || {}; + options.moveEl = self.div; + options.moveFn = function(x, y, width, height, diffX, diffY) { + if ((x = x + diffX) < 0) { + x = 0; + } + if ((y = y + diffY) < 0) { + y = 0; + } + self.pos(x, y); + }; + _drag(options); + return self; + } +}); +function _widget(options) { + return new KWidget(options); +} +K.WidgetClass = KWidget; +K.widget = _widget; + + +function _iframeDoc(iframe) { + iframe = _get(iframe); + return iframe.contentDocument || iframe.contentWindow.document; +} +var html, _direction = ''; +if ((html = document.getElementsByTagName('html'))) { + _direction = html[0].dir; +} +function _getInitHtml(themesPath, bodyClass, cssPath, cssData) { + var arr = [ + (_direction === '' ? '' : ''), + '', + '' + ]; + if (!_isArray(cssPath)) { + cssPath = [cssPath]; + } + _each(cssPath, function(i, path) { + if (path) { + arr.push(''); + } + }); + if (cssData) { + arr.push(''); + } + arr.push(''); + return arr.join('\n'); +} +function _elementVal(knode, val) { + if (knode.hasVal()) { + if (val === undefined) { + var html = knode.val(); + html = html.replace(/(<(?:p|p\s[^>]*)>) *(<\/p>)/ig, ''); + return html; + } + return knode.val(val); + } + return knode.html(val); +} + +function KEdit(options) { + this.init(options); +} +_extend(KEdit, KWidget, { + init : function(options) { + var self = this; + KEdit.parent.init.call(self, options); + self.srcElement = K(options.srcElement); + self.div.addClass('ke-edit'); + self.designMode = _undef(options.designMode, true); + self.beforeGetHtml = options.beforeGetHtml; + self.beforeSetHtml = options.beforeSetHtml; + self.afterSetHtml = options.afterSetHtml; + var themesPath = _undef(options.themesPath, ''), + bodyClass = options.bodyClass, + cssPath = options.cssPath, + cssData = options.cssData, + isDocumentDomain = location.protocol != 'res:' && location.host.replace(/:\d+/, '') !== document.domain, + srcScript = ('document.open();' + + (isDocumentDomain ? 'document.domain="' + document.domain + '";' : '') + + 'document.close();'), + iframeSrc = _IE ? ' src="javascript:void(function(){' + encodeURIComponent(srcScript) + '}())"' : ''; + self.iframe = K('').css('width', '100%'); + self.textarea = K('').css('width', '100%'); + self.tabIndex = isNaN(parseInt(options.tabIndex, 10)) ? self.srcElement.attr('tabindex') : parseInt(options.tabIndex, 10); + self.iframe.attr('tabindex', self.tabIndex); + self.textarea.attr('tabindex', self.tabIndex); + if (self.width) { + self.setWidth(self.width); + } + if (self.height) { + self.setHeight(self.height); + } + if (self.designMode) { + self.textarea.hide(); + } else { + self.iframe.hide(); + } + function ready() { + var doc = _iframeDoc(self.iframe); + doc.open(); + if (isDocumentDomain) { + doc.domain = document.domain; + } + doc.write(_getInitHtml(themesPath, bodyClass, cssPath, cssData)); + doc.close(); + self.win = self.iframe[0].contentWindow; + self.doc = doc; + var cmd = _cmd(doc); + self.afterChange(function(e) { + cmd.selection(); + }); + if (_WEBKIT) { + K(doc).click(function(e) { + if (K(e.target).name === 'img') { + cmd.selection(true); + cmd.range.selectNode(e.target); + cmd.select(); + } + }); + } + if (_IE) { + self._mousedownHandler = function() { + var newRange = cmd.range.cloneRange(); + newRange.shrink(); + if (newRange.isControl()) { + self.blur(); + } + }; + K(document).mousedown(self._mousedownHandler); + K(doc).keydown(function(e) { + if (e.which == 8) { + cmd.selection(); + var rng = cmd.range; + if (rng.isControl()) { + rng.collapse(true); + K(rng.startContainer.childNodes[rng.startOffset]).remove(); + e.preventDefault(); + } + } + }); + } + self.cmd = cmd; + self.html(_elementVal(self.srcElement)); + if (_IE) { + doc.body.disabled = true; + doc.body.contentEditable = true; + doc.body.removeAttribute('disabled'); + } else { + doc.designMode = 'on'; + } + if (options.afterCreate) { + options.afterCreate.call(self); + } + } + if (isDocumentDomain) { + self.iframe.bind('load', function(e) { + self.iframe.unbind('load'); + if (_IE) { + ready(); + } else { + setTimeout(ready, 0); + } + }); + } + self.div.append(self.iframe); + self.div.append(self.textarea); + self.srcElement.hide(); + !isDocumentDomain && ready(); + }, + setWidth : function(val) { + var self = this; + val = _addUnit(val); + self.width = val; + self.div.css('width', val); + return self; + }, + setHeight : function(val) { + var self = this; + val = _addUnit(val); + self.height = val; + self.div.css('height', val); + self.iframe.css('height', val); + if ((_IE && _V < 8) || _QUIRKS) { + val = _addUnit(_removeUnit(val) - 2); + } + self.textarea.css('height', val); + return self; + }, + remove : function() { + var self = this, doc = self.doc; + K(doc.body).unbind(); + K(doc).unbind(); + K(self.win).unbind(); + if (self._mousedownHandler) { + K(document).unbind('mousedown', self._mousedownHandler); + } + _elementVal(self.srcElement, self.html()); + self.srcElement.show(); + self.iframe.unbind(); + self.textarea.unbind(); + KEdit.parent.remove.call(self); + }, + html : function(val, isFull) { + var self = this, doc = self.doc; + if (self.designMode) { + var body = doc.body; + if (val === undefined) { + if (isFull) { + val = '' + body.parentNode.innerHTML + ''; + } else { + val = body.innerHTML; + } + if (self.beforeGetHtml) { + val = self.beforeGetHtml(val); + } + if (_GECKO && val == '
    ') { + val = ''; + } + return val; + } + if (self.beforeSetHtml) { + val = self.beforeSetHtml(val); + } + if (_IE && _V >= 9) { + val = val.replace(/(<.*?checked=")checked(".*>)/ig, '$1$2'); + } + K(body).html(val); + if (self.afterSetHtml) { + self.afterSetHtml(); + } + return self; + } + if (val === undefined) { + return self.textarea.val(); + } + self.textarea.val(val); + return self; + }, + design : function(bool) { + var self = this, val; + if (bool === undefined ? !self.designMode : bool) { + if (!self.designMode) { + val = self.html(); + self.designMode = true; + self.textarea.hide(); + self.html(val); + var iframe = self.iframe; + var height = _removeUnit(self.height); + iframe.height(height - 2); + iframe.show(); + setTimeout(function() { + iframe.height(height); + }, 0); + } + } else { + if (self.designMode) { + val = self.html(); + self.designMode = false; + self.html(val); + self.iframe.hide(); + self.textarea.show(); + } + } + return self.focus(); + }, + focus : function() { + var self = this; + self.designMode ? self.win.focus() : self.textarea[0].focus(); + return self; + }, + blur : function() { + var self = this; + if (_IE) { + var input = K('', self.div); + self.div.append(input); + input[0].focus(); + input.remove(); + } else { + self.designMode ? self.win.blur() : self.textarea[0].blur(); + } + return self; + }, + afterChange : function(fn) { + var self = this, doc = self.doc, body = doc.body; + K(doc).keyup(function(e) { + if (!e.ctrlKey && !e.altKey && _CHANGE_KEY_MAP[e.which]) { + fn(e); + } + }); + K(doc).mouseup(fn).contextmenu(fn); + K(self.win).blur(fn); + function timeoutHandler(e) { + setTimeout(function() { + fn(e); + }, 1); + } + K(body).bind('paste', timeoutHandler); + K(body).bind('cut', timeoutHandler); + return self; + } +}); +function _edit(options) { + return new KEdit(options); +} +K.EditClass = KEdit; +K.edit = _edit; +K.iframeDoc = _iframeDoc; + + +function _selectToolbar(name, fn) { + var self = this, + knode = self.get(name); + if (knode) { + if (knode.hasClass('ke-disabled')) { + return; + } + fn(knode); + } +} + +function KToolbar(options) { + this.init(options); +} +_extend(KToolbar, KWidget, { + init : function(options) { + var self = this; + KToolbar.parent.init.call(self, options); + self.disableMode = _undef(options.disableMode, false); + self.noDisableItemMap = _toMap(_undef(options.noDisableItems, [])); + self._itemMap = {}; + self.div.addClass('ke-toolbar').bind('contextmenu,mousedown,mousemove', function(e) { + e.preventDefault(); + }).attr('unselectable', 'on'); + function find(target) { + var knode = K(target); + if (knode.hasClass('ke-outline')) { + return knode; + } + if (knode.hasClass('ke-toolbar-icon')) { + return knode.parent(); + } + } + function hover(e, method) { + var knode = find(e.target); + if (knode) { + if (knode.hasClass('ke-disabled')) { + return; + } + if (knode.hasClass('ke-selected')) { + return; + } + knode[method]('ke-on'); + } + } + self.div.mouseover(function(e) { + hover(e, 'addClass'); + }) + .mouseout(function(e) { + hover(e, 'removeClass'); + }) + .click(function(e) { + var knode = find(e.target); + if (knode) { + if (knode.hasClass('ke-disabled')) { + return; + } + self.options.click.call(this, e, knode.attr('data-name')); + } + }); + }, + get : function(name) { + if (this._itemMap[name]) { + return this._itemMap[name]; + } + return (this._itemMap[name] = K('span.ke-icon-' + name, this.div).parent()); + }, + select : function(name) { + _selectToolbar.call(this, name, function(knode) { + knode.addClass('ke-selected'); + }); + return self; + }, + unselect : function(name) { + _selectToolbar.call(this, name, function(knode) { + knode.removeClass('ke-selected').removeClass('ke-on'); + }); + return self; + }, + enable : function(name) { + var self = this, + knode = name.get ? name : self.get(name); + if (knode) { + knode.removeClass('ke-disabled'); + knode.opacity(1); + } + return self; + }, + disable : function(name) { + var self = this, + knode = name.get ? name : self.get(name); + if (knode) { + knode.removeClass('ke-selected').addClass('ke-disabled'); + knode.opacity(0.5); + } + return self; + }, + disableAll : function(bool, noDisableItems) { + var self = this, map = self.noDisableItemMap, item; + if (noDisableItems) { + map = _toMap(noDisableItems); + } + if (bool === undefined ? !self.disableMode : bool) { + K('span.ke-outline', self.div).each(function() { + var knode = K(this), + name = knode[0].getAttribute('data-name', 2); + if (!map[name]) { + self.disable(knode); + } + }); + self.disableMode = true; + } else { + K('span.ke-outline', self.div).each(function() { + var knode = K(this), + name = knode[0].getAttribute('data-name', 2); + if (!map[name]) { + self.enable(knode); + } + }); + self.disableMode = false; + } + return self; + } +}); +function _toolbar(options) { + return new KToolbar(options); +} +K.ToolbarClass = KToolbar; +K.toolbar = _toolbar; + + +function KMenu(options) { + this.init(options); +} +_extend(KMenu, KWidget, { + init : function(options) { + var self = this; + options.z = options.z || 811213; + KMenu.parent.init.call(self, options); + self.centerLineMode = _undef(options.centerLineMode, true); + self.div.addClass('ke-menu').bind('click,mousedown', function(e){ + e.stopPropagation(); + }).attr('unselectable', 'on'); + }, + addItem : function(item) { + var self = this; + if (item.title === '-') { + self.div.append(K('
    ')); + return; + } + var itemDiv = K('
    '), + leftDiv = K('
    '), + rightDiv = K('
    '), + height = _addUnit(item.height), + iconClass = _undef(item.iconClass, ''); + self.div.append(itemDiv); + if (height) { + itemDiv.css('height', height); + rightDiv.css('line-height', height); + } + var centerDiv; + if (self.centerLineMode) { + centerDiv = K('
    '); + if (height) { + centerDiv.css('height', height); + } + } + itemDiv.mouseover(function(e) { + K(this).addClass('ke-menu-item-on'); + if (centerDiv) { + centerDiv.addClass('ke-menu-item-center-on'); + } + }) + .mouseout(function(e) { + K(this).removeClass('ke-menu-item-on'); + if (centerDiv) { + centerDiv.removeClass('ke-menu-item-center-on'); + } + }) + .click(function(e) { + item.click.call(K(this)); + e.stopPropagation(); + }) + .append(leftDiv); + if (centerDiv) { + itemDiv.append(centerDiv); + } + itemDiv.append(rightDiv); + if (item.checked) { + iconClass = 'ke-icon-checked'; + } + if (iconClass !== '') { + leftDiv.html(''); + } + rightDiv.html(item.title); + return self; + }, + remove : function() { + var self = this; + if (self.options.beforeRemove) { + self.options.beforeRemove.call(self); + } + K('.ke-menu-item', self.div[0]).unbind(); + KMenu.parent.remove.call(self); + return self; + } +}); +function _menu(options) { + return new KMenu(options); +} +K.MenuClass = KMenu; +K.menu = _menu; + + +function KColorPicker(options) { + this.init(options); +} +_extend(KColorPicker, KWidget, { + init : function(options) { + var self = this; + options.z = options.z || 811213; + KColorPicker.parent.init.call(self, options); + var colors = options.colors || [ + ['#E53333', '#E56600', '#FF9900', '#64451D', '#DFC5A4', '#FFE500'], + ['#009900', '#006600', '#99BB00', '#B8D100', '#60D978', '#00D5FF'], + ['#337FE5', '#003399', '#4C33E5', '#9933E5', '#CC33E5', '#EE33EE'], + ['#FFFFFF', '#CCCCCC', '#999999', '#666666', '#333333', '#000000'] + ]; + self.selectedColor = (options.selectedColor || '').toLowerCase(); + self._cells = []; + self.div.addClass('ke-colorpicker').bind('click,mousedown', function(e){ + e.stopPropagation(); + }).attr('unselectable', 'on'); + var table = self.doc.createElement('table'); + self.div.append(table); + table.className = 'ke-colorpicker-table'; + table.cellPadding = 0; + table.cellSpacing = 0; + table.border = 0; + var row = table.insertRow(0), cell = row.insertCell(0); + cell.colSpan = colors[0].length; + self._addAttr(cell, '', 'ke-colorpicker-cell-top'); + for (var i = 0; i < colors.length; i++) { + row = table.insertRow(i + 1); + for (var j = 0; j < colors[i].length; j++) { + cell = row.insertCell(j); + self._addAttr(cell, colors[i][j], 'ke-colorpicker-cell'); + } + } + }, + _addAttr : function(cell, color, cls) { + var self = this; + cell = K(cell).addClass(cls); + if (self.selectedColor === color.toLowerCase()) { + cell.addClass('ke-colorpicker-cell-selected'); + } + cell.attr('title', color || self.options.noColor); + cell.mouseover(function(e) { + K(this).addClass('ke-colorpicker-cell-on'); + }); + cell.mouseout(function(e) { + K(this).removeClass('ke-colorpicker-cell-on'); + }); + cell.click(function(e) { + e.stop(); + self.options.click.call(K(this), color); + }); + if (color) { + cell.append(K('
    ').css('background-color', color)); + } else { + cell.html(self.options.noColor); + } + K(cell).attr('unselectable', 'on'); + self._cells.push(cell); + }, + remove : function() { + var self = this; + _each(self._cells, function() { + this.unbind(); + }); + KColorPicker.parent.remove.call(self); + return self; + } +}); +function _colorpicker(options) { + return new KColorPicker(options); +} +K.ColorPickerClass = KColorPicker; +K.colorpicker = _colorpicker; + + +function KUploadButton(options) { + this.init(options); +} +_extend(KUploadButton, { + init : function(options) { + var self = this, + button = K(options.button), + fieldName = options.fieldName || 'file', + url = options.url || '', + title = button.val(), + extraParams = options.extraParams || {}, + cls = button[0].className || '', + target = options.target || 'kindeditor_upload_iframe_' + new Date().getTime(); + options.afterError = options.afterError || function(str) { + alert(str); + }; + var hiddenElements = []; + for(var k in extraParams){ + hiddenElements.push(''); + } + var html = [ + '
    ', + (options.target ? '' : ''), + (options.form ? '
    ' : '
    '), + '', + hiddenElements.join(''), + '', + '', + '', + (options.form ? '
    ' : ''), + '
    '].join(''); + var div = K(html, button.doc); + button.hide(); + button.before(div); + self.div = div; + self.button = button; + self.iframe = options.target ? K('iframe[name="' + target + '"]') : K('iframe', div); + self.form = options.form ? K(options.form) : K('form', div); + self.fileBox = K('.ke-upload-file', div); + var width = options.width || K('.ke-button-common', div).width(); + K('.ke-upload-area', div).width(width); + self.options = options; + }, + submit : function() { + var self = this, + iframe = self.iframe; + iframe.bind('load', function() { + iframe.unbind(); + var tempForm = document.createElement('form'); + self.fileBox.before(tempForm); + K(tempForm).append(self.fileBox); + tempForm.reset(); + K(tempForm).remove(true); + var doc = K.iframeDoc(iframe), + pre = doc.getElementsByTagName('pre')[0], + str = '', data; + if (pre) { + str = pre.innerHTML; + } else { + str = doc.body.innerHTML; + } + str = _unescape(str); + iframe[0].src = 'javascript:false'; + try { + data = K.json(str); + } catch (e) { + self.options.afterError.call(self, '' + doc.body.parentNode.innerHTML + ''); + } + if (data) { + self.options.afterUpload.call(self, data); + } + }); + self.form[0].submit(); + return self; + }, + remove : function() { + var self = this; + if (self.fileBox) { + self.fileBox.unbind(); + } + self.iframe.remove(); + self.div.remove(); + self.button.show(); + return self; + } +}); +function _uploadbutton(options) { + return new KUploadButton(options); +} +K.UploadButtonClass = KUploadButton; +K.uploadbutton = _uploadbutton; + + +function _createButton(arg) { + arg = arg || {}; + var name = arg.name || '', + span = K(''), + btn = K(''); + if (arg.click) { + btn.click(arg.click); + } + span.append(btn); + return span; +} + +function KDialog(options) { + this.init(options); +} +_extend(KDialog, KWidget, { + init : function(options) { + var self = this; + var shadowMode = _undef(options.shadowMode, true); + options.z = options.z || 811213; + options.shadowMode = false; + options.autoScroll = _undef(options.autoScroll, true); + KDialog.parent.init.call(self, options); + var title = options.title, + body = K(options.body, self.doc), + previewBtn = options.previewBtn, + yesBtn = options.yesBtn, + noBtn = options.noBtn, + closeBtn = options.closeBtn, + showMask = _undef(options.showMask, true); + self.div.addClass('ke-dialog').bind('click,mousedown', function(e){ + e.stopPropagation(); + }); + var contentDiv = K('
    ').appendTo(self.div); + if (_IE && _V < 7) { + self.iframeMask = K('').appendTo(self.div); + } else if (shadowMode) { + K('
    ').appendTo(self.div); + } + var headerDiv = K('
    '); + contentDiv.append(headerDiv); + headerDiv.html(title); + self.closeIcon = K('').click(closeBtn.click); + headerDiv.append(self.closeIcon); + self.draggable({ + clickEl : headerDiv, + beforeDrag : options.beforeDrag + }); + var bodyDiv = K('
    '); + contentDiv.append(bodyDiv); + bodyDiv.append(body); + var footerDiv = K(''); + if (previewBtn || yesBtn || noBtn) { + contentDiv.append(footerDiv); + } + _each([ + { btn : previewBtn, name : 'preview' }, + { btn : yesBtn, name : 'yes' }, + { btn : noBtn, name : 'no' } + ], function() { + if (this.btn) { + var button = _createButton(this.btn); + button.addClass('ke-dialog-' + this.name); + footerDiv.append(button); + } + }); + if (self.height) { + bodyDiv.height(_removeUnit(self.height) - headerDiv.height() - footerDiv.height()); + } + self.div.width(self.div.width()); + self.div.height(self.div.height()); + self.mask = null; + if (showMask) { + var docEl = _docElement(self.doc), + docWidth = Math.max(docEl.scrollWidth, docEl.clientWidth), + docHeight = Math.max(docEl.scrollHeight, docEl.clientHeight); + self.mask = _widget({ + x : 0, + y : 0, + z : self.z - 1, + cls : 'ke-dialog-mask', + width : docWidth, + height : docHeight + }); + } + self.autoPos(self.div.width(), self.div.height()); + self.footerDiv = footerDiv; + self.bodyDiv = bodyDiv; + self.headerDiv = headerDiv; + self.isLoading = false; + }, + setMaskIndex : function(z) { + var self = this; + self.mask.div.css('z-index', z); + }, + showLoading : function(msg) { + msg = _undef(msg, ''); + var self = this, body = self.bodyDiv; + self.loading = K('
    ' + msg + '
    ') + .width(body.width()).height(body.height()) + .css('top', self.headerDiv.height() + 'px'); + body.css('visibility', 'hidden').after(self.loading); + self.isLoading = true; + return self; + }, + hideLoading : function() { + this.loading && this.loading.remove(); + this.bodyDiv.css('visibility', 'visible'); + this.isLoading = false; + return this; + }, + remove : function() { + var self = this; + if (self.options.beforeRemove) { + self.options.beforeRemove.call(self); + } + self.mask && self.mask.remove(); + self.iframeMask && self.iframeMask.remove(); + self.closeIcon.unbind(); + K('input', self.div).unbind(); + K('button', self.div).unbind(); + self.footerDiv.unbind(); + self.bodyDiv.unbind(); + self.headerDiv.unbind(); + K('iframe', self.div).each(function() { + K(this).remove(); + }); + KDialog.parent.remove.call(self); + return self; + } +}); +function _dialog(options) { + return new KDialog(options); +} +K.DialogClass = KDialog; +K.dialog = _dialog; + + +function _tabs(options) { + var self = _widget(options), + remove = self.remove, + afterSelect = options.afterSelect, + div = self.div, + liList = []; + div.addClass('ke-tabs') + .bind('contextmenu,mousedown,mousemove', function(e) { + e.preventDefault(); + }); + var ul = K('
      '); + div.append(ul); + self.add = function(tab) { + var li = K('
    • ' + tab.title + '
    • '); + li.data('tab', tab); + liList.push(li); + ul.append(li); + }; + self.selectedIndex = 0; + self.select = function(index) { + self.selectedIndex = index; + _each(liList, function(i, li) { + li.unbind(); + if (i === index) { + li.addClass('ke-tabs-li-selected'); + K(li.data('tab').panel).show(''); + } else { + li.removeClass('ke-tabs-li-selected').removeClass('ke-tabs-li-on') + .mouseover(function() { + K(this).addClass('ke-tabs-li-on'); + }) + .mouseout(function() { + K(this).removeClass('ke-tabs-li-on'); + }) + .click(function() { + self.select(i); + }); + K(li.data('tab').panel).hide(); + } + }); + if (afterSelect) { + afterSelect.call(self, index); + } + }; + self.remove = function() { + _each(liList, function() { + this.remove(); + }); + ul.remove(); + remove.call(self); + }; + return self; +} +K.tabs = _tabs; + + +function _loadScript(url, fn) { + var head = document.getElementsByTagName('head')[0] || (_QUIRKS ? document.body : document.documentElement), + script = document.createElement('script'); + head.appendChild(script); + script.src = url; + script.charset = 'utf-8'; + script.onload = script.onreadystatechange = function() { + if (!this.readyState || this.readyState === 'loaded') { + if (fn) { + fn(); + } + script.onload = script.onreadystatechange = null; + head.removeChild(script); + } + }; +} + +function _chopQuery(url) { + var index = url.indexOf('?'); + return index > 0 ? url.substr(0, index) : url; +} +function _loadStyle(url) { + var head = document.getElementsByTagName('head')[0] || (_QUIRKS ? document.body : document.documentElement), + link = document.createElement('link'), + absoluteUrl = _chopQuery(_formatUrl(url, 'absolute')); + var links = K('link[rel="stylesheet"]', head); + for (var i = 0, len = links.length; i < len; i++) { + if (_chopQuery(_formatUrl(links[i].href, 'absolute')) === absoluteUrl) { + return; + } + } + head.appendChild(link); + link.href = url; + link.rel = 'stylesheet'; +} +function _ajax(url, fn, method, param, dataType) { + method = method || 'GET'; + dataType = dataType || 'json'; + var xhr = window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); + xhr.open(method, url, true); + xhr.onreadystatechange = function () { + if (xhr.readyState == 4 && xhr.status == 200) { + if (fn) { + var data = _trim(xhr.responseText); + if (dataType == 'json') { + data = _json(data); + } + fn(data); + } + } + }; + if (method == 'POST') { + var params = []; + _each(param, function(key, val) { + params.push(encodeURIComponent(key) + '=' + encodeURIComponent(val)); + }); + try { + xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + } catch (e) {} + xhr.send(params.join('&')); + } else { + xhr.send(null); + } +} +K.loadScript = _loadScript; +K.loadStyle = _loadStyle; +K.ajax = _ajax; + + +var _plugins = {}; +function _plugin(name, fn) { + if (name === undefined) { + return _plugins; + } + if (!fn) { + return _plugins[name]; + } + _plugins[name] = fn; +} +var _language = {}; +function _parseLangKey(key) { + var match, ns = 'core'; + if ((match = /^(\w+)\.(\w+)$/.exec(key))) { + ns = match[1]; + key = match[2]; + } + return { ns : ns, key : key }; +} +function _lang(mixed, langType) { + langType = langType === undefined ? K.options.langType : langType; + if (typeof mixed === 'string') { + if (!_language[langType]) { + return 'no language'; + } + var pos = mixed.length - 1; + if (mixed.substr(pos) === '.') { + return _language[langType][mixed.substr(0, pos)]; + } + var obj = _parseLangKey(mixed); + return _language[langType][obj.ns][obj.key]; + } + _each(mixed, function(key, val) { + var obj = _parseLangKey(key); + if (!_language[langType]) { + _language[langType] = {}; + } + if (!_language[langType][obj.ns]) { + _language[langType][obj.ns] = {}; + } + _language[langType][obj.ns][obj.key] = val; + }); +} + +function _getImageFromRange(range, fn) { + if (range.collapsed) { + return; + } + range = range.cloneRange().up(); + var sc = range.startContainer, so = range.startOffset; + if (!_WEBKIT && !range.isControl()) { + return; + } + var img = K(sc.childNodes[so]); + if (!img || img.name != 'img') { + return; + } + if (fn(img)) { + return img; + } +} +function _bindContextmenuEvent() { + var self = this, doc = self.edit.doc; + K(doc).contextmenu(function(e) { + if (self.menu) { + self.hideMenu(); + } + if (!self.useContextmenu) { + e.preventDefault(); + return; + } + if (self._contextmenus.length === 0) { + return; + } + var maxWidth = 0, items = []; + _each(self._contextmenus, function() { + if (this.title == '-') { + items.push(this); + return; + } + if (this.cond && this.cond()) { + items.push(this); + if (this.width && this.width > maxWidth) { + maxWidth = this.width; + } + } + }); + while (items.length > 0 && items[0].title == '-') { + items.shift(); + } + while (items.length > 0 && items[items.length - 1].title == '-') { + items.pop(); + } + var prevItem = null; + _each(items, function(i) { + if (this.title == '-' && prevItem.title == '-') { + delete items[i]; + } + prevItem = this; + }); + if (items.length > 0) { + e.preventDefault(); + var pos = K(self.edit.iframe).pos(), + menu = _menu({ + x : pos.x + e.clientX, + y : pos.y + e.clientY, + width : maxWidth, + css : { visibility: 'hidden' }, + shadowMode : self.shadowMode + }); + _each(items, function() { + if (this.title) { + menu.addItem(this); + } + }); + var docEl = _docElement(menu.doc), + menuHeight = menu.div.height(); + if (e.clientY + menuHeight >= docEl.clientHeight - 100) { + menu.pos(menu.x, _removeUnit(menu.y) - menuHeight); + } + menu.div.css('visibility', 'visible'); + self.menu = menu; + } + }); +} +function _bindNewlineEvent() { + var self = this, doc = self.edit.doc, newlineTag = self.newlineTag; + if (_IE && newlineTag !== 'br') { + return; + } + if (_GECKO && _V < 3 && newlineTag !== 'p') { + return; + } + if (_OPERA && _V < 9) { + return; + } + var brSkipTagMap = _toMap('h1,h2,h3,h4,h5,h6,pre,li'), + pSkipTagMap = _toMap('p,h1,h2,h3,h4,h5,h6,pre,li,blockquote'); + function getAncestorTagName(range) { + var ancestor = K(range.commonAncestor()); + while (ancestor) { + if (ancestor.type == 1 && !ancestor.isStyle()) { + break; + } + ancestor = ancestor.parent(); + } + return ancestor.name; + } + K(doc).keydown(function(e) { + if (e.which != 13 || e.shiftKey || e.ctrlKey || e.altKey) { + return; + } + self.cmd.selection(); + var tagName = getAncestorTagName(self.cmd.range); + if (tagName == 'marquee' || tagName == 'select') { + return; + } + if (newlineTag === 'br' && !brSkipTagMap[tagName]) { + e.preventDefault(); + self.insertHtml('
      ' + (_IE && _V < 9 ? '' : '\u200B')); + return; + } + if (!pSkipTagMap[tagName]) { + _nativeCommand(doc, 'formatblock', '

      '); + } + }); + K(doc).keyup(function(e) { + if (e.which != 13 || e.shiftKey || e.ctrlKey || e.altKey) { + return; + } + if (newlineTag == 'br') { + return; + } + if (_GECKO) { + var root = self.cmd.commonAncestor('p'); + var a = self.cmd.commonAncestor('a'); + if (a && a.text() == '') { + a.remove(true); + self.cmd.range.selectNodeContents(root[0]).collapse(true); + self.cmd.select(); + } + return; + } + self.cmd.selection(); + var tagName = getAncestorTagName(self.cmd.range); + if (tagName == 'marquee' || tagName == 'select') { + return; + } + if (!pSkipTagMap[tagName]) { + _nativeCommand(doc, 'formatblock', '

      '); + } + var div = self.cmd.commonAncestor('div'); + if (div) { + var p = K('

      '), + child = div[0].firstChild; + while (child) { + var next = child.nextSibling; + p.append(child); + child = next; + } + div.before(p); + div.remove(); + self.cmd.range.selectNodeContents(p[0]); + self.cmd.select(); + } + }); +} +function _bindTabEvent() { + var self = this, doc = self.edit.doc; + K(doc).keydown(function(e) { + if (e.which == 9) { + e.preventDefault(); + if (self.afterTab) { + self.afterTab.call(self, e); + return; + } + var cmd = self.cmd, range = cmd.range; + range.shrink(); + if (range.collapsed && range.startContainer.nodeType == 1) { + range.insertNode(K('@ ', doc)[0]); + cmd.select(); + } + self.insertHtml('    '); + } + }); +} +function _bindFocusEvent() { + var self = this; + K(self.edit.textarea[0], self.edit.win).focus(function(e) { + if (self.afterFocus) { + self.afterFocus.call(self, e); + } + }).blur(function(e) { + if (self.afterBlur) { + self.afterBlur.call(self, e); + } + }); +} +function _removeBookmarkTag(html) { + return _trim(html.replace(/]*id="?__kindeditor_bookmark_\w+_\d+__"?[^>]*><\/span>/ig, '')); +} +function _removeTempTag(html) { + return html.replace(/]+class="?__kindeditor_paste__"?[^>]*>[\s\S]*?<\/div>/ig, ''); +} +function _addBookmarkToStack(stack, bookmark) { + if (stack.length === 0) { + stack.push(bookmark); + return; + } + var prev = stack[stack.length - 1]; + if (_removeBookmarkTag(bookmark.html) !== _removeBookmarkTag(prev.html)) { + stack.push(bookmark); + } +} + +function _undoToRedo(fromStack, toStack) { + var self = this, edit = self.edit, + body = edit.doc.body, + range, bookmark; + if (fromStack.length === 0) { + return self; + } + if (edit.designMode) { + range = self.cmd.range; + bookmark = range.createBookmark(true); + bookmark.html = body.innerHTML; + } else { + bookmark = { + html : body.innerHTML + }; + } + _addBookmarkToStack(toStack, bookmark); + var prev = fromStack.pop(); + if (_removeBookmarkTag(bookmark.html) === _removeBookmarkTag(prev.html) && fromStack.length > 0) { + prev = fromStack.pop(); + } + if (edit.designMode) { + edit.html(prev.html); + if (prev.start) { + range.moveToBookmark(prev); + self.select(); + } + } else { + K(body).html(_removeBookmarkTag(prev.html)); + } + return self; +} +function KEditor(options) { + var self = this; + self.options = {}; + function setOption(key, val) { + if (KEditor.prototype[key] === undefined) { + self[key] = val; + } + self.options[key] = val; + } + _each(options, function(key, val) { + setOption(key, options[key]); + }); + _each(K.options, function(key, val) { + if (self[key] === undefined) { + setOption(key, val); + } + }); + var se = K(self.srcElement || '', + ''].join(''), + dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var type = K('.ke-code-type', dialog.div).val(), + code = textarea.val(), + cls = type === '' ? '' : ' lang-' + type, + html = '
      \n' + K.escape(code) + '
      '; + if (K.trim(code) === '') { + alert(lang.pleaseInput); + textarea[0].focus(); + return; + } + self.insertHtml(html).hideDialog().focus(); + } + } + }), + textarea = K('textarea', dialog.div); + textarea[0].focus(); + }); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('emoticons', function(K) { + var self = this, name = 'emoticons', + path = (self.emoticonsPath || self.pluginsPath + 'emoticons/images/'), + allowPreview = self.allowPreviewEmoticons === undefined ? true : self.allowPreviewEmoticons, + currentPageNum = 1; + self.clickToolbar(name, function() { + var rows = 5, cols = 9, total = 135, startNum = 0, + cells = rows * cols, pages = Math.ceil(total / cells), + colsHalf = Math.floor(cols / 2), + wrapperDiv = K('
      '), + elements = [], + menu = self.createMenu({ + name : name, + beforeRemove : function() { + removeEvent(); + } + }); + menu.div.append(wrapperDiv); + var previewDiv, previewImg; + if (allowPreview) { + previewDiv = K('
      ').css('right', 0); + previewImg = K(''); + wrapperDiv.append(previewDiv); + previewDiv.append(previewImg); + } + function bindCellEvent(cell, j, num) { + if (previewDiv) { + cell.mouseover(function() { + if (j > colsHalf) { + previewDiv.css('left', 0); + previewDiv.css('right', ''); + } else { + previewDiv.css('left', ''); + previewDiv.css('right', 0); + } + previewImg.attr('src', path + num + '.gif'); + K(this).addClass('ke-on'); + }); + } else { + cell.mouseover(function() { + K(this).addClass('ke-on'); + }); + } + cell.mouseout(function() { + K(this).removeClass('ke-on'); + }); + cell.click(function(e) { + self.insertHtml('').hideMenu().focus(); + e.stop(); + }); + } + function createEmoticonsTable(pageNum, parentDiv) { + var table = document.createElement('table'); + parentDiv.append(table); + if (previewDiv) { + K(table).mouseover(function() { + previewDiv.show('block'); + }); + K(table).mouseout(function() { + previewDiv.hide(); + }); + elements.push(K(table)); + } + table.className = 'ke-table'; + table.cellPadding = 0; + table.cellSpacing = 0; + table.border = 0; + var num = (pageNum - 1) * cells + startNum; + for (var i = 0; i < rows; i++) { + var row = table.insertRow(i); + for (var j = 0; j < cols; j++) { + var cell = K(row.insertCell(j)); + cell.addClass('ke-cell'); + bindCellEvent(cell, j, num); + var span = K('') + .css('background-position', '-' + (24 * num) + 'px 0px') + .css('background-image', 'url(' + path + 'static.gif)'); + cell.append(span); + elements.push(cell); + num++; + } + } + return table; + } + var table = createEmoticonsTable(currentPageNum, wrapperDiv); + function removeEvent() { + K.each(elements, function() { + this.unbind(); + }); + } + var pageDiv; + function bindPageEvent(el, pageNum) { + el.click(function(e) { + removeEvent(); + table.parentNode.removeChild(table); + pageDiv.remove(); + table = createEmoticonsTable(pageNum, wrapperDiv); + createPageTable(pageNum); + currentPageNum = pageNum; + e.stop(); + }); + } + function createPageTable(currentPageNum) { + pageDiv = K('
      '); + wrapperDiv.append(pageDiv); + for (var pageNum = 1; pageNum <= pages; pageNum++) { + if (currentPageNum !== pageNum) { + var a = K('[' + pageNum + ']'); + bindPageEvent(a, pageNum); + pageDiv.append(a); + elements.push(a); + } else { + pageDiv.append(K('@[' + pageNum + ']')); + } + pageDiv.append(K('@ ')); + } + } + createPageTable(currentPageNum); + }); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('filemanager', function(K) { + var self = this, name = 'filemanager', + fileManagerJson = K.undef(self.fileManagerJson, self.basePath + 'php/file_manager_json.php'), + imgPath = self.pluginsPath + name + '/images/', + lang = self.lang(name + '.'); + function makeFileTitle(filename, filesize, datetime) { + return filename + ' (' + Math.ceil(filesize / 1024) + 'KB, ' + datetime + ')'; + } + function bindTitle(el, data) { + if (data.is_dir) { + el.attr('title', data.filename); + } else { + el.attr('title', makeFileTitle(data.filename, data.filesize, data.datetime)); + } + } + self.plugin.filemanagerDialog = function(options) { + var width = K.undef(options.width, 650), + height = K.undef(options.height, 510), + dirName = K.undef(options.dirName, ''), + viewType = K.undef(options.viewType, 'VIEW').toUpperCase(), + clickFn = options.clickFn; + var html = [ + '
      ', + '
      ', + '
      ', + ' ', + '' + lang.moveup + '', + '
      ', + '
      ', + lang.viewType + ' ', + lang.orderType + ' ', + '
      ', + '
      ', + '
      ', + '
      ', + '
      ' + ].join(''); + var dialog = self.createDialog({ + name : name, + width : width, + height : height, + title : self.lang(name), + body : html + }), + div = dialog.div, + bodyDiv = K('.ke-plugin-filemanager-body', div), + moveupImg = K('[name="moveupImg"]', div), + moveupLink = K('[name="moveupLink"]', div), + viewServerBtn = K('[name="viewServer"]', div), + viewTypeBox = K('[name="viewType"]', div), + orderTypeBox = K('[name="orderType"]', div); + function reloadPage(path, order, func) { + var param = 'path=' + path + '&order=' + order + '&dir=' + dirName; + dialog.showLoading(self.lang('ajaxLoading')); + K.ajax(K.addParam(fileManagerJson, param + '&' + new Date().getTime()), function(data) { + dialog.hideLoading(); + func(data); + }); + } + var elList = []; + function bindEvent(el, result, data, createFunc) { + var fileUrl = K.formatUrl(result.current_url + data.filename, 'absolute'), + dirPath = encodeURIComponent(result.current_dir_path + data.filename + '/'); + if (data.is_dir) { + el.click(function(e) { + reloadPage(dirPath, orderTypeBox.val(), createFunc); + }); + } else if (data.is_photo) { + el.click(function(e) { + clickFn.call(this, fileUrl, data.filename); + }); + } else { + el.click(function(e) { + clickFn.call(this, fileUrl, data.filename); + }); + } + elList.push(el); + } + function createCommon(result, createFunc) { + K.each(elList, function() { + this.unbind(); + }); + moveupLink.unbind(); + viewTypeBox.unbind(); + orderTypeBox.unbind(); + if (result.current_dir_path) { + moveupLink.click(function(e) { + reloadPage(result.moveup_dir_path, orderTypeBox.val(), createFunc); + }); + } + function changeFunc() { + if (viewTypeBox.val() == 'VIEW') { + reloadPage(result.current_dir_path, orderTypeBox.val(), createView); + } else { + reloadPage(result.current_dir_path, orderTypeBox.val(), createList); + } + } + viewTypeBox.change(changeFunc); + orderTypeBox.change(changeFunc); + bodyDiv.html(''); + } + function createList(result) { + createCommon(result, createList); + var table = document.createElement('table'); + table.className = 'ke-table'; + table.cellPadding = 0; + table.cellSpacing = 0; + table.border = 0; + bodyDiv.append(table); + var fileList = result.file_list; + for (var i = 0, len = fileList.length; i < len; i++) { + var data = fileList[i], row = K(table.insertRow(i)); + row.mouseover(function(e) { + K(this).addClass('ke-on'); + }) + .mouseout(function(e) { + K(this).removeClass('ke-on'); + }); + var iconUrl = imgPath + (data.is_dir ? 'folder-16.gif' : 'file-16.gif'), + img = K('' + data.filename + ''), + cell0 = K(row[0].insertCell(0)).addClass('ke-cell ke-name').append(img).append(document.createTextNode(' ' + data.filename)); + if (!data.is_dir || data.has_file) { + row.css('cursor', 'pointer'); + cell0.attr('title', data.filename); + bindEvent(cell0, result, data, createList); + } else { + cell0.attr('title', lang.emptyFolder); + } + K(row[0].insertCell(1)).addClass('ke-cell ke-size').html(data.is_dir ? '-' : Math.ceil(data.filesize / 1024) + 'KB'); + K(row[0].insertCell(2)).addClass('ke-cell ke-datetime').html(data.datetime); + } + } + function createView(result) { + createCommon(result, createView); + var fileList = result.file_list; + for (var i = 0, len = fileList.length; i < len; i++) { + var data = fileList[i], + div = K('
      '); + bodyDiv.append(div); + var photoDiv = K('
      ') + .mouseover(function(e) { + K(this).addClass('ke-on'); + }) + .mouseout(function(e) { + K(this).removeClass('ke-on'); + }); + div.append(photoDiv); + var fileUrl = result.current_url + data.filename, + iconUrl = data.is_dir ? imgPath + 'folder-64.gif' : (data.is_photo ? fileUrl : imgPath + 'file-64.gif'); + var img = K('' + data.filename + ''); + if (!data.is_dir || data.has_file) { + photoDiv.css('cursor', 'pointer'); + bindTitle(photoDiv, data); + bindEvent(photoDiv, result, data, createView); + } else { + photoDiv.attr('title', lang.emptyFolder); + } + photoDiv.append(img); + div.append('
      ' + data.filename + '
      '); + } + } + viewTypeBox.val(viewType); + reloadPage('', orderTypeBox.val(), viewType == 'VIEW' ? createView : createList); + return dialog; + } +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('flash', function(K) { + var self = this, name = 'flash', lang = self.lang(name + '.'), + allowFlashUpload = K.undef(self.allowFlashUpload, true), + allowFileManager = K.undef(self.allowFileManager, false), + formatUploadUrl = K.undef(self.formatUploadUrl, true), + extraParams = K.undef(self.extraFileUploadParams, {}), + filePostName = K.undef(self.filePostName, 'imgFile'), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'); + self.plugin.flash = { + edit : function() { + var html = [ + '
      ', + '
      ', + '', + '  ', + '  ', + '', + '', + '', + '
      ', + '
      ', + '', + ' ', + '
      ', + '
      ', + '', + ' ', + '
      ', + '
      ' + ].join(''); + var dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var url = K.trim(urlBox.val()), + width = widthBox.val(), + height = heightBox.val(); + if (url == 'http://' || K.invalidUrl(url)) { + alert(self.lang('invalidUrl')); + urlBox[0].focus(); + return; + } + if (!/^\d*$/.test(width)) { + alert(self.lang('invalidWidth')); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + alert(self.lang('invalidHeight')); + heightBox[0].focus(); + return; + } + var html = K.mediaImg(self.themesPath + 'common/blank.gif', { + src : url, + type : K.mediaType('.swf'), + width : width, + height : height, + quality : 'high' + }); + self.insertHtml(html).hideDialog().focus(); + } + } + }), + div = dialog.div, + urlBox = K('[name="url"]', div), + viewServerBtn = K('[name="viewServer"]', div), + widthBox = K('[name="width"]', div), + heightBox = K('[name="height"]', div); + urlBox.val('http://'); + if (allowFlashUpload) { + var uploadbutton = K.uploadbutton({ + button : K('.ke-upload-button', div)[0], + fieldName : filePostName, + extraParams : extraParams, + url : K.addParam(uploadJson, 'dir=flash'), + afterUpload : function(data) { + dialog.hideLoading(); + if (data.error === 0) { + var url = data.url; + if (formatUploadUrl) { + url = K.formatUrl(url, 'absolute'); + } + urlBox.val(url); + if (self.afterUpload) { + self.afterUpload.call(self, url, data, name); + } + alert(self.lang('uploadSuccess')); + } else { + alert(data.message); + } + }, + afterError : function(html) { + dialog.hideLoading(); + self.errorDialog(html); + } + }); + uploadbutton.fileBox.change(function(e) { + dialog.showLoading(self.lang('uploadLoading')); + uploadbutton.submit(); + }); + } else { + K('.ke-upload-button', div).hide(); + } + if (allowFileManager) { + viewServerBtn.click(function(e) { + self.loadPlugin('filemanager', function() { + self.plugin.filemanagerDialog({ + viewType : 'LIST', + dirName : 'flash', + clickFn : function(url, title) { + if (self.dialogs.length > 1) { + K('[name="url"]', div).val(url); + if (self.afterSelectFile) { + self.afterSelectFile.call(self, url); + } + self.hideDialog(); + } + } + }); + }); + }); + } else { + viewServerBtn.hide(); + } + var img = self.plugin.getSelectedFlash(); + if (img) { + var attrs = K.mediaAttrs(img.attr('data-ke-tag')); + urlBox.val(attrs.src); + widthBox.val(K.removeUnit(img.css('width')) || attrs.width || 0); + heightBox.val(K.removeUnit(img.css('height')) || attrs.height || 0); + } + urlBox[0].focus(); + urlBox[0].select(); + }, + 'delete' : function() { + self.plugin.getSelectedFlash().remove(); + self.addBookmark(); + } + }; + self.clickToolbar(name, self.plugin.flash.edit); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('image', function(K) { + var self = this, name = 'image', + allowImageUpload = K.undef(self.allowImageUpload, true), + allowImageRemote = K.undef(self.allowImageRemote, true), + formatUploadUrl = K.undef(self.formatUploadUrl, true), + allowFileManager = K.undef(self.allowFileManager, false), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'), + imageTabIndex = K.undef(self.imageTabIndex, 0), + imgPath = self.pluginsPath + 'image/images/', + extraParams = K.undef(self.extraFileUploadParams, {}), + filePostName = K.undef(self.filePostName, 'imgFile'), + fillDescAfterUploadImage = K.undef(self.fillDescAfterUploadImage, false), + lang = self.lang(name + '.'); + self.plugin.imageDialog = function(options) { + var imageUrl = options.imageUrl, + imageWidth = K.undef(options.imageWidth, ''), + imageHeight = K.undef(options.imageHeight, ''), + imageTitle = K.undef(options.imageTitle, ''), + imageAlign = K.undef(options.imageAlign, ''), + showRemote = K.undef(options.showRemote, true), + showLocal = K.undef(options.showLocal, true), + tabIndex = K.undef(options.tabIndex, 0), + clickFn = options.clickFn; + var target = 'kindeditor_upload_iframe_' + new Date().getTime(); + var hiddenElements = []; + for(var k in extraParams){ + hiddenElements.push(''); + } + var html = [ + '
      ', + '
      ', + '', + '', + '
      ' + ].join(''); + var dialogWidth = showLocal || allowFileManager ? 450 : 400, + dialogHeight = showLocal && showRemote ? 300 : 250; + var dialog = self.createDialog({ + name : name, + width : dialogWidth, + height : dialogHeight, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + if (dialog.isLoading) { + return; + } + if (showLocal && showRemote && tabs && tabs.selectedIndex === 1 || !showRemote) { + if (uploadbutton.fileBox.val() == '') { + alert(self.lang('pleaseSelectFile')); + return; + } + dialog.showLoading(self.lang('uploadLoading')); + uploadbutton.submit(); + localUrlBox.val(''); + return; + } + var url = K.trim(urlBox.val()), + width = widthBox.val(), + height = heightBox.val(), + title = titleBox.val(), + align = ''; + alignBox.each(function() { + if (this.checked) { + align = this.value; + return false; + } + }); + if (url == 'http://' || K.invalidUrl(url)) { + alert(self.lang('invalidUrl')); + urlBox[0].focus(); + return; + } + if (!/^\d*$/.test(width)) { + alert(self.lang('invalidWidth')); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + alert(self.lang('invalidHeight')); + heightBox[0].focus(); + return; + } + clickFn.call(self, url, title, width, height, 0, align); + } + }, + beforeRemove : function() { + viewServerBtn.unbind(); + widthBox.unbind(); + heightBox.unbind(); + refreshBtn.unbind(); + } + }), + div = dialog.div; + var urlBox = K('[name="url"]', div), + localUrlBox = K('[name="localUrl"]', div), + viewServerBtn = K('[name="viewServer"]', div), + widthBox = K('.tab1 [name="width"]', div), + heightBox = K('.tab1 [name="height"]', div), + refreshBtn = K('.ke-refresh-btn', div), + titleBox = K('.tab1 [name="title"]', div), + alignBox = K('.tab1 [name="align"]', div); + var tabs; + if (showRemote && showLocal) { + tabs = K.tabs({ + src : K('.tabs', div), + afterSelect : function(i) {} + }); + tabs.add({ + title : lang.remoteImage, + panel : K('.tab1', div) + }); + tabs.add({ + title : lang.localImage, + panel : K('.tab2', div) + }); + tabs.select(tabIndex); + } else if (showRemote) { + K('.tab1', div).show(); + } else if (showLocal) { + K('.tab2', div).show(); + } + var uploadbutton = K.uploadbutton({ + button : K('.ke-upload-button', div)[0], + fieldName : filePostName, + form : K('.ke-form', div), + target : target, + width: 60, + afterUpload : function(data) { + dialog.hideLoading(); + if (data.error === 0) { + var url = data.url; + if (formatUploadUrl) { + url = K.formatUrl(url, 'absolute'); + } + if (self.afterUpload) { + self.afterUpload.call(self, url, data, name); + } + if (!fillDescAfterUploadImage) { + clickFn.call(self, url, data.title, data.width, data.height, data.border, data.align); + } else { + K(".ke-dialog-row #remoteUrl", div).val(url); + K(".ke-tabs-li", div)[0].click(); + K(".ke-refresh-btn", div).click(); + } + } else { + alert(data.message); + } + }, + afterError : function(html) { + dialog.hideLoading(); + self.errorDialog(html); + } + }); + uploadbutton.fileBox.change(function(e) { + localUrlBox.val(uploadbutton.fileBox.val()); + }); + if (allowFileManager) { + viewServerBtn.click(function(e) { + self.loadPlugin('filemanager', function() { + self.plugin.filemanagerDialog({ + viewType : 'VIEW', + dirName : 'image', + clickFn : function(url, title) { + if (self.dialogs.length > 1) { + K('[name="url"]', div).val(url); + if (self.afterSelectFile) { + self.afterSelectFile.call(self, url); + } + self.hideDialog(); + } + } + }); + }); + }); + } else { + viewServerBtn.hide(); + } + var originalWidth = 0, originalHeight = 0; + function setSize(width, height) { + widthBox.val(width); + heightBox.val(height); + originalWidth = width; + originalHeight = height; + } + refreshBtn.click(function(e) { + var tempImg = K('', document).css({ + position : 'absolute', + visibility : 'hidden', + top : 0, + left : '-1000px' + }); + tempImg.bind('load', function() { + setSize(tempImg.width(), tempImg.height()); + tempImg.remove(); + }); + K(document.body).append(tempImg); + }); + widthBox.change(function(e) { + if (originalWidth > 0) { + heightBox.val(Math.round(originalHeight / originalWidth * parseInt(this.value, 10))); + } + }); + heightBox.change(function(e) { + if (originalHeight > 0) { + widthBox.val(Math.round(originalWidth / originalHeight * parseInt(this.value, 10))); + } + }); + urlBox.val(options.imageUrl); + setSize(options.imageWidth, options.imageHeight); + titleBox.val(options.imageTitle); + alignBox.each(function() { + if (this.value === options.imageAlign) { + this.checked = true; + return false; + } + }); + if (showRemote && tabIndex === 0) { + urlBox[0].focus(); + urlBox[0].select(); + } + return dialog; + }; + self.plugin.image = { + edit : function() { + var img = self.plugin.getSelectedImage(); + self.plugin.imageDialog({ + imageUrl : img ? img.attr('data-ke-src') : 'http://', + imageWidth : img ? img.width() : '', + imageHeight : img ? img.height() : '', + imageTitle : img ? img.attr('title') : '', + imageAlign : img ? img.attr('align') : '', + showRemote : allowImageRemote, + showLocal : allowImageUpload, + tabIndex: img ? 0 : imageTabIndex, + clickFn : function(url, title, width, height, border, align) { + if (img) { + img.attr('src', url); + img.attr('data-ke-src', url); + img.attr('width', width); + img.attr('height', height); + img.attr('title', title); + img.attr('align', align); + img.attr('alt', title); + } else { + self.exec('insertimage', url, title, width, height, border, align); + } + setTimeout(function() { + self.hideDialog().focus(); + }, 0); + } + }); + }, + 'delete' : function() { + var target = self.plugin.getSelectedImage(); + if (target.parent().name == 'a') { + target = target.parent(); + } + target.remove(); + self.addBookmark(); + } + }; + self.clickToolbar(name, self.plugin.image.edit); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('insertfile', function(K) { + var self = this, name = 'insertfile', + allowFileUpload = K.undef(self.allowFileUpload, true), + allowFileManager = K.undef(self.allowFileManager, false), + formatUploadUrl = K.undef(self.formatUploadUrl, true), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'), + extraParams = K.undef(self.extraFileUploadParams, {}), + filePostName = K.undef(self.filePostName, 'imgFile'), + lang = self.lang(name + '.'); + self.plugin.fileDialog = function(options) { + var fileUrl = K.undef(options.fileUrl, 'http://'), + fileTitle = K.undef(options.fileTitle, ''), + clickFn = options.clickFn; + var html = [ + '
      ', + '
      ', + '', + '  ', + '  ', + '', + '', + '', + '
      ', + '
      ', + '', + '
      ', + '
      ', + '', + '' + ].join(''); + var dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var url = K.trim(urlBox.val()), + title = titleBox.val(); + if (url == 'http://' || K.invalidUrl(url)) { + alert(self.lang('invalidUrl')); + urlBox[0].focus(); + return; + } + if (K.trim(title) === '') { + title = url; + } + clickFn.call(self, url, title); + } + } + }), + div = dialog.div; + var urlBox = K('[name="url"]', div), + viewServerBtn = K('[name="viewServer"]', div), + titleBox = K('[name="title"]', div); + if (allowFileUpload) { + var uploadbutton = K.uploadbutton({ + button : K('.ke-upload-button', div)[0], + fieldName : filePostName, + url : K.addParam(uploadJson, 'dir=file'), + extraParams : extraParams, + afterUpload : function(data) { + dialog.hideLoading(); + if (data.error === 0) { + var url = data.url; + if (formatUploadUrl) { + url = K.formatUrl(url, 'absolute'); + } + urlBox.val(url); + if (self.afterUpload) { + self.afterUpload.call(self, url, data, name); + } + alert(self.lang('uploadSuccess')); + } else { + alert(data.message); + } + }, + afterError : function(html) { + dialog.hideLoading(); + self.errorDialog(html); + } + }); + uploadbutton.fileBox.change(function(e) { + dialog.showLoading(self.lang('uploadLoading')); + uploadbutton.submit(); + }); + } else { + K('.ke-upload-button', div).hide(); + } + if (allowFileManager) { + viewServerBtn.click(function(e) { + self.loadPlugin('filemanager', function() { + self.plugin.filemanagerDialog({ + viewType : 'LIST', + dirName : 'file', + clickFn : function(url, title) { + if (self.dialogs.length > 1) { + K('[name="url"]', div).val(url); + if (self.afterSelectFile) { + self.afterSelectFile.call(self, url); + } + self.hideDialog(); + } + } + }); + }); + }); + } else { + viewServerBtn.hide(); + } + urlBox.val(fileUrl); + titleBox.val(fileTitle); + urlBox[0].focus(); + urlBox[0].select(); + }; + self.clickToolbar(name, function() { + self.plugin.fileDialog({ + clickFn : function(url, title) { + var html = '' + title + ''; + self.insertHtml(html).hideDialog().focus(); + } + }); + }); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('lineheight', function(K) { + var self = this, name = 'lineheight', lang = self.lang(name + '.'); + self.clickToolbar(name, function() { + var curVal = '', commonNode = self.cmd.commonNode({'*' : '.line-height'}); + if (commonNode) { + curVal = commonNode.css('line-height'); + } + var menu = self.createMenu({ + name : name, + width : 150 + }); + K.each(lang.lineHeight, function(i, row) { + K.each(row, function(key, val) { + menu.addItem({ + title : val, + checked : curVal === key, + click : function() { + self.cmd.toggle('', { + span : '.line-height=' + key + }); + self.updateState(); + self.addBookmark(); + self.hideMenu(); + } + }); + }); + }); + }); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('link', function(K) { + var self = this, name = 'link'; + self.plugin.link = { + edit : function() { + var lang = self.lang(name + '.'), + html = '
      ' + + '
      ' + + '' + + '
      ' + + '
      ' + + '' + + '' + + '
      ' + + '
      ', + dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var url = K.trim(urlBox.val()); + if (url == 'http://' || K.invalidUrl(url)) { + alert(self.lang('invalidUrl')); + urlBox[0].focus(); + return; + } + self.exec('createlink', url, typeBox.val()).hideDialog().focus(); + } + } + }), + div = dialog.div, + urlBox = K('input[name="url"]', div), + typeBox = K('select[name="type"]', div); + urlBox.val('http://'); + typeBox[0].options[0] = new Option(lang.newWindow, '_blank'); + typeBox[0].options[1] = new Option(lang.selfWindow, ''); + self.cmd.selection(); + var a = self.plugin.getSelectedLink(); + if (a) { + self.cmd.range.selectNode(a[0]); + self.cmd.select(); + urlBox.val(a.attr('data-ke-src')); + typeBox.val(a.attr('target')); + } + urlBox[0].focus(); + urlBox[0].select(); + }, + 'delete' : function() { + self.exec('unlink', null); + } + }; + self.clickToolbar(name, self.plugin.link.edit); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('media', function(K) { + var self = this, name = 'media', lang = self.lang(name + '.'), + allowMediaUpload = K.undef(self.allowMediaUpload, true), + allowFileManager = K.undef(self.allowFileManager, false), + formatUploadUrl = K.undef(self.formatUploadUrl, true), + extraParams = K.undef(self.extraFileUploadParams, {}), + filePostName = K.undef(self.filePostName, 'imgFile'), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'); + self.plugin.media = { + edit : function() { + var html = [ + '
      ', + '
      ', + '', + '  ', + '  ', + '', + '', + '', + '
      ', + '
      ', + '', + '', + '
      ', + '
      ', + '', + '', + '
      ', + '
      ', + '', + ' ', + '
      ', + '
      ' + ].join(''); + var dialog = self.createDialog({ + name : name, + width : 450, + height : 230, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var url = K.trim(urlBox.val()), + width = widthBox.val(), + height = heightBox.val(); + if (url == 'http://' || K.invalidUrl(url)) { + alert(self.lang('invalidUrl')); + urlBox[0].focus(); + return; + } + if (!/^\d*$/.test(width)) { + alert(self.lang('invalidWidth')); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + alert(self.lang('invalidHeight')); + heightBox[0].focus(); + return; + } + var html = K.mediaImg(self.themesPath + 'common/blank.gif', { + src : url, + type : K.mediaType(url), + width : width, + height : height, + autostart : autostartBox[0].checked ? 'true' : 'false', + loop : 'true' + }); + self.insertHtml(html).hideDialog().focus(); + } + } + }), + div = dialog.div, + urlBox = K('[name="url"]', div), + viewServerBtn = K('[name="viewServer"]', div), + widthBox = K('[name="width"]', div), + heightBox = K('[name="height"]', div), + autostartBox = K('[name="autostart"]', div); + urlBox.val('http://'); + if (allowMediaUpload) { + var uploadbutton = K.uploadbutton({ + button : K('.ke-upload-button', div)[0], + fieldName : filePostName, + extraParams : extraParams, + url : K.addParam(uploadJson, 'dir=media'), + afterUpload : function(data) { + dialog.hideLoading(); + if (data.error === 0) { + var url = data.url; + if (formatUploadUrl) { + url = K.formatUrl(url, 'absolute'); + } + urlBox.val(url); + if (self.afterUpload) { + self.afterUpload.call(self, url, data, name); + } + alert(self.lang('uploadSuccess')); + } else { + alert(data.message); + } + }, + afterError : function(html) { + dialog.hideLoading(); + self.errorDialog(html); + } + }); + uploadbutton.fileBox.change(function(e) { + dialog.showLoading(self.lang('uploadLoading')); + uploadbutton.submit(); + }); + } else { + K('.ke-upload-button', div).hide(); + } + if (allowFileManager) { + viewServerBtn.click(function(e) { + self.loadPlugin('filemanager', function() { + self.plugin.filemanagerDialog({ + viewType : 'LIST', + dirName : 'media', + clickFn : function(url, title) { + if (self.dialogs.length > 1) { + K('[name="url"]', div).val(url); + if (self.afterSelectFile) { + self.afterSelectFile.call(self, url); + } + self.hideDialog(); + } + } + }); + }); + }); + } else { + viewServerBtn.hide(); + } + var img = self.plugin.getSelectedMedia(); + if (img) { + var attrs = K.mediaAttrs(img.attr('data-ke-tag')); + urlBox.val(attrs.src); + widthBox.val(K.removeUnit(img.css('width')) || attrs.width || 0); + heightBox.val(K.removeUnit(img.css('height')) || attrs.height || 0); + autostartBox[0].checked = (attrs.autostart === 'true'); + } + urlBox[0].focus(); + urlBox[0].select(); + }, + 'delete' : function() { + self.plugin.getSelectedMedia().remove(); + self.addBookmark(); + } + }; + self.clickToolbar(name, self.plugin.media.edit); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +(function(K) { +function KSWFUpload(options) { + this.init(options); +} +K.extend(KSWFUpload, { + init : function(options) { + var self = this; + options.afterError = options.afterError || function(str) { + alert(str); + }; + self.options = options; + self.progressbars = {}; + self.div = K(options.container).html([ + '
      ', + '
      ', + '
      ', + '', + '
      ', + '
      ' + options.uploadDesc + '
      ', + '', + '', + '', + '
      ', + '
      ', + '
      ' + ].join('')); + self.bodyDiv = K('.ke-swfupload-body', self.div); + function showError(itemDiv, msg) { + K('.ke-status > div', itemDiv).hide(); + K('.ke-message', itemDiv).addClass('ke-error').show().html(K.escape(msg)); + } + var settings = { + debug : false, + upload_url : options.uploadUrl, + flash_url : options.flashUrl, + file_post_name : options.filePostName, + button_placeholder : K('.ke-swfupload-button > input', self.div)[0], + button_image_url: options.buttonImageUrl, + button_width: options.buttonWidth, + button_height: options.buttonHeight, + button_cursor : SWFUpload.CURSOR.HAND, + file_types : options.fileTypes, + file_types_description : options.fileTypesDesc, + file_upload_limit : options.fileUploadLimit, + file_size_limit : options.fileSizeLimit, + post_params : options.postParams, + file_queued_handler : function(file) { + file.url = self.options.fileIconUrl; + self.appendFile(file); + }, + file_queue_error_handler : function(file, errorCode, message) { + var errorName = ''; + switch (errorCode) { + case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED: + errorName = options.queueLimitExceeded; + break; + case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT: + errorName = options.fileExceedsSizeLimit; + break; + case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE: + errorName = options.zeroByteFile; + break; + case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE: + errorName = options.invalidFiletype; + break; + default: + errorName = options.unknownError; + break; + } + K.DEBUG && alert(errorName); + }, + upload_start_handler : function(file) { + var self = this; + var itemDiv = K('div[data-id="' + file.id + '"]', self.bodyDiv); + K('.ke-status > div', itemDiv).hide(); + K('.ke-progressbar', itemDiv).show(); + }, + upload_progress_handler : function(file, bytesLoaded, bytesTotal) { + var percent = Math.round(bytesLoaded * 100 / bytesTotal); + var progressbar = self.progressbars[file.id]; + progressbar.bar.css('width', Math.round(percent * 80 / 100) + 'px'); + progressbar.percent.html(percent + '%'); + }, + upload_error_handler : function(file, errorCode, message) { + if (file && file.filestatus == SWFUpload.FILE_STATUS.ERROR) { + var itemDiv = K('div[data-id="' + file.id + '"]', self.bodyDiv).eq(0); + showError(itemDiv, self.options.errorMessage); + } + }, + upload_success_handler : function(file, serverData) { + var itemDiv = K('div[data-id="' + file.id + '"]', self.bodyDiv).eq(0); + var data = {}; + try { + data = K.json(serverData); + } catch (e) { + self.options.afterError.call(this, '' + serverData + ''); + } + if (data.error !== 0) { + showError(itemDiv, K.DEBUG ? data.message : self.options.errorMessage); + return; + } + file.url = data.url; + K('.ke-img', itemDiv).attr('src', file.url).attr('data-status', file.filestatus).data('data', data); + K('.ke-status > div', itemDiv).hide(); + } + }; + self.swfu = new SWFUpload(settings); + K('.ke-swfupload-startupload input', self.div).click(function() { + self.swfu.startUpload(); + }); + }, + getUrlList : function() { + var list = []; + K('.ke-img', self.bodyDiv).each(function() { + var img = K(this); + var status = img.attr('data-status'); + if (status == SWFUpload.FILE_STATUS.COMPLETE) { + list.push(img.data('data')); + } + }); + return list; + }, + removeFile : function(fileId) { + var self = this; + self.swfu.cancelUpload(fileId); + var itemDiv = K('div[data-id="' + fileId + '"]', self.bodyDiv); + K('.ke-photo', itemDiv).unbind(); + K('.ke-delete', itemDiv).unbind(); + itemDiv.remove(); + }, + removeFiles : function() { + var self = this; + K('.ke-item', self.bodyDiv).each(function() { + self.removeFile(K(this).attr('data-id')); + }); + }, + appendFile : function(file) { + var self = this; + var itemDiv = K('
      '); + self.bodyDiv.append(itemDiv); + var photoDiv = K('
      ') + .mouseover(function(e) { + K(this).addClass('ke-on'); + }) + .mouseout(function(e) { + K(this).removeClass('ke-on'); + }); + itemDiv.append(photoDiv); + var img = K('' + file.name + ''); + photoDiv.append(img); + K('').appendTo(photoDiv).click(function() { + self.removeFile(file.id); + }); + var statusDiv = K('
      ').appendTo(photoDiv); + K(['
      ', + '
      ', + '
      0%
      '].join('')).hide().appendTo(statusDiv); + K('
      ' + self.options.pendingMessage + '
      ').appendTo(statusDiv); + itemDiv.append('
      ' + file.name + '
      '); + self.progressbars[file.id] = { + bar : K('.ke-progressbar-bar-inner', photoDiv), + percent : K('.ke-progressbar-percent', photoDiv) + }; + }, + remove : function() { + this.removeFiles(); + this.swfu.destroy(); + this.div.html(''); + } +}); +K.swfupload = function(element, options) { + return new KSWFUpload(element, options); +}; +})(KindEditor); +KindEditor.plugin('multiimage', function(K) { + var self = this, name = 'multiimage', + formatUploadUrl = K.undef(self.formatUploadUrl, true), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'), + imgPath = self.pluginsPath + 'multiimage/images/', + imageSizeLimit = K.undef(self.imageSizeLimit, '1MB'), + imageFileTypes = K.undef(self.imageFileTypes, '*.jpg;*.gif;*.png'), + imageUploadLimit = K.undef(self.imageUploadLimit, 20), + filePostName = K.undef(self.filePostName, 'imgFile'), + lang = self.lang(name + '.'); + self.plugin.multiImageDialog = function(options) { + var clickFn = options.clickFn, + uploadDesc = K.tmpl(lang.uploadDesc, {uploadLimit : imageUploadLimit, sizeLimit : imageSizeLimit}); + var html = [ + '
      ', + '
      ', + '
      ', + '
      ' + ].join(''); + var dialog = self.createDialog({ + name : name, + width : 650, + height : 510, + title : self.lang(name), + body : html, + previewBtn : { + name : lang.insertAll, + click : function(e) { + clickFn.call(self, swfupload.getUrlList()); + } + }, + yesBtn : { + name : lang.clearAll, + click : function(e) { + swfupload.removeFiles(); + } + }, + beforeRemove : function() { + if (!K.IE || K.V <= 8) { + swfupload.remove(); + } + } + }), + div = dialog.div; + var swfupload = K.swfupload({ + container : K('.swfupload', div), + buttonImageUrl : imgPath + (self.langType == 'zh-CN' ? 'select-files-zh-CN.png' : 'select-files-en.png'), + buttonWidth : self.langType == 'zh-CN' ? 72 : 88, + buttonHeight : 23, + fileIconUrl : imgPath + 'image.png', + uploadDesc : uploadDesc, + startButtonValue : lang.startUpload, + uploadUrl : K.addParam(uploadJson, 'dir=image'), + flashUrl : imgPath + 'swfupload.swf', + filePostName : filePostName, + fileTypes : '*.jpg;*.jpeg;*.gif;*.png;*.bmp', + fileTypesDesc : 'Image Files', + fileUploadLimit : imageUploadLimit, + fileSizeLimit : imageSizeLimit, + postParams : K.undef(self.extraFileUploadParams, {}), + queueLimitExceeded : lang.queueLimitExceeded, + fileExceedsSizeLimit : lang.fileExceedsSizeLimit, + zeroByteFile : lang.zeroByteFile, + invalidFiletype : lang.invalidFiletype, + unknownError : lang.unknownError, + pendingMessage : lang.pending, + errorMessage : lang.uploadError, + afterError : function(html) { + self.errorDialog(html); + } + }); + return dialog; + }; + self.clickToolbar(name, function() { + self.plugin.multiImageDialog({ + clickFn : function (urlList) { + if (urlList.length === 0) { + return; + } + K.each(urlList, function(i, data) { + if (self.afterUpload) { + self.afterUpload.call(self, data.url, data, 'multiimage'); + } + self.exec('insertimage', data.url, data.title, data.width, data.height, data.border, data.align); + }); + setTimeout(function() { + self.hideDialog().focus(); + }, 0); + } + }); + }); +}); +/* ******************* */ +/* Constructor & Init */ +/* ******************* */ +(function() { +window.SWFUpload = function (settings) { + this.initSWFUpload(settings); +}; +SWFUpload.prototype.initSWFUpload = function (settings) { + try { + this.customSettings = {}; + this.settings = settings; + this.eventQueue = []; + this.movieName = "KindEditor_SWFUpload_" + SWFUpload.movieCount++; + this.movieElement = null; + SWFUpload.instances[this.movieName] = this; + this.initSettings(); + this.loadFlash(); + this.displayDebugInfo(); + } catch (ex) { + delete SWFUpload.instances[this.movieName]; + throw ex; + } +}; +/* *************** */ +/* Static Members */ +/* *************** */ +SWFUpload.instances = {}; +SWFUpload.movieCount = 0; +SWFUpload.version = "2.2.0 2009-03-25"; +SWFUpload.QUEUE_ERROR = { + QUEUE_LIMIT_EXCEEDED : -100, + FILE_EXCEEDS_SIZE_LIMIT : -110, + ZERO_BYTE_FILE : -120, + INVALID_FILETYPE : -130 +}; +SWFUpload.UPLOAD_ERROR = { + HTTP_ERROR : -200, + MISSING_UPLOAD_URL : -210, + IO_ERROR : -220, + SECURITY_ERROR : -230, + UPLOAD_LIMIT_EXCEEDED : -240, + UPLOAD_FAILED : -250, + SPECIFIED_FILE_ID_NOT_FOUND : -260, + FILE_VALIDATION_FAILED : -270, + FILE_CANCELLED : -280, + UPLOAD_STOPPED : -290 +}; +SWFUpload.FILE_STATUS = { + QUEUED : -1, + IN_PROGRESS : -2, + ERROR : -3, + COMPLETE : -4, + CANCELLED : -5 +}; +SWFUpload.BUTTON_ACTION = { + SELECT_FILE : -100, + SELECT_FILES : -110, + START_UPLOAD : -120 +}; +SWFUpload.CURSOR = { + ARROW : -1, + HAND : -2 +}; +SWFUpload.WINDOW_MODE = { + WINDOW : "window", + TRANSPARENT : "transparent", + OPAQUE : "opaque" +}; +SWFUpload.completeURL = function(url) { + if (typeof(url) !== "string" || url.match(/^https?:\/\//i) || url.match(/^\//)) { + return url; + } + var currentURL = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ":" + window.location.port : ""); + var indexSlash = window.location.pathname.lastIndexOf("/"); + if (indexSlash <= 0) { + path = "/"; + } else { + path = window.location.pathname.substr(0, indexSlash) + "/"; + } + return /*currentURL +*/ path + url; +}; +/* ******************** */ +/* Instance Members */ +/* ******************** */ +SWFUpload.prototype.initSettings = function () { + this.ensureDefault = function (settingName, defaultValue) { + this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName]; + }; + this.ensureDefault("upload_url", ""); + this.ensureDefault("preserve_relative_urls", false); + this.ensureDefault("file_post_name", "Filedata"); + this.ensureDefault("post_params", {}); + this.ensureDefault("use_query_string", false); + this.ensureDefault("requeue_on_error", false); + this.ensureDefault("http_success", []); + this.ensureDefault("assume_success_timeout", 0); + this.ensureDefault("file_types", "*.*"); + this.ensureDefault("file_types_description", "All Files"); + this.ensureDefault("file_size_limit", 0); + this.ensureDefault("file_upload_limit", 0); + this.ensureDefault("file_queue_limit", 0); + this.ensureDefault("flash_url", "swfupload.swf"); + this.ensureDefault("prevent_swf_caching", true); + this.ensureDefault("button_image_url", ""); + this.ensureDefault("button_width", 1); + this.ensureDefault("button_height", 1); + this.ensureDefault("button_text", ""); + this.ensureDefault("button_text_style", "color: #000000; font-size: 16pt;"); + this.ensureDefault("button_text_top_padding", 0); + this.ensureDefault("button_text_left_padding", 0); + this.ensureDefault("button_action", SWFUpload.BUTTON_ACTION.SELECT_FILES); + this.ensureDefault("button_disabled", false); + this.ensureDefault("button_placeholder_id", ""); + this.ensureDefault("button_placeholder", null); + this.ensureDefault("button_cursor", SWFUpload.CURSOR.ARROW); + this.ensureDefault("button_window_mode", SWFUpload.WINDOW_MODE.WINDOW); + this.ensureDefault("debug", false); + this.settings.debug_enabled = this.settings.debug; + this.settings.return_upload_start_handler = this.returnUploadStart; + this.ensureDefault("swfupload_loaded_handler", null); + this.ensureDefault("file_dialog_start_handler", null); + this.ensureDefault("file_queued_handler", null); + this.ensureDefault("file_queue_error_handler", null); + this.ensureDefault("file_dialog_complete_handler", null); + this.ensureDefault("upload_start_handler", null); + this.ensureDefault("upload_progress_handler", null); + this.ensureDefault("upload_error_handler", null); + this.ensureDefault("upload_success_handler", null); + this.ensureDefault("upload_complete_handler", null); + this.ensureDefault("debug_handler", this.debugMessage); + this.ensureDefault("custom_settings", {}); + this.customSettings = this.settings.custom_settings; + if (!!this.settings.prevent_swf_caching) { + this.settings.flash_url = this.settings.flash_url + (this.settings.flash_url.indexOf("?") < 0 ? "?" : "&") + "preventswfcaching=" + new Date().getTime(); + } + if (!this.settings.preserve_relative_urls) { + this.settings.upload_url = SWFUpload.completeURL(this.settings.upload_url); + this.settings.button_image_url = SWFUpload.completeURL(this.settings.button_image_url); + } + delete this.ensureDefault; +}; +SWFUpload.prototype.loadFlash = function () { + var targetElement, tempParent; + if (document.getElementById(this.movieName) !== null) { + throw "ID " + this.movieName + " is already in use. The Flash Object could not be added"; + } + targetElement = document.getElementById(this.settings.button_placeholder_id) || this.settings.button_placeholder; + if (targetElement == undefined) { + throw "Could not find the placeholder element: " + this.settings.button_placeholder_id; + } + tempParent = document.createElement("div"); + tempParent.innerHTML = this.getFlashHTML(); + targetElement.parentNode.replaceChild(tempParent.firstChild, targetElement); + if (window[this.movieName] == undefined) { + window[this.movieName] = this.getMovieElement(); + } +}; +SWFUpload.prototype.getFlashHTML = function () { + var classid = ''; + if (KindEditor.IE && KindEditor.V > 8) { + classid = ' classid = "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"'; + } + return ['', + '', + '', + '', + '', + '', + '', + ''].join(""); +}; +SWFUpload.prototype.getFlashVars = function () { + var paramString = this.buildParamString(); + var httpSuccessString = this.settings.http_success.join(","); + return ["movieName=", encodeURIComponent(this.movieName), + "&uploadURL=", encodeURIComponent(this.settings.upload_url), + "&useQueryString=", encodeURIComponent(this.settings.use_query_string), + "&requeueOnError=", encodeURIComponent(this.settings.requeue_on_error), + "&httpSuccess=", encodeURIComponent(httpSuccessString), + "&assumeSuccessTimeout=", encodeURIComponent(this.settings.assume_success_timeout), + "&params=", encodeURIComponent(paramString), + "&filePostName=", encodeURIComponent(this.settings.file_post_name), + "&fileTypes=", encodeURIComponent(this.settings.file_types), + "&fileTypesDescription=", encodeURIComponent(this.settings.file_types_description), + "&fileSizeLimit=", encodeURIComponent(this.settings.file_size_limit), + "&fileUploadLimit=", encodeURIComponent(this.settings.file_upload_limit), + "&fileQueueLimit=", encodeURIComponent(this.settings.file_queue_limit), + "&debugEnabled=", encodeURIComponent(this.settings.debug_enabled), + "&buttonImageURL=", encodeURIComponent(this.settings.button_image_url), + "&buttonWidth=", encodeURIComponent(this.settings.button_width), + "&buttonHeight=", encodeURIComponent(this.settings.button_height), + "&buttonText=", encodeURIComponent(this.settings.button_text), + "&buttonTextTopPadding=", encodeURIComponent(this.settings.button_text_top_padding), + "&buttonTextLeftPadding=", encodeURIComponent(this.settings.button_text_left_padding), + "&buttonTextStyle=", encodeURIComponent(this.settings.button_text_style), + "&buttonAction=", encodeURIComponent(this.settings.button_action), + "&buttonDisabled=", encodeURIComponent(this.settings.button_disabled), + "&buttonCursor=", encodeURIComponent(this.settings.button_cursor) + ].join(""); +}; +SWFUpload.prototype.getMovieElement = function () { + if (this.movieElement == undefined) { + this.movieElement = document.getElementById(this.movieName); + } + if (this.movieElement === null) { + throw "Could not find Flash element"; + } + return this.movieElement; +}; +SWFUpload.prototype.buildParamString = function () { + var postParams = this.settings.post_params; + var paramStringPairs = []; + if (typeof(postParams) === "object") { + for (var name in postParams) { + if (postParams.hasOwnProperty(name)) { + paramStringPairs.push(encodeURIComponent(name.toString()) + "=" + encodeURIComponent(postParams[name].toString())); + } + } + } + return paramStringPairs.join("&"); +}; +SWFUpload.prototype.destroy = function () { + try { + this.cancelUpload(null, false); + var movieElement = null; + movieElement = this.getMovieElement(); + if (movieElement && typeof(movieElement.CallFunction) === "unknown") { + for (var i in movieElement) { + try { + if (typeof(movieElement[i]) === "function") { + movieElement[i] = null; + } + } catch (ex1) {} + } + try { + movieElement.parentNode.removeChild(movieElement); + } catch (ex) {} + } + window[this.movieName] = null; + SWFUpload.instances[this.movieName] = null; + delete SWFUpload.instances[this.movieName]; + this.movieElement = null; + this.settings = null; + this.customSettings = null; + this.eventQueue = null; + this.movieName = null; + return true; + } catch (ex2) { + return false; + } +}; +SWFUpload.prototype.displayDebugInfo = function () { + this.debug( + [ + "---SWFUpload Instance Info---\n", + "Version: ", SWFUpload.version, "\n", + "Movie Name: ", this.movieName, "\n", + "Settings:\n", + "\t", "upload_url: ", this.settings.upload_url, "\n", + "\t", "flash_url: ", this.settings.flash_url, "\n", + "\t", "use_query_string: ", this.settings.use_query_string.toString(), "\n", + "\t", "requeue_on_error: ", this.settings.requeue_on_error.toString(), "\n", + "\t", "http_success: ", this.settings.http_success.join(", "), "\n", + "\t", "assume_success_timeout: ", this.settings.assume_success_timeout, "\n", + "\t", "file_post_name: ", this.settings.file_post_name, "\n", + "\t", "post_params: ", this.settings.post_params.toString(), "\n", + "\t", "file_types: ", this.settings.file_types, "\n", + "\t", "file_types_description: ", this.settings.file_types_description, "\n", + "\t", "file_size_limit: ", this.settings.file_size_limit, "\n", + "\t", "file_upload_limit: ", this.settings.file_upload_limit, "\n", + "\t", "file_queue_limit: ", this.settings.file_queue_limit, "\n", + "\t", "debug: ", this.settings.debug.toString(), "\n", + "\t", "prevent_swf_caching: ", this.settings.prevent_swf_caching.toString(), "\n", + "\t", "button_placeholder_id: ", this.settings.button_placeholder_id.toString(), "\n", + "\t", "button_placeholder: ", (this.settings.button_placeholder ? "Set" : "Not Set"), "\n", + "\t", "button_image_url: ", this.settings.button_image_url.toString(), "\n", + "\t", "button_width: ", this.settings.button_width.toString(), "\n", + "\t", "button_height: ", this.settings.button_height.toString(), "\n", + "\t", "button_text: ", this.settings.button_text.toString(), "\n", + "\t", "button_text_style: ", this.settings.button_text_style.toString(), "\n", + "\t", "button_text_top_padding: ", this.settings.button_text_top_padding.toString(), "\n", + "\t", "button_text_left_padding: ", this.settings.button_text_left_padding.toString(), "\n", + "\t", "button_action: ", this.settings.button_action.toString(), "\n", + "\t", "button_disabled: ", this.settings.button_disabled.toString(), "\n", + "\t", "custom_settings: ", this.settings.custom_settings.toString(), "\n", + "Event Handlers:\n", + "\t", "swfupload_loaded_handler assigned: ", (typeof this.settings.swfupload_loaded_handler === "function").toString(), "\n", + "\t", "file_dialog_start_handler assigned: ", (typeof this.settings.file_dialog_start_handler === "function").toString(), "\n", + "\t", "file_queued_handler assigned: ", (typeof this.settings.file_queued_handler === "function").toString(), "\n", + "\t", "file_queue_error_handler assigned: ", (typeof this.settings.file_queue_error_handler === "function").toString(), "\n", + "\t", "upload_start_handler assigned: ", (typeof this.settings.upload_start_handler === "function").toString(), "\n", + "\t", "upload_progress_handler assigned: ", (typeof this.settings.upload_progress_handler === "function").toString(), "\n", + "\t", "upload_error_handler assigned: ", (typeof this.settings.upload_error_handler === "function").toString(), "\n", + "\t", "upload_success_handler assigned: ", (typeof this.settings.upload_success_handler === "function").toString(), "\n", + "\t", "upload_complete_handler assigned: ", (typeof this.settings.upload_complete_handler === "function").toString(), "\n", + "\t", "debug_handler assigned: ", (typeof this.settings.debug_handler === "function").toString(), "\n" + ].join("") + ); +}; +/* Note: addSetting and getSetting are no longer used by SWFUpload but are included + the maintain v2 API compatibility +*/ +SWFUpload.prototype.addSetting = function (name, value, default_value) { + if (value == undefined) { + return (this.settings[name] = default_value); + } else { + return (this.settings[name] = value); + } +}; +SWFUpload.prototype.getSetting = function (name) { + if (this.settings[name] != undefined) { + return this.settings[name]; + } + return ""; +}; +SWFUpload.prototype.callFlash = function (functionName, argumentArray) { + argumentArray = argumentArray || []; + var movieElement = this.getMovieElement(); + var returnValue, returnString; + try { + returnString = movieElement.CallFunction('' + __flash__argumentsToXML(argumentArray, 0) + ''); + returnValue = eval(returnString); + } catch (ex) { + throw "Call to " + functionName + " failed"; + } + if (returnValue != undefined && typeof returnValue.post === "object") { + returnValue = this.unescapeFilePostParams(returnValue); + } + return returnValue; +}; +/* ***************************** + -- Flash control methods -- + Your UI should use these + to operate SWFUpload + ***************************** */ +SWFUpload.prototype.selectFile = function () { + this.callFlash("SelectFile"); +}; +SWFUpload.prototype.selectFiles = function () { + this.callFlash("SelectFiles"); +}; +SWFUpload.prototype.startUpload = function (fileID) { + this.callFlash("StartUpload", [fileID]); +}; +SWFUpload.prototype.cancelUpload = function (fileID, triggerErrorEvent) { + if (triggerErrorEvent !== false) { + triggerErrorEvent = true; + } + this.callFlash("CancelUpload", [fileID, triggerErrorEvent]); +}; +SWFUpload.prototype.stopUpload = function () { + this.callFlash("StopUpload"); +}; +/* ************************ + * Settings methods + * These methods change the SWFUpload settings. + * SWFUpload settings should not be changed directly on the settings object + * since many of the settings need to be passed to Flash in order to take + * effect. + * *********************** */ +SWFUpload.prototype.getStats = function () { + return this.callFlash("GetStats"); +}; +SWFUpload.prototype.setStats = function (statsObject) { + this.callFlash("SetStats", [statsObject]); +}; +SWFUpload.prototype.getFile = function (fileID) { + if (typeof(fileID) === "number") { + return this.callFlash("GetFileByIndex", [fileID]); + } else { + return this.callFlash("GetFile", [fileID]); + } +}; +SWFUpload.prototype.addFileParam = function (fileID, name, value) { + return this.callFlash("AddFileParam", [fileID, name, value]); +}; +SWFUpload.prototype.removeFileParam = function (fileID, name) { + this.callFlash("RemoveFileParam", [fileID, name]); +}; +SWFUpload.prototype.setUploadURL = function (url) { + this.settings.upload_url = url.toString(); + this.callFlash("SetUploadURL", [url]); +}; +SWFUpload.prototype.setPostParams = function (paramsObject) { + this.settings.post_params = paramsObject; + this.callFlash("SetPostParams", [paramsObject]); +}; +SWFUpload.prototype.addPostParam = function (name, value) { + this.settings.post_params[name] = value; + this.callFlash("SetPostParams", [this.settings.post_params]); +}; +SWFUpload.prototype.removePostParam = function (name) { + delete this.settings.post_params[name]; + this.callFlash("SetPostParams", [this.settings.post_params]); +}; +SWFUpload.prototype.setFileTypes = function (types, description) { + this.settings.file_types = types; + this.settings.file_types_description = description; + this.callFlash("SetFileTypes", [types, description]); +}; +SWFUpload.prototype.setFileSizeLimit = function (fileSizeLimit) { + this.settings.file_size_limit = fileSizeLimit; + this.callFlash("SetFileSizeLimit", [fileSizeLimit]); +}; +SWFUpload.prototype.setFileUploadLimit = function (fileUploadLimit) { + this.settings.file_upload_limit = fileUploadLimit; + this.callFlash("SetFileUploadLimit", [fileUploadLimit]); +}; +SWFUpload.prototype.setFileQueueLimit = function (fileQueueLimit) { + this.settings.file_queue_limit = fileQueueLimit; + this.callFlash("SetFileQueueLimit", [fileQueueLimit]); +}; +SWFUpload.prototype.setFilePostName = function (filePostName) { + this.settings.file_post_name = filePostName; + this.callFlash("SetFilePostName", [filePostName]); +}; +SWFUpload.prototype.setUseQueryString = function (useQueryString) { + this.settings.use_query_string = useQueryString; + this.callFlash("SetUseQueryString", [useQueryString]); +}; +SWFUpload.prototype.setRequeueOnError = function (requeueOnError) { + this.settings.requeue_on_error = requeueOnError; + this.callFlash("SetRequeueOnError", [requeueOnError]); +}; +SWFUpload.prototype.setHTTPSuccess = function (http_status_codes) { + if (typeof http_status_codes === "string") { + http_status_codes = http_status_codes.replace(" ", "").split(","); + } + this.settings.http_success = http_status_codes; + this.callFlash("SetHTTPSuccess", [http_status_codes]); +}; +SWFUpload.prototype.setAssumeSuccessTimeout = function (timeout_seconds) { + this.settings.assume_success_timeout = timeout_seconds; + this.callFlash("SetAssumeSuccessTimeout", [timeout_seconds]); +}; +SWFUpload.prototype.setDebugEnabled = function (debugEnabled) { + this.settings.debug_enabled = debugEnabled; + this.callFlash("SetDebugEnabled", [debugEnabled]); +}; +SWFUpload.prototype.setButtonImageURL = function (buttonImageURL) { + if (buttonImageURL == undefined) { + buttonImageURL = ""; + } + this.settings.button_image_url = buttonImageURL; + this.callFlash("SetButtonImageURL", [buttonImageURL]); +}; +SWFUpload.prototype.setButtonDimensions = function (width, height) { + this.settings.button_width = width; + this.settings.button_height = height; + var movie = this.getMovieElement(); + if (movie != undefined) { + movie.style.width = width + "px"; + movie.style.height = height + "px"; + } + this.callFlash("SetButtonDimensions", [width, height]); +}; +SWFUpload.prototype.setButtonText = function (html) { + this.settings.button_text = html; + this.callFlash("SetButtonText", [html]); +}; +SWFUpload.prototype.setButtonTextPadding = function (left, top) { + this.settings.button_text_top_padding = top; + this.settings.button_text_left_padding = left; + this.callFlash("SetButtonTextPadding", [left, top]); +}; +SWFUpload.prototype.setButtonTextStyle = function (css) { + this.settings.button_text_style = css; + this.callFlash("SetButtonTextStyle", [css]); +}; +SWFUpload.prototype.setButtonDisabled = function (isDisabled) { + this.settings.button_disabled = isDisabled; + this.callFlash("SetButtonDisabled", [isDisabled]); +}; +SWFUpload.prototype.setButtonAction = function (buttonAction) { + this.settings.button_action = buttonAction; + this.callFlash("SetButtonAction", [buttonAction]); +}; +SWFUpload.prototype.setButtonCursor = function (cursor) { + this.settings.button_cursor = cursor; + this.callFlash("SetButtonCursor", [cursor]); +}; +/* ******************************* + Flash Event Interfaces + These functions are used by Flash to trigger the various + events. + All these functions a Private. + Because the ExternalInterface library is buggy the event calls + are added to a queue and the queue then executed by a setTimeout. + This ensures that events are executed in a determinate order and that + the ExternalInterface bugs are avoided. +******************************* */ +SWFUpload.prototype.queueEvent = function (handlerName, argumentArray) { + if (argumentArray == undefined) { + argumentArray = []; + } else if (!(argumentArray instanceof Array)) { + argumentArray = [argumentArray]; + } + var self = this; + if (typeof this.settings[handlerName] === "function") { + this.eventQueue.push(function () { + this.settings[handlerName].apply(this, argumentArray); + }); + setTimeout(function () { + self.executeNextEvent(); + }, 0); + } else if (this.settings[handlerName] !== null) { + throw "Event handler " + handlerName + " is unknown or is not a function"; + } +}; +SWFUpload.prototype.executeNextEvent = function () { + var f = this.eventQueue ? this.eventQueue.shift() : null; + if (typeof(f) === "function") { + f.apply(this); + } +}; +SWFUpload.prototype.unescapeFilePostParams = function (file) { + var reg = /[$]([0-9a-f]{4})/i; + var unescapedPost = {}; + var uk; + if (file != undefined) { + for (var k in file.post) { + if (file.post.hasOwnProperty(k)) { + uk = k; + var match; + while ((match = reg.exec(uk)) !== null) { + uk = uk.replace(match[0], String.fromCharCode(parseInt("0x" + match[1], 16))); + } + unescapedPost[uk] = file.post[k]; + } + } + file.post = unescapedPost; + } + return file; +}; +SWFUpload.prototype.testExternalInterface = function () { + try { + return this.callFlash("TestExternalInterface"); + } catch (ex) { + return false; + } +}; +SWFUpload.prototype.flashReady = function () { + var movieElement = this.getMovieElement(); + if (!movieElement) { + this.debug("Flash called back ready but the flash movie can't be found."); + return; + } + this.cleanUp(movieElement); + this.queueEvent("swfupload_loaded_handler"); +}; +SWFUpload.prototype.cleanUp = function (movieElement) { + try { + if (this.movieElement && typeof(movieElement.CallFunction) === "unknown") { + this.debug("Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)"); + for (var key in movieElement) { + try { + if (typeof(movieElement[key]) === "function") { + movieElement[key] = null; + } + } catch (ex) { + } + } + } + } catch (ex1) { + } + window["__flash__removeCallback"] = function (instance, name) { + try { + if (instance) { + instance[name] = null; + } + } catch (flashEx) { + } + }; +}; +/* This is a chance to do something before the browse window opens */ +SWFUpload.prototype.fileDialogStart = function () { + this.queueEvent("file_dialog_start_handler"); +}; +/* Called when a file is successfully added to the queue. */ +SWFUpload.prototype.fileQueued = function (file) { + file = this.unescapeFilePostParams(file); + this.queueEvent("file_queued_handler", file); +}; +/* Handle errors that occur when an attempt to queue a file fails. */ +SWFUpload.prototype.fileQueueError = function (file, errorCode, message) { + file = this.unescapeFilePostParams(file); + this.queueEvent("file_queue_error_handler", [file, errorCode, message]); +}; +/* Called after the file dialog has closed and the selected files have been queued. + You could call startUpload here if you want the queued files to begin uploading immediately. */ +SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued, numFilesInQueue) { + this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued, numFilesInQueue]); +}; +SWFUpload.prototype.uploadStart = function (file) { + file = this.unescapeFilePostParams(file); + this.queueEvent("return_upload_start_handler", file); +}; +SWFUpload.prototype.returnUploadStart = function (file) { + var returnValue; + if (typeof this.settings.upload_start_handler === "function") { + file = this.unescapeFilePostParams(file); + returnValue = this.settings.upload_start_handler.call(this, file); + } else if (this.settings.upload_start_handler != undefined) { + throw "upload_start_handler must be a function"; + } + if (returnValue === undefined) { + returnValue = true; + } + returnValue = !!returnValue; + this.callFlash("ReturnUploadStart", [returnValue]); +}; +SWFUpload.prototype.uploadProgress = function (file, bytesComplete, bytesTotal) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_progress_handler", [file, bytesComplete, bytesTotal]); +}; +SWFUpload.prototype.uploadError = function (file, errorCode, message) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_error_handler", [file, errorCode, message]); +}; +SWFUpload.prototype.uploadSuccess = function (file, serverData, responseReceived) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_success_handler", [file, serverData, responseReceived]); +}; +SWFUpload.prototype.uploadComplete = function (file) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_complete_handler", file); +}; +/* Called by SWFUpload JavaScript and Flash functions when debug is enabled. By default it writes messages to the + internal debug console. You can override this event and have messages written where you want. */ +SWFUpload.prototype.debug = function (message) { + this.queueEvent("debug_handler", message); +}; +/* ********************************** + Debug Console + The debug console is a self contained, in page location + for debug message to be sent. The Debug Console adds + itself to the body if necessary. + The console is automatically scrolled as messages appear. + If you are using your own debug handler or when you deploy to production and + have debug disabled you can remove these functions to reduce the file size + and complexity. +********************************** */ +SWFUpload.prototype.debugMessage = function (message) { + if (this.settings.debug) { + var exceptionMessage, exceptionValues = []; + if (typeof message === "object" && typeof message.name === "string" && typeof message.message === "string") { + for (var key in message) { + if (message.hasOwnProperty(key)) { + exceptionValues.push(key + ": " + message[key]); + } + } + exceptionMessage = exceptionValues.join("\n") || ""; + exceptionValues = exceptionMessage.split("\n"); + exceptionMessage = "EXCEPTION: " + exceptionValues.join("\nEXCEPTION: "); + SWFUpload.Console.writeLine(exceptionMessage); + } else { + SWFUpload.Console.writeLine(message); + } + } +}; +SWFUpload.Console = {}; +SWFUpload.Console.writeLine = function (message) { + var console, documentForm; + try { + console = document.getElementById("SWFUpload_Console"); + if (!console) { + documentForm = document.createElement("form"); + document.getElementsByTagName("body")[0].appendChild(documentForm); + console = document.createElement("textarea"); + console.id = "SWFUpload_Console"; + console.style.fontFamily = "monospace"; + console.setAttribute("wrap", "off"); + console.wrap = "off"; + console.style.overflow = "auto"; + console.style.width = "700px"; + console.style.height = "350px"; + console.style.margin = "5px"; + documentForm.appendChild(console); + } + console.value += message + "\n"; + console.scrollTop = console.scrollHeight - console.clientHeight; + } catch (ex) { + alert("Exception: " + ex.name + " Message: " + ex.message); + } +}; +})(); +(function() { +/* + Queue Plug-in + Features: + *Adds a cancelQueue() method for cancelling the entire queue. + *All queued files are uploaded when startUpload() is called. + *If false is returned from uploadComplete then the queue upload is stopped. + If false is not returned (strict comparison) then the queue upload is continued. + *Adds a QueueComplete event that is fired when all the queued files have finished uploading. + Set the event handler with the queue_complete_handler setting. + */ +if (typeof(SWFUpload) === "function") { + SWFUpload.queue = {}; + SWFUpload.prototype.initSettings = (function (oldInitSettings) { + return function () { + if (typeof(oldInitSettings) === "function") { + oldInitSettings.call(this); + } + this.queueSettings = {}; + this.queueSettings.queue_cancelled_flag = false; + this.queueSettings.queue_upload_count = 0; + this.queueSettings.user_upload_complete_handler = this.settings.upload_complete_handler; + this.queueSettings.user_upload_start_handler = this.settings.upload_start_handler; + this.settings.upload_complete_handler = SWFUpload.queue.uploadCompleteHandler; + this.settings.upload_start_handler = SWFUpload.queue.uploadStartHandler; + this.settings.queue_complete_handler = this.settings.queue_complete_handler || null; + }; + })(SWFUpload.prototype.initSettings); + SWFUpload.prototype.startUpload = function (fileID) { + this.queueSettings.queue_cancelled_flag = false; + this.callFlash("StartUpload", [fileID]); + }; + SWFUpload.prototype.cancelQueue = function () { + this.queueSettings.queue_cancelled_flag = true; + this.stopUpload(); + var stats = this.getStats(); + while (stats.files_queued > 0) { + this.cancelUpload(); + stats = this.getStats(); + } + }; + SWFUpload.queue.uploadStartHandler = function (file) { + var returnValue; + if (typeof(this.queueSettings.user_upload_start_handler) === "function") { + returnValue = this.queueSettings.user_upload_start_handler.call(this, file); + } + returnValue = (returnValue === false) ? false : true; + this.queueSettings.queue_cancelled_flag = !returnValue; + return returnValue; + }; + SWFUpload.queue.uploadCompleteHandler = function (file) { + var user_upload_complete_handler = this.queueSettings.user_upload_complete_handler; + var continueUpload; + if (file.filestatus === SWFUpload.FILE_STATUS.COMPLETE) { + this.queueSettings.queue_upload_count++; + } + if (typeof(user_upload_complete_handler) === "function") { + continueUpload = (user_upload_complete_handler.call(this, file) === false) ? false : true; + } else if (file.filestatus === SWFUpload.FILE_STATUS.QUEUED) { + continueUpload = false; + } else { + continueUpload = true; + } + if (continueUpload) { + var stats = this.getStats(); + if (stats.files_queued > 0 && this.queueSettings.queue_cancelled_flag === false) { + this.startUpload(); + } else if (this.queueSettings.queue_cancelled_flag === false) { + this.queueEvent("queue_complete_handler", [this.queueSettings.queue_upload_count]); + this.queueSettings.queue_upload_count = 0; + } else { + this.queueSettings.queue_cancelled_flag = false; + this.queueSettings.queue_upload_count = 0; + } + } + }; +} +})(); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('pagebreak', function(K) { + var self = this; + var name = 'pagebreak'; + var pagebreakHtml = K.undef(self.pagebreakHtml, '
      '); + self.clickToolbar(name, function() { + var cmd = self.cmd, range = cmd.range; + self.focus(); + var tail = self.newlineTag == 'br' || K.WEBKIT ? '' : ''; + self.insertHtml(pagebreakHtml + tail); + if (tail !== '') { + var p = K('#__kindeditor_tail_tag__', self.edit.doc); + range.selectNodeContents(p[0]); + p.removeAttr('id'); + cmd.select(); + } + }); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('plainpaste', function(K) { + var self = this, name = 'plainpaste'; + self.clickToolbar(name, function() { + var lang = self.lang(name + '.'), + html = '
      ' + + '
      ' + lang.comment + '
      ' + + '' + + '
      ', + dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var html = textarea.val(); + html = K.escape(html); + html = html.replace(/ {2}/g, '  '); + if (self.newlineTag == 'p') { + html = html.replace(/^/, '

      ').replace(/$/, '

      ').replace(/\n/g, '

      '); + } else { + html = html.replace(/\n/g, '
      $&'); + } + self.insertHtml(html).hideDialog().focus(); + } + } + }), + textarea = K('textarea', dialog.div); + textarea[0].focus(); + }); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('preview', function(K) { + var self = this, name = 'preview', undefined; + self.clickToolbar(name, function() { + var lang = self.lang(name + '.'), + html = '

      ' + + '' + + '
      ', + dialog = self.createDialog({ + name : name, + width : 750, + title : self.lang(name), + body : html + }), + iframe = K('iframe', dialog.div), + doc = K.iframeDoc(iframe); + doc.open(); + doc.write(self.fullHtml()); + doc.close(); + K(doc.body).css('background-color', '#FFF'); + iframe[0].contentWindow.focus(); + }); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('quickformat', function(K) { + var self = this, name = 'quickformat', + blockMap = K.toMap('blockquote,center,div,h1,h2,h3,h4,h5,h6,p'); + function getFirstChild(knode) { + var child = knode.first(); + while (child && child.first()) { + child = child.first(); + } + return child; + } + self.clickToolbar(name, function() { + self.focus(); + var doc = self.edit.doc, + range = self.cmd.range, + child = K(doc.body).first(), next, + nodeList = [], subList = [], + bookmark = range.createBookmark(true); + while(child) { + next = child.next(); + var firstChild = getFirstChild(child); + if (!firstChild || firstChild.name != 'img') { + if (blockMap[child.name]) { + child.html(child.html().replace(/^(\s| | )+/ig, '')); + child.css('text-indent', '2em'); + } else { + subList.push(child); + } + if (!next || (blockMap[next.name] || blockMap[child.name] && !blockMap[next.name])) { + if (subList.length > 0) { + nodeList.push(subList); + } + subList = []; + } + } + child = next; + } + K.each(nodeList, function(i, subList) { + var wrapper = K('

      ', doc); + subList[0].before(wrapper); + K.each(subList, function(i, knode) { + wrapper.append(knode); + }); + }); + range.moveToBookmark(bookmark); + self.addBookmark(); + }); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('table', function(K) { + var self = this, name = 'table', lang = self.lang(name + '.'), zeroborder = 'ke-zeroborder'; + function _setColor(box, color) { + color = color.toUpperCase(); + box.css('background-color', color); + box.css('color', color === '#000000' ? '#FFFFFF' : '#000000'); + box.html(color); + } + var pickerList = []; + function _initColorPicker(dialogDiv, colorBox) { + colorBox.bind('click,mousedown', function(e){ + e.stopPropagation(); + }); + function removePicker() { + K.each(pickerList, function() { + this.remove(); + }); + pickerList = []; + K(document).unbind('click,mousedown', removePicker); + dialogDiv.unbind('click,mousedown', removePicker); + } + colorBox.click(function(e) { + removePicker(); + var box = K(this), + pos = box.pos(); + var picker = K.colorpicker({ + x : pos.x, + y : pos.y + box.height(), + z : 811214, + selectedColor : K(this).html(), + colors : self.colorTable, + noColor : self.lang('noColor'), + shadowMode : self.shadowMode, + click : function(color) { + _setColor(box, color); + removePicker(); + } + }); + pickerList.push(picker); + K(document).bind('click,mousedown', removePicker); + dialogDiv.bind('click,mousedown', removePicker); + }); + } + function _getCellIndex(table, row, cell) { + var rowSpanCount = 0; + for (var i = 0, len = row.cells.length; i < len; i++) { + if (row.cells[i] == cell) { + break; + } + rowSpanCount += row.cells[i].rowSpan - 1; + } + return cell.cellIndex - rowSpanCount; + } + self.plugin.table = { + prop : function(isInsert) { + var html = [ + '
      ', + '
      ', + '', + lang.rows + '   ', + lang.cols + ' ', + '
      ', + '
      ', + '', + lang.width + '   ', + '   ', + lang.height + '   ', + '', + '
      ', + '
      ', + '', + lang.padding + '   ', + lang.spacing + ' ', + '
      ', + '
      ', + '', + '', + '
      ', + '
      ', + '', + lang.borderWidth + '   ', + lang.borderColor + ' ', + '
      ', + '
      ', + '', + '', + '
      ', + '
      ' + ].join(''); + var bookmark = self.cmd.range.createBookmark(); + var dialog = self.createDialog({ + name : name, + width : 500, + title : self.lang(name), + body : html, + beforeRemove : function() { + colorBox.unbind(); + }, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var rows = rowsBox.val(), + cols = colsBox.val(), + width = widthBox.val(), + height = heightBox.val(), + widthType = widthTypeBox.val(), + heightType = heightTypeBox.val(), + padding = paddingBox.val(), + spacing = spacingBox.val(), + align = alignBox.val(), + border = borderBox.val(), + borderColor = K(colorBox[0]).html() || '', + bgColor = K(colorBox[1]).html() || ''; + if (rows == 0 || !/^\d+$/.test(rows)) { + alert(self.lang('invalidRows')); + rowsBox[0].focus(); + return; + } + if (cols == 0 || !/^\d+$/.test(cols)) { + alert(self.lang('invalidRows')); + colsBox[0].focus(); + return; + } + if (!/^\d*$/.test(width)) { + alert(self.lang('invalidWidth')); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + alert(self.lang('invalidHeight')); + heightBox[0].focus(); + return; + } + if (!/^\d*$/.test(padding)) { + alert(self.lang('invalidPadding')); + paddingBox[0].focus(); + return; + } + if (!/^\d*$/.test(spacing)) { + alert(self.lang('invalidSpacing')); + spacingBox[0].focus(); + return; + } + if (!/^\d*$/.test(border)) { + alert(self.lang('invalidBorder')); + borderBox[0].focus(); + return; + } + if (table) { + if (width !== '') { + table.width(width + widthType); + } else { + table.css('width', ''); + } + if (table[0].width !== undefined) { + table.removeAttr('width'); + } + if (height !== '') { + table.height(height + heightType); + } else { + table.css('height', ''); + } + if (table[0].height !== undefined) { + table.removeAttr('height'); + } + table.css('background-color', bgColor); + if (table[0].bgColor !== undefined) { + table.removeAttr('bgColor'); + } + if (padding !== '') { + table[0].cellPadding = padding; + } else { + table.removeAttr('cellPadding'); + } + if (spacing !== '') { + table[0].cellSpacing = spacing; + } else { + table.removeAttr('cellSpacing'); + } + if (align !== '') { + table[0].align = align; + } else { + table.removeAttr('align'); + } + if (border !== '') { + table.attr('border', border); + } else { + table.removeAttr('border'); + } + if (border === '' || border === '0') { + table.addClass(zeroborder); + } else { + table.removeClass(zeroborder); + } + if (borderColor !== '') { + table.attr('borderColor', borderColor); + } else { + table.removeAttr('borderColor'); + } + self.hideDialog().focus(); + self.cmd.range.moveToBookmark(bookmark); + self.cmd.select(); + self.addBookmark(); + return; + } + var style = ''; + if (width !== '') { + style += 'width:' + width + widthType + ';'; + } + if (height !== '') { + style += 'height:' + height + heightType + ';'; + } + if (bgColor !== '') { + style += 'background-color:' + bgColor + ';'; + } + var html = '') + ''; + } + html += ''; + } + html += ''; + if (!K.IE) { + html += '
      '; + } + self.insertHtml(html); + self.select().hideDialog().focus(); + self.addBookmark(); + } + } + }), + div = dialog.div, + rowsBox = K('[name="rows"]', div).val(3), + colsBox = K('[name="cols"]', div).val(2), + widthBox = K('[name="width"]', div).val(100), + heightBox = K('[name="height"]', div), + widthTypeBox = K('[name="widthType"]', div), + heightTypeBox = K('[name="heightType"]', div), + paddingBox = K('[name="padding"]', div).val(2), + spacingBox = K('[name="spacing"]', div).val(0), + alignBox = K('[name="align"]', div), + borderBox = K('[name="border"]', div).val(1), + colorBox = K('.ke-input-color', div); + _initColorPicker(div, colorBox.eq(0)); + _initColorPicker(div, colorBox.eq(1)); + _setColor(colorBox.eq(0), '#000000'); + _setColor(colorBox.eq(1), ''); + rowsBox[0].focus(); + rowsBox[0].select(); + var table; + if (isInsert) { + return; + } + table = self.plugin.getSelectedTable(); + if (table) { + rowsBox.val(table[0].rows.length); + colsBox.val(table[0].rows.length > 0 ? table[0].rows[0].cells.length : 0); + rowsBox.attr('disabled', true); + colsBox.attr('disabled', true); + var match, + tableWidth = table[0].style.width || table[0].width, + tableHeight = table[0].style.height || table[0].height; + if (tableWidth !== undefined && (match = /^(\d+)((?:px|%)*)$/.exec(tableWidth))) { + widthBox.val(match[1]); + widthTypeBox.val(match[2]); + } else { + widthBox.val(''); + } + if (tableHeight !== undefined && (match = /^(\d+)((?:px|%)*)$/.exec(tableHeight))) { + heightBox.val(match[1]); + heightTypeBox.val(match[2]); + } + paddingBox.val(table[0].cellPadding || ''); + spacingBox.val(table[0].cellSpacing || ''); + alignBox.val(table[0].align || ''); + borderBox.val(table[0].border === undefined ? '' : table[0].border); + _setColor(colorBox.eq(0), K.toHex(table.attr('borderColor') || '')); + _setColor(colorBox.eq(1), K.toHex(table[0].style.backgroundColor || table[0].bgColor || '')); + widthBox[0].focus(); + widthBox[0].select(); + } + }, + cellprop : function() { + var html = [ + '
      ', + '
      ', + '', + lang.width + '   ', + '   ', + lang.height + '   ', + '', + '
      ', + '
      ', + '', + lang.textAlign + ' ', + lang.verticalAlign + ' ', + '
      ', + '
      ', + '', + lang.borderWidth + '   ', + lang.borderColor + ' ', + '
      ', + '
      ', + '', + '', + '
      ', + '
      ' + ].join(''); + var bookmark = self.cmd.range.createBookmark(); + var dialog = self.createDialog({ + name : name, + width : 500, + title : self.lang('tablecell'), + body : html, + beforeRemove : function() { + colorBox.unbind(); + }, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var width = widthBox.val(), + height = heightBox.val(), + widthType = widthTypeBox.val(), + heightType = heightTypeBox.val(), + padding = paddingBox.val(), + spacing = spacingBox.val(), + textAlign = textAlignBox.val(), + verticalAlign = verticalAlignBox.val(), + border = borderBox.val(), + borderColor = K(colorBox[0]).html() || '', + bgColor = K(colorBox[1]).html() || ''; + if (!/^\d*$/.test(width)) { + alert(self.lang('invalidWidth')); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + alert(self.lang('invalidHeight')); + heightBox[0].focus(); + return; + } + if (!/^\d*$/.test(border)) { + alert(self.lang('invalidBorder')); + borderBox[0].focus(); + return; + } + cell.css({ + width : width !== '' ? (width + widthType) : '', + height : height !== '' ? (height + heightType) : '', + 'background-color' : bgColor, + 'text-align' : textAlign, + 'vertical-align' : verticalAlign, + 'border-width' : border, + 'border-style' : border !== '' ? 'solid' : '', + 'border-color' : borderColor + }); + self.hideDialog().focus(); + self.cmd.range.moveToBookmark(bookmark); + self.cmd.select(); + self.addBookmark(); + } + } + }), + div = dialog.div, + widthBox = K('[name="width"]', div).val(100), + heightBox = K('[name="height"]', div), + widthTypeBox = K('[name="widthType"]', div), + heightTypeBox = K('[name="heightType"]', div), + paddingBox = K('[name="padding"]', div).val(2), + spacingBox = K('[name="spacing"]', div).val(0), + textAlignBox = K('[name="textAlign"]', div), + verticalAlignBox = K('[name="verticalAlign"]', div), + borderBox = K('[name="border"]', div).val(1), + colorBox = K('.ke-input-color', div); + _initColorPicker(div, colorBox.eq(0)); + _initColorPicker(div, colorBox.eq(1)); + _setColor(colorBox.eq(0), '#000000'); + _setColor(colorBox.eq(1), ''); + widthBox[0].focus(); + widthBox[0].select(); + var cell = self.plugin.getSelectedCell(); + var match, + cellWidth = cell[0].style.width || cell[0].width || '', + cellHeight = cell[0].style.height || cell[0].height || ''; + if ((match = /^(\d+)((?:px|%)*)$/.exec(cellWidth))) { + widthBox.val(match[1]); + widthTypeBox.val(match[2]); + } else { + widthBox.val(''); + } + if ((match = /^(\d+)((?:px|%)*)$/.exec(cellHeight))) { + heightBox.val(match[1]); + heightTypeBox.val(match[2]); + } + textAlignBox.val(cell[0].style.textAlign || ''); + verticalAlignBox.val(cell[0].style.verticalAlign || ''); + var border = cell[0].style.borderWidth || ''; + if (border) { + border = parseInt(border); + } + borderBox.val(border); + _setColor(colorBox.eq(0), K.toHex(cell[0].style.borderColor || '')); + _setColor(colorBox.eq(1), K.toHex(cell[0].style.backgroundColor || '')); + widthBox[0].focus(); + widthBox[0].select(); + }, + insert : function() { + this.prop(true); + }, + 'delete' : function() { + var table = self.plugin.getSelectedTable(); + self.cmd.range.setStartBefore(table[0]).collapse(true); + self.cmd.select(); + table.remove(); + self.addBookmark(); + }, + colinsert : function(offset) { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + index = cell.cellIndex + offset; + index += table.rows[0].cells.length - row.cells.length; + for (var i = 0, len = table.rows.length; i < len; i++) { + var newRow = table.rows[i], + newCell = newRow.insertCell(index); + newCell.innerHTML = K.IE ? '' : '
      '; + index = _getCellIndex(table, newRow, newCell); + } + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + colinsertleft : function() { + this.colinsert(0); + }, + colinsertright : function() { + this.colinsert(1); + }, + rowinsert : function(offset) { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0]; + var rowIndex = row.rowIndex; + if (offset === 1) { + rowIndex = row.rowIndex + (cell.rowSpan - 1) + offset; + } + var newRow = table.insertRow(rowIndex); + for (var i = 0, len = row.cells.length; i < len; i++) { + if (row.cells[i].rowSpan > 1) { + len -= row.cells[i].rowSpan - 1; + } + var newCell = newRow.insertCell(i); + if (offset === 1 && row.cells[i].colSpan > 1) { + newCell.colSpan = row.cells[i].colSpan; + } + newCell.innerHTML = K.IE ? '' : '
      '; + } + for (var j = rowIndex; j >= 0; j--) { + var cells = table.rows[j].cells; + if (cells.length > i) { + for (var k = cell.cellIndex; k >= 0; k--) { + if (cells[k].rowSpan > 1) { + cells[k].rowSpan += 1; + } + } + break; + } + } + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + rowinsertabove : function() { + this.rowinsert(0); + }, + rowinsertbelow : function() { + this.rowinsert(1); + }, + rowmerge : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + rowIndex = row.rowIndex, + nextRowIndex = rowIndex + cell.rowSpan, + nextRow = table.rows[nextRowIndex]; + if (table.rows.length <= nextRowIndex) { + return; + } + var cellIndex = cell.cellIndex; + if (nextRow.cells.length <= cellIndex) { + return; + } + var nextCell = nextRow.cells[cellIndex]; + if (cell.colSpan !== nextCell.colSpan) { + return; + } + cell.rowSpan += nextCell.rowSpan; + nextRow.deleteCell(cellIndex); + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + colmerge : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + rowIndex = row.rowIndex, + cellIndex = cell.cellIndex, + nextCellIndex = cellIndex + 1; + if (row.cells.length <= nextCellIndex) { + return; + } + var nextCell = row.cells[nextCellIndex]; + if (cell.rowSpan !== nextCell.rowSpan) { + return; + } + cell.colSpan += nextCell.colSpan; + row.deleteCell(nextCellIndex); + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + rowsplit : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + rowIndex = row.rowIndex; + if (cell.rowSpan === 1) { + return; + } + var cellIndex = _getCellIndex(table, row, cell); + for (var i = 1, len = cell.rowSpan; i < len; i++) { + var newRow = table.rows[rowIndex + i], + newCell = newRow.insertCell(cellIndex); + if (cell.colSpan > 1) { + newCell.colSpan = cell.colSpan; + } + newCell.innerHTML = K.IE ? '' : '
      '; + cellIndex = _getCellIndex(table, newRow, newCell); + } + K(cell).removeAttr('rowSpan'); + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + colsplit : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + cellIndex = cell.cellIndex; + if (cell.colSpan === 1) { + return; + } + for (var i = 1, len = cell.colSpan; i < len; i++) { + var newCell = row.insertCell(cellIndex + i); + if (cell.rowSpan > 1) { + newCell.rowSpan = cell.rowSpan; + } + newCell.innerHTML = K.IE ? '' : '
      '; + } + K(cell).removeAttr('colSpan'); + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + coldelete : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + index = cell.cellIndex; + for (var i = 0, len = table.rows.length; i < len; i++) { + var newRow = table.rows[i], + newCell = newRow.cells[index]; + if (newCell.colSpan > 1) { + newCell.colSpan -= 1; + if (newCell.colSpan === 1) { + K(newCell).removeAttr('colSpan'); + } + } else { + newRow.deleteCell(index); + } + if (newCell.rowSpan > 1) { + i += newCell.rowSpan - 1; + } + } + if (row.cells.length === 0) { + self.cmd.range.setStartBefore(table).collapse(true); + self.cmd.select(); + K(table).remove(); + } else { + self.cmd.selection(true); + } + self.addBookmark(); + }, + rowdelete : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + rowIndex = row.rowIndex; + for (var i = cell.rowSpan - 1; i >= 0; i--) { + table.deleteRow(rowIndex + i); + } + if (table.rows.length === 0) { + self.cmd.range.setStartBefore(table).collapse(true); + self.cmd.select(); + K(table).remove(); + } else { + self.cmd.selection(true); + } + self.addBookmark(); + } + }; + self.clickToolbar(name, self.plugin.table.prop); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('template', function(K) { + var self = this, name = 'template', lang = self.lang(name + '.'), + htmlPath = self.pluginsPath + name + '/html/'; + function getFilePath(fileName) { + return htmlPath + fileName + '?ver=' + encodeURIComponent(K.DEBUG ? K.TIME : K.VERSION); + } + self.clickToolbar(name, function() { + var lang = self.lang(name + '.'), + arr = ['
      ', + '
      ', + '
      ', + lang. selectTemplate + '
      ', + '
      ', + ' ', + '
      ', + '
      ', + '
      ', + '', + '
      '].join(''); + var dialog = self.createDialog({ + name : name, + width : 500, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var doc = K.iframeDoc(iframe); + self[checkbox[0].checked ? 'html' : 'insertHtml'](doc.body.innerHTML).hideDialog().focus(); + } + } + }); + var selectBox = K('select', dialog.div), + checkbox = K('[name="replaceFlag"]', dialog.div), + iframe = K('iframe', dialog.div); + checkbox[0].checked = true; + iframe.attr('src', getFilePath(selectBox.val())); + selectBox.change(function() { + iframe.attr('src', getFilePath(this.value)); + }); + }); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('wordpaste', function(K) { + var self = this, name = 'wordpaste'; + self.clickToolbar(name, function() { + var lang = self.lang(name + '.'), + html = '
      ' + + '
      ' + lang.comment + '
      ' + + '' + + '
      ', + dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var str = doc.body.innerHTML; + str = K.clearMsWord(str, self.filterMode ? self.htmlTags : K.options.htmlTags); + self.insertHtml(str).hideDialog().focus(); + } + } + }), + div = dialog.div, + iframe = K('iframe', div), + doc = K.iframeDoc(iframe); + if (!K.IE) { + doc.designMode = 'on'; + } + doc.open(); + doc.write('WordPaste'); + doc.write(''); + if (!K.IE) { + doc.write('
      '); + } + doc.write(''); + doc.close(); + if (K.IE) { + doc.body.contentEditable = 'true'; + } + iframe[0].contentWindow.focus(); + }); +}); + + +KindEditor.plugin('fixtoolbar', function (K) { + var self = this; + if (!self.fixToolBar) { + return; + } + function init() { + var toolbar = K('.ke-toolbar'); + var originY = toolbar.pos().y; + K(window).bind('scroll', function () { + if (toolbar.css('position') == 'fixed') { + if(document.body.scrollTop - originY < 0){ + toolbar.css('position', 'static'); + toolbar.css('top', 'auto'); + } + } else { + if (toolbar.pos().y - document.body.scrollTop < 0) { + toolbar.css('position', 'fixed'); + toolbar.css('top', 0); + } + } + }); + } + if (self.isCreated) { + init(); + } else { + self.afterCreate(init); + } +}); diff --git a/php/kindeditor_demo/kindeditor/lang/ar.js b/php/kindeditor_demo/kindeditor/lang/ar.js new file mode 100755 index 0000000..99dcfd6 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lang/ar.js @@ -0,0 +1,242 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +* Arabic Translation By daif alotaibi (http://daif.net/) +*******************************************************************************/ + +KindEditor.lang({ + source : 'عرض المصدر', + preview : 'معاينة الصفحة', + undo : 'تراجع(Ctrl+Z)', + redo : 'إعادة التراجع(Ctrl+Y)', + cut : 'قص(Ctrl+X)', + copy : 'نسخ(Ctrl+C)', + paste : 'لصق(Ctrl+V)', + plainpaste : 'لصق كنص عادي', + wordpaste : 'لصق من مايكروسفت ورد', + selectall : 'تحديد الكل', + justifyleft : 'محاذاه لليسار', + justifycenter : 'محاذاه للوسط', + justifyright : 'محاذاه لليمين', + justifyfull : 'محاذاه تلقائية', + insertorderedlist : 'قائمة مرقمه', + insertunorderedlist : 'قائمة نقطية', + indent : 'إزاحه النص', + outdent : 'إلغاء الازاحة', + subscript : 'أسفل النص', + superscript : 'أعلى النص', + formatblock : 'Paragraph format', + fontname : 'نوع الخط', + fontsize : 'حجم الخط', + forecolor : 'لون النص', + hilitecolor : 'لون خلفية النص', + bold : 'عريض(Ctrl+B)', + italic : 'مائل(Ctrl+I)', + underline : 'خط تحت النص(Ctrl+U)', + strikethrough : 'خط على النص', + removeformat : 'إزالة التنسيق', + image : 'إدراج صورة', + multiimage : 'Multi image', + flash : 'إدراج فلاش', + media : 'إدراج وسائط متعددة', + table : 'إدراج جدول', + tablecell : 'خلية', + hr : 'إدراج خط أفقي', + emoticons : 'إدراج وجه ضاحك', + link : 'رابط', + unlink : 'إزالة الرابط', + fullscreen : 'محرر ملئ الشاشة', + about : 'حول', + print : 'طباعة', + filemanager : 'مدير الملفات', + code : 'إدراج نص برمجي', + map : 'خرائط قووقل', + baidumap : 'خرائط قووقل', + lineheight : 'إرتفاع السطر', + clearhtml : 'مسح كود HTML', + pagebreak : 'إدراج فاصل صفحات', + quickformat : 'تنسيق سريع', + insertfile : 'إدراج ملف', + template : 'إدراج قالب', + anchor : 'رابط', + yes : 'موافق', + no : 'إلغاء', + close : 'إغلاق', + editImage : 'خصائص الصورة', + deleteImage : 'حذفالصورة', + editFlash : 'خصائص الفلاش', + deleteFlash : 'حذف الفلاش', + editMedia : 'خصائص الوسائط', + deleteMedia : 'حذف الوسائط', + editLink : 'خصائص الرابط', + deleteLink : 'إزالة الرابط', + editAnchor : 'Anchor properties', + deleteAnchor : 'Delete Anchor', + tableprop : 'خصائص الجدول', + tablecellprop : 'خصائص الخلية', + tableinsert : 'إدراج جدول', + tabledelete : 'حذف جدول', + tablecolinsertleft : 'إدراج عمود لليسار', + tablecolinsertright : 'إدراج عمود لليسار', + tablerowinsertabove : 'إدراج صف للأعلى', + tablerowinsertbelow : 'إدراج صف للأسفل', + tablerowmerge : 'دمج للأسفل', + tablecolmerge : 'دمج لليمين', + tablerowsplit : 'تقسم الصف', + tablecolsplit : 'تقسيم العمود', + tablecoldelete : 'حذف العمود', + tablerowdelete : 'حذف الصف', + noColor : 'إفتراضي', + pleaseSelectFile : 'Please select file.', + invalidImg : "الرجاء إدخال رابط صحيح.\nالملفات المسموح بها: jpg,gif,bmp,png", + invalidMedia : "الرجاء إدخال رابط صحيح.\nالملفات المسموح بها: swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb", + invalidWidth : "العرض يجب أن يكون رقم.", + invalidHeight : "الإرتفاع يجب أن يكون رقم.", + invalidBorder : "عرض الحد يجب أن يكون رقم.", + invalidUrl : "الرجاء إدخال رابط حيح.", + invalidRows : 'صفوف غير صحيح.', + invalidCols : 'أعمدة غير صحيحة.', + invalidPadding : 'The padding must be number.', + invalidSpacing : 'The spacing must be number.', + invalidJson : 'Invalid JSON string.', + uploadSuccess : 'تم رفع الملف بنجاح.', + cutError : 'حاليا غير مدعومة من المتصفح, إستخدم إختصار لوحة المفاتيح (Ctrl+X).', + copyError : 'حاليا غير مدعومة من المتصفح, إستخدم إختصار لوحة المفاتيح (Ctrl+C).', + pasteError : 'حاليا غير مدعومة من المتصفح, إستخدم إختصار لوحة المفاتيح (Ctrl+V).', + ajaxLoading : 'Loading ...', + uploadLoading : 'Uploading ...', + uploadError : 'Upload Error', + 'plainpaste.comment' : 'إستخدم إختصار لوحة المفاتيح (Ctrl+V) للصق داخل النافذة.', + 'wordpaste.comment' : 'إستخدم إختصار لوحة المفاتيح (Ctrl+V) للصق داخل النافذة.', + 'code.pleaseInput' : 'Please input code.', + 'link.url' : 'الرابط', + 'link.linkType' : 'الهدف', + 'link.newWindow' : 'نافذة جديدة', + 'link.selfWindow' : 'نفس النافذة', + 'flash.url' : 'الرابط', + 'flash.width' : 'العرض', + 'flash.height' : 'الإرتفاع', + 'flash.upload' : 'رفع', + 'flash.viewServer' : 'أستعراض', + 'media.url' : 'الرابط', + 'media.width' : 'العرض', + 'media.height' : 'الإرتفاع', + 'media.autostart' : 'تشغيل تلقائي', + 'media.upload' : 'رفع', + 'media.viewServer' : 'أستعراض', + 'image.remoteImage' : 'إدراج الرابط', + 'image.localImage' : 'رفع', + 'image.remoteUrl' : 'الرابط', + 'image.localUrl' : 'الملف', + 'image.size' : 'الحجم', + 'image.width' : 'العرض', + 'image.height' : 'الإرتفاع', + 'image.resetSize' : 'إستعادة الأبعاد', + 'image.align' : 'محاذاة', + 'image.defaultAlign' : 'الإفتراضي', + 'image.leftAlign' : 'اليسار', + 'image.rightAlign' : 'اليمين', + 'image.imgTitle' : 'العنوان', + 'image.upload' : 'أستعراض', + 'image.viewServer' : 'أستعراض', + 'multiimage.uploadDesc' : 'Allows users to upload <%=uploadLimit%> images, single image size not exceeding <%=sizeLimit%>', + 'multiimage.startUpload' : 'Start upload', + 'multiimage.clearAll' : 'Clear all', + 'multiimage.insertAll' : 'Insert all', + 'multiimage.queueLimitExceeded' : 'Queue limit exceeded.', + 'multiimage.fileExceedsSizeLimit' : 'File exceeds size limit.', + 'multiimage.zeroByteFile' : 'Zero byte file.', + 'multiimage.invalidFiletype' : 'Invalid file type.', + 'multiimage.unknownError' : 'Unknown upload error.', + 'multiimage.pending' : 'Pending ...', + 'multiimage.uploadError' : 'Upload error', + 'filemanager.emptyFolder' : 'فارغ', + 'filemanager.moveup' : 'المجلد الأب', + 'filemanager.viewType' : 'العرض: ', + 'filemanager.viewImage' : 'مصغرات', + 'filemanager.listImage' : 'قائمة', + 'filemanager.orderType' : 'الترتيب: ', + 'filemanager.fileName' : 'بالإسم', + 'filemanager.fileSize' : 'بالحجم', + 'filemanager.fileType' : 'بالنوع', + 'insertfile.url' : 'الرابط', + 'insertfile.title' : 'العنوان', + 'insertfile.upload' : 'رفع', + 'insertfile.viewServer' : 'أستعراض', + 'table.cells' : 'خلايا', + 'table.rows' : 'صفوف', + 'table.cols' : 'أعمدة', + 'table.size' : 'الأبعاد', + 'table.width' : 'العرض', + 'table.height' : 'الإرتفاع', + 'table.percent' : '%', + 'table.px' : 'px', + 'table.space' : 'الخارج', + 'table.padding' : 'الداخل', + 'table.spacing' : 'الفراغات', + 'table.align' : 'محاذاه', + 'table.textAlign' : 'افقى', + 'table.verticalAlign' : 'رأسي', + 'table.alignDefault' : 'إفتراضي', + 'table.alignLeft' : 'يسار', + 'table.alignCenter' : 'وسط', + 'table.alignRight' : 'يمين', + 'table.alignTop' : 'أعلى', + 'table.alignMiddle' : 'منتصف', + 'table.alignBottom' : 'أسفل', + 'table.alignBaseline' : 'Baseline', + 'table.border' : 'الحدود', + 'table.borderWidth' : 'العرض', + 'table.borderColor' : 'اللون', + 'table.backgroundColor' : 'الخلفية', + 'map.address' : 'العنوان: ', + 'map.search' : 'بحث', + 'baidumap.address' : 'العنوان: ', + 'baidumap.search' : 'بحث', + 'baidumap.insertDynamicMap' : 'Dynamic Map', + 'anchor.name' : 'إسم الرابط', + 'formatblock.formatBlock' : { + h1 : 'عنوان 1', + h2 : 'عنوان 2', + h3 : 'عنوان 3', + h4 : 'عنوان 4', + p : 'عادي' + }, + 'fontname.fontName' : { + 'Arial' : 'Arial', + 'Arial Black' : 'Arial Black', + 'Comic Sans MS' : 'Comic Sans MS', + 'Courier New' : 'Courier New', + 'Garamond' : 'Garamond', + 'Georgia' : 'Georgia', + 'Tahoma' : 'Tahoma', + 'Times New Roman' : 'Times New Roman', + 'Trebuchet MS' : 'Trebuchet MS', + 'Verdana' : 'Verdana' + }, + 'lineheight.lineHeight' : [ + {'1' : 'إرتفاع السطر 1'}, + {'1.5' : 'إرتفاع السطر 1.5'}, + {'2' : 'إرتفاع السطر 2'}, + {'2.5' : 'إرتفاع السطر 2.5'}, + {'3' : 'إرتفاع السطر 3'} + ], + 'template.selectTemplate' : 'قالب', + 'template.replaceContent' : 'إستبدال المحتوى الحالي', + 'template.fileList' : { + '1.html' : 'صورة ونص', + '2.html' : 'جدول', + '3.html' : 'قائمة' + } +}, 'ar'); + +KindEditor.each(KindEditor.options.items, function(i, name) { + if (name == 'baidumap') { + KindEditor.options.items[i] = 'map'; + } +}); +KindEditor.options.langType = 'ar'; \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/lang/en.js b/php/kindeditor_demo/kindeditor/lang/en.js new file mode 100755 index 0000000..909bf49 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lang/en.js @@ -0,0 +1,241 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.lang({ + source : 'Source', + preview : 'Preview', + undo : 'Undo(Ctrl+Z)', + redo : 'Redo(Ctrl+Y)', + cut : 'Cut(Ctrl+X)', + copy : 'Copy(Ctrl+C)', + paste : 'Paste(Ctrl+V)', + plainpaste : 'Paste as plain text', + wordpaste : 'Paste from Word', + selectall : 'Select all', + justifyleft : 'Align left', + justifycenter : 'Align center', + justifyright : 'Align right', + justifyfull : 'Align full', + insertorderedlist : 'Ordered list', + insertunorderedlist : 'Unordered list', + indent : 'Increase indent', + outdent : 'Decrease indent', + subscript : 'Subscript', + superscript : 'Superscript', + formatblock : 'Paragraph format', + fontname : 'Font family', + fontsize : 'Font size', + forecolor : 'Text color', + hilitecolor : 'Highlight color', + bold : 'Bold(Ctrl+B)', + italic : 'Italic(Ctrl+I)', + underline : 'Underline(Ctrl+U)', + strikethrough : 'Strikethrough', + removeformat : 'Remove format', + image : 'Image', + multiimage : 'Multi image', + flash : 'Flash', + media : 'Embeded media', + table : 'Table', + tablecell : 'Cell', + hr : 'Insert horizontal line', + emoticons : 'Insert emoticon', + link : 'Link', + unlink : 'Unlink', + fullscreen : 'Toggle fullscreen mode', + about : 'About', + print : 'Print', + filemanager : 'File Manager', + code : 'Insert code', + map : 'Google Maps', + baidumap : 'Baidu Maps', + lineheight : 'Line height', + clearhtml : 'Clear HTML code', + pagebreak : 'Insert Page Break', + quickformat : 'Quick Format', + insertfile : 'Insert file', + template : 'Insert Template', + anchor : 'Anchor', + yes : 'OK', + no : 'Cancel', + close : 'Close', + editImage : 'Image properties', + deleteImage : 'Delete image', + editFlash : 'Flash properties', + deleteFlash : 'Delete flash', + editMedia : 'Media properties', + deleteMedia : 'Delete media', + editLink : 'Link properties', + deleteLink : 'Unlink', + editAnchor : 'Anchor properties', + deleteAnchor : 'Delete Anchor', + tableprop : 'Table properties', + tablecellprop : 'Cell properties', + tableinsert : 'Insert table', + tabledelete : 'Delete table', + tablecolinsertleft : 'Insert column left', + tablecolinsertright : 'Insert column right', + tablerowinsertabove : 'Insert row above', + tablerowinsertbelow : 'Insert row below', + tablerowmerge : 'Merge down', + tablecolmerge : 'Merge right', + tablerowsplit : 'Split row', + tablecolsplit : 'Split column', + tablecoldelete : 'Delete column', + tablerowdelete : 'Delete row', + noColor : 'Default', + pleaseSelectFile : 'Please select file.', + invalidImg : "Please type valid URL.\nAllowed file extension: jpg,gif,bmp,png", + invalidMedia : "Please type valid URL.\nAllowed file extension: swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb", + invalidWidth : "The width must be number.", + invalidHeight : "The height must be number.", + invalidBorder : "The border must be number.", + invalidUrl : "Please type valid URL.", + invalidRows : 'Invalid rows.', + invalidCols : 'Invalid columns.', + invalidPadding : 'The padding must be number.', + invalidSpacing : 'The spacing must be number.', + invalidJson : 'Invalid JSON string.', + uploadSuccess : 'Upload success.', + cutError : 'Currently not supported by your browser, use keyboard shortcut(Ctrl+X) instead.', + copyError : 'Currently not supported by your browser, use keyboard shortcut(Ctrl+C) instead.', + pasteError : 'Currently not supported by your browser, use keyboard shortcut(Ctrl+V) instead.', + ajaxLoading : 'Loading ...', + uploadLoading : 'Uploading ...', + uploadError : 'Upload Error', + 'plainpaste.comment' : 'Use keyboard shortcut(Ctrl+V) to paste the text into the window.', + 'wordpaste.comment' : 'Use keyboard shortcut(Ctrl+V) to paste the text into the window.', + 'code.pleaseInput' : 'Please input code.', + 'link.url' : 'URL', + 'link.linkType' : 'Target', + 'link.newWindow' : 'New window', + 'link.selfWindow' : 'Same window', + 'flash.url' : 'URL', + 'flash.width' : 'Width', + 'flash.height' : 'Height', + 'flash.upload' : 'Upload', + 'flash.viewServer' : 'Browse', + 'media.url' : 'URL', + 'media.width' : 'Width', + 'media.height' : 'Height', + 'media.autostart' : 'Auto start', + 'media.upload' : 'Upload', + 'media.viewServer' : 'Browse', + 'image.remoteImage' : 'Insert URL', + 'image.localImage' : 'Upload', + 'image.remoteUrl' : 'URL', + 'image.localUrl' : 'File', + 'image.size' : 'Size', + 'image.width' : 'Width', + 'image.height' : 'Height', + 'image.resetSize' : 'Reset dimensions', + 'image.align' : 'Align', + 'image.defaultAlign' : 'Default', + 'image.leftAlign' : 'Left', + 'image.rightAlign' : 'Right', + 'image.imgTitle' : 'Title', + 'image.upload' : 'Browse', + 'image.viewServer' : 'Browse', + 'multiimage.uploadDesc' : 'Allows users to upload <%=uploadLimit%> images, single image size not exceeding <%=sizeLimit%>', + 'multiimage.startUpload' : 'Start upload', + 'multiimage.clearAll' : 'Clear all', + 'multiimage.insertAll' : 'Insert all', + 'multiimage.queueLimitExceeded' : 'Queue limit exceeded.', + 'multiimage.fileExceedsSizeLimit' : 'File exceeds size limit.', + 'multiimage.zeroByteFile' : 'Zero byte file.', + 'multiimage.invalidFiletype' : 'Invalid file type.', + 'multiimage.unknownError' : 'Unknown upload error.', + 'multiimage.pending' : 'Pending ...', + 'multiimage.uploadError' : 'Upload error', + 'filemanager.emptyFolder' : 'Blank', + 'filemanager.moveup' : 'Parent folder', + 'filemanager.viewType' : 'Display: ', + 'filemanager.viewImage' : 'Thumbnails', + 'filemanager.listImage' : 'List', + 'filemanager.orderType' : 'Sorting: ', + 'filemanager.fileName' : 'By name', + 'filemanager.fileSize' : 'By size', + 'filemanager.fileType' : 'By type', + 'insertfile.url' : 'URL', + 'insertfile.title' : 'Title', + 'insertfile.upload' : 'Upload', + 'insertfile.viewServer' : 'Browse', + 'table.cells' : 'Cells', + 'table.rows' : 'Rows', + 'table.cols' : 'Columns', + 'table.size' : 'Dimensions', + 'table.width' : 'Width', + 'table.height' : 'Height', + 'table.percent' : '%', + 'table.px' : 'px', + 'table.space' : 'Space', + 'table.padding' : 'Padding', + 'table.spacing' : 'Spacing', + 'table.align' : 'Align', + 'table.textAlign' : 'Horizontal', + 'table.verticalAlign' : 'Vertical', + 'table.alignDefault' : 'Default', + 'table.alignLeft' : 'Left', + 'table.alignCenter' : 'Center', + 'table.alignRight' : 'Right', + 'table.alignTop' : 'Top', + 'table.alignMiddle' : 'Middle', + 'table.alignBottom' : 'Bottom', + 'table.alignBaseline' : 'Baseline', + 'table.border' : 'Border', + 'table.borderWidth' : 'Width', + 'table.borderColor' : 'Color', + 'table.backgroundColor' : 'Background', + 'map.address' : 'Address: ', + 'map.search' : 'Search', + 'baidumap.address' : 'Address: ', + 'baidumap.search' : 'Search', + 'baidumap.insertDynamicMap' : 'Dynamic Map', + 'anchor.name' : 'Anchor name', + 'formatblock.formatBlock' : { + h1 : 'Heading 1', + h2 : 'Heading 2', + h3 : 'Heading 3', + h4 : 'Heading 4', + p : 'Normal' + }, + 'fontname.fontName' : { + 'Arial' : 'Arial', + 'Arial Black' : 'Arial Black', + 'Comic Sans MS' : 'Comic Sans MS', + 'Courier New' : 'Courier New', + 'Garamond' : 'Garamond', + 'Georgia' : 'Georgia', + 'Tahoma' : 'Tahoma', + 'Times New Roman' : 'Times New Roman', + 'Trebuchet MS' : 'Trebuchet MS', + 'Verdana' : 'Verdana' + }, + 'lineheight.lineHeight' : [ + {'1' : 'Line height 1'}, + {'1.5' : 'Line height 1.5'}, + {'2' : 'Line height 2'}, + {'2.5' : 'Line height 2.5'}, + {'3' : 'Line height 3'} + ], + 'template.selectTemplate' : 'Template', + 'template.replaceContent' : 'Replace current content', + 'template.fileList' : { + '1.html' : 'Image and Text', + '2.html' : 'Table', + '3.html' : 'List' + } +}, 'en'); + +KindEditor.each(KindEditor.options.items, function(i, name) { + if (name == 'baidumap') { + KindEditor.options.items[i] = 'map'; + } +}); +KindEditor.options.langType = 'en'; diff --git a/php/kindeditor_demo/kindeditor/lang/ko.js b/php/kindeditor_demo/kindeditor/lang/ko.js new file mode 100755 index 0000000..bf5eb22 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lang/ko.js @@ -0,0 +1,246 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Composite +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.lang({ + source : '소스', + preview : '미리보기', + undo : '작업취소(Ctrl+Z)', + redo : '작업재개(Ctrl+Y)', + cut : '잘라내기(Ctrl+X)', + copy : '복사(Ctrl+C)', + paste : '붙여넣기(Ctrl+V)', + plainpaste : '일반 텍스트로 붙여넣기', + wordpaste : '워드 문서로 붙여넣기', + selectall : '전체 선택', + justifyleft : '왼쪽 정렬', + justifycenter : '가운데 정렬', + justifyright : '오른쪽 정렬', + justifyfull : '양쪽 정렬', + insertorderedlist : '순서 목록', + insertunorderedlist : '비순서 목록', + indent : '들여쓰기', + outdent : '내어쓰기', + subscript : '아랫첨자', + superscript : '윗첨자', + formatblock : '문단 형식', + fontname : '글꼴', + fontsize : '글자 크기', + forecolor : '글자색', + hilitecolor : '강조색', + bold : '굵게(Ctrl+B)', + italic : '이텔릭(Ctrl+I)', + underline : '빝줄(Ctrl+U)', + strikethrough : '취소선', + removeformat : '형식 제거', + image : '이미지 추가', + multiimage : '여러 이미지 추가', + flash : '플래시 추가', + media : '미디어 추가', + table : '표', + tablecell : '열', + hr : '구분선 추가', + emoticons : '이모티콘 추가', + link : '링크', + unlink : '링크 제거', + fullscreen : '전체 화면 모드', + about : '이 에디터는...', + print : '인쇄', + filemanager : '파일 관리자', + code : '코드 추가', + map : '구글 맵 추가', + baidumap : '바이두 맵 추가', + lineheight : '행 간격', + clearhtml : 'HTML 코드 정리', + pagebreak : '페이지 구분 추가', + quickformat : '빠른 형식', + insertfile : '파일 추가', + template : '템플릿 추가', + anchor : '책갈피', + yes : '확인', + no : '취소', + close : '닫기', + editImage : '이미지 속성', + deleteImage : '이미지 삭제', + editFlash : '플래시 속성', + deleteFlash : '플래시 삭제', + editMedia : '미디어 속성', + deleteMedia : '미디어 삭제', + editLink : '링크 속성', + deleteLink : '링크 삭제', + editAnchor : 'Anchor properties', + deleteAnchor : 'Delete Anchor', + tableprop : '표 속성', + tablecellprop : '열 속성', + tableinsert : '표 추가', + tabledelete : '표 삭제', + tablecolinsertleft : '왼쪽으로 열 추가', + tablecolinsertright : '오른쪽으로 열 추가', + tablerowinsertabove : '위쪽으로 열 추가', + tablerowinsertbelow : '아래쪽으로 열 추가', + tablerowmerge : '아래로 병합', + tablecolmerge : '오른쪽으로 병합', + tablerowsplit : '행 나누기', + tablecolsplit : '열 나누기', + tablecoldelete : '열 삭제', + tablerowdelete : '행 삭제', + noColor : '기본색', + pleaseSelectFile : '파일 선택', + invalidImg : "올바른 주소를 입력하세요.\njpg,gif,bmp,png 형식이 가능합니다.", + invalidMedia : "올바른 주소를 입력하세요.\nswf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb 형식이 가능합니다.", + invalidWidth : "넓이 값은 숫자여야 합니다.", + invalidHeight : "높이 값은 숫자여야 합니다.", + invalidBorder : "굵기 값은 숫자여야 합니다.", + invalidUrl : "올바른 주소를 입력하세요.", + invalidRows : '올바른 행이 아닙니다.', + invalidCols : '올바른 열이 아닙니다.', + invalidPadding : '안쪽 여백 값은 숫자여야 합니다.', + invalidSpacing : '간격 길이 값은 숫자여야 합니다.', + invalidJson : '올바른 JSON 형식이 아닙니다.', + uploadSuccess : '업로드가 완료되었습니다.', + cutError : '브라우저가 잘라내기 기능을 지원하지 않습니다, 단축키로 대신 사용하세요. (Ctrl+X)', + copyError : '브라우저가 복사 기능을 지원하지 않습니다, 단축키로 대신 사용하세요. (Ctrl+X)', + pasteError : '브라우저가 붙여넣기 기능을 지원하지 않습니다, 단축키로 대신 사용하세요. (Ctrl+X)', + ajaxLoading : '불러오는 중 ...', + uploadLoading : '업로드 중 ...', + uploadError : '업로드 오류', + 'plainpaste.comment' : '단축키(Ctrl+V)를 통하여 여기에 텍스트를 붙여넣으세요.', + 'wordpaste.comment' : '단축키(Ctrl+V)를 통하여 여기에 워드 텍스트를 붙여넣으세요.', + 'code.pleaseInput' : 'Please input code.', + 'link.url' : '주소', + 'link.linkType' : '창', + 'link.newWindow' : '새 창', + 'link.selfWindow' : '현재 창', + 'flash.url' : '주소', + 'flash.width' : '넓이', + 'flash.height' : '높이', + 'flash.upload' : '업로드', + 'flash.viewServer' : '찾아보기', + 'media.url' : '주소', + 'media.width' : '넓이', + 'media.height' : '높이', + 'media.autostart' : '자동 시작', + 'media.upload' : '업로드', + 'media.viewServer' : '찾아보기', + 'image.remoteImage' : '외부 이미지', + 'image.localImage' : '내부 이미지', + 'image.remoteUrl' : '주소', + 'image.localUrl' : '파일', + 'image.size' : '크기', + 'image.width' : '넓이', + 'image.height' : '높이', + 'image.resetSize' : '기본 크기로', + 'image.align' : '정렬', + 'image.defaultAlign' : '기본', + 'image.leftAlign' : '왼쪽', + 'image.rightAlign' : '오른쪽', + 'image.imgTitle' : '제목', + 'image.upload' : '찾아보기', + 'image.viewServer' : '찾아보기', + 'multiimage.uploadDesc' : '최대 이미지 개수: <%=uploadLimit%>개, 개당 이미지 크기: <%=sizeLimit%>', + 'multiimage.startUpload' : '업로드 시작', + 'multiimage.clearAll' : '모두 삭제', + 'multiimage.insertAll' : '모두 삽입', + 'multiimage.queueLimitExceeded' : '업로드 개수가 초과되었습니다.', + 'multiimage.fileExceedsSizeLimit' : '업로드 크기가 초과되었습니다.', + 'multiimage.zeroByteFile' : '파일 크기가 없습니다.', + 'multiimage.invalidFiletype' : '올바른 이미지가 아닙니다.', + 'multiimage.unknownError' : '알 수 없는 업로드 오류가 발생하였습니다.', + 'multiimage.pending' : '처리 중 ...', + 'multiimage.uploadError' : '업로드 오류', + 'filemanager.emptyFolder' : '빈 폴더', + 'filemanager.moveup' : '위로', + 'filemanager.viewType' : '보기 방식: ', + 'filemanager.viewImage' : '미리 보기', + 'filemanager.listImage' : '목록', + 'filemanager.orderType' : '정렬 방식: ', + 'filemanager.fileName' : '이름별', + 'filemanager.fileSize' : '크기별', + 'filemanager.fileType' : '종류별', + 'insertfile.url' : '주소', + 'insertfile.title' : '제목', + 'insertfile.upload' : '업로드', + 'insertfile.viewServer' : '찾아보기', + 'table.cells' : '열', + 'table.rows' : '행', + 'table.cols' : '열', + 'table.size' : '표 크기', + 'table.width' : '넓이', + 'table.height' : '높이', + 'table.percent' : '%', + 'table.px' : 'px', + 'table.space' : '간격', + 'table.padding' : '안쪽여백', + 'table.spacing' : '간격', + 'table.align' : '정렬', + 'table.textAlign' : '수직', + 'table.verticalAlign' : '수평', + 'table.alignDefault' : '기본', + 'table.alignLeft' : '왼쪽', + 'table.alignCenter' : '가운데', + 'table.alignRight' : '오른쪽', + 'table.alignTop' : '위쪽', + 'table.alignMiddle' : '중간', + 'table.alignBottom' : '아래쪽', + 'table.alignBaseline' : '글자기준', + 'table.border' : '테두리', + 'table.borderWidth' : '크기', + 'table.borderColor' : '색상', + 'table.backgroundColor' : '배경', + 'map.address' : '주소: ', + 'map.search' : '검색', + 'baidumap.address' : '주소: ', + 'baidumap.search' : '검색', + 'baidumap.insertDynamicMap' : '동적 지도', + 'anchor.name' : '책갈피명', + 'formatblock.formatBlock' : { + h1 : '제목 1', + h2 : '제목 2', + h3 : '제목 3', + h4 : '제목 4', + p : '본문' + }, + 'fontname.fontName' : { + 'Gulim' : '굴림', + 'Dotum' : '돋움', + 'Batang' : '바탕', + 'Gungsuh' : '궁서', + 'Malgun Gothic' : '맑은 고딕', + 'Arial' : 'Arial', + 'Arial Black' : 'Arial Black', + 'Comic Sans MS' : 'Comic Sans MS', + 'Courier New' : 'Courier New', + 'Garamond' : 'Garamond', + 'Georgia' : 'Georgia', + 'Tahoma' : 'Tahoma', + 'Times New Roman' : 'Times New Roman', + 'Trebuchet MS' : 'Trebuchet MS', + 'Verdana' : 'Verdana' + }, + 'lineheight.lineHeight' : [ + {'1' : '행간 1'}, + {'1.5' : '행간 1.5'}, + {'2' : '행간 2'}, + {'2.5' : '행간 2.5'}, + {'3' : '행간 3'} + ], + 'template.selectTemplate' : '템플릿', + 'template.replaceContent' : '내용 바꾸기', + 'template.fileList' : { + '1.html' : '이미지와 텍스트', + '2.html' : '표', + '3.html' : '목록' + } +}, 'ko'); + +KindEditor.each(KindEditor.options.items, function(i, name) { + if (name == 'baidumap') { + KindEditor.options.items[i] = 'map'; + } +}); +KindEditor.options.langType = 'ko'; diff --git a/php/kindeditor_demo/kindeditor/lang/ru.js b/php/kindeditor_demo/kindeditor/lang/ru.js new file mode 100755 index 0000000..dda10bf --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lang/ru.js @@ -0,0 +1,242 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +* Translated to Russian by Valery Votintsev (http://codersclub.org/) +*******************************************************************************/ + +KindEditor.lang({ + source : 'Source', + preview : 'Preview', + undo : 'Отмена(Ctrl+Z)', + redo : 'Повтор(Ctrl+Y)', + cut : 'Вырезать(Ctrl+X)', + copy : 'Копировать(Ctrl+C)', + paste : 'Вставить(Ctrl+V)', + plainpaste : 'Вставить как простой текст', + wordpaste : 'Вставить из Word', + selectall : 'Выбрать все', + justifyleft : 'Выравнивание влево', + justifycenter : 'Выравнивание по центру', + justifyright : 'Выравнивание вправо', + justifyfull : 'Выравнивание по обеим сторонам', + insertorderedlist : 'Нумерованый список', + insertunorderedlist : 'Ненумерованый список', + indent : 'Добавить отступ', + outdent : 'Убрать отступ', + subscript : 'Надстрочный', + superscript : 'Подстрочный', + formatblock : 'Формат параграфа', + fontname : 'Шрифт', + fontsize : 'Размер', + forecolor : 'Цвет текста', + hilitecolor : 'Цвет фона', + bold : 'Жирный(Ctrl+B)', + italic : 'Наклонный(Ctrl+I)', + underline : 'Подчёркнутый(Ctrl+U)', + strikethrough : 'Перечёркнутый', + removeformat : 'Удалить формат', + image : 'Изображение', + multiimage : 'Мульти-загрузка', + flash : 'Flash', + media : 'Встроенные данные', + table : 'Таблица', + tablecell : 'Ячейка', + hr : 'Горизонтальный разделитель', + emoticons : 'Смайл', + link : 'Ссылка', + unlink : 'Убрать ссылку', + fullscreen : 'На весь экран', + about : 'О программе', + print : 'Печать', + filemanager : 'Файлы', + code : 'Код', + map : 'Карта Google', + baidumap : 'Карта Baidu', + lineheight : 'Межстрочный интервал', + clearhtml : 'Очистить HTML код', + pagebreak : 'Разрыв страницы', + quickformat : 'Быстрый формат', + insertfile : 'Вставить файл', + template : 'Вставить шаблон', + anchor : 'Якорь', + yes : 'OK', + no : 'Отмена', + close : 'Закрыть', + editImage : 'Свойства изображения', + deleteImage : 'Удалить изображение', + editFlash : 'Свойства Flash', + deleteFlash : 'Удалить Flash', + editMedia : 'Свойства Media', + deleteMedia : 'Удалить Media', + editLink : 'Свойства ссылки', + deleteLink : 'Удалить ссылку', + editAnchor : 'Anchor properties', + deleteAnchor : 'Delete Anchor', + tableprop : 'Свойства таблицы', + tablecellprop : 'Свойства ячейки', + tableinsert : 'Вставить таблицу', + tabledelete : 'Удалить таблицу', + tablecolinsertleft : 'Добавить столбец слева', + tablecolinsertright : 'Добавить столбец справа', + tablerowinsertabove : 'Добавить строку выше', + tablerowinsertbelow : 'Добавить строку ниже', + tablerowmerge : 'Объединить вниз', + tablecolmerge : 'Объединить вправо', + tablerowsplit : 'Разделить строку', + tablecolsplit : 'Разделить столбец', + tablecoldelete : 'Удалить столбец', + tablerowdelete : 'Удалить строку', + noColor : 'По умолчанию', + pleaseSelectFile : 'Выберите файл.', + invalidImg : "Укажите корректный URL изображения.\nРазрешённые форматы: jpg,gif,bmp,png", + invalidMedia : "Укажите корректный тип медиа-объекта.\nРазрешённые типы: swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb", + invalidWidth : "Ширина должна быть числом.", + invalidHeight : "Высота должна быть числом.", + invalidBorder : "Ширина рамки должна быть числом.", + invalidUrl : "Укажите корректный URL.", + invalidRows : 'Неверные строки.', + invalidCols : 'Неверные столбцы.', + invalidPadding : 'padding должен быть числом.', + invalidSpacing : 'spacing должен быть числом.', + invalidJson : 'Неверная JSON строка.', + uploadSuccess : 'Загрузка завершена.', + cutError : 'Данная опция не поддерживается вашим браузером, воспользуйтесь комбинацией клавиш (Ctrl+X).', + copyError : 'Данная опция не поддерживается вашим браузером, воспользуйтесь комбинацией клавиш (Ctrl+C).', + pasteError : 'Данная опция не поддерживается вашим браузером, воспользуйтесь комбинацией клавиш (Ctrl+V).', + ajaxLoading : 'Загрузка ...', + uploadLoading : 'Загрузка ...', + uploadError : 'Сбой загрузки', + 'plainpaste.comment' : 'Для вставки скопированного текста воспользуйтесь комбинацией клавиш (Ctrl+V).', + 'wordpaste.comment' : 'Для вставки скопированного текста воспользуйтесь комбинацией клавиш (Ctrl+V).', + 'code.pleaseInput' : 'Введите код.', + 'link.url' : 'URL', + 'link.linkType' : 'Открывать ссылку', + 'link.newWindow' : 'в новом окне', + 'link.selfWindow' : 'в том же окне', + 'flash.url' : 'URL', + 'flash.width' : 'Ширина', + 'flash.height' : 'Высота', + 'flash.upload' : 'Загрузить', + 'flash.viewServer' : 'Выбрать', + 'media.url' : 'URL', + 'media.width' : 'Ширина', + 'media.height' : 'Высота', + 'media.autostart' : 'Автостарт', + 'media.upload' : 'Загрузить', + 'media.viewServer' : 'Выбрать', + 'image.remoteImage' : 'Вставить URL изображения', + 'image.localImage' : 'Загрузить', + 'image.remoteUrl' : 'URL', + 'image.localUrl' : 'Файл', + 'image.size' : 'Размер', + 'image.width' : 'Ширина', + 'image.height' : 'Высота', + 'image.resetSize' : 'Сбросить размеры', + 'image.align' : 'Выравнивание', + 'image.defaultAlign' : 'По умолчанию', + 'image.leftAlign' : 'Влево', + 'image.rightAlign' : 'Вправо', + 'image.imgTitle' : 'Название', + 'image.upload' : 'Загрузить', + 'image.viewServer' : 'Выбрать', + 'multiimage.uploadDesc' : 'Максимальное кол-во изображений: <%=uploadLimit%>, Максимальный размер одного изображения: <%=sizeLimit%>', + 'multiimage.startUpload' : 'Начать загрузку', + 'multiimage.clearAll' : 'Очистить все', + 'multiimage.insertAll' : 'Вставить все', + 'multiimage.queueLimitExceeded' : 'Превышен лимит очереди.', + 'multiimage.fileExceedsSizeLimit' : 'Превышен максимальный размер файла.', + 'multiimage.zeroByteFile' : 'Файл нулевой длины.', + 'multiimage.invalidFiletype' : 'Недопустимый тип файла.', + 'multiimage.unknownError' : 'Непредвиденная ошибка загрузки.', + 'multiimage.pending' : 'Ожидает ...', + 'multiimage.uploadError' : 'Ошибка загрузки', + 'filemanager.emptyFolder' : 'Папка пуста', + 'filemanager.moveup' : 'Наверх', + 'filemanager.viewType' : 'Тип показа: ', + 'filemanager.viewImage' : 'Превьюшки', + 'filemanager.listImage' : 'Список', + 'filemanager.orderType' : 'Сортировка: ', + 'filemanager.fileName' : 'По имени', + 'filemanager.fileSize' : 'По размеру', + 'filemanager.fileType' : 'По типу', + 'insertfile.url' : 'URL', + 'insertfile.title' : 'Название', + 'insertfile.upload' : 'Загрузить', + 'insertfile.viewServer' : 'Выбрать', + 'table.cells' : 'Ячейки', + 'table.rows' : 'Строки', + 'table.cols' : 'Столбцы', + 'table.size' : 'Размеры', + 'table.width' : 'Ширина', + 'table.height' : 'Высота', + 'table.percent' : '%', + 'table.px' : 'px', + 'table.space' : 'Space', + 'table.padding' : 'Padding', + 'table.spacing' : 'Spacing', + 'table.align' : 'Выравнивание', + 'table.textAlign' : 'По горизонтали', + 'table.verticalAlign' : 'По вертикали', + 'table.alignDefault' : 'По умолчанию', + 'table.alignLeft' : 'Влево', + 'table.alignCenter' : 'По центру', + 'table.alignRight' : 'Вправо', + 'table.alignTop' : 'Вверх', + 'table.alignMiddle' : 'Посередине', + 'table.alignBottom' : 'Вниз', + 'table.alignBaseline' : 'По базовой линии', + 'table.border' : 'Рамка', + 'table.borderWidth' : 'Ширина', + 'table.borderColor' : 'Цвет', + 'table.backgroundColor' : 'Цвет фона', + 'map.address' : 'Адрес: ', + 'map.search' : 'Поиск', + 'baidumap.address' : 'Адрес: ', + 'baidumap.search' : 'Поиск', + 'baidumap.insertDynamicMap' : 'Динамическая карта', + 'anchor.name' : 'Имя якоря', + 'formatblock.formatBlock' : { + h1 : 'Заголовок 1', + h2 : 'Заголовок 2', + h3 : 'Заголовок 3', + h4 : 'Заголовок 4', + p : 'Обычный текст' + }, + 'fontname.fontName' : { + 'Arial' : 'Arial', + 'Arial Black' : 'Arial Black', + 'Comic Sans MS' : 'Comic Sans MS', + 'Courier New' : 'Courier New', + 'Garamond' : 'Garamond', + 'Georgia' : 'Georgia', + 'Tahoma' : 'Tahoma', + 'Times New Roman' : 'Times New Roman', + 'Trebuchet MS' : 'Trebuchet MS', + 'Verdana' : 'Verdana' + }, + 'lineheight.lineHeight' : [ + {'1' : '1'}, + {'1.5' : '1.5'}, + {'2' : '2'}, + {'2.5' : '2.5'}, + {'3' : '3'} + ], + 'template.selectTemplate' : 'Шаблон', + 'template.replaceContent' : 'Заменить текущий шаблон', + 'template.fileList' : { + '1.html' : 'Текст и изображения', + '2.html' : 'Таблица', + '3.html' : 'Список' + } +}, 'en'); + +KindEditor.each(KindEditor.options.items, function(i, name) { + if (name == 'baidumap') { + KindEditor.options.items[i] = 'map'; + } +}); +KindEditor.options.langType = 'ru'; diff --git a/php/kindeditor_demo/kindeditor/lang/zh-CN.js b/php/kindeditor_demo/kindeditor/lang/zh-CN.js new file mode 100755 index 0000000..d9aa96e --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lang/zh-CN.js @@ -0,0 +1,238 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.lang({ + source : 'HTML代码', + preview : '预览', + undo : '后退(Ctrl+Z)', + redo : '前进(Ctrl+Y)', + cut : '剪切(Ctrl+X)', + copy : '复制(Ctrl+C)', + paste : '粘贴(Ctrl+V)', + plainpaste : '粘贴为无格式文本', + wordpaste : '从Word粘贴', + selectall : '全选(Ctrl+A)', + justifyleft : '左对齐', + justifycenter : '居中', + justifyright : '右对齐', + justifyfull : '两端对齐', + insertorderedlist : '编号', + insertunorderedlist : '项目符号', + indent : '增加缩进', + outdent : '减少缩进', + subscript : '下标', + superscript : '上标', + formatblock : '段落', + fontname : '字体', + fontsize : '文字大小', + forecolor : '文字颜色', + hilitecolor : '文字背景', + bold : '粗体(Ctrl+B)', + italic : '斜体(Ctrl+I)', + underline : '下划线(Ctrl+U)', + strikethrough : '删除线', + removeformat : '删除格式', + image : '图片', + multiimage : '批量图片上传', + flash : 'Flash', + media : '视音频', + table : '表格', + tablecell : '单元格', + hr : '插入横线', + emoticons : '插入表情', + link : '超级链接', + unlink : '取消超级链接', + fullscreen : '全屏显示', + about : '关于', + print : '打印(Ctrl+P)', + filemanager : '文件空间', + code : '插入程序代码', + map : 'Google地图', + baidumap : '百度地图', + lineheight : '行距', + clearhtml : '清理HTML代码', + pagebreak : '插入分页符', + quickformat : '一键排版', + insertfile : '插入文件', + template : '插入模板', + anchor : '锚点', + yes : '确定', + no : '取消', + close : '关闭', + editImage : '图片属性', + deleteImage : '删除图片', + editFlash : 'Flash属性', + deleteFlash : '删除Flash', + editMedia : '视音频属性', + deleteMedia : '删除视音频', + editLink : '超级链接属性', + deleteLink : '取消超级链接', + editAnchor : '锚点属性', + deleteAnchor : '删除锚点', + tableprop : '表格属性', + tablecellprop : '单元格属性', + tableinsert : '插入表格', + tabledelete : '删除表格', + tablecolinsertleft : '左侧插入列', + tablecolinsertright : '右侧插入列', + tablerowinsertabove : '上方插入行', + tablerowinsertbelow : '下方插入行', + tablerowmerge : '向下合并单元格', + tablecolmerge : '向右合并单元格', + tablerowsplit : '拆分行', + tablecolsplit : '拆分列', + tablecoldelete : '删除列', + tablerowdelete : '删除行', + noColor : '无颜色', + pleaseSelectFile : '请选择文件。', + invalidImg : "请输入有效的URL地址。\n只允许jpg,gif,bmp,png格式。", + invalidMedia : "请输入有效的URL地址。\n只允许swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb格式。", + invalidWidth : "宽度必须为数字。", + invalidHeight : "高度必须为数字。", + invalidBorder : "边框必须为数字。", + invalidUrl : "请输入有效的URL地址。", + invalidRows : '行数为必选项,只允许输入大于0的数字。', + invalidCols : '列数为必选项,只允许输入大于0的数字。', + invalidPadding : '边距必须为数字。', + invalidSpacing : '间距必须为数字。', + invalidJson : '服务器发生故障。', + uploadSuccess : '上传成功。', + cutError : '您的浏览器安全设置不允许使用剪切操作,请使用快捷键(Ctrl+X)来完成。', + copyError : '您的浏览器安全设置不允许使用复制操作,请使用快捷键(Ctrl+C)来完成。', + pasteError : '您的浏览器安全设置不允许使用粘贴操作,请使用快捷键(Ctrl+V)来完成。', + ajaxLoading : '加载中,请稍候 ...', + uploadLoading : '上传中,请稍候 ...', + uploadError : '上传错误', + 'plainpaste.comment' : '请使用快捷键(Ctrl+V)把内容粘贴到下面的方框里。', + 'wordpaste.comment' : '请使用快捷键(Ctrl+V)把内容粘贴到下面的方框里。', + 'code.pleaseInput' : '请输入程序代码。', + 'link.url' : 'URL', + 'link.linkType' : '打开类型', + 'link.newWindow' : '新窗口', + 'link.selfWindow' : '当前窗口', + 'flash.url' : 'URL', + 'flash.width' : '宽度', + 'flash.height' : '高度', + 'flash.upload' : '上传', + 'flash.viewServer' : '文件空间', + 'media.url' : 'URL', + 'media.width' : '宽度', + 'media.height' : '高度', + 'media.autostart' : '自动播放', + 'media.upload' : '上传', + 'media.viewServer' : '文件空间', + 'image.remoteImage' : '网络图片', + 'image.localImage' : '本地上传', + 'image.remoteUrl' : '图片地址', + 'image.localUrl' : '上传文件', + 'image.size' : '图片大小', + 'image.width' : '宽', + 'image.height' : '高', + 'image.resetSize' : '重置大小', + 'image.align' : '对齐方式', + 'image.defaultAlign' : '默认方式', + 'image.leftAlign' : '左对齐', + 'image.rightAlign' : '右对齐', + 'image.imgTitle' : '图片说明', + 'image.upload' : '浏览...', + 'image.viewServer' : '图片空间', + 'multiimage.uploadDesc' : '允许用户同时上传<%=uploadLimit%>张图片,单张图片容量不超过<%=sizeLimit%>', + 'multiimage.startUpload' : '开始上传', + 'multiimage.clearAll' : '全部清空', + 'multiimage.insertAll' : '全部插入', + 'multiimage.queueLimitExceeded' : '文件数量超过限制。', + 'multiimage.fileExceedsSizeLimit' : '文件大小超过限制。', + 'multiimage.zeroByteFile' : '无法上传空文件。', + 'multiimage.invalidFiletype' : '文件类型不正确。', + 'multiimage.unknownError' : '发生异常,无法上传。', + 'multiimage.pending' : '等待上传', + 'multiimage.uploadError' : '上传失败', + 'filemanager.emptyFolder' : '空文件夹', + 'filemanager.moveup' : '移到上一级文件夹', + 'filemanager.viewType' : '显示方式:', + 'filemanager.viewImage' : '缩略图', + 'filemanager.listImage' : '详细信息', + 'filemanager.orderType' : '排序方式:', + 'filemanager.fileName' : '名称', + 'filemanager.fileSize' : '大小', + 'filemanager.fileType' : '类型', + 'insertfile.url' : 'URL', + 'insertfile.title' : '文件说明', + 'insertfile.upload' : '上传', + 'insertfile.viewServer' : '文件空间', + 'table.cells' : '单元格数', + 'table.rows' : '行数', + 'table.cols' : '列数', + 'table.size' : '大小', + 'table.width' : '宽度', + 'table.height' : '高度', + 'table.percent' : '%', + 'table.px' : 'px', + 'table.space' : '边距间距', + 'table.padding' : '边距', + 'table.spacing' : '间距', + 'table.align' : '对齐方式', + 'table.textAlign' : '水平对齐', + 'table.verticalAlign' : '垂直对齐', + 'table.alignDefault' : '默认', + 'table.alignLeft' : '左对齐', + 'table.alignCenter' : '居中', + 'table.alignRight' : '右对齐', + 'table.alignTop' : '顶部', + 'table.alignMiddle' : '中部', + 'table.alignBottom' : '底部', + 'table.alignBaseline' : '基线', + 'table.border' : '边框', + 'table.borderWidth' : '边框', + 'table.borderColor' : '颜色', + 'table.backgroundColor' : '背景颜色', + 'map.address' : '地址: ', + 'map.search' : '搜索', + 'baidumap.address' : '地址: ', + 'baidumap.search' : '搜索', + 'baidumap.insertDynamicMap' : '插入动态地图', + 'anchor.name' : '锚点名称', + 'formatblock.formatBlock' : { + h1 : '标题 1', + h2 : '标题 2', + h3 : '标题 3', + h4 : '标题 4', + p : '正 文' + }, + 'fontname.fontName' : { + 'SimSun' : '宋体', + 'NSimSun' : '新宋体', + 'FangSong_GB2312' : '仿宋_GB2312', + 'KaiTi_GB2312' : '楷体_GB2312', + 'SimHei' : '黑体', + 'Microsoft YaHei' : '微软雅黑', + 'Arial' : 'Arial', + 'Arial Black' : 'Arial Black', + 'Times New Roman' : 'Times New Roman', + 'Courier New' : 'Courier New', + 'Tahoma' : 'Tahoma', + 'Verdana' : 'Verdana' + }, + 'lineheight.lineHeight' : [ + {'1' : '单倍行距'}, + {'1.5' : '1.5倍行距'}, + {'2' : '2倍行距'}, + {'2.5' : '2.5倍行距'}, + {'3' : '3倍行距'} + ], + 'template.selectTemplate' : '可选模板', + 'template.replaceContent' : '替换当前内容', + 'template.fileList' : { + '1.html' : '图片和文字', + '2.html' : '表格', + '3.html' : '项目编号' + } +}, 'zh-CN'); + +KindEditor.options.langType = 'zh-CN'; \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/lang/zh-TW.js b/php/kindeditor_demo/kindeditor/lang/zh-TW.js new file mode 100755 index 0000000..4946898 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lang/zh-TW.js @@ -0,0 +1,243 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.lang({ + source : '原始碼', + preview : '預覽', + undo : '復原(Ctrl+Z)', + redo : '重複(Ctrl+Y)', + cut : '剪下(Ctrl+X)', + copy : '複製(Ctrl+C)', + paste : '貼上(Ctrl+V)', + plainpaste : '貼為純文字格式', + wordpaste : '自Word貼上', + selectall : '全選(Ctrl+A)', + justifyleft : '靠左對齊', + justifycenter : '置中', + justifyright : '靠右對齊', + justifyfull : '左右對齊', + insertorderedlist : '編號清單', + insertunorderedlist : '項目清單', + indent : '增加縮排', + outdent : '減少縮排', + subscript : '下標', + superscript : '上標', + formatblock : '標題', + fontname : '字體', + fontsize : '文字大小', + forecolor : '文字顏色', + hilitecolor : '背景顏色', + bold : '粗體(Ctrl+B)', + italic : '斜體(Ctrl+I)', + underline : '底線(Ctrl+U)', + strikethrough : '刪除線', + removeformat : '清除格式', + image : '影像', + multiimage : '批量影像上傳', + flash : 'Flash', + media : '多媒體', + table : '表格', + tablecell : '儲存格', + hr : '插入水平線', + emoticons : '插入表情', + link : '超連結', + unlink : '移除超連結', + fullscreen : '最大化', + about : '關於', + print : '列印(Ctrl+P)', + filemanager : '瀏覽伺服器', + code : '插入程式代碼', + map : 'Google地圖', + baidumap : 'Baidu地圖', + lineheight : '行距', + clearhtml : '清理HTML代碼', + pagebreak : '插入分頁符號', + quickformat : '快速排版', + insertfile : '插入文件', + template : '插入樣板', + anchor : '錨點', + yes : '確定', + no : '取消', + close : '關閉', + editImage : '影像屬性', + deleteImage : '刪除影像', + editFlash : 'Flash屬性', + deleteFlash : '删除Flash', + editMedia : '多媒體屬性', + deleteMedia : '删除多媒體', + editLink : '超連結屬性', + deleteLink : '移除超連結', + editAnchor : '锚点属性', + deleteAnchor : '删除锚点', + tableprop : '表格屬性', + tablecellprop : '儲存格屬性', + tableinsert : '插入表格', + tabledelete : '刪除表格', + tablecolinsertleft : '向左插入列', + tablecolinsertright : '向右插入列', + tablerowinsertabove : '向上插入欄', + tablerowinsertbelow : '下方插入欄', + tablerowmerge : '向下合併單元格', + tablecolmerge : '向右合併單元格', + tablerowsplit : '分割欄', + tablecolsplit : '分割列', + tablecoldelete : '删除列', + tablerowdelete : '删除欄', + noColor : '自動', + pleaseSelectFile : '請選擇文件。', + invalidImg : "請輸入有效的URL。\n只允許jpg,gif,bmp,png格式。", + invalidMedia : "請輸入有效的URL。\n只允許swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb格式。", + invalidWidth : "寬度必須是數字。", + invalidHeight : "高度必須是數字。", + invalidBorder : "邊框必須是數字。", + invalidUrl : "請輸入有效的URL。", + invalidRows : '欄數是必須輸入項目,只允許輸入大於0的數字。', + invalidCols : '列數是必須輸入項目,只允許輸入大於0的數字。', + invalidPadding : '內距必須是數字。', + invalidSpacing : '間距必須是數字。', + invalidJson : '伺服器發生故障。', + uploadSuccess : '上傳成功。', + cutError : '您的瀏覽器安全設置不允許使用剪下操作,請使用快捷鍵(Ctrl+X)完成。', + copyError : '您的瀏覽器安全設置不允許使用剪下操作,請使用快捷鍵(Ctrl+C)完成。', + pasteError : '您的瀏覽器安全設置不允許使用剪下操作,請使用快捷鍵(Ctrl+V)完成。', + ajaxLoading : '加載中,請稍候 ...', + uploadLoading : '上傳中,請稍候 ...', + uploadError : '上傳錯誤', + 'plainpaste.comment' : '請使用快捷鍵(Ctrl+V)把內容貼到下方區域裡。', + 'wordpaste.comment' : '請使用快捷鍵(Ctrl+V)把內容貼到下方區域裡。', + 'code.pleaseInput' : 'Please input code.', + 'link.url' : 'URL', + 'link.linkType' : '打開類型', + 'link.newWindow' : '新窗口', + 'link.selfWindow' : '本頁窗口', + 'flash.url' : 'URL', + 'flash.width' : '寬度', + 'flash.height' : '高度', + 'flash.upload' : '上傳', + 'flash.viewServer' : '瀏覽', + 'media.url' : 'URL', + 'media.width' : '寬度', + 'media.height' : '高度', + 'media.autostart' : '自動播放', + 'media.upload' : '上傳', + 'media.viewServer' : '瀏覽', + 'image.remoteImage' : '網絡影像', + 'image.localImage' : '上傳影像', + 'image.remoteUrl' : '影像URL', + 'image.localUrl' : '影像URL', + 'image.size' : '影像大小', + 'image.width' : '寬度', + 'image.height' : '高度', + 'image.resetSize' : '原始大小', + 'image.align' : '對齊方式', + 'image.defaultAlign' : '未設定', + 'image.leftAlign' : '向左對齊', + 'image.rightAlign' : '向右對齊', + 'image.imgTitle' : '影像說明', + 'image.upload' : '瀏覽...', + 'image.viewServer' : '瀏覽...', + 'multiimage.uploadDesc' : 'Allows users to upload <%=uploadLimit%> images, single image size not exceeding <%=sizeLimit%>', + 'multiimage.startUpload' : 'Start upload', + 'multiimage.clearAll' : 'Clear all', + 'multiimage.insertAll' : 'Insert all', + 'multiimage.queueLimitExceeded' : 'Queue limit exceeded.', + 'multiimage.fileExceedsSizeLimit' : 'File exceeds size limit.', + 'multiimage.zeroByteFile' : 'Zero byte file.', + 'multiimage.invalidFiletype' : 'Invalid file type.', + 'multiimage.unknownError' : 'Unknown upload error.', + 'multiimage.pending' : 'Pending ...', + 'multiimage.uploadError' : 'Upload error', + 'filemanager.emptyFolder' : '空文件夾', + 'filemanager.moveup' : '至上一級文件夾', + 'filemanager.viewType' : '顯示方式:', + 'filemanager.viewImage' : '縮略圖', + 'filemanager.listImage' : '詳細信息', + 'filemanager.orderType' : '排序方式:', + 'filemanager.fileName' : '名稱', + 'filemanager.fileSize' : '大小', + 'filemanager.fileType' : '類型', + 'insertfile.url' : 'URL', + 'insertfile.title' : '文件說明', + 'insertfile.upload' : '上傳', + 'insertfile.viewServer' : '瀏覽', + 'table.cells' : '儲存格數', + 'table.rows' : '欄數', + 'table.cols' : '列數', + 'table.size' : '表格大小', + 'table.width' : '寬度', + 'table.height' : '高度', + 'table.percent' : '%', + 'table.px' : 'px', + 'table.space' : '內距間距', + 'table.padding' : '內距', + 'table.spacing' : '間距', + 'table.align' : '對齊方式', + 'table.textAlign' : '水平對齊', + 'table.verticalAlign' : '垂直對齊', + 'table.alignDefault' : '未設定', + 'table.alignLeft' : '向左對齊', + 'table.alignCenter' : '置中', + 'table.alignRight' : '向右對齊', + 'table.alignTop' : '靠上', + 'table.alignMiddle' : '置中', + 'table.alignBottom' : '靠下', + 'table.alignBaseline' : '基線', + 'table.border' : '表格邊框', + 'table.borderWidth' : '邊框', + 'table.borderColor' : '顏色', + 'table.backgroundColor' : '背景顏色', + 'map.address' : '住所: ', + 'map.search' : '尋找', + 'baidumap.address' : '住所: ', + 'baidumap.search' : '尋找', + 'baidumap.insertDynamicMap' : '插入動態地圖', + 'anchor.name' : '錨點名稱', + 'formatblock.formatBlock' : { + h1 : '標題 1', + h2 : '標題 2', + h3 : '標題 3', + h4 : '標題 4', + p : '一般' + }, + 'fontname.fontName' : { + 'MingLiU' : '細明體', + 'PMingLiU' : '新細明體', + 'DFKai-SB' : '標楷體', + 'SimSun' : '宋體', + 'NSimSun' : '新宋體', + 'FangSong' : '仿宋體', + 'Arial' : 'Arial', + 'Arial Black' : 'Arial Black', + 'Times New Roman' : 'Times New Roman', + 'Courier New' : 'Courier New', + 'Tahoma' : 'Tahoma', + 'Verdana' : 'Verdana' + }, + 'lineheight.lineHeight' : [ + {'1' : '单倍行距'}, + {'1.5' : '1.5倍行距'}, + {'2' : '2倍行距'}, + {'2.5' : '2.5倍行距'}, + {'3' : '3倍行距'} + ], + 'template.selectTemplate' : '可選樣板', + 'template.replaceContent' : '取代當前內容', + 'template.fileList' : { + '1.html' : '影像和文字', + '2.html' : '表格', + '3.html' : '项目清單' + } +}, 'zh-TW'); + +KindEditor.each(KindEditor.options.items, function(i, name) { + if (name == 'baidumap') { + KindEditor.options.items[i] = 'map'; + } +}); +KindEditor.options.langType = 'zh-TW'; \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/.htaccess b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/.htaccess new file mode 100755 index 0000000..cb38bde --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/.htaccess @@ -0,0 +1,15 @@ +AddType "text/javascript;charset=UTF-8" .jgz .js +AddEncoding gzip .jgz + + + ExpiresActive On + ExpiresDefault A86400 + + + + RewriteEngine on + #RewriteCond %{HTTP_USER_AGENT} ".*Safari.*" [OR] + RewriteCond %{HTTP_USER_AGENT} ".*MSIE 6.*" [OR] + RewriteCond %{HTTP:Accept-Encoding} !gzip + RewriteRule (.*)\.jgz$ $1.js [L] + \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/build.bat b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/build.bat new file mode 100755 index 0000000..6e71c22 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/build.bat @@ -0,0 +1,21 @@ +rd firebug-lite /s /q +rd pub /s /q + +svn export "../" "./firebug-lite" + +md pub +xcopy ".\firebug-lite\skin\." ".\pub\skin" /s /i +copy "..\docs\beta\index.html" ".\pub\index.html" +copy "..\content\changelog.txt" ".\pub" +copy ".\firebug-lite\build\*.*" ".\pub" +del ".\pub\*.bat" + +tar -cv --file=firebug-lite.tar firebug-lite/* +gzip -9 < firebug-lite.tar > ./pub/firebug-lite.tar.tgz + +del firebug-lite.tar + +rd firebug-lite /s /q + +pause + diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/background.html b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/background.html new file mode 100755 index 0000000..c4133a1 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/background.html @@ -0,0 +1,187 @@ + \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/contentScript.js b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/contentScript.js new file mode 100755 index 0000000..1dad3c1 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/contentScript.js @@ -0,0 +1,378 @@ +// ************************************************************************************************* + +var isActive = false; +var isOpen = false; +var extensionURL = null; + +var contextMenuElementXPath = null; +var isListeningKeyboardActivation = false; + +// ************************************************************************************************* + +// restore Firebug Lite state +var loadStateData = function() +{ + var FirebugData = localStorage.getItem("Firebug"); + + isActive = false; + isOpen = false; + extensionURL = chrome.extension.getURL(""); + + if (FirebugData) + { + FirebugData = FirebugData.split(","); + isActive = FirebugData[0] == "1"; + isOpen = FirebugData[1] == "1"; + } +} + +// ************************************************************************************************* + +// load Firebug Lite application +var loadFirebug = function() +{ + document.documentElement.setAttribute("debug", isOpen); + + injectScriptText("("+listenConsoleCalls+")()"); + + // TODO: xxxpedro - change to XHR when Issue 41024 is solved + // Issue 41024: XHR using file: and chrome-extension: protocols not working. + // http://code.google.com/p/chromium/issues/detail?id=41024 + injectFirebugScript(); +} + +// TODO: think a better solution than using the stateData parameter, required +// by the keyboard activation. +var loadFirebugAndWait = function(callback, stateData) +{ + stateData = stateData || ('1,1,'+extensionURL); + localStorage.setItem('Firebug', stateData); + loadStateData(); + chrome.extension.sendRequest({name: isActive ? "FB_enableIcon" : "FB_disableIcon"}); + + document.documentElement.setAttribute("debug", isOpen); + + injectFirebugScript(); + + setTimeout(function(){ + waitFirebug(callback); + },0); +}; + +var waitFirebug = function(callback) +{ + if (document && document.getElementById("FirebugChannel")) + { + stopListeningKeyboardActivation(); + callback(); + } + else + setTimeout(function(){ waitFirebug(callback); }, 100); + +}; + +// ************************************************************************************************* + +// inject Firebug Lite script into the page +var injectFirebugScript = function(url) +{ + scriptElement = document.getElementById("FirebugLite"); + if (scriptElement) + { + firebugDispatch("FB_toggle"); + } + else + { + var script = document.createElement("script"); + + script.src = extensionURL + "firebug-lite-beta.js"; + script.setAttribute("id", "FirebugLite"); + script.setAttribute("firebugIgnore", "true"); + script.setAttribute("extension", "Chrome"); + document.documentElement.appendChild(script); + + script.onload = function() { + // TODO: xxxpedro remove this files when deploy the new structure + script = document.createElement("script"); + script.src = extensionURL + "googleChrome.js"; + document.documentElement.appendChild(script); + }; + } +} + +// inject a script into the page +var injectScriptText = function(text) +{ + var script = document.createElement("script"); + var parent = document.documentElement; + + script.text = text; + script.setAttribute("id", "FirebugLite"); + script.setAttribute("firebugIgnore", "true"); + script.setAttribute("extension", "Chrome"); + parent.appendChild(script); + parent.removeChild(script); +} + +// ************************************************************************************************* + +// communication with the background page +chrome.extension.onRequest.addListener +( + function(request, sender, sendResponse) + { + // check if Firebug Lite is active + if (request.name == "FB_isActive") + { + loadStateData(); + sendResponse({value: ""+isActive}); + } + // load Firebug Lite application + else if (request.name == "FB_loadFirebug") + { + setTimeout(function(){ + + loadStateData(); + + //loadFirebug(); + loadFirebugAndWait(function(){ + + isActive = true; + var message = isActive ? "FB_enableIcon" : "FB_disableIcon"; + chrome.extension.sendRequest({name: message}); + + loadChannel(); + }); + + },0); + + sendResponse({}); + } + // handle context menu click by sending "FB_contextMenuClick" message + // to Firebug Lite application + else if (request.name == "FB_contextMenuClick") + { + // TODO: if not active, activate first, wait the activation to complete + // and only then dispatch the event to Firebug Lite application + if (isActive) + firebugDispatch("FB_contextMenuClick,"+contextMenuElementXPath); + else + loadFirebugAndWait(function(){ + firebugDispatch("FB_contextMenuClick,"+contextMenuElementXPath); + }); + } + else if (request.name == "FB_deactivate") + { + listenKeyboardActivation(); + } + else + sendResponse({}); // snub them. + } +); + +// ************************************************************************************************* + +// communication with the page +var channel = null; +var channelEvent; + +var onFirebugChannelEvent = function() +{ + channel = document.getElementById("FirebugChannel"); + + if (channel) + { + chrome.extension.sendRequest({name: channel.innerText}); + } +}; + +var loadChannel = function() +{ + channel = document.getElementById("FirebugChannel"); + + if (channel) + { + channel.addEventListener("FirebugChannelEvent", onFirebugChannelEvent); + channelEvent = document.createEvent("Event"); + channelEvent.initEvent("FirebugChannelEvent", true, true); + } +} + +var firebugDispatch = function(data) +{ + if (!channel) + loadChannel(); + + channel.innerText = data; + channel.dispatchEvent(channelEvent); +}; + +// ************************************************************************************************* + +var onContextMenu = function(event) +{ + contextMenuElementXPath = getElementXPath(event.target); +}; + +var loadListeners = function() +{ + window.addEventListener("contextmenu", onContextMenu); + window.addEventListener("unload", unloadListeners); +}; + +var unloadListeners = function() +{ + if (channel) + { + channel.removeEventListener("FirebugChannelEvent", onFirebugChannelEvent); + } + + window.removeEventListener("contextmenu", onContextMenu); + window.removeEventListener("unload", unloadListeners); +}; + +// ************************************************************************************************* + +// listen to console calls before Firebug Lite finishes to load +var listenConsoleCalls = function() +{ + // TODO: xxxpedro add all console functions + var fns = ["log", "info", "warn", "error"]; + + var listener = {consoleQueue: ["chromeConsoleQueueHack"]}; + var queue = listener.consoleQueue; + + for (var i=0, l=fns.length; i 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}"}; + } + + 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; + + // 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 + 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; + } + } + } + + // 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) + return ob + ""; + + 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, ""); + + if (elt.offsetLeft) + coords.x += elt.offsetLeft + parseInt(style.borderLeftWidth); + if (elt.offsetTop) + coords.y += elt.offsetTop + parseInt(style.borderTopWidth); + + if (p) + { + if (p.nodeType == 1) + addOffset(p, coords, view); + } + else + { + var otherView = isIE ? elt.ownerDocument.parentWindow : elt.ownerDocument.defaultView; + if (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; + + return toString.call(object) === "[object Function]" || + this.isIE && typeof object != "string" && reFunction.test(""+object); +}; + + +// ************************************************************************************************ +// 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 = this.getXHRObject(); + }, + + 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); + +/* See license.txt for terms of usage */ + +FBL.ns( /** @scope ns-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; +}; + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +FBL.ns( /** @scope ns-firebug */ function() { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +// Globals + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Internals + +var modules = []; +var panelTypes = []; +var panelTypeMap = {}; +var reps = []; + +var parentPanelMap = {}; + + +// ************************************************************************************************ +// Firebug + +/** + * @namespace describe Firebug + * @exports window.Firebug as Firebug + */ +window.Firebug = FBL.Firebug = +{ + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + version: "Firebug Lite 1.3.2", + revision: "$Revision: 9759 $", + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + 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; + + // Document must be cached before chrome initialization + cacheDocument(); + + if (Firebug.Inspector) + Firebug.Inspector.create(); + + if (FBL.processAllStyleSheets) + processAllStyleSheets(Firebug.browser.document); + + FirebugChrome.initialize(); + + dispatch(modules, "initialize", []); + + if (Env.onLoad) + { + var onLoad = Env.onLoad; + delete Env.onLoad; + + setTimeout(onLoad, 200); + } + }, + + shutdown: function() + { + if (Firebug.Inspector) + Firebug.Inspector.destroy(); + + dispatch(modules, "shutdown", []); + + var chromeMap = FirebugChrome.chromeMap; + + for (var name in chromeMap) + { + if (chromeMap.hasOwnProperty(name)) + { + chromeMap[name].destroy(); + } + } + + 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; + + this.savePrefs(); + }, + + setPrefs: function(prefs) + { + for (var name in prefs) + { + if (prefs.hasOwnProperty(name)) + Firebug[name] = prefs[name]; + } + + this.savePrefs(); + }, + + restorePrefs: function() + { + var Options = Env.Options; + + for (var name in Options) + { + Firebug[name] = Options[name]; + } + }, + + loadPrefs: function(prefs) + { + this.restorePrefs(); + + prefs = prefs || eval("(" + readCookie("FirebugLite") + ")"); + + for (var name in prefs) + { + if (prefs.hasOwnProperty(name)) + Firebug[name] = prefs[name]; + } + }, + + savePrefs: function() + { + var json = ['{'], jl = 0; + var Options = Env.Options; + + for (var name in Options) + { + if (Options.hasOwnProperty(name)) + { + var value = Firebug[name]; + + json[++jl] = '"'; + json[++jl] = name; + + var type = typeof value; + if (type == "boolean" || type == "number") + { + json[++jl] = '":'; + json[++jl] = value; + json[++jl] = ','; + } + else + { + json[++jl] = '":"'; + json[++jl] = value; + json[++jl] = '",'; + } + } + } + + json.length = jl--; + json[++jl] = '}'; + + createCookie("FirebugLite", json.join("")); + }, + + erasePrefs: function() + { + removeCookie("FirebugLite"); + } +}; + +Firebug.restorePrefs(); + +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; + Firebug.InfoTip.initializeBrowser(Firebug.chrome); + }, + + shutdown: function() + { + if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.Panel.shutdown", this.name); + + /// TODO: xxxpedro infoTip Hack + 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.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"; + } +}); + +// ************************************************************************************************ + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +FBL.ns( /** @scope ns-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) + FirebugChrome.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 width || el.scrollHeight > height)) + { + width = el.scrollWidth; + height = el.scrollHeight; + } + + return {width: width, height: height}; + }, + + getWindowScrollPosition: function() + { + var top=0, left=0, el; + + if(typeof this.window.pageYOffset == "number") + { + top = this.window.pageYOffset; + left = this.window.pageXOffset; + } + else if((el=this.document.body) && (el.scrollTop || el.scrollLeft)) + { + top = el.scrollTop; + left = el.scrollLeft; + } + else if((el=this.document.documentElement) && (el.scrollTop || el.scrollLeft)) + { + top = el.scrollTop; + left = el.scrollLeft; + } + + return {top:top, left:left}; + }, + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Element Methods + + getElementFromPoint: function(x, y) + { + if (shouldFixElementFromPoint) + { + var scroll = this.getWindowScrollPosition(); + return this.document.elementFromPoint(x + scroll.left, y + scroll.top); + } + else + return this.document.elementFromPoint(x, y); + }, + + getElementPosition: function(el) + { + var left = 0 + var top = 0; + + do + { + left += el.offsetLeft; + top += el.offsetTop; + } + while (el = el.offsetParent); + + return {left:left, top:top}; + }, + + getElementBox: function(el) + { + var result = {}; + + if (el.getBoundingClientRect) + { + var rect = el.getBoundingClientRect(); + + // fix IE problem with offset when not in fullscreen mode + var offset = isIE ? this.document.body.clientTop || this.document.documentElement.clientTop: 0; + + var scroll = this.getWindowScrollPosition(); + + result.top = Math.round(rect.top - offset + scroll.top); + result.left = Math.round(rect.left - offset + scroll.left); + result.height = Math.round(rect.bottom - rect.top); + result.width = Math.round(rect.right - rect.left); + } + else + { + var position = this.getElementPosition(el); + + result.top = position.top; + result.left = position.left; + result.height = el.offsetHeight; + result.width = el.offsetWidth; + } + + return result; + }, + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Measurement Methods + + getMeasurement: function(el, name) + { + var result = {value: 0, unit: "px"}; + + var cssValue = this.getStyle(el, name); + + if (!cssValue) return result; + if (cssValue.toLowerCase() == "auto") return result; + + var reMeasure = /(\d+\.?\d*)(.*)/; + var m = cssValue.match(reMeasure); + + if (m) + { + result.value = m[1]-0; + result.unit = m[2].toLowerCase(); + } + + return result; + }, + + getMeasurementInPixels: function(el, name) + { + if (!el) return null; + + var m = this.getMeasurement(el, name); + var value = m.value; + var unit = m.unit; + + if (unit == "px") + return value; + + else if (unit == "pt") + return this.pointsToPixels(name, value); + + if (unit == "em") + return this.emToPixels(el, value); + + else if (unit == "%") + return this.percentToPixels(el, value); + }, + + getMeasurementBox1: function(el, name) + { + var sufixes = ["Top", "Left", "Bottom", "Right"]; + var result = []; + + for(var i=0, sufix; sufix=sufixes[i]; i++) + result[i] = Math.round(this.getMeasurementInPixels(el, name + sufix)); + + return {top:result[0], left:result[1], bottom:result[2], right:result[3]}; + }, + + getMeasurementBox: function(el, name) + { + var result = []; + var sufixes = name == "border" ? + ["TopWidth", "LeftWidth", "BottomWidth", "RightWidth"] : + ["Top", "Left", "Bottom", "Right"]; + + if (isIE) + { + var propName, cssValue; + var autoMargin = null; + + for(var i=0, sufix; sufix=sufixes[i]; i++) + { + propName = name + sufix; + + cssValue = el.currentStyle[propName] || el.style[propName]; + + if (cssValue == "auto") + { + if (!autoMargin) + autoMargin = this.getCSSAutoMarginBox(el); + + result[i] = autoMargin[sufix.toLowerCase()]; + } + else + result[i] = this.getMeasurementInPixels(el, propName); + + } + + } + else + { + for(var i=0, sufix; sufix=sufixes[i]; i++) + result[i] = this.getMeasurementInPixels(el, name + sufix); + } + + return {top:result[0], left:result[1], bottom:result[2], right:result[3]}; + }, + + getCSSAutoMarginBox: function(el) + { + if (isIE && " meta title input script link a ".indexOf(" "+el.nodeName.toLowerCase()+" ") != -1) + return {top:0, left:0, bottom:0, right:0}; + /**/ + + if (isIE && " h1 h2 h3 h4 h5 h6 h7 ul p ".indexOf(" "+el.nodeName.toLowerCase()+" ") == -1) + return {top:0, left:0, bottom:0, right:0}; + /**/ + + var offsetTop = 0; + if (false && isIEStantandMode) + { + var scrollSize = Firebug.browser.getWindowScrollSize(); + offsetTop = scrollSize.height; + } + + var box = this.document.createElement("div"); + //box.style.cssText = "margin:0; padding:1px; border: 0; position:static; overflow:hidden; visibility: hidden;"; + box.style.cssText = "margin:0; padding:1px; border: 0; visibility: hidden;"; + + var clone = el.cloneNode(false); + var text = this.document.createTextNode(" "); + clone.appendChild(text); + + box.appendChild(clone); + + this.document.body.appendChild(box); + + var marginTop = clone.offsetTop - box.offsetTop - 1; + var marginBottom = box.offsetHeight - clone.offsetHeight - 2 - marginTop; + + var marginLeft = clone.offsetLeft - box.offsetLeft - 1; + var marginRight = box.offsetWidth - clone.offsetWidth - 2 - marginLeft; + + this.document.body.removeChild(box); + + return {top:marginTop+offsetTop, left:marginLeft, bottom:marginBottom-offsetTop, right:marginRight}; + }, + + getFontSizeInPixels: function(el) + { + var size = this.getMeasurement(el, "fontSize"); + + if (size.unit == "px") return size.value; + + // get font size, the dirty way + var computeDirtyFontSize = function(el, calibration) + { + var div = this.document.createElement("div"); + var divStyle = offscreenStyle; + + if (calibration) + divStyle += " font-size:"+calibration+"px;"; + + div.style.cssText = divStyle; + div.innerHTML = "A"; + el.appendChild(div); + + var value = div.offsetHeight; + el.removeChild(div); + return value; + } + + /* + var calibrationBase = 200; + var calibrationValue = computeDirtyFontSize(el, calibrationBase); + var rate = calibrationBase / calibrationValue; + /**/ + + // the "dirty technique" fails in some environments, so we're using a static value + // based in some tests. + var rate = 200 / 225; + + var value = computeDirtyFontSize(el); + + return value * rate; + }, + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Unit Funtions + + pointsToPixels: function(name, value, returnFloat) + { + var axis = /Top$|Bottom$/.test(name) ? "y" : "x"; + + var result = value * pixelsPerInch[axis] / 72; + + return returnFloat ? result : Math.round(result); + }, + + emToPixels: function(el, value) + { + if (!el) return null; + + var fontSize = this.getFontSizeInPixels(el); + + return Math.round(value * fontSize); + }, + + exToPixels: function(el, value) + { + if (!el) return null; + + // get ex value, the dirty way + var div = this.document.createElement("div"); + div.style.cssText = offscreenStyle + "width:"+value + "ex;"; + + el.appendChild(div); + var value = div.offsetWidth; + el.removeChild(div); + + return value; + }, + + percentToPixels: function(el, value) + { + if (!el) return null; + + // get % value, the dirty way + var div = this.document.createElement("div"); + div.style.cssText = offscreenStyle + "width:"+value + "%;"; + + el.appendChild(div); + var value = div.offsetWidth; + el.removeChild(div); + + return value; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getStyle: isIE ? function(el, name) + { + return el.currentStyle[name] || el.style[name] || undefined; + } + : function(el, name) + { + return this.document.defaultView.getComputedStyle(el,null)[name] + || el.style[name] || undefined; + } + +}; + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +FBL.ns( /**@scope ns-chrome*/ function() { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +// Globals + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Window Options + +var WindowDefaultOptions = + { + type: "frame", + id: "FirebugUI", + height: 250 + }, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Instantiated objects + + commandLine, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Interface Elements Cache + + fbTop, + fbContent, + fbContentStyle, + fbBottom, + fbBtnInspect, + + fbToolbar, + + fbPanelBox1, + fbPanelBox1Style, + fbPanelBox2, + fbPanelBox2Style, + fbPanelBar2Box, + fbPanelBar2BoxStyle, + + fbHSplitter, + fbVSplitter, + fbVSplitterStyle, + + fbPanel1, + fbPanel1Style, + fbPanel2, + fbPanel2Style, + + fbConsole, + fbConsoleStyle, + fbHTML, + + fbCommandLine, + fbLargeCommandLine, + fbLargeCommandButtons, + +//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Cached size values + + topHeight, + topPartialHeight, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + chromeRedrawSkipRate = isIE ? 75 : isOpera ? 80 : 75, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + lastSelectedPanelName, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + focusCommandLineState = 0, + lastFocusedPanelName, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + lastHSplitterMouseMove = 0, + onHSplitterMouseMoveBuffer = null, + onHSplitterMouseMoveTimer = null, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + lastVSplitterMouseMove = 0; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + +// ************************************************************************************************ +// FirebugChrome + +/**@namespace*/ +FBL.FirebugChrome = +{ + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + isOpen: false, + height: 250, + sidePanelWidth: 350, + + selectedPanelName: "Console", + selectedHTMLElementId: null, + + chromeMap: {}, + + htmlSelectionStack: [], + consoleMessageQueue: [], + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + create: function() + { + if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("FirebugChrome.create", "creating chrome window"); + + createChromeWindow(); + }, + + initialize: function() + { + if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("FirebugChrome.initialize", "initializing chrome window"); + + if (Env.chrome.type == "frame" || Env.chrome.type == "div") + ChromeMini.create(Env.chrome); + + var chrome = Firebug.chrome = new Chrome(Env.chrome); + FirebugChrome.chromeMap[chrome.type] = chrome; + + addGlobalEvent("keydown", onGlobalKeyDown); + + if (Env.Options.enablePersistent && chrome.type == "popup") + { + // TODO: xxxpedro persist - revise chrome synchronization when in persistent mode + var frame = FirebugChrome.chromeMap.frame; + if (frame) + frame.close(); + + //chrome.reattach(frame, chrome); + //TODO: xxxpedro persist synchronize? + chrome.initialize(); + } + }, + + clone: function(FBChrome) + { + for (var name in FBChrome) + { + var prop = FBChrome[name]; + if (FBChrome.hasOwnProperty(name) && !isFunction(prop)) + { + this[name] = prop; + } + } + } +}; + + + +// ************************************************************************************************ +// Chrome Window Creation + +var createChromeWindow = function(options) +{ + options = extend(WindowDefaultOptions, options || {}); + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Locals + + var chrome = {}, + + context = options.context || Env.browser, + + type = chrome.type = Env.Options.enablePersistent ? + "popup" : + options.type, + + isChromeFrame = type == "frame", + + useLocalSkin = Env.useLocalSkin, + + url = useLocalSkin ? + Env.Location.skin : + "about:blank", + + // document.body not available in XML+XSL documents in Firefox + body = context.document.getElementsByTagName("body")[0], + + formatNode = function(node) + { + if (!Env.isDebugMode) + { + node.firebugIgnore = true; + } + + node.style.border = "0"; + node.style.visibility = "hidden"; + node.style.zIndex = "2147483647"; // MAX z-index = 2147483647 + node.style.position = noFixedPosition ? "absolute" : "fixed"; + node.style.width = "100%"; // "102%"; IE auto margin bug + node.style.left = "0"; + node.style.bottom = noFixedPosition ? "-1px" : "0"; + node.style.height = options.height + "px"; + + // avoid flickering during chrome rendering + if (isFirefox) + node.style.display = "none"; + }, + + createChromeDiv = function() + { + //Firebug.Console.warn("Firebug Lite GUI is working in 'windowless mode'. It may behave slower and receive interferences from the page in which it is installed."); + + var node = chrome.node = createGlobalElement("div"), + style = createGlobalElement("style"), + + css = FirebugChrome.Skin.CSS + /* + .replace(/;/g, " !important;") + .replace(/!important\s!important/g, "!important") + .replace(/display\s*:\s*(\w+)\s*!important;/g, "display:$1;")*/, + + // reset some styles to minimize interference from the main page's style + rules = ".fbBody *{margin:0;padding:0;font-size:11px;line-height:13px;color:inherit;}" + + // load the chrome styles + css + + // adjust some remaining styles + ".fbBody #fbHSplitter{position:absolute !important;} .fbBody #fbHTML span{line-height:14px;} .fbBody .lineNo div{line-height:inherit !important;}"; + /* + if (isIE) + { + // IE7 CSS bug (FbChrome table bigger than its parent div) + rules += ".fbBody table.fbChrome{position: static !important;}"; + }/**/ + + style.type = "text/css"; + + if (style.styleSheet) + style.styleSheet.cssText = rules; + else + style.appendChild(context.document.createTextNode(rules)); + + document.getElementsByTagName("head")[0].appendChild(style); + + node.className = "fbBody"; + node.style.overflow = "hidden"; + node.innerHTML = getChromeDivTemplate(); + + if (isIE) + { + // IE7 CSS bug (FbChrome table bigger than its parent div) + setTimeout(function(){ + node.firstChild.style.height = "1px"; + node.firstChild.style.position = "static"; + },0); + /**/ + } + + formatNode(node); + + body.appendChild(node); + + chrome.window = window; + chrome.document = document; + onChromeLoad(chrome); + }; + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + try + { + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // create the Chrome as a "div" (windowless mode) + if (type == "div") + { + createChromeDiv(); + return; + } + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // cretate the Chrome as an "iframe" + else if (isChromeFrame) + { + // Create the Chrome Frame + var node = chrome.node = createGlobalElement("iframe"); + node.setAttribute("src", url); + node.setAttribute("frameBorder", "0"); + + formatNode(node); + + body.appendChild(node); + + // must set the id after appending to the document, otherwise will cause an + // strange error in IE, making the iframe load the page in which the bookmarklet + // was created (like getfirebug.com), before loading the injected UI HTML, + // generating an "Access Denied" error. + node.id = options.id; + } + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // create the Chrome as a "popup" + else + { + var height = FirebugChrome.height || options.height, + + options = [ + "true,top=", + Math.max(screen.availHeight - height - 61 /* Google Chrome bug */, 0), + ",left=0,height=", + height, + ",width=", + screen.availWidth-10, // Opera opens popup in a new tab if it's too big! + ",resizable" + ].join(""), + + node = chrome.node = context.window.open( + url, + "popup", + options + ); + + if (node) + { + try + { + node.focus(); + } + catch(E) + { + alert("Firebug Error: Firebug popup was blocked."); + return; + } + } + else + { + alert("Firebug Error: Firebug popup was blocked."); + return; + } + } + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Inject the interface HTML if it is not using the local skin + + if (!useLocalSkin) + { + var tpl = getChromeTemplate(!isChromeFrame), + doc = isChromeFrame ? node.contentWindow.document : node.document; + + doc.write(tpl); + doc.close(); + } + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Wait the Window to be loaded + + var win, + + waitDelay = useLocalSkin ? isChromeFrame ? 200 : 300 : 100, + + waitForWindow = function() + { + if ( // Frame loaded... OR + isChromeFrame && (win=node.contentWindow) && + node.contentWindow.document.getElementById("fbCommandLine") || + + // Popup loaded + !isChromeFrame && (win=node.window) && node.document && + node.document.getElementById("fbCommandLine") ) + { + chrome.window = win.window; + chrome.document = win.document; + + // Prevent getting the wrong chrome height in FF when opening a popup + setTimeout(function(){ + onChromeLoad(chrome); + },0); + } + else + setTimeout(waitForWindow, waitDelay); + }; + + waitForWindow(); + } + catch(e) + { + var msg = e.message || e; + + if (/access/i.test(msg)) + { + // Firebug Lite could not create a window for its Graphical User Interface due to + // a access restriction. This happens in some pages, when loading via bookmarklet. + // In such cases, the only way is to load the GUI in a "windowless mode". + + if (isChromeFrame) + body.removeChild(node); + else if(type == "popup") + node.close(); + + // Load the GUI in a "windowless mode" + createChromeDiv(); + } + else + { + alert("Firebug Error: Firebug GUI could not be created."); + } + } +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var onChromeLoad = function onChromeLoad(chrome) +{ + Env.chrome = chrome; + + if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Chrome onChromeLoad", "chrome window loaded"); + + if (Env.Options.enablePersistent) + { + // TODO: xxxpedro persist - make better chrome synchronization when in persistent mode + Env.FirebugChrome = FirebugChrome; + + chrome.window.Firebug = chrome.window.Firebug || {}; + chrome.window.Firebug.SharedEnv = Env; + + if (Env.isDevelopmentMode) + { + Env.browser.window.FBDev.loadChromeApplication(chrome); + } + else + { + var doc = chrome.document; + var script = doc.createElement("script"); + script.src = Env.Location.app + "#remote,persist"; + doc.getElementsByTagName("head")[0].appendChild(script); + } + } + else + { + if (chrome.type == "frame" || chrome.type == "div") + { + // initialize the chrome application + setTimeout(function(){ + FBL.Firebug.initialize(); + },0); + } + else if (chrome.type == "popup") + { + var oldChrome = FirebugChrome.chromeMap.frame; + + var newChrome = new Chrome(chrome); + + // TODO: xxxpedro sync detach reattach attach + dispatch(newChrome.panelMap, "detach", [oldChrome, newChrome]); + + if (oldChrome) + oldChrome.close(); + + newChrome.reattach(oldChrome, newChrome); + } + } +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var getChromeDivTemplate = function() +{ + return FirebugChrome.Skin.HTML; +}; + +var getChromeTemplate = function(isPopup) +{ + var tpl = FirebugChrome.Skin; + var r = [], i = -1; + + r[++i] = ''; + r[++i] = ''; + r[++i] = Firebug.version; + + /* + r[++i] = ''; + /**/ + + r[++i] = ''; + /**/ + + r[++i] = ''; + r[++i] = tpl.HTML; + r[++i] = ''; + + return r.join(""); +}; + + +// ************************************************************************************************ +// Chrome Class + +/**@class*/ +var Chrome = function Chrome(chrome) +{ + var type = chrome.type; + var Base = type == "frame" || type == "div" ? ChromeFrameBase : ChromePopupBase; + + append(this, Base); // inherit from base class (ChromeFrameBase or ChromePopupBase) + append(this, chrome); // inherit chrome window properties + append(this, new Context(chrome.window)); // inherit from Context class + + FirebugChrome.chromeMap[type] = this; + Firebug.chrome = this; + Env.chrome = chrome.window; + + this.commandLineVisible = false; + this.sidePanelVisible = false; + + this.create(); + + return this; +}; + +// ************************************************************************************************ +// ChromeBase + +/** + * @namespace + * @extends FBL.Controller + * @extends FBL.PanelBar + **/ +var ChromeBase = {}; +append(ChromeBase, Controller); +append(ChromeBase, PanelBar); +append(ChromeBase, +/**@extend ns-chrome-ChromeBase*/ +{ + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // inherited properties + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // inherited from createChrome function + + node: null, + type: null, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // inherited from Context.prototype + + document: null, + window: null, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // value properties + + sidePanelVisible: false, + commandLineVisible: false, + largeCommandLineVisible: false, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // object properties + + inspectButton: null, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + create: function() + { + PanelBar.create.call(this); + + if (Firebug.Inspector) + this.inspectButton = new Button({ + type: "toggle", + element: $("fbChrome_btInspect"), + owner: Firebug.Inspector, + + onPress: Firebug.Inspector.startInspecting, + onUnpress: Firebug.Inspector.stopInspecting + }); + }, + + destroy: function() + { + if(Firebug.Inspector) + this.inspectButton.destroy(); + + PanelBar.destroy.call(this); + + this.shutdown(); + }, + + testMenu: function() + { + var firebugMenu = new Menu( + { + id: "fbFirebugMenu", + + items: + [ + { + label: "Open Firebug", + type: "shortcut", + key: isFirefox ? "Shift+F12" : "F12", + checked: true, + command: "toggleChrome" + }, + { + label: "Open Firebug in New Window", + type: "shortcut", + key: isFirefox ? "Ctrl+Shift+F12" : "Ctrl+F12", + command: "openPopup" + }, + { + label: "Inspect Element", + type: "shortcut", + key: "Ctrl+Shift+C", + command: "toggleInspect" + }, + { + label: "Command Line", + type: "shortcut", + key: "Ctrl+Shift+L", + command: "focusCommandLine" + }, + "-", + { + label: "Options", + type: "group", + child: "fbFirebugOptionsMenu" + }, + "-", + { + label: "Firebug Lite Website...", + command: "visitWebsite" + }, + { + label: "Discussion Group...", + command: "visitDiscussionGroup" + }, + { + label: "Issue Tracker...", + command: "visitIssueTracker" + } + ], + + onHide: function() + { + iconButton.restore(); + }, + + toggleChrome: function() + { + Firebug.chrome.toggle(); + }, + + openPopup: function() + { + Firebug.chrome.toggle(true, true); + }, + + toggleInspect: function() + { + Firebug.Inspector.toggleInspect(); + }, + + focusCommandLine: function() + { + Firebug.chrome.focusCommandLine(); + }, + + visitWebsite: function() + { + this.visit("http://getfirebug.com/lite.html"); + }, + + visitDiscussionGroup: function() + { + this.visit("http://groups.google.com/group/firebug"); + }, + + visitIssueTracker: function() + { + this.visit("http://code.google.com/p/fbug/issues/list"); + }, + + visit: function(url) + { + window.open(url); + } + + }); + + /**@private*/ + var firebugOptionsMenu = + { + id: "fbFirebugOptionsMenu", + + getItems: function() + { + var cookiesDisabled = !Firebug.saveCookies; + + return [ + { + label: "Save Options in Cookies", + type: "checkbox", + value: "saveCookies", + checked: Firebug.saveCookies, + command: "saveOptions" + }, + "-", + { + label: "Start Opened", + type: "checkbox", + value: "startOpened", + checked: Firebug.startOpened, + disabled: cookiesDisabled + }, + { + label: "Start in New Window", + type: "checkbox", + value: "startInNewWindow", + checked: Firebug.startInNewWindow, + disabled: cookiesDisabled + }, + { + label: "Show Icon When Hidden", + type: "checkbox", + value: "showIconWhenHidden", + checked: Firebug.showIconWhenHidden, + disabled: cookiesDisabled + }, + { + label: "Override Console Object", + type: "checkbox", + value: "overrideConsole", + checked: Firebug.overrideConsole, + disabled: cookiesDisabled + }, + { + label: "Ignore Firebug Elements", + type: "checkbox", + value: "ignoreFirebugElements", + checked: Firebug.ignoreFirebugElements, + disabled: cookiesDisabled + }, + { + label: "Disable When Firebug Active", + type: "checkbox", + value: "disableWhenFirebugActive", + checked: Firebug.disableWhenFirebugActive, + disabled: cookiesDisabled + }, + { + label: "Disable XHR Listener", + type: "checkbox", + value: "disableXHRListener", + checked: Firebug.disableXHRListener, + disabled: cookiesDisabled + }, + { + label: "Enable Trace Mode", + type: "checkbox", + value: "enableTrace", + checked: Firebug.enableTrace, + disabled: cookiesDisabled + }, + { + label: "Enable Persistent Mode (experimental)", + type: "checkbox", + value: "enablePersistent", + checked: Firebug.enablePersistent, + disabled: cookiesDisabled + }, + "-", + { + label: "Reset All Firebug Options", + command: "restorePrefs", + disabled: cookiesDisabled + } + ]; + }, + + onCheck: function(target, value, checked) + { + Firebug.setPref(value, checked); + }, + + saveOptions: function(target) + { + var saveEnabled = target.getAttribute("checked"); + + if (!saveEnabled) this.restorePrefs(); + + this.updateMenu(target); + + return false; + }, + + restorePrefs: function(target) + { + Firebug.restorePrefs(); + + if(Firebug.saveCookies) + Firebug.savePrefs(); + else + Firebug.erasePrefs(); + + if (target) + this.updateMenu(target); + + return false; + }, + + updateMenu: function(target) + { + var options = getElementsByClass(target.parentNode, "fbMenuOption"); + + var firstOption = options[0]; + var enabled = Firebug.saveCookies; + if (enabled) + Menu.check(firstOption); + else + Menu.uncheck(firstOption); + + if (enabled) + Menu.check(options[0]); + else + Menu.uncheck(options[0]); + + for (var i = 1, length = options.length; i < length; i++) + { + var option = options[i]; + + var value = option.getAttribute("value"); + var pref = Firebug[value]; + + if (pref) + Menu.check(option); + else + Menu.uncheck(option); + + if (enabled) + Menu.enable(option); + else + Menu.disable(option); + } + } + }; + + Menu.register(firebugOptionsMenu); + + var menu = firebugMenu; + + var testMenuClick = function(event) + { + //console.log("testMenuClick"); + cancelEvent(event, true); + + var target = event.target || event.srcElement; + + if (menu.isVisible) + menu.hide(); + else + { + var offsetLeft = isIE6 ? 1 : -4, // IE6 problem with fixed position + + chrome = Firebug.chrome, + + box = chrome.getElementBox(target), + + offset = chrome.type == "div" ? + chrome.getElementPosition(chrome.node) : + {top: 0, left: 0}; + + menu.show( + box.left + offsetLeft - offset.left, + box.top + box.height -5 - offset.top + ); + } + + return false; + }; + + var iconButton = new IconButton({ + type: "toggle", + element: $("fbFirebugButton"), + + onClick: testMenuClick + }); + + iconButton.initialize(); + + //addEvent($("fbToolbarIcon"), "click", testMenuClick); + }, + + initialize: function() + { + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + if (Env.bookmarkletOutdated) + Firebug.Console.logFormatted([ + "A new bookmarklet version is available. " + + "Please visit http://getfirebug.com/firebuglite#Install and update it." + ], Firebug.context, "warn"); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + if (Firebug.Console) + Firebug.Console.flush(); + + if (Firebug.Trace) + FBTrace.flush(Firebug.Trace); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.chrome.initialize", "initializing chrome application"); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // initialize inherited classes + Controller.initialize.call(this); + PanelBar.initialize.call(this); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // create the interface elements cache + + fbTop = $("fbTop"); + fbContent = $("fbContent"); + fbContentStyle = fbContent.style; + fbBottom = $("fbBottom"); + fbBtnInspect = $("fbBtnInspect"); + + fbToolbar = $("fbToolbar"); + + fbPanelBox1 = $("fbPanelBox1"); + fbPanelBox1Style = fbPanelBox1.style; + fbPanelBox2 = $("fbPanelBox2"); + fbPanelBox2Style = fbPanelBox2.style; + fbPanelBar2Box = $("fbPanelBar2Box"); + fbPanelBar2BoxStyle = fbPanelBar2Box.style; + + fbHSplitter = $("fbHSplitter"); + fbVSplitter = $("fbVSplitter"); + fbVSplitterStyle = fbVSplitter.style; + + fbPanel1 = $("fbPanel1"); + fbPanel1Style = fbPanel1.style; + fbPanel2 = $("fbPanel2"); + fbPanel2Style = fbPanel2.style; + + fbConsole = $("fbConsole"); + fbConsoleStyle = fbConsole.style; + fbHTML = $("fbHTML"); + + fbCommandLine = $("fbCommandLine"); + fbLargeCommandLine = $("fbLargeCommandLine"); + fbLargeCommandButtons = $("fbLargeCommandButtons"); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // static values cache + topHeight = fbTop.offsetHeight; + topPartialHeight = fbToolbar.offsetHeight; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + disableTextSelection($("fbToolbar")); + disableTextSelection($("fbPanelBarBox")); + disableTextSelection($("fbPanelBar1")); + disableTextSelection($("fbPanelBar2")); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Add the "javascript:void(0)" href attributes used to make the hover effect in IE6 + if (isIE6 && Firebug.Selector) + { + // TODO: xxxpedro change to getElementsByClass + var as = $$(".fbHover"); + for (var i=0, a; a=as[i]; i++) + { + a.setAttribute("href", "javascript:void(0)"); + } + } + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // initialize all panels + /* + var panelMap = Firebug.panelTypes; + for (var i=0, p; p=panelMap[i]; i++) + { + if (!p.parentPanel) + { + this.addPanel(p.prototype.name); + } + } + /**/ + + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + + if(Firebug.Inspector) + this.inspectButton.initialize(); + + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + + this.addController( + [$("fbLargeCommandLineIcon"), "click", this.showLargeCommandLine] + ); + + // ************************************************************************************************ + + // Select the first registered panel + // TODO: BUG IE7 + var self = this; + setTimeout(function(){ + self.selectPanel(FirebugChrome.selectedPanelName); + + if (FirebugChrome.selectedPanelName == "Console" && Firebug.CommandLine) + Firebug.chrome.focusCommandLine(); + },0); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + //this.draw(); + + + + + + + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + var onPanelMouseDown = function onPanelMouseDown(event) + { + //console.log("onPanelMouseDown", event.target || event.srcElement, event); + + var target = event.target || event.srcElement; + + if (FBL.isLeftClick(event)) + { + var editable = FBL.getAncestorByClass(target, "editable"); + + // if an editable element has been clicked then start editing + if (editable) + { + Firebug.Editor.startEditing(editable); + FBL.cancelEvent(event); + } + // if any other element has been clicked then stop editing + else + { + if (!hasClass(target, "textEditorInner")) + Firebug.Editor.stopEditing(); + } + } + else if (FBL.isMiddleClick(event) && Firebug.getRepNode(target)) + { + // Prevent auto-scroll when middle-clicking a rep object + FBL.cancelEvent(event); + } + }; + + Firebug.getElementPanel = function(element) + { + var panelNode = getAncestorByClass(element, "fbPanel"); + var id = panelNode.id.substr(2); + + var panel = Firebug.chrome.panelMap[id]; + + if (!panel) + { + if (Firebug.chrome.selectedPanel.sidePanelBar) + panel = Firebug.chrome.selectedPanel.sidePanelBar.panelMap[id]; + } + + return panel; + }; + + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + // TODO: xxxpedro port to Firebug + + // Improved window key code event listener. Only one "keydown" event will be attached + // to the window, and the onKeyCodeListen() function will delegate which listeners + // should be called according to the event.keyCode fired. + var onKeyCodeListenersMap = []; + var onKeyCodeListen = function(event) + { + for (var keyCode in onKeyCodeListenersMap) + { + var listeners = onKeyCodeListenersMap[keyCode]; + + for (var i = 0, listener; listener = listeners[i]; i++) + { + var filter = listener.filter || FBL.noKeyModifiers; + + if (event.keyCode == keyCode && (!filter || filter(event))) + { + listener.listener(); + FBL.cancelEvent(event, true); + return false; + } + } + } + }; + + addEvent(Firebug.chrome.document, "keydown", onKeyCodeListen); + + /** + * @name keyCodeListen + * @memberOf FBL.FirebugChrome + */ + Firebug.chrome.keyCodeListen = function(key, filter, listener, capture) + { + var keyCode = KeyEvent["DOM_VK_"+key]; + + if (!onKeyCodeListenersMap[keyCode]) + onKeyCodeListenersMap[keyCode] = []; + + onKeyCodeListenersMap[keyCode].push({ + filter: filter, + listener: listener + }); + + return keyCode; + }; + + /** + * @name keyIgnore + * @memberOf FBL.FirebugChrome + */ + Firebug.chrome.keyIgnore = function(keyCode) + { + onKeyCodeListenersMap[keyCode] = null; + delete onKeyCodeListenersMap[keyCode]; + }; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + /**/ + // move to shutdown + //removeEvent(Firebug.chrome.document, "keydown", listener[0]); + + + /* + Firebug.chrome.keyCodeListen = function(key, filter, listener, capture) + { + if (!filter) + filter = FBL.noKeyModifiers; + + var keyCode = KeyEvent["DOM_VK_"+key]; + + var fn = function fn(event) + { + if (event.keyCode == keyCode && (!filter || filter(event))) + { + listener(); + FBL.cancelEvent(event, true); + return false; + } + } + + addEvent(Firebug.chrome.document, "keydown", fn); + + return [fn, capture]; + }; + + Firebug.chrome.keyIgnore = function(listener) + { + removeEvent(Firebug.chrome.document, "keydown", listener[0]); + }; + /**/ + + + this.addController( + [fbPanel1, "mousedown", onPanelMouseDown], + [fbPanel2, "mousedown", onPanelMouseDown] + ); +/**/ + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + + // menus can be used without domplate + if (FBL.domplate) + this.testMenu(); + /**/ + + //test XHR + /* + setTimeout(function(){ + + FBL.Ajax.request({url: "../content/firebug/boot.js"}); + FBL.Ajax.request({url: "../content/firebug/boot.js.invalid"}); + + },1000); + /**/ + }, + + shutdown: function() + { + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + + if(Firebug.Inspector) + this.inspectButton.shutdown(); + + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + // remove disableTextSelection event handlers + restoreTextSelection($("fbToolbar")); + restoreTextSelection($("fbPanelBarBox")); + restoreTextSelection($("fbPanelBar1")); + restoreTextSelection($("fbPanelBar2")); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // shutdown inherited classes + Controller.shutdown.call(this); + PanelBar.shutdown.call(this); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Remove the interface elements cache (this must happen after calling + // the shutdown method of all dependent components to avoid errors) + + fbTop = null; + fbContent = null; + fbContentStyle = null; + fbBottom = null; + fbBtnInspect = null; + + fbToolbar = null; + + fbPanelBox1 = null; + fbPanelBox1Style = null; + fbPanelBox2 = null; + fbPanelBox2Style = null; + fbPanelBar2Box = null; + fbPanelBar2BoxStyle = null; + + fbHSplitter = null; + fbVSplitter = null; + fbVSplitterStyle = null; + + fbPanel1 = null; + fbPanel1Style = null; + fbPanel2 = null; + + fbConsole = null; + fbConsoleStyle = null; + fbHTML = null; + + fbCommandLine = null; + fbLargeCommandLine = null; + fbLargeCommandButtons = null; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // static values cache + + topHeight = null; + topPartialHeight = null; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + toggle: function(forceOpen, popup) + { + if(popup) + { + this.detach(); + } + else + { + if (isOpera && Firebug.chrome.type == "popup" && Firebug.chrome.node.closed) + { + var frame = FirebugChrome.chromeMap.frame; + frame.reattach(); + + FirebugChrome.chromeMap.popup = null; + + frame.open(); + + return; + } + + // If the context is a popup, ignores the toggle process + if (Firebug.chrome.type == "popup") return; + + var shouldOpen = forceOpen || !FirebugChrome.isOpen; + + if(shouldOpen) + this.open(); + else + this.close(); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + detach: function() + { + if(!FirebugChrome.chromeMap.popup) + { + createChromeWindow({type: "popup"}); + } + }, + + reattach: function(oldChrome, newChrome) + { + Firebug.browser.window.Firebug = Firebug; + + // chrome synchronization + var newPanelMap = newChrome.panelMap; + var oldPanelMap = oldChrome.panelMap; + + var panel; + for(var name in newPanelMap) + { + // TODO: xxxpedro innerHTML + panel = newPanelMap[name]; + if (panel.options.innerHTMLSync) + panel.panelNode.innerHTML = oldPanelMap[name].panelNode.innerHTML; + } + + Firebug.chrome = newChrome; + + // TODO: xxxpedro sync detach reattach attach + //dispatch(Firebug.chrome.panelMap, "detach", [oldChrome, newChrome]); + + if (newChrome.type == "popup") + { + newChrome.initialize(); + //dispatch(Firebug.modules, "initialize", []); + } + else + { + // TODO: xxxpedro only needed in persistent + // should use FirebugChrome.clone, but popup FBChrome + // isn't acessible + FirebugChrome.selectedPanelName = oldChrome.selectedPanel.name; + } + + dispatch(newPanelMap, "reattach", [oldChrome, newChrome]); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + draw: function() + { + var size = this.getSize(); + + // Height related values + var commandLineHeight = Firebug.chrome.commandLineVisible ? fbCommandLine.offsetHeight : 0, + + y = Math.max(size.height /* chrome height */, topHeight), + + heightValue = Math.max(y - topHeight - commandLineHeight /* fixed height */, 0), + + height = heightValue + "px", + + // Width related values + sideWidthValue = Firebug.chrome.sidePanelVisible ? FirebugChrome.sidePanelWidth : 0, + + width = Math.max(size.width /* chrome width */ - sideWidthValue, 0) + "px"; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Height related rendering + fbPanelBox1Style.height = height; + fbPanel1Style.height = height; + + if (isIE || isOpera) + { + // Fix IE and Opera problems with auto resizing the verticall splitter + fbVSplitterStyle.height = Math.max(y - topPartialHeight - commandLineHeight, 0) + "px"; + } + //xxxpedro FF2 only? + /* + else if (isFirefox) + { + // Fix Firefox problem with table rows with 100% height (fit height) + fbContentStyle.maxHeight = Math.max(y - fixedHeight, 0)+ "px"; + }/**/ + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Width related rendering + fbPanelBox1Style.width = width; + fbPanel1Style.width = width; + + // SidePanel rendering + if (Firebug.chrome.sidePanelVisible) + { + sideWidthValue = Math.max(sideWidthValue - 6, 0); + + var sideWidth = sideWidthValue + "px"; + + fbPanelBox2Style.width = sideWidth; + + fbVSplitterStyle.right = sideWidth; + + if (Firebug.chrome.largeCommandLineVisible) + { + fbLargeCommandLine = $("fbLargeCommandLine"); + + fbLargeCommandLine.style.height = heightValue - 4 + "px"; + fbLargeCommandLine.style.width = sideWidthValue - 2 + "px"; + + fbLargeCommandButtons = $("fbLargeCommandButtons"); + fbLargeCommandButtons.style.width = sideWidth; + } + else + { + fbPanel2Style.height = height; + fbPanel2Style.width = sideWidth; + + fbPanelBar2BoxStyle.width = sideWidth; + } + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getSize: function() + { + return this.type == "div" ? + { + height: this.node.offsetHeight, + width: this.node.offsetWidth + } + : + this.getWindowSize(); + }, + + resize: function() + { + var self = this; + + // avoid partial resize when maximizing window + setTimeout(function(){ + self.draw(); + + if (noFixedPosition && (self.type == "frame" || self.type == "div")) + self.fixIEPosition(); + }, 0); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + layout: function(panel) + { + if (FBTrace.DBG_CHROME) FBTrace.sysout("Chrome.layout", ""); + + var options = panel.options; + + changeCommandLineVisibility(options.hasCommandLine); + changeSidePanelVisibility(panel.hasSidePanel); + + Firebug.chrome.draw(); + }, + + showLargeCommandLine: function(hideToggleIcon) + { + var chrome = Firebug.chrome; + + if (!chrome.largeCommandLineVisible) + { + chrome.largeCommandLineVisible = true; + + if (chrome.selectedPanel.options.hasCommandLine) + { + if (Firebug.CommandLine) + Firebug.CommandLine.blur(); + + changeCommandLineVisibility(false); + } + + changeSidePanelVisibility(true); + + fbLargeCommandLine.style.display = "block"; + fbLargeCommandButtons.style.display = "block"; + + fbPanel2Style.display = "none"; + fbPanelBar2BoxStyle.display = "none"; + + chrome.draw(); + + fbLargeCommandLine.focus(); + + if (Firebug.CommandLine) + Firebug.CommandLine.setMultiLine(true); + } + }, + + hideLargeCommandLine: function() + { + if (Firebug.chrome.largeCommandLineVisible) + { + Firebug.chrome.largeCommandLineVisible = false; + + if (Firebug.CommandLine) + Firebug.CommandLine.setMultiLine(false); + + fbLargeCommandLine.blur(); + + fbPanel2Style.display = "block"; + fbPanelBar2BoxStyle.display = "block"; + + fbLargeCommandLine.style.display = "none"; + fbLargeCommandButtons.style.display = "none"; + + changeSidePanelVisibility(false); + + if (Firebug.chrome.selectedPanel.options.hasCommandLine) + changeCommandLineVisibility(true); + + Firebug.chrome.draw(); + + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + focusCommandLine: function() + { + var selectedPanelName = this.selectedPanel.name, panelToSelect; + + if (focusCommandLineState == 0 || selectedPanelName != "Console") + { + focusCommandLineState = 0; + lastFocusedPanelName = selectedPanelName; + + panelToSelect = "Console"; + } + if (focusCommandLineState == 1) + { + panelToSelect = lastFocusedPanelName; + } + + this.selectPanel(panelToSelect); + + try + { + if (Firebug.CommandLine) + { + if (panelToSelect == "Console") + Firebug.CommandLine.focus(); + else + Firebug.CommandLine.blur(); + } + } + catch(e) + { + //TODO: xxxpedro trace error + } + + focusCommandLineState = ++focusCommandLineState % 2; + } + +}); + +// ************************************************************************************************ +// ChromeFrameBase + +/** + * @namespace + * @extends ns-chrome-ChromeBase + */ +var ChromeFrameBase = extend(ChromeBase, +/**@extend ns-chrome-ChromeFrameBase*/ +{ + create: function() + { + ChromeBase.create.call(this); + + // restore display for the anti-flicker trick + if (isFirefox) + this.node.style.display = "block"; + + if (Env.Options.startInNewWindow) + { + this.close(); + this.toggle(true, true); + return; + } + + if (Env.Options.startOpened) + this.open(); + else + this.close(); + }, + + destroy: function() + { + removeGlobalEvent("keydown", onGlobalKeyDown); + + ChromeBase.destroy.call(this); + + this.document = null; + delete this.document; + + this.window = null; + delete this.window; + + this.node.parentNode.removeChild(this.node); + this.node = null; + delete this.node; + }, + + initialize: function() + { + //FBTrace.sysout("Frame", "initialize();") + ChromeBase.initialize.call(this); + + this.addController( + [Firebug.browser.window, "resize", this.resize], + [$("fbWindow_btClose"), "click", this.close], + [$("fbWindow_btDetach"), "click", this.detach], + [$("fbWindow_btDeactivate"), "click", this.deactivate] + ); + + if (!Env.Options.enablePersistent) + this.addController([Firebug.browser.window, "unload", Firebug.shutdown]); + + if (noFixedPosition) + { + this.addController( + [Firebug.browser.window, "scroll", this.fixIEPosition] + ); + } + + fbVSplitter.onmousedown = onVSplitterMouseDown; + fbHSplitter.onmousedown = onHSplitterMouseDown; + + this.isInitialized = true; + }, + + shutdown: function() + { + fbVSplitter.onmousedown = null; + fbHSplitter.onmousedown = null; + + ChromeBase.shutdown.apply(this); + + this.isInitialized = false; + }, + + reattach: function() + { + var frame = FirebugChrome.chromeMap.frame; + + ChromeBase.reattach(FirebugChrome.chromeMap.popup, this); + }, + + open: function() + { + if (!FirebugChrome.isOpen) + { + FirebugChrome.isOpen = true; + + if (Env.isChromeExtension) + localStorage.setItem("Firebug", "1,1"); + + var node = this.node; + + node.style.visibility = "hidden"; // Avoid flickering + + if (Firebug.showIconWhenHidden) + { + if (ChromeMini.isInitialized) + { + ChromeMini.shutdown(); + } + + } + else + node.style.display = "block"; + + var main = $("fbChrome"); + + // IE6 throws an error when setting this property! why? + //main.style.display = "table"; + main.style.display = ""; + + var self = this; + setTimeout(function(){ + node.style.visibility = "visible"; + + //dispatch(Firebug.modules, "initialize", []); + self.initialize(); + + if (noFixedPosition) + self.fixIEPosition(); + + self.draw(); + + }, 10); + } + }, + + close: function() + { + if (FirebugChrome.isOpen || !this.isInitialized) + { + if (this.isInitialized) + { + //dispatch(Firebug.modules, "shutdown", []); + this.shutdown(); + } + + FirebugChrome.isOpen = false; + + if (Env.isChromeExtension) + localStorage.setItem("Firebug", "1,0"); + + var node = this.node; + + if (Firebug.showIconWhenHidden) + { + node.style.visibility = "hidden"; // Avoid flickering + + // TODO: xxxpedro - persist IE fixed? + var main = $("fbChrome", FirebugChrome.chromeMap.frame.document); + main.style.display = "none"; + + ChromeMini.initialize(); + + node.style.visibility = "visible"; + } + else + node.style.display = "none"; + } + }, + + deactivate: function() + { + // if it is running as a Chrome extension, dispatch a message to the extension signaling + // that Firebug should be deactivated for the current tab + if (Env.isChromeExtension) + { + localStorage.removeItem("Firebug"); + Firebug.GoogleChrome.dispatch("FB_deactivate"); + + // xxxpedro problem here regarding Chrome extension. We can't deactivate the whole + // app, otherwise it won't be able to be reactivated without reloading the page. + // but we need to stop listening global keys, otherwise the key activation won't work. + Firebug.chrome.close(); + } + else + { + Firebug.shutdown(); + } + }, + + fixIEPosition: function() + { + // fix IE problem with offset when not in fullscreen mode + var doc = this.document; + var offset = isIE ? doc.body.clientTop || doc.documentElement.clientTop: 0; + + var size = Firebug.browser.getWindowSize(); + var scroll = Firebug.browser.getWindowScrollPosition(); + var maxHeight = size.height; + var height = this.node.offsetHeight; + + var bodyStyle = doc.body.currentStyle; + + this.node.style.top = maxHeight - height + scroll.top + "px"; + + if ((this.type == "frame" || this.type == "div") && + (bodyStyle.marginLeft || bodyStyle.marginRight)) + { + this.node.style.width = size.width + "px"; + } + + if (fbVSplitterStyle) + fbVSplitterStyle.right = FirebugChrome.sidePanelWidth + "px"; + + this.draw(); + } + +}); + + +// ************************************************************************************************ +// ChromeMini + +/** + * @namespace + * @extends FBL.Controller + */ +var ChromeMini = extend(Controller, +/**@extend ns-chrome-ChromeMini*/ +{ + create: function(chrome) + { + append(this, chrome); + this.type = "mini"; + }, + + initialize: function() + { + Controller.initialize.apply(this); + + var doc = FirebugChrome.chromeMap.frame.document; + + var mini = $("fbMiniChrome", doc); + mini.style.display = "block"; + + var miniIcon = $("fbMiniIcon", doc); + var width = miniIcon.offsetWidth + 10; + miniIcon.title = "Open " + Firebug.version; + + var errors = $("fbMiniErrors", doc); + if (errors.offsetWidth) + width += errors.offsetWidth + 10; + + var node = this.node; + node.style.height = "27px"; + node.style.width = width + "px"; + node.style.left = ""; + node.style.right = 0; + + if (this.node.nodeName.toLowerCase() == "iframe") + { + node.setAttribute("allowTransparency", "true"); + this.document.body.style.backgroundColor = "transparent"; + } + else + node.style.background = "transparent"; + + if (noFixedPosition) + this.fixIEPosition(); + + this.addController( + [$("fbMiniIcon", doc), "click", onMiniIconClick] + ); + + if (noFixedPosition) + { + this.addController( + [Firebug.browser.window, "scroll", this.fixIEPosition] + ); + } + + this.isInitialized = true; + }, + + shutdown: function() + { + var node = this.node; + node.style.height = FirebugChrome.height + "px"; + node.style.width = "100%"; + node.style.left = 0; + node.style.right = ""; + + if (this.node.nodeName.toLowerCase() == "iframe") + { + node.setAttribute("allowTransparency", "false"); + this.document.body.style.backgroundColor = "#fff"; + } + else + node.style.background = "#fff"; + + if (noFixedPosition) + this.fixIEPosition(); + + var doc = FirebugChrome.chromeMap.frame.document; + + var mini = $("fbMiniChrome", doc); + mini.style.display = "none"; + + Controller.shutdown.apply(this); + + this.isInitialized = false; + }, + + draw: function() + { + + }, + + fixIEPosition: ChromeFrameBase.fixIEPosition + +}); + + +// ************************************************************************************************ +// ChromePopupBase + +/** + * @namespace + * @extends ns-chrome-ChromeBase + */ +var ChromePopupBase = extend(ChromeBase, +/**@extend ns-chrome-ChromePopupBase*/ +{ + + initialize: function() + { + setClass(this.document.body, "FirebugPopup"); + + ChromeBase.initialize.call(this); + + this.addController( + [Firebug.chrome.window, "resize", this.resize], + [Firebug.chrome.window, "unload", this.destroy] + ); + + if (Env.Options.enablePersistent) + { + this.persist = bind(this.persist, this); + addEvent(Firebug.browser.window, "unload", this.persist); + } + else + this.addController( + [Firebug.browser.window, "unload", this.close] + ); + + fbVSplitter.onmousedown = onVSplitterMouseDown; + }, + + destroy: function() + { + // TODO: xxxpedro sync detach reattach attach + var frame = FirebugChrome.chromeMap.frame; + + if(frame) + { + dispatch(frame.panelMap, "detach", [this, frame]); + + frame.reattach(this, frame); + } + + if (Env.Options.enablePersistent) + { + removeEvent(Firebug.browser.window, "unload", this.persist); + } + + ChromeBase.destroy.apply(this); + + FirebugChrome.chromeMap.popup = null; + + this.node.close(); + }, + + persist: function() + { + persistTimeStart = new Date().getTime(); + + removeEvent(Firebug.browser.window, "unload", this.persist); + + Firebug.Inspector.destroy(); + Firebug.browser.window.FirebugOldBrowser = true; + + var persistTimeStart = new Date().getTime(); + + var waitMainWindow = function() + { + var doc, head; + + try + { + if (window.opener && !window.opener.FirebugOldBrowser && (doc = window.opener.document)/* && + doc.documentElement && (head = doc.documentElement.firstChild)*/) + { + + try + { + // exposes the FBL to the global namespace when in debug mode + if (Env.isDebugMode) + { + window.FBL = FBL; + } + + window.Firebug = Firebug; + window.opener.Firebug = Firebug; + + Env.browser = window.opener; + Firebug.browser = Firebug.context = new Context(Env.browser); + + registerConsole(); + + // the delay time should be calculated right after registering the + // console, once right after the console registration, call log messages + // will be properly handled + var persistDelay = new Date().getTime() - persistTimeStart; + + var chrome = Firebug.chrome; + addEvent(Firebug.browser.window, "unload", chrome.persist); + + FBL.cacheDocument(); + Firebug.Inspector.create(); + + var htmlPanel = chrome.getPanel("HTML"); + htmlPanel.createUI(); + + Firebug.Console.logFormatted( + ["Firebug could not capture console calls during " + + persistDelay + "ms"], + Firebug.context, + "info" + ); + } + catch(pE) + { + alert("persist error: " + (pE.message || pE)); + } + + } + else + { + window.setTimeout(waitMainWindow, 0); + } + + } catch (E) { + window.close(); + } + }; + + waitMainWindow(); + }, + + close: function() + { + this.destroy(); + } + +}); + + +//************************************************************************************************ +// UI helpers + +var changeCommandLineVisibility = function changeCommandLineVisibility(visibility) +{ + var last = Firebug.chrome.commandLineVisible; + var visible = Firebug.chrome.commandLineVisible = + typeof visibility == "boolean" ? visibility : !Firebug.chrome.commandLineVisible; + + if (visible != last) + { + if (visible) + { + fbBottom.className = ""; + + if (Firebug.CommandLine) + Firebug.CommandLine.activate(); + } + else + { + if (Firebug.CommandLine) + Firebug.CommandLine.deactivate(); + + fbBottom.className = "hide"; + } + } +}; + +var changeSidePanelVisibility = function changeSidePanelVisibility(visibility) +{ + var last = Firebug.chrome.sidePanelVisible; + Firebug.chrome.sidePanelVisible = + typeof visibility == "boolean" ? visibility : !Firebug.chrome.sidePanelVisible; + + if (Firebug.chrome.sidePanelVisible != last) + { + fbPanelBox2.className = Firebug.chrome.sidePanelVisible ? "" : "hide"; + fbPanelBar2Box.className = Firebug.chrome.sidePanelVisible ? "" : "hide"; + } +}; + + +// ************************************************************************************************ +// F12 Handler + +var onGlobalKeyDown = function onGlobalKeyDown(event) +{ + var keyCode = event.keyCode; + var shiftKey = event.shiftKey; + var ctrlKey = event.ctrlKey; + + if (keyCode == 123 /* F12 */ && (!isFirefox && !shiftKey || shiftKey && isFirefox)) + { + Firebug.chrome.toggle(false, ctrlKey); + cancelEvent(event, true); + + // TODO: xxxpedro replace with a better solution. we're doing this + // to allow reactivating with the F12 key after being deactivated + if (Env.isChromeExtension) + { + Firebug.GoogleChrome.dispatch("FB_enableIcon"); + } + } + else if (keyCode == 67 /* C */ && ctrlKey && shiftKey) + { + Firebug.Inspector.toggleInspect(); + cancelEvent(event, true); + } + else if (keyCode == 76 /* L */ && ctrlKey && shiftKey) + { + Firebug.chrome.focusCommandLine(); + cancelEvent(event, true); + } +}; + +var onMiniIconClick = function onMiniIconClick(event) +{ + Firebug.chrome.toggle(false, event.ctrlKey); + cancelEvent(event, true); +}; + + +// ************************************************************************************************ +// Horizontal Splitter Handling + +var onHSplitterMouseDown = function onHSplitterMouseDown(event) +{ + addGlobalEvent("mousemove", onHSplitterMouseMove); + addGlobalEvent("mouseup", onHSplitterMouseUp); + + if (isIE) + addEvent(Firebug.browser.document.documentElement, "mouseleave", onHSplitterMouseUp); + + fbHSplitter.className = "fbOnMovingHSplitter"; + + return false; +}; + +var onHSplitterMouseMove = function onHSplitterMouseMove(event) +{ + cancelEvent(event, true); + + var clientY = event.clientY; + var win = isIE + ? event.srcElement.ownerDocument.parentWindow + : event.target.ownerDocument && event.target.ownerDocument.defaultView; + + if (!win) + return; + + if (win != win.parent) + { + var frameElement = win.frameElement; + if (frameElement) + { + var framePos = Firebug.browser.getElementPosition(frameElement).top; + clientY += framePos; + + if (frameElement.style.position != "fixed") + clientY -= Firebug.browser.getWindowScrollPosition().top; + } + } + + if (isOpera && isQuiksMode && win.frameElement.id == "FirebugUI") + { + clientY = Firebug.browser.getWindowSize().height - win.frameElement.offsetHeight + clientY; + } + /* + console.log( + typeof win.FBL != "undefined" ? "no-Chrome" : "Chrome", + //win.frameElement.id, + event.target, + clientY + );/**/ + + onHSplitterMouseMoveBuffer = clientY; // buffer + + if (new Date().getTime() - lastHSplitterMouseMove > chromeRedrawSkipRate) // frame skipping + { + lastHSplitterMouseMove = new Date().getTime(); + handleHSplitterMouseMove(); + } + else + if (!onHSplitterMouseMoveTimer) + onHSplitterMouseMoveTimer = setTimeout(handleHSplitterMouseMove, chromeRedrawSkipRate); + + // improving the resizing performance by canceling the mouse event. + // canceling events will prevent the page to receive such events, which would imply + // in more processing being expended. + cancelEvent(event, true); + return false; +}; + +var handleHSplitterMouseMove = function() +{ + if (onHSplitterMouseMoveTimer) + { + clearTimeout(onHSplitterMouseMoveTimer); + onHSplitterMouseMoveTimer = null; + } + + var clientY = onHSplitterMouseMoveBuffer; + + var windowSize = Firebug.browser.getWindowSize(); + var scrollSize = Firebug.browser.getWindowScrollSize(); + + // compute chrome fixed size (top bar and command line) + var commandLineHeight = Firebug.chrome.commandLineVisible ? fbCommandLine.offsetHeight : 0; + var fixedHeight = topHeight + commandLineHeight; + var chromeNode = Firebug.chrome.node; + + var scrollbarSize = !isIE && (scrollSize.width > windowSize.width) ? 17 : 0; + + //var height = !isOpera ? chromeNode.offsetTop + chromeNode.clientHeight : windowSize.height; + var height = windowSize.height; + + // compute the min and max size of the chrome + var chromeHeight = Math.max(height - clientY + 5 - scrollbarSize, fixedHeight); + chromeHeight = Math.min(chromeHeight, windowSize.height - scrollbarSize); + + FirebugChrome.height = chromeHeight; + chromeNode.style.height = chromeHeight + "px"; + + if (noFixedPosition) + Firebug.chrome.fixIEPosition(); + + Firebug.chrome.draw(); +}; + +var onHSplitterMouseUp = function onHSplitterMouseUp(event) +{ + removeGlobalEvent("mousemove", onHSplitterMouseMove); + removeGlobalEvent("mouseup", onHSplitterMouseUp); + + if (isIE) + removeEvent(Firebug.browser.document.documentElement, "mouseleave", onHSplitterMouseUp); + + fbHSplitter.className = ""; + + Firebug.chrome.draw(); + + // avoid text selection in IE when returning to the document + // after the mouse leaves the document during the resizing + return false; +}; + + +// ************************************************************************************************ +// Vertical Splitter Handling + +var onVSplitterMouseDown = function onVSplitterMouseDown(event) +{ + addGlobalEvent("mousemove", onVSplitterMouseMove); + addGlobalEvent("mouseup", onVSplitterMouseUp); + + return false; +}; + +var onVSplitterMouseMove = function onVSplitterMouseMove(event) +{ + if (new Date().getTime() - lastVSplitterMouseMove > chromeRedrawSkipRate) // frame skipping + { + var target = event.target || event.srcElement; + if (target && target.ownerDocument) // avoid error when cursor reaches out of the chrome + { + var clientX = event.clientX; + var win = document.all + ? event.srcElement.ownerDocument.parentWindow + : event.target.ownerDocument.defaultView; + + if (win != win.parent) + clientX += win.frameElement ? win.frameElement.offsetLeft : 0; + + var size = Firebug.chrome.getSize(); + var x = Math.max(size.width - clientX + 3, 6); + + FirebugChrome.sidePanelWidth = x; + Firebug.chrome.draw(); + } + + lastVSplitterMouseMove = new Date().getTime(); + } + + cancelEvent(event, true); + return false; +}; + +var onVSplitterMouseUp = function onVSplitterMouseUp(event) +{ + removeGlobalEvent("mousemove", onVSplitterMouseMove); + removeGlobalEvent("mouseup", onVSplitterMouseUp); + + Firebug.chrome.draw(); +}; + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +Firebug.Lite = +{ +}; + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + + +Firebug.Lite.Browser = function(window) +{ + this.contentWindow = window; + this.contentDocument = window.document; + this.currentURI = + { + spec: window.location.href + }; +}; + +Firebug.Lite.Browser.prototype = +{ + toString: function() + { + return "Firebug.Lite.Browser"; + } +}; + + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +Firebug.Lite.Cache = +{ + ID: "firebug" + new Date().getTime() +}; + +// ************************************************************************************************ + +/** + * TODO: if a cached element is cloned, the expando property will be cloned too in IE + * which will result in a bug. Firebug Lite will think the new cloned node is the old + * one. + * + * TODO: Investigate a possibility of cache validation, to be customized by each + * kind of cache. For ElementCache it should validate if the element still is + * inserted at the DOM. + */ +var cacheUID = 0; +var createCache = function() +{ + var map = {}; + var 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 = element[CID]; + + if (!id) + { + id = ++cacheUID; + element[CID] = id; + } + + if (!map.hasOwnProperty(id)) + { + map[id] = element; + } + + return id; + }, + + unset: function(element) + { + var id = element[CID]; + + if (supportsDeleteExpando) + { + delete element[CID]; + } + else if (element.removeAttribute) + { + element.removeAttribute(CID); + } + + delete map[id]; + + }, + + key: function(element) + { + return element[CID]; + }, + + has: function(element) + { + return map.hasOwnProperty(element[CID]); + }, + + clear: function() + { + for (var id in map) + { + var element = map[id]; + cacheAPI.unset(element); + } + } + }; + + 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(); + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + + +Firebug.Lite.Proxy = +{ + // jsonp callbacks + _callbacks: {}, + + /** + * Load a resource, either locally (directly) or externally (via proxy) using + * synchronous XHR calls. Loading external resources requires the proxy plugin to + * be installed and configured (see /plugin/proxy/proxy.php). + */ + load: function(url) + { + var resourceDomain = getDomain(url); + var isLocalResource = + // empty domain means local URL + !resourceDomain || + // same domain means local too + resourceDomain == Firebug.context.window.location.host; // TODO: xxxpedro context + + return isLocalResource ? fetchResource(url) : fetchProxyResource(url); + }, + + /** + * Load a resource using JSONP technique. + */ + loadJSONP: function(url, callback) + { + var script = createGlobalElement("script"), + doc = Firebug.context.document, + + uid = "" + new Date().getTime(), + callbackName = "callback=Firebug.Lite.Proxy._callbacks." + uid, + + jsonpURL = url.indexOf("?") != -1 ? + url + "&" + callbackName : + url + "?" + callbackName; + + Firebug.Lite.Proxy._callbacks[uid] = function(data) + { + if (callback) + callback(data); + + script.parentNode.removeChild(script); + delete Firebug.Lite.Proxy._callbacks[uid]; + }; + + script.src = jsonpURL; + + if (doc.documentElement) + doc.documentElement.appendChild(script); + }, + + /** + * Load a resource using YQL (not reliable). + */ + YQL: function(url, callback) + { + var yql = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22" + + encodeURIComponent(url) + "%22&format=xml"; + + this.loadJSONP(yql, function(data) + { + var source = data.results[0]; + + // clean up YQL bogus elements + var match = /\s+

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

      "; + + // Safari can't handle uppercase or unicode characters when + // in quirks mode. + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function(query, context, extra, seed){ + context = context || document; + + // Only use querySelectorAll on non-XML documents + // (ID selectors don't work in non-HTML documents) + if ( !seed && context.nodeType === 9 && !isXML(context) ) { + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(e){} + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; + } + + div = null; // release memory in IE +})(); + +if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){ + var div = document.createElement("div"); + div.innerHTML = "
      "; + + // Opera can't find a second classname (in 9.6) + if ( div.getElementsByClassName("e").length === 0 ) + return; + + // Safari caches class attributes, doesn't catch changes (in 3.2) + div.lastChild.className = "e"; + + if ( div.getElementsByClassName("e").length === 1 ) + return; + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS = function(match, context, isXML) { + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { + return context.getElementsByClassName(match[1]); + } + }; + + div = null; // release memory in IE +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + var sibDir = dir == "previousSibling" && !isXML; + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + if ( elem ) { + if ( sibDir && elem.nodeType === 1 ){ + elem.sizcache = doneName; + elem.sizset = i; + } + elem = elem[dir]; + var match = false; + + while ( elem ) { + if ( elem.sizcache === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem.sizcache = doneName; + elem.sizset = i; + } + + if ( elem.nodeName === cur ) { + match = elem; + break; + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + var sibDir = dir == "previousSibling" && !isXML; + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + if ( elem ) { + if ( sibDir && elem.nodeType === 1 ) { + elem.sizcache = doneName; + elem.sizset = i; + } + elem = elem[dir]; + var match = false; + + while ( elem ) { + if ( elem.sizcache === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem.sizcache = doneName; + elem.sizset = i; + } + if ( typeof cur !== "string" ) { + if ( elem === cur ) { + match = true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match = elem; + break; + } + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +var contains = document.compareDocumentPosition ? function(a, b){ + return a.compareDocumentPosition(b) & 16; +} : function(a, b){ + return a !== b && (a.contains ? a.contains(b) : true); +}; + +var isXML = function(elem){ + return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" || + !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML"; +}; + +var posProcess = function(selector, context){ + var tmpSet = [], later = "", match, + root = context.nodeType ? [context] : context; + + // Position selectors must be done after the filter + // And so must :not(positional) so we move all PSEUDOs to the end + while ( (match = Expr.match.PSEUDO.exec( selector )) ) { + later += match[0]; + selector = selector.replace( Expr.match.PSEUDO, "" ); + } + + selector = Expr.relative[selector] ? selector + "*" : selector; + + for ( var i = 0, l = root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE + +Firebug.Selector = Sizzle; + +/**#@-*/ + +// ************************************************************************************************ +}}); + +// Problems in IE +// FIXED - eval return +// FIXED - addEventListener problem in IE +// FIXED doc.createRange? +// +// class reserved word +// test all honza examples in IE6 and IE7 + + +/* See license.txt for terms of usage */ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +function DomplateTag(tagName) +{ + this.tagName = tagName; +} + +function DomplateEmbed() +{ +} + +function DomplateLoop() +{ +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +( /** @scope ns-domplate */ function() { + +var womb = null; + +var domplate = FBL.domplate = function() +{ + var lastSubject; + for (var i = 0; i < arguments.length; ++i) + lastSubject = lastSubject ? copyObject(lastSubject, arguments[i]) : arguments[i]; + + for (var name in lastSubject) + { + var val = lastSubject[name]; + if (isTag(val)) + val.tag.subject = lastSubject; + } + + return lastSubject; +}; + +domplate.context = function(context, fn) +{ + var lastContext = domplate.lastContext; + domplate.topContext = context; + fn.apply(context); + domplate.topContext = lastContext; +}; + +FBL.TAG = function() +{ + var embed = new DomplateEmbed(); + return embed.merge(arguments); +}; + +FBL.FOR = function() +{ + var loop = new DomplateLoop(); + return loop.merge(arguments); +}; + +DomplateTag.prototype = +{ + merge: function(args, oldTag) + { + if (oldTag) + this.tagName = oldTag.tagName; + + this.context = oldTag ? oldTag.context : null; + this.subject = oldTag ? oldTag.subject : null; + this.attrs = oldTag ? copyObject(oldTag.attrs) : {}; + this.classes = oldTag ? copyObject(oldTag.classes) : {}; + this.props = oldTag ? copyObject(oldTag.props) : null; + this.listeners = oldTag ? copyArray(oldTag.listeners) : null; + this.children = oldTag ? copyArray(oldTag.children) : []; + this.vars = oldTag ? copyArray(oldTag.vars) : []; + + var attrs = args.length ? args[0] : null; + var hasAttrs = typeof(attrs) == "object" && !isTag(attrs); + + this.children = []; + + if (domplate.topContext) + this.context = domplate.topContext; + + if (args.length) + parseChildren(args, hasAttrs ? 1 : 0, this.vars, this.children); + + if (hasAttrs) + this.parseAttrs(attrs); + + return creator(this, DomplateTag); + }, + + parseAttrs: function(args) + { + for (var name in args) + { + var val = parseValue(args[name]); + readPartNames(val, this.vars); + + if (name.indexOf("on") == 0) + { + var eventName = name.substr(2); + if (!this.listeners) + this.listeners = []; + this.listeners.push(eventName, val); + } + else if (name.indexOf("_") == 0) + { + var propName = name.substr(1); + if (!this.props) + this.props = {}; + this.props[propName] = val; + } + else if (name.indexOf("$") == 0) + { + var className = name.substr(1); + if (!this.classes) + this.classes = {}; + this.classes[className] = val; + } + else + { + if (name == "class" && this.attrs.hasOwnProperty(name) ) + this.attrs[name] += " " + val; + else + this.attrs[name] = val; + } + } + }, + + compile: function() + { + if (this.renderMarkup) + return; + + this.compileMarkup(); + this.compileDOM(); + + //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate renderMarkup: ", this.renderMarkup); + //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate renderDOM:", this.renderDOM); + //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate domArgs:", this.domArgs); + }, + + compileMarkup: function() + { + this.markupArgs = []; + var topBlock = [], topOuts = [], blocks = [], info = {args: this.markupArgs, argIndex: 0}; + + this.generateMarkup(topBlock, topOuts, blocks, info); + this.addCode(topBlock, topOuts, blocks); + + var fnBlock = ['r=(function (__code__, __context__, __in__, __out__']; + for (var i = 0; i < info.argIndex; ++i) + fnBlock.push(', s', i); + fnBlock.push(') {'); + + if (this.subject) + fnBlock.push('with (this) {'); + if (this.context) + fnBlock.push('with (__context__) {'); + fnBlock.push('with (__in__) {'); + + fnBlock.push.apply(fnBlock, blocks); + + if (this.subject) + fnBlock.push('}'); + if (this.context) + fnBlock.push('}'); + + fnBlock.push('}})'); + + function __link__(tag, code, outputs, args) + { + if (!tag || !tag.tag) + return; + + tag.tag.compile(); + + var tagOutputs = []; + var markupArgs = [code, tag.tag.context, args, tagOutputs]; + markupArgs.push.apply(markupArgs, tag.tag.markupArgs); + tag.tag.renderMarkup.apply(tag.tag.subject, markupArgs); + + outputs.push(tag); + outputs.push(tagOutputs); + } + + function __escape__(value) + { + function replaceChars(ch) + { + switch (ch) + { + case "<": + return "<"; + case ">": + return ">"; + case "&": + return "&"; + case "'": + return "'"; + case '"': + return """; + } + return "?"; + }; + return String(value).replace(/[<>&"']/g, replaceChars); + } + + function __loop__(iter, outputs, fn) + { + var iterOuts = []; + outputs.push(iterOuts); + + if (iter instanceof Array) + iter = new ArrayIterator(iter); + + try + { + while (1) + { + var value = iter.next(); + var itemOuts = [0,0]; + iterOuts.push(itemOuts); + fn.apply(this, [value, itemOuts]); + } + } + catch (exc) + { + if (exc != StopIteration) + throw exc; + } + } + + var js = fnBlock.join(""); + var r = null; + eval(js); + this.renderMarkup = r; + }, + + getVarNames: function(args) + { + if (this.vars) + args.push.apply(args, this.vars); + + for (var i = 0; i < this.children.length; ++i) + { + var child = this.children[i]; + if (isTag(child)) + child.tag.getVarNames(args); + else if (child instanceof Parts) + { + for (var i = 0; i < child.parts.length; ++i) + { + if (child.parts[i] instanceof Variable) + { + var name = child.parts[i].name; + var names = name.split("."); + args.push(names[0]); + } + } + } + } + }, + + generateMarkup: function(topBlock, topOuts, blocks, info) + { + topBlock.push(',"<', this.tagName, '"'); + + for (var name in this.attrs) + { + if (name != "class") + { + var val = this.attrs[name]; + topBlock.push(', " ', name, '=\\""'); + addParts(val, ',', topBlock, info, true); + topBlock.push(', "\\""'); + } + } + + if (this.listeners) + { + for (var i = 0; i < this.listeners.length; i += 2) + readPartNames(this.listeners[i+1], topOuts); + } + + if (this.props) + { + for (var name in this.props) + readPartNames(this.props[name], topOuts); + } + + if ( this.attrs.hasOwnProperty("class") || this.classes) + { + topBlock.push(', " class=\\""'); + if (this.attrs.hasOwnProperty("class")) + addParts(this.attrs["class"], ',', topBlock, info, true); + topBlock.push(', " "'); + for (var name in this.classes) + { + topBlock.push(', ('); + addParts(this.classes[name], '', topBlock, info); + topBlock.push(' ? "', name, '" + " " : "")'); + } + topBlock.push(', "\\""'); + } + topBlock.push(',">"'); + + this.generateChildMarkup(topBlock, topOuts, blocks, info); + topBlock.push(',""'); + }, + + generateChildMarkup: function(topBlock, topOuts, blocks, info) + { + for (var i = 0; i < this.children.length; ++i) + { + var child = this.children[i]; + if (isTag(child)) + child.tag.generateMarkup(topBlock, topOuts, blocks, info); + else + addParts(child, ',', topBlock, info, true); + } + }, + + addCode: function(topBlock, topOuts, blocks) + { + if (topBlock.length) + blocks.push('__code__.push(""', topBlock.join(""), ');'); + if (topOuts.length) + blocks.push('__out__.push(', topOuts.join(","), ');'); + topBlock.splice(0, topBlock.length); + topOuts.splice(0, topOuts.length); + }, + + addLocals: function(blocks) + { + var varNames = []; + this.getVarNames(varNames); + + var map = {}; + for (var i = 0; i < varNames.length; ++i) + { + var name = varNames[i]; + if ( map.hasOwnProperty(name) ) + continue; + + map[name] = 1; + var names = name.split("."); + blocks.push('var ', names[0] + ' = ' + '__in__.' + names[0] + ';'); + } + }, + + compileDOM: function() + { + var path = []; + var blocks = []; + this.domArgs = []; + path.embedIndex = 0; + path.loopIndex = 0; + path.staticIndex = 0; + path.renderIndex = 0; + var nodeCount = this.generateDOM(path, blocks, this.domArgs); + + var fnBlock = ['r=(function (root, context, o']; + + for (var i = 0; i < path.staticIndex; ++i) + fnBlock.push(', ', 's'+i); + + for (var i = 0; i < path.renderIndex; ++i) + fnBlock.push(', ', 'd'+i); + + fnBlock.push(') {'); + for (var i = 0; i < path.loopIndex; ++i) + fnBlock.push('var l', i, ' = 0;'); + for (var i = 0; i < path.embedIndex; ++i) + fnBlock.push('var e', i, ' = 0;'); + + if (this.subject) + fnBlock.push('with (this) {'); + if (this.context) + fnBlock.push('with (context) {'); + + fnBlock.push(blocks.join("")); + + if (this.subject) + fnBlock.push('}'); + if (this.context) + fnBlock.push('}'); + + fnBlock.push('return ', nodeCount, ';'); + fnBlock.push('})'); + + function __bind__(object, fn) + { + return function(event) { return fn.apply(object, [event]); }; + } + + function __link__(node, tag, args) + { + if (!tag || !tag.tag) + return; + + tag.tag.compile(); + + var domArgs = [node, tag.tag.context, 0]; + domArgs.push.apply(domArgs, tag.tag.domArgs); + domArgs.push.apply(domArgs, args); + //if (FBTrace.DBG_DOM) FBTrace.dumpProperties("domplate__link__ domArgs:", domArgs); + return tag.tag.renderDOM.apply(tag.tag.subject, domArgs); + } + + var self = this; + function __loop__(iter, fn) + { + var nodeCount = 0; + for (var i = 0; i < iter.length; ++i) + { + iter[i][0] = i; + iter[i][1] = nodeCount; + nodeCount += fn.apply(this, iter[i]); + //if (FBTrace.DBG_DOM) FBTrace.sysout("nodeCount", nodeCount); + } + return nodeCount; + } + + function __path__(parent, offset) + { + //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate __path__ offset: "+ offset+"\n"); + var root = parent; + + for (var i = 2; i < arguments.length; ++i) + { + var index = arguments[i]; + if (i == 3) + index += offset; + + if (index == -1) + parent = parent.parentNode; + else + parent = parent.childNodes[index]; + } + + //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate: "+arguments[2]+", root: "+ root+", parent: "+ parent+"\n"); + return parent; + } + + var js = fnBlock.join(""); + //if (FBTrace.DBG_DOM) FBTrace.sysout(js.replace(/(\;|\{)/g, "$1\n")); + var r = null; + eval(js); + this.renderDOM = r; + }, + + generateDOM: function(path, blocks, args) + { + if (this.listeners || this.props) + this.generateNodePath(path, blocks); + + if (this.listeners) + { + for (var i = 0; i < this.listeners.length; i += 2) + { + var val = this.listeners[i+1]; + var arg = generateArg(val, path, args); + //blocks.push('node.addEventListener("', this.listeners[i], '", __bind__(this, ', arg, '), false);'); + blocks.push('addEvent(node, "', this.listeners[i], '", __bind__(this, ', arg, '), false);'); + } + } + + if (this.props) + { + for (var name in this.props) + { + var val = this.props[name]; + var arg = generateArg(val, path, args); + blocks.push('node.', name, ' = ', arg, ';'); + } + } + + this.generateChildDOM(path, blocks, args); + return 1; + }, + + generateNodePath: function(path, blocks) + { + blocks.push("var node = __path__(root, o"); + for (var i = 0; i < path.length; ++i) + blocks.push(",", path[i]); + blocks.push(");"); + }, + + generateChildDOM: function(path, blocks, args) + { + path.push(0); + for (var i = 0; i < this.children.length; ++i) + { + var child = this.children[i]; + if (isTag(child)) + path[path.length-1] += '+' + child.tag.generateDOM(path, blocks, args); + else + path[path.length-1] += '+1'; + } + path.pop(); + } +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +DomplateEmbed.prototype = copyObject(DomplateTag.prototype, +{ + merge: function(args, oldTag) + { + this.value = oldTag ? oldTag.value : parseValue(args[0]); + this.attrs = oldTag ? oldTag.attrs : {}; + this.vars = oldTag ? copyArray(oldTag.vars) : []; + + var attrs = args[1]; + for (var name in attrs) + { + var val = parseValue(attrs[name]); + this.attrs[name] = val; + readPartNames(val, this.vars); + } + + return creator(this, DomplateEmbed); + }, + + getVarNames: function(names) + { + if (this.value instanceof Parts) + names.push(this.value.parts[0].name); + + if (this.vars) + names.push.apply(names, this.vars); + }, + + generateMarkup: function(topBlock, topOuts, blocks, info) + { + this.addCode(topBlock, topOuts, blocks); + + blocks.push('__link__('); + addParts(this.value, '', blocks, info); + blocks.push(', __code__, __out__, {'); + + var lastName = null; + for (var name in this.attrs) + { + if (lastName) + blocks.push(','); + lastName = name; + + var val = this.attrs[name]; + blocks.push('"', name, '":'); + addParts(val, '', blocks, info); + } + + blocks.push('});'); + //this.generateChildMarkup(topBlock, topOuts, blocks, info); + }, + + generateDOM: function(path, blocks, args) + { + var embedName = 'e'+path.embedIndex++; + + this.generateNodePath(path, blocks); + + var valueName = 'd' + path.renderIndex++; + var argsName = 'd' + path.renderIndex++; + blocks.push(embedName + ' = __link__(node, ', valueName, ', ', argsName, ');'); + + return embedName; + } +}); + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +DomplateLoop.prototype = copyObject(DomplateTag.prototype, +{ + merge: function(args, oldTag) + { + this.varName = oldTag ? oldTag.varName : args[0]; + this.iter = oldTag ? oldTag.iter : parseValue(args[1]); + this.vars = []; + + this.children = oldTag ? copyArray(oldTag.children) : []; + + var offset = Math.min(args.length, 2); + parseChildren(args, offset, this.vars, this.children); + + return creator(this, DomplateLoop); + }, + + getVarNames: function(names) + { + if (this.iter instanceof Parts) + names.push(this.iter.parts[0].name); + + DomplateTag.prototype.getVarNames.apply(this, [names]); + }, + + generateMarkup: function(topBlock, topOuts, blocks, info) + { + this.addCode(topBlock, topOuts, blocks); + + var iterName; + if (this.iter instanceof Parts) + { + var part = this.iter.parts[0]; + iterName = part.name; + + if (part.format) + { + for (var i = 0; i < part.format.length; ++i) + iterName = part.format[i] + "(" + iterName + ")"; + } + } + else + iterName = this.iter; + + blocks.push('__loop__.apply(this, [', iterName, ', __out__, function(', this.varName, ', __out__) {'); + this.generateChildMarkup(topBlock, topOuts, blocks, info); + this.addCode(topBlock, topOuts, blocks); + blocks.push('}]);'); + }, + + generateDOM: function(path, blocks, args) + { + var iterName = 'd'+path.renderIndex++; + var counterName = 'i'+path.loopIndex; + var loopName = 'l'+path.loopIndex++; + + if (!path.length) + path.push(-1, 0); + + var preIndex = path.renderIndex; + path.renderIndex = 0; + + var nodeCount = 0; + + var subBlocks = []; + var basePath = path[path.length-1]; + for (var i = 0; i < this.children.length; ++i) + { + path[path.length-1] = basePath+'+'+loopName+'+'+nodeCount; + + var child = this.children[i]; + if (isTag(child)) + nodeCount += '+' + child.tag.generateDOM(path, subBlocks, args); + else + nodeCount += '+1'; + } + + path[path.length-1] = basePath+'+'+loopName; + + blocks.push(loopName,' = __loop__.apply(this, [', iterName, ', function(', counterName,',',loopName); + for (var i = 0; i < path.renderIndex; ++i) + blocks.push(',d'+i); + blocks.push(') {'); + blocks.push(subBlocks.join("")); + blocks.push('return ', nodeCount, ';'); + blocks.push('}]);'); + + path.renderIndex = preIndex; + + return loopName; + } +}); + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +function Variable(name, format) +{ + this.name = name; + this.format = format; +} + +function Parts(parts) +{ + this.parts = parts; +} + +// ************************************************************************************************ + +function parseParts(str) +{ + var re = /\$([_A-Za-z][_A-Za-z0-9.|]*)/g; + var index = 0; + var parts = []; + + var m; + while (m = re.exec(str)) + { + var pre = str.substr(index, (re.lastIndex-m[0].length)-index); + if (pre) + parts.push(pre); + + var expr = m[1].split("|"); + parts.push(new Variable(expr[0], expr.slice(1))); + index = re.lastIndex; + } + + if (!index) + return str; + + var post = str.substr(index); + if (post) + parts.push(post); + + return new Parts(parts); +} + +function parseValue(val) +{ + return typeof(val) == 'string' ? parseParts(val) : val; +} + +function parseChildren(args, offset, vars, children) +{ + for (var i = offset; i < args.length; ++i) + { + var val = parseValue(args[i]); + children.push(val); + readPartNames(val, vars); + } +} + +function readPartNames(val, vars) +{ + if (val instanceof Parts) + { + for (var i = 0; i < val.parts.length; ++i) + { + var part = val.parts[i]; + if (part instanceof Variable) + vars.push(part.name); + } + } +} + +function generateArg(val, path, args) +{ + if (val instanceof Parts) + { + var vals = []; + for (var i = 0; i < val.parts.length; ++i) + { + var part = val.parts[i]; + if (part instanceof Variable) + { + var varName = 'd'+path.renderIndex++; + if (part.format) + { + for (var j = 0; j < part.format.length; ++j) + varName = part.format[j] + '(' + varName + ')'; + } + + vals.push(varName); + } + else + vals.push('"'+part.replace(/"/g, '\\"')+'"'); + } + + return vals.join('+'); + } + else + { + args.push(val); + return 's' + path.staticIndex++; + } +} + +function addParts(val, delim, block, info, escapeIt) +{ + var vals = []; + if (val instanceof Parts) + { + for (var i = 0; i < val.parts.length; ++i) + { + var part = val.parts[i]; + if (part instanceof Variable) + { + var partName = part.name; + if (part.format) + { + for (var j = 0; j < part.format.length; ++j) + partName = part.format[j] + "(" + partName + ")"; + } + + if (escapeIt) + vals.push("__escape__(" + partName + ")"); + else + vals.push(partName); + } + else + vals.push('"'+ part + '"'); + } + } + else if (isTag(val)) + { + info.args.push(val); + vals.push('s'+info.argIndex++); + } + else + vals.push('"'+ val + '"'); + + var parts = vals.join(delim); + if (parts) + block.push(delim, parts); +} + +function isTag(obj) +{ + return (typeof(obj) == "function" || obj instanceof Function) && !!obj.tag; +} + +function creator(tag, cons) +{ + var fn = new Function( + "var tag = arguments.callee.tag;" + + "var cons = arguments.callee.cons;" + + "var newTag = new cons();" + + "return newTag.merge(arguments, tag);"); + + fn.tag = tag; + fn.cons = cons; + extend(fn, Renderer); + + return fn; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +function copyArray(oldArray) +{ + var ary = []; + if (oldArray) + for (var i = 0; i < oldArray.length; ++i) + ary.push(oldArray[i]); + return ary; +} + +function copyObject(l, r) +{ + var m = {}; + extend(m, l); + extend(m, r); + return m; +} + +function extend(l, r) +{ + for (var n in r) + l[n] = r[n]; +} + +function addEvent(object, name, handler) +{ + if (document.all) + object.attachEvent("on"+name, handler); + else + object.addEventListener(name, handler, false); +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +function ArrayIterator(array) +{ + var index = -1; + + this.next = function() + { + if (++index >= array.length) + throw StopIteration; + + return array[index]; + }; +} + +function StopIteration() {} + +FBL.$break = function() +{ + throw StopIteration; +}; + +// ************************************************************************************************ + +var Renderer = +{ + renderHTML: function(args, outputs, self) + { + var code = []; + var markupArgs = [code, this.tag.context, args, outputs]; + markupArgs.push.apply(markupArgs, this.tag.markupArgs); + this.tag.renderMarkup.apply(self ? self : this.tag.subject, markupArgs); + return code.join(""); + }, + + insertRows: function(args, before, self) + { + this.tag.compile(); + + var outputs = []; + var html = this.renderHTML(args, outputs, self); + + var doc = before.ownerDocument; + var div = doc.createElement("div"); + div.innerHTML = ""+html+"
      "; + + var tbody = div.firstChild.firstChild; + var parent = before.tagName == "TR" ? before.parentNode : before; + var after = before.tagName == "TR" ? before.nextSibling : null; + + var firstRow = tbody.firstChild, lastRow; + while (tbody.firstChild) + { + lastRow = tbody.firstChild; + if (after) + parent.insertBefore(lastRow, after); + else + parent.appendChild(lastRow); + } + + var offset = 0; + if (before.tagName == "TR") + { + var node = firstRow.parentNode.firstChild; + for (; node && node != firstRow; node = node.nextSibling) + ++offset; + } + + var domArgs = [firstRow, this.tag.context, offset]; + domArgs.push.apply(domArgs, this.tag.domArgs); + domArgs.push.apply(domArgs, outputs); + + this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs); + return [firstRow, lastRow]; + }, + + insertBefore: function(args, before, self) + { + return this.insertNode(args, before.ownerDocument, before, false, self); + }, + + insertAfter: function(args, after, self) + { + return this.insertNode(args, after.ownerDocument, after, true, self); + }, + + insertNode: function(args, doc, element, isAfter, self) + { + if (!args) + args = {}; + + this.tag.compile(); + + var outputs = []; + var html = this.renderHTML(args, outputs, self); + + //if (FBTrace.DBG_DOM) + // FBTrace.sysout("domplate.insertNode html: "+html+"\n"); + + var doc = element.ownerDocument; + if (!womb || womb.ownerDocument != doc) + womb = doc.createElement("div"); + + womb.innerHTML = html; + + var root = womb.firstChild; + if (isAfter) + { + while (womb.firstChild) + if (element.nextSibling) + element.parentNode.insertBefore(womb.firstChild, element.nextSibling); + else + element.parentNode.appendChild(womb.firstChild); + } + else + { + while (womb.lastChild) + element.parentNode.insertBefore(womb.lastChild, element); + } + + var domArgs = [root, this.tag.context, 0]; + domArgs.push.apply(domArgs, this.tag.domArgs); + domArgs.push.apply(domArgs, outputs); + + //if (FBTrace.DBG_DOM) + // FBTrace.sysout("domplate.insertNode domArgs:", domArgs); + this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs); + + return root; + }, + /**/ + + /* + insertAfter: function(args, before, self) + { + this.tag.compile(); + + var outputs = []; + var html = this.renderHTML(args, outputs, self); + + var doc = before.ownerDocument; + if (!womb || womb.ownerDocument != doc) + womb = doc.createElement("div"); + + womb.innerHTML = html; + + var root = womb.firstChild; + while (womb.firstChild) + if (before.nextSibling) + before.parentNode.insertBefore(womb.firstChild, before.nextSibling); + else + before.parentNode.appendChild(womb.firstChild); + + var domArgs = [root, this.tag.context, 0]; + domArgs.push.apply(domArgs, this.tag.domArgs); + domArgs.push.apply(domArgs, outputs); + + this.tag.renderDOM.apply(self ? self : (this.tag.subject ? this.tag.subject : null), + domArgs); + + return root; + }, + /**/ + + replace: function(args, parent, self) + { + this.tag.compile(); + + var outputs = []; + var html = this.renderHTML(args, outputs, self); + + var root; + if (parent.nodeType == 1) + { + parent.innerHTML = html; + root = parent.firstChild; + } + else + { + if (!parent || parent.nodeType != 9) + parent = document; + + if (!womb || womb.ownerDocument != parent) + womb = parent.createElement("div"); + womb.innerHTML = html; + + root = womb.firstChild; + //womb.removeChild(root); + } + + var domArgs = [root, this.tag.context, 0]; + domArgs.push.apply(domArgs, this.tag.domArgs); + domArgs.push.apply(domArgs, outputs); + this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs); + + return root; + }, + + append: function(args, parent, self) + { + this.tag.compile(); + + var outputs = []; + var html = this.renderHTML(args, outputs, self); + //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate.append html: "+html+"\n"); + + if (!womb || womb.ownerDocument != parent.ownerDocument) + womb = parent.ownerDocument.createElement("div"); + womb.innerHTML = html; + + // TODO: xxxpedro domplate port to Firebug + var root = womb.firstChild; + while (womb.firstChild) + parent.appendChild(womb.firstChild); + + // clearing element reference to avoid reference error in IE8 when switching contexts + womb = null; + + var domArgs = [root, this.tag.context, 0]; + domArgs.push.apply(domArgs, this.tag.domArgs); + domArgs.push.apply(domArgs, outputs); + + //if (FBTrace.DBG_DOM) FBTrace.dumpProperties("domplate append domArgs:", domArgs); + this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs); + + return root; + } +}; + +// ************************************************************************************************ + +function defineTags() +{ + for (var i = 0; i < arguments.length; ++i) + { + var tagName = arguments[i]; + var fn = new Function("var newTag = new arguments.callee.DomplateTag('"+tagName+"'); return newTag.merge(arguments);"); + fn.DomplateTag = DomplateTag; + + var fnName = tagName.toUpperCase(); + FBL[fnName] = fn; + } +} + +defineTags( + "a", "button", "br", "canvas", "code", "col", "colgroup", "div", "fieldset", "form", "h1", "h2", "h3", "hr", + "img", "input", "label", "legend", "li", "ol", "optgroup", "option", "p", "pre", "select", + "span", "strong", "table", "tbody", "td", "textarea", "tfoot", "th", "thead", "tr", "tt", "ul", "iframe" +); + +})(); + + +/* See license.txt for terms of usage */ + +var FirebugReps = FBL.ns(function() { with (FBL) { + + +// ************************************************************************************************ +// Common Tags + +var OBJECTBOX = this.OBJECTBOX = + SPAN({"class": "objectBox objectBox-$className"}); + +var OBJECTBLOCK = this.OBJECTBLOCK = + DIV({"class": "objectBox objectBox-$className"}); + +var OBJECTLINK = this.OBJECTLINK = isIE6 ? // IE6 object link representation + A({ + "class": "objectLink objectLink-$className a11yFocus", + href: "javascript:void(0)", + _repObject: "$object" + }) + : // Other browsers + A({ + "class": "objectLink objectLink-$className a11yFocus", + _repObject: "$object" + }); + + +// ************************************************************************************************ + +this.Undefined = domplate(Firebug.Rep, +{ + tag: OBJECTBOX("undefined"), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "undefined", + + supportsObject: function(object, type) + { + return type == "undefined"; + } +}); + +// ************************************************************************************************ + +this.Null = domplate(Firebug.Rep, +{ + tag: OBJECTBOX("null"), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "null", + + supportsObject: function(object, type) + { + return object == null; + } +}); + +// ************************************************************************************************ + +this.Nada = domplate(Firebug.Rep, +{ + tag: SPAN(""), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "nada" +}); + +// ************************************************************************************************ + +this.Number = domplate(Firebug.Rep, +{ + tag: OBJECTBOX("$object"), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "number", + + supportsObject: function(object, type) + { + return type == "boolean" || type == "number"; + } +}); + +// ************************************************************************************************ + +this.String = domplate(Firebug.Rep, +{ + tag: OBJECTBOX(""$object""), + + shortTag: OBJECTBOX(""$object|cropString""), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "string", + + supportsObject: function(object, type) + { + return type == "string"; + } +}); + +// ************************************************************************************************ + +this.Text = domplate(Firebug.Rep, +{ + tag: OBJECTBOX("$object"), + + shortTag: OBJECTBOX("$object|cropString"), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "text" +}); + +// ************************************************************************************************ + +this.Caption = domplate(Firebug.Rep, +{ + tag: SPAN({"class": "caption"}, "$object") +}); + +// ************************************************************************************************ + +this.Warning = domplate(Firebug.Rep, +{ + tag: DIV({"class": "warning focusRow", role : 'listitem'}, "$object|STR") +}); + +// ************************************************************************************************ + +this.Func = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK("$object|summarizeFunction"), + + summarizeFunction: function(fn) + { + var fnRegex = /function ([^(]+\([^)]*\)) \{/; + var fnText = safeToString(fn); + + var m = fnRegex.exec(fnText); + return m ? m[1] : "function()"; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + copySource: function(fn) + { + copyToClipboard(safeToString(fn)); + }, + + monitor: function(fn, script, monitored) + { + if (monitored) + Firebug.Debugger.unmonitorScript(fn, script, "monitor"); + else + Firebug.Debugger.monitorScript(fn, script, "monitor"); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "function", + + supportsObject: function(object, type) + { + return isFunction(object); + }, + + inspectObject: function(fn, context) + { + var sourceLink = findSourceForFunction(fn, context); + if (sourceLink) + Firebug.chrome.select(sourceLink); + if (FBTrace.DBG_FUNCTION_NAME) + FBTrace.sysout("reps.function.inspectObject selected sourceLink is ", sourceLink); + }, + + getTooltip: function(fn, context) + { + var script = findScriptForFunctionInContext(context, fn); + if (script) + return $STRF("Line", [normalizeURL(script.fileName), script.baseLineNumber]); + else + if (fn.toString) + return fn.toString(); + }, + + getTitle: function(fn, context) + { + var name = fn.name ? fn.name : "function"; + return name + "()"; + }, + + getContextMenuItems: function(fn, target, context, script) + { + if (!script) + script = findScriptForFunctionInContext(context, fn); + if (!script) + return; + + var scriptInfo = getSourceFileAndLineByScript(context, script); + var monitored = scriptInfo ? fbs.isMonitored(scriptInfo.sourceFile.href, scriptInfo.lineNo) : false; + + var name = script ? getFunctionName(script, context) : fn.name; + return [ + {label: "CopySource", command: bindFixed(this.copySource, this, fn) }, + "-", + {label: $STRF("ShowCallsInConsole", [name]), nol10n: true, + type: "checkbox", checked: monitored, + command: bindFixed(this.monitor, this, fn, script, monitored) } + ]; + } +}); + +// ************************************************************************************************ +/* +this.jsdScript = domplate(Firebug.Rep, +{ + copySource: function(script) + { + var fn = script.functionObject.getWrappedValue(); + return FirebugReps.Func.copySource(fn); + }, + + monitor: function(fn, script, monitored) + { + fn = script.functionObject.getWrappedValue(); + return FirebugReps.Func.monitor(fn, script, monitored); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "jsdScript", + inspectable: false, + + supportsObject: function(object, type) + { + return object instanceof jsdIScript; + }, + + inspectObject: function(script, context) + { + var sourceLink = getSourceLinkForScript(script, context); + if (sourceLink) + Firebug.chrome.select(sourceLink); + }, + + getRealObject: function(script, context) + { + return script; + }, + + getTooltip: function(script) + { + return $STRF("jsdIScript", [script.tag]); + }, + + getTitle: function(script, context) + { + var fn = script.functionObject.getWrappedValue(); + return FirebugReps.Func.getTitle(fn, context); + }, + + getContextMenuItems: function(script, target, context) + { + var fn = script.functionObject.getWrappedValue(); + + var scriptInfo = getSourceFileAndLineByScript(context, script); + var monitored = scriptInfo ? fbs.isMonitored(scriptInfo.sourceFile.href, scriptInfo.lineNo) : false; + + var name = getFunctionName(script, context); + + return [ + {label: "CopySource", command: bindFixed(this.copySource, this, script) }, + "-", + {label: $STRF("ShowCallsInConsole", [name]), nol10n: true, + type: "checkbox", checked: monitored, + command: bindFixed(this.monitor, this, fn, script, monitored) } + ]; + } +}); +/**/ +//************************************************************************************************ + +this.Obj = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK( + SPAN({"class": "objectTitle"}, "$object|getTitle "), + + SPAN({"class": "objectProps"}, + SPAN({"class": "objectLeftBrace", role: "presentation"}, "{"), + FOR("prop", "$object|propIterator", + SPAN({"class": "objectPropName", role: "presentation"}, "$prop.name"), + SPAN({"class": "objectEqual", role: "presentation"}, "$prop.equal"), + TAG("$prop.tag", {object: "$prop.object"}), + SPAN({"class": "objectComma", role: "presentation"}, "$prop.delim") + ), + SPAN({"class": "objectRightBrace"}, "}") + ) + ), + + propNumberTag: + SPAN({"class": "objectProp-number"}, "$object"), + + propStringTag: + SPAN({"class": "objectProp-string"}, ""$object""), + + propObjectTag: + SPAN({"class": "objectProp-object"}, "$object"), + + propIterator: function (object) + { + ///Firebug.ObjectShortIteratorMax; + var maxLength = 55; // default max length for long representation + + if (!object) + return []; + + var props = []; + var length = 0; + + var numProperties = 0; + var numPropertiesShown = 0; + var maxLengthReached = false; + + var lib = this; + + var propRepsMap = + { + "boolean": this.propNumberTag, + "number": this.propNumberTag, + "string": this.propStringTag, + "object": this.propObjectTag + }; + + try + { + var title = Firebug.Rep.getTitle(object); + length += title.length; + + for (var name in object) + { + var value; + try + { + value = object[name]; + } + catch (exc) + { + continue; + } + + var type = typeof(value); + if (type == "boolean" || + type == "number" || + (type == "string" && value) || + (type == "object" && value && value.toString)) + { + var tag = propRepsMap[type]; + + var value = (type == "object") ? + Firebug.getRep(value).getTitle(value) : + value + ""; + + length += name.length + value.length + 4; + + if (length <= maxLength) + { + props.push({ + tag: tag, + name: name, + object: value, + equal: "=", + delim: ", " + }); + + numPropertiesShown++; + } + else + maxLengthReached = true; + + } + + numProperties++; + + if (maxLengthReached && numProperties > numPropertiesShown) + break; + } + + if (numProperties > numPropertiesShown) + { + props.push({ + object: "...", //xxxHonza localization + tag: FirebugReps.Caption.tag, + name: "", + equal:"", + delim:"" + }); + } + else if (props.length > 0) + { + props[props.length-1].delim = ''; + } + } + catch (exc) + { + // Sometimes we get exceptions when trying to read from certain objects, like + // StorageList, but don't let that gum up the works + // XXXjjb also History.previous fails because object is a web-page object which does not have + // permission to read the history + } + return props; + }, + + fb_1_6_propIterator: function (object, max) + { + max = max || 3; + if (!object) + return []; + + var props = []; + var len = 0, count = 0; + + try + { + for (var name in object) + { + var value; + try + { + value = object[name]; + } + catch (exc) + { + continue; + } + + var t = typeof(value); + if (t == "boolean" || t == "number" || (t == "string" && value) + || (t == "object" && value && value.toString)) + { + var rep = Firebug.getRep(value); + var tag = rep.shortTag || rep.tag; + if (t == "object") + { + value = rep.getTitle(value); + tag = rep.titleTag; + } + count++; + if (count <= max) + props.push({tag: tag, name: name, object: value, equal: "=", delim: ", "}); + else + break; + } + } + if (count > max) + { + props[Math.max(1,max-1)] = { + object: "more...", //xxxHonza localization + tag: FirebugReps.Caption.tag, + name: "", + equal:"", + delim:"" + }; + } + else if (props.length > 0) + { + props[props.length-1].delim = ''; + } + } + catch (exc) + { + // Sometimes we get exceptions when trying to read from certain objects, like + // StorageList, but don't let that gum up the works + // XXXjjb also History.previous fails because object is a web-page object which does not have + // permission to read the history + } + return props; + }, + + /* + propIterator: function (object) + { + if (!object) + return []; + + var props = []; + var len = 0; + + try + { + for (var name in object) + { + var val; + try + { + val = object[name]; + } + catch (exc) + { + continue; + } + + var t = typeof val; + if (t == "boolean" || t == "number" || (t == "string" && val) + || (t == "object" && !isFunction(val) && val && val.toString)) + { + var title = (t == "object") + ? Firebug.getRep(val).getTitle(val) + : val+""; + + len += name.length + title.length + 1; + if (len < 50) + props.push({name: name, value: title}); + else + break; + } + } + } + catch (exc) + { + // Sometimes we get exceptions when trying to read from certain objects, like + // StorageList, but don't let that gum up the works + // XXXjjb also History.previous fails because object is a web-page object which does not have + // permission to read the history + } + + return props; + }, + /**/ + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "object", + + supportsObject: function(object, type) + { + return true; + } +}); + + +// ************************************************************************************************ + +this.Arr = domplate(Firebug.Rep, +{ + tag: + OBJECTBOX({_repObject: "$object"}, + SPAN({"class": "arrayLeftBracket", role : "presentation"}, "["), + FOR("item", "$object|arrayIterator", + TAG("$item.tag", {object: "$item.object"}), + SPAN({"class": "arrayComma", role : "presentation"}, "$item.delim") + ), + SPAN({"class": "arrayRightBracket", role : "presentation"}, "]") + ), + + shortTag: + OBJECTBOX({_repObject: "$object"}, + SPAN({"class": "arrayLeftBracket", role : "presentation"}, "["), + FOR("item", "$object|shortArrayIterator", + TAG("$item.tag", {object: "$item.object"}), + SPAN({"class": "arrayComma", role : "presentation"}, "$item.delim") + ), + // TODO: xxxpedro - confirm this on Firebug + //FOR("prop", "$object|shortPropIterator", + // " $prop.name=", + // SPAN({"class": "objectPropValue"}, "$prop.value|cropString") + //), + SPAN({"class": "arrayRightBracket"}, "]") + ), + + arrayIterator: function(array) + { + var items = []; + for (var i = 0; i < array.length; ++i) + { + var value = array[i]; + var rep = Firebug.getRep(value); + var tag = rep.shortTag ? rep.shortTag : rep.tag; + var delim = (i == array.length-1 ? "" : ", "); + + items.push({object: value, tag: tag, delim: delim}); + } + + return items; + }, + + shortArrayIterator: function(array) + { + var items = []; + for (var i = 0; i < array.length && i < 3; ++i) + { + var value = array[i]; + var rep = Firebug.getRep(value); + var tag = rep.shortTag ? rep.shortTag : rep.tag; + var delim = (i == array.length-1 ? "" : ", "); + + items.push({object: value, tag: tag, delim: delim}); + } + + if (array.length > 3) + items.push({object: (array.length-3) + " more...", tag: FirebugReps.Caption.tag, delim: ""}); + + return items; + }, + + shortPropIterator: this.Obj.propIterator, + + getItemIndex: function(child) + { + var arrayIndex = 0; + for (child = child.previousSibling; child; child = child.previousSibling) + { + if (child.repObject) + ++arrayIndex; + } + return arrayIndex; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "array", + + supportsObject: function(object) + { + return this.isArray(object); + }, + + // http://code.google.com/p/fbug/issues/detail?id=874 + // BEGIN Yahoo BSD Source (modified here) YAHOO.lang.isArray, YUI 2.2.2 June 2007 + isArray: function(obj) { + try { + if (!obj) + return false; + else if (isIE && !isFunction(obj) && typeof obj == "object" && isFinite(obj.length) && obj.nodeType != 8) + return true; + else if (isFinite(obj.length) && isFunction(obj.splice)) + return true; + else if (isFinite(obj.length) && isFunction(obj.callee)) // arguments + return true; + else if (instanceOf(obj, "HTMLCollection")) + return true; + else if (instanceOf(obj, "NodeList")) + return true; + else + return false; + } + catch(exc) + { + if (FBTrace.DBG_ERRORS) + { + FBTrace.sysout("isArray FAILS:", exc); /* Something weird: without the try/catch, OOM, with no exception?? */ + FBTrace.sysout("isArray Fails on obj", obj); + } + } + + return false; + }, + // END Yahoo BSD SOURCE See license below. + + getTitle: function(object, context) + { + return "[" + object.length + "]"; + } +}); + +// ************************************************************************************************ + +this.Property = domplate(Firebug.Rep, +{ + supportsObject: function(object) + { + return object instanceof Property; + }, + + getRealObject: function(prop, context) + { + return prop.object[prop.name]; + }, + + getTitle: function(prop, context) + { + return prop.name; + } +}); + +// ************************************************************************************************ + +this.NetFile = domplate(this.Obj, +{ + supportsObject: function(object) + { + return object instanceof Firebug.NetFile; + }, + + browseObject: function(file, context) + { + openNewTab(file.href); + return true; + }, + + getRealObject: function(file, context) + { + return null; + } +}); + +// ************************************************************************************************ + +this.Except = domplate(Firebug.Rep, +{ + tag: + OBJECTBOX({_repObject: "$object"}, "$object.message"), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "exception", + + supportsObject: function(object) + { + return object instanceof ErrorCopy; + } +}); + + +// ************************************************************************************************ + +this.Element = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK( + "<", + SPAN({"class": "nodeTag"}, "$object.nodeName|toLowerCase"), + FOR("attr", "$object|attrIterator", + " $attr.nodeName="", SPAN({"class": "nodeValue"}, "$attr.nodeValue"), """ + ), + ">" + ), + + shortTag: + OBJECTLINK( + SPAN({"class": "$object|getVisible"}, + SPAN({"class": "selectorTag"}, "$object|getSelectorTag"), + SPAN({"class": "selectorId"}, "$object|getSelectorId"), + SPAN({"class": "selectorClass"}, "$object|getSelectorClass"), + SPAN({"class": "selectorValue"}, "$object|getValue") + ) + ), + + getVisible: function(elt) + { + return isVisible(elt) ? "" : "selectorHidden"; + }, + + getSelectorTag: function(elt) + { + return elt.nodeName.toLowerCase(); + }, + + getSelectorId: function(elt) + { + return elt.id ? "#" + elt.id : ""; + }, + + getSelectorClass: function(elt) + { + return elt.className ? "." + elt.className.split(" ")[0] : ""; + }, + + getValue: function(elt) + { + // TODO: xxxpedro + return ""; + var value; + if (elt instanceof HTMLImageElement) + value = getFileName(elt.src); + else if (elt instanceof HTMLAnchorElement) + value = getFileName(elt.href); + else if (elt instanceof HTMLInputElement) + value = elt.value; + else if (elt instanceof HTMLFormElement) + value = getFileName(elt.action); + else if (elt instanceof HTMLScriptElement) + value = getFileName(elt.src); + + return value ? " " + cropString(value, 20) : ""; + }, + + attrIterator: function(elt) + { + var attrs = []; + var idAttr, classAttr; + if (elt.attributes) + { + for (var i = 0; i < elt.attributes.length; ++i) + { + var attr = elt.attributes[i]; + if (attr.nodeName && attr.nodeName.indexOf("firebug-") != -1) + continue; + else if (attr.nodeName == "id") + idAttr = attr; + else if (attr.nodeName == "class") + classAttr = attr; + else + attrs.push(attr); + } + } + if (classAttr) + attrs.splice(0, 0, classAttr); + if (idAttr) + attrs.splice(0, 0, idAttr); + + return attrs; + }, + + shortAttrIterator: function(elt) + { + var attrs = []; + if (elt.attributes) + { + for (var i = 0; i < elt.attributes.length; ++i) + { + var attr = elt.attributes[i]; + if (attr.nodeName == "id" || attr.nodeName == "class") + attrs.push(attr); + } + } + + return attrs; + }, + + getHidden: function(elt) + { + return isVisible(elt) ? "" : "nodeHidden"; + }, + + getXPath: function(elt) + { + return getElementTreeXPath(elt); + }, + + // TODO: xxxpedro remove this? + getNodeText: function(element) + { + var text = element.textContent; + if (Firebug.showFullTextNodes) + return text; + else + return cropString(text, 50); + }, + /**/ + + getNodeTextGroups: function(element) + { + var text = element.textContent; + if (!Firebug.showFullTextNodes) + { + text=cropString(text,50); + } + + var escapeGroups=[]; + + if (Firebug.showTextNodesWithWhitespace) + escapeGroups.push({ + 'group': 'whitespace', + 'class': 'nodeWhiteSpace', + 'extra': { + '\t': '_Tab', + '\n': '_Para', + ' ' : '_Space' + } + }); + if (Firebug.showTextNodesWithEntities) + escapeGroups.push({ + 'group':'text', + 'class':'nodeTextEntity', + 'extra':{} + }); + + if (escapeGroups.length) + return escapeGroupsForEntities(text, escapeGroups); + else + return [{str:text,'class':'',extra:''}]; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + copyHTML: function(elt) + { + var html = getElementXML(elt); + copyToClipboard(html); + }, + + copyInnerHTML: function(elt) + { + copyToClipboard(elt.innerHTML); + }, + + copyXPath: function(elt) + { + var xpath = getElementXPath(elt); + copyToClipboard(xpath); + }, + + persistor: function(context, xpath) + { + var elts = xpath + ? getElementsByXPath(context.window.document, xpath) + : null; + + return elts && elts.length ? elts[0] : null; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "element", + + supportsObject: function(object) + { + //return object instanceof Element || object.nodeType == 1 && typeof object.nodeName == "string"; + return instanceOf(object, "Element"); + }, + + browseObject: function(elt, context) + { + var tag = elt.nodeName.toLowerCase(); + if (tag == "script") + openNewTab(elt.src); + else if (tag == "link") + openNewTab(elt.href); + else if (tag == "a") + openNewTab(elt.href); + else if (tag == "img") + openNewTab(elt.src); + + return true; + }, + + persistObject: function(elt, context) + { + var xpath = getElementXPath(elt); + + return bind(this.persistor, top, xpath); + }, + + getTitle: function(element, context) + { + return getElementCSSSelector(element); + }, + + getTooltip: function(elt) + { + return this.getXPath(elt); + }, + + getContextMenuItems: function(elt, target, context) + { + var monitored = areEventsMonitored(elt, null, context); + + return [ + {label: "CopyHTML", command: bindFixed(this.copyHTML, this, elt) }, + {label: "CopyInnerHTML", command: bindFixed(this.copyInnerHTML, this, elt) }, + {label: "CopyXPath", command: bindFixed(this.copyXPath, this, elt) }, + "-", + {label: "ShowEventsInConsole", type: "checkbox", checked: monitored, + command: bindFixed(toggleMonitorEvents, FBL, elt, null, monitored, context) }, + "-", + {label: "ScrollIntoView", command: bindFixed(elt.scrollIntoView, elt) } + ]; + } +}); + +// ************************************************************************************************ + +this.TextNode = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK( + "<", + SPAN({"class": "nodeTag"}, "TextNode"), + " textContent="", SPAN({"class": "nodeValue"}, "$object.textContent|cropString"), """, + ">" + ), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "textNode", + + supportsObject: function(object) + { + return object instanceof Text; + } +}); + +// ************************************************************************************************ + +this.Document = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK("Document ", SPAN({"class": "objectPropValue"}, "$object|getLocation")), + + getLocation: function(doc) + { + return doc.location ? getFileName(doc.location.href) : ""; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "object", + + supportsObject: function(object) + { + //return object instanceof Document || object instanceof XMLDocument; + return instanceOf(object, "Document"); + }, + + browseObject: function(doc, context) + { + openNewTab(doc.location.href); + return true; + }, + + persistObject: function(doc, context) + { + return this.persistor; + }, + + persistor: function(context) + { + return context.window.document; + }, + + getTitle: function(win, context) + { + return "document"; + }, + + getTooltip: function(doc) + { + return doc.location.href; + } +}); + +// ************************************************************************************************ + +this.StyleSheet = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK("StyleSheet ", SPAN({"class": "objectPropValue"}, "$object|getLocation")), + + getLocation: function(styleSheet) + { + return getFileName(styleSheet.href); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + copyURL: function(styleSheet) + { + copyToClipboard(styleSheet.href); + }, + + openInTab: function(styleSheet) + { + openNewTab(styleSheet.href); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "object", + + supportsObject: function(object) + { + //return object instanceof CSSStyleSheet; + return instanceOf(object, "CSSStyleSheet"); + }, + + browseObject: function(styleSheet, context) + { + openNewTab(styleSheet.href); + return true; + }, + + persistObject: function(styleSheet, context) + { + return bind(this.persistor, top, styleSheet.href); + }, + + getTooltip: function(styleSheet) + { + return styleSheet.href; + }, + + getContextMenuItems: function(styleSheet, target, context) + { + return [ + {label: "CopyLocation", command: bindFixed(this.copyURL, this, styleSheet) }, + "-", + {label: "OpenInTab", command: bindFixed(this.openInTab, this, styleSheet) } + ]; + }, + + persistor: function(context, href) + { + return getStyleSheetByHref(href, context); + } +}); + +// ************************************************************************************************ + +this.Window = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK("Window ", SPAN({"class": "objectPropValue"}, "$object|getLocation")), + + getLocation: function(win) + { + try + { + return (win && win.location && !win.closed) ? getFileName(win.location.href) : ""; + } + catch (exc) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("reps.Window window closed?"); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "object", + + supportsObject: function(object) + { + return instanceOf(object, "Window"); + }, + + browseObject: function(win, context) + { + openNewTab(win.location.href); + return true; + }, + + persistObject: function(win, context) + { + return this.persistor; + }, + + persistor: function(context) + { + return context.window; + }, + + getTitle: function(win, context) + { + return "window"; + }, + + getTooltip: function(win) + { + if (win && !win.closed) + return win.location.href; + } +}); + +// ************************************************************************************************ + +this.Event = domplate(Firebug.Rep, +{ + tag: TAG("$copyEventTag", {object: "$object|copyEvent"}), + + copyEventTag: + OBJECTLINK("$object|summarizeEvent"), + + summarizeEvent: function(event) + { + var info = [event.type, ' ']; + + var eventFamily = getEventFamily(event.type); + if (eventFamily == "mouse") + info.push("clientX=", event.clientX, ", clientY=", event.clientY); + else if (eventFamily == "key") + info.push("charCode=", event.charCode, ", keyCode=", event.keyCode); + + return info.join(""); + }, + + copyEvent: function(event) + { + return new EventCopy(event); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "object", + + supportsObject: function(object) + { + //return object instanceof Event || object instanceof EventCopy; + return instanceOf(object, "Event") || instanceOf(object, "EventCopy"); + }, + + getTitle: function(event, context) + { + return "Event " + event.type; + } +}); + +// ************************************************************************************************ + +this.SourceLink = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK({$collapsed: "$object|hideSourceLink"}, "$object|getSourceLinkTitle"), + + hideSourceLink: function(sourceLink) + { + return sourceLink ? sourceLink.href.indexOf("XPCSafeJSObjectWrapper") != -1 : true; + }, + + getSourceLinkTitle: function(sourceLink) + { + if (!sourceLink) + return ""; + + try + { + var fileName = getFileName(sourceLink.href); + fileName = decodeURIComponent(fileName); + fileName = cropString(fileName, 17); + } + catch(exc) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("reps.getSourceLinkTitle decodeURIComponent fails for \'"+fileName+"\': "+exc, exc); + } + + return typeof sourceLink.line == "number" ? + fileName + " (line " + sourceLink.line + ")" : + fileName; + + // TODO: xxxpedro + //return $STRF("Line", [fileName, sourceLink.line]); + }, + + copyLink: function(sourceLink) + { + copyToClipboard(sourceLink.href); + }, + + openInTab: function(sourceLink) + { + openNewTab(sourceLink.href); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "sourceLink", + + supportsObject: function(object) + { + return object instanceof SourceLink; + }, + + getTooltip: function(sourceLink) + { + return decodeURI(sourceLink.href); + }, + + inspectObject: function(sourceLink, context) + { + if (sourceLink.type == "js") + { + var scriptFile = getSourceFileByHref(sourceLink.href, context); + if (scriptFile) + return Firebug.chrome.select(sourceLink); + } + else if (sourceLink.type == "css") + { + // If an object is defined, treat it as the highest priority for + // inspect actions + if (sourceLink.object) { + Firebug.chrome.select(sourceLink.object); + return; + } + + var stylesheet = getStyleSheetByHref(sourceLink.href, context); + if (stylesheet) + { + var ownerNode = stylesheet.ownerNode; + if (ownerNode) + { + Firebug.chrome.select(sourceLink, "html"); + return; + } + + var panel = context.getPanel("stylesheet"); + if (panel && panel.getRuleByLine(stylesheet, sourceLink.line)) + return Firebug.chrome.select(sourceLink); + } + } + + // Fallback is to just open the view-source window on the file + viewSource(sourceLink.href, sourceLink.line); + }, + + browseObject: function(sourceLink, context) + { + openNewTab(sourceLink.href); + return true; + }, + + getContextMenuItems: function(sourceLink, target, context) + { + return [ + {label: "CopyLocation", command: bindFixed(this.copyLink, this, sourceLink) }, + "-", + {label: "OpenInTab", command: bindFixed(this.openInTab, this, sourceLink) } + ]; + } +}); + +// ************************************************************************************************ + +this.SourceFile = domplate(this.SourceLink, +{ + tag: + OBJECTLINK({$collapsed: "$object|hideSourceLink"}, "$object|getSourceLinkTitle"), + + persistor: function(context, href) + { + return getSourceFileByHref(href, context); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "sourceFile", + + supportsObject: function(object) + { + return object instanceof SourceFile; + }, + + persistObject: function(sourceFile) + { + return bind(this.persistor, top, sourceFile.href); + }, + + browseObject: function(sourceLink, context) + { + }, + + getTooltip: function(sourceFile) + { + return sourceFile.href; + } +}); + +// ************************************************************************************************ + +this.StackFrame = domplate(Firebug.Rep, // XXXjjb Since the repObject is fn the stack does not have correct line numbers +{ + tag: + OBJECTBLOCK( + A({"class": "objectLink objectLink-function focusRow a11yFocus", _repObject: "$object.fn"}, "$object|getCallName"), + " ( ", + FOR("arg", "$object|argIterator", + TAG("$arg.tag", {object: "$arg.value"}), + SPAN({"class": "arrayComma"}, "$arg.delim") + ), + " )", + SPAN({"class": "objectLink-sourceLink objectLink"}, "$object|getSourceLinkTitle") + ), + + getCallName: function(frame) + { + //TODO: xxxpedro reps StackFrame + return frame.name || "anonymous"; + + //return getFunctionName(frame.script, frame.context); + }, + + getSourceLinkTitle: function(frame) + { + //TODO: xxxpedro reps StackFrame + var fileName = cropString(getFileName(frame.href), 20); + return fileName + (frame.lineNo ? " (line " + frame.lineNo + ")" : ""); + + var fileName = cropString(getFileName(frame.href), 17); + return $STRF("Line", [fileName, frame.lineNo]); + }, + + argIterator: function(frame) + { + if (!frame.args) + return []; + + var items = []; + + for (var i = 0; i < frame.args.length; ++i) + { + var arg = frame.args[i]; + + if (!arg) + break; + + var rep = Firebug.getRep(arg.value); + var tag = rep.shortTag ? rep.shortTag : rep.tag; + + var delim = (i == frame.args.length-1 ? "" : ", "); + + items.push({name: arg.name, value: arg.value, tag: tag, delim: delim}); + } + + return items; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "stackFrame", + + supportsObject: function(object) + { + return object instanceof StackFrame; + }, + + inspectObject: function(stackFrame, context) + { + var sourceLink = new SourceLink(stackFrame.href, stackFrame.lineNo, "js"); + Firebug.chrome.select(sourceLink); + }, + + getTooltip: function(stackFrame, context) + { + return $STRF("Line", [stackFrame.href, stackFrame.lineNo]); + } + +}); + +// ************************************************************************************************ + +this.StackTrace = domplate(Firebug.Rep, +{ + tag: + FOR("frame", "$object.frames focusRow", + TAG(this.StackFrame.tag, {object: "$frame"}) + ), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "stackTrace", + + supportsObject: function(object) + { + return object instanceof StackTrace; + } +}); + +// ************************************************************************************************ + +this.jsdStackFrame = domplate(Firebug.Rep, +{ + inspectable: false, + + supportsObject: function(object) + { + return (object instanceof jsdIStackFrame) && (object.isValid); + }, + + getTitle: function(frame, context) + { + if (!frame.isValid) return "(invalid frame)"; // XXXjjb avoid frame.script == null + return getFunctionName(frame.script, context); + }, + + getTooltip: function(frame, context) + { + if (!frame.isValid) return "(invalid frame)"; // XXXjjb avoid frame.script == null + var sourceInfo = FBL.getSourceFileAndLineByScript(context, frame.script, frame); + if (sourceInfo) + return $STRF("Line", [sourceInfo.sourceFile.href, sourceInfo.lineNo]); + else + return $STRF("Line", [frame.script.fileName, frame.line]); + }, + + getContextMenuItems: function(frame, target, context) + { + var fn = frame.script.functionObject.getWrappedValue(); + return FirebugReps.Func.getContextMenuItems(fn, target, context, frame.script); + } +}); + +// ************************************************************************************************ + +this.ErrorMessage = domplate(Firebug.Rep, +{ + tag: + OBJECTBOX({ + $hasTwisty: "$object|hasStackTrace", + $hasBreakSwitch: "$object|hasBreakSwitch", + $breakForError: "$object|hasErrorBreak", + _repObject: "$object", + _stackTrace: "$object|getLastErrorStackTrace", + onclick: "$onToggleError"}, + + DIV({"class": "errorTitle a11yFocus", role : 'checkbox', 'aria-checked' : 'false'}, + "$object.message|getMessage" + ), + DIV({"class": "errorTrace"}), + DIV({"class": "errorSourceBox errorSource-$object|getSourceType"}, + IMG({"class": "errorBreak a11yFocus", src:"blank.gif", role : 'checkbox', 'aria-checked':'false', title: "Break on this error"}), + A({"class": "errorSource a11yFocus"}, "$object|getLine") + ), + TAG(this.SourceLink.tag, {object: "$object|getSourceLink"}) + ), + + getLastErrorStackTrace: function(error) + { + return error.trace; + }, + + hasStackTrace: function(error) + { + var url = error.href.toString(); + var fromCommandLine = (url.indexOf("XPCSafeJSObjectWrapper") != -1); + return !fromCommandLine && error.trace; + }, + + hasBreakSwitch: function(error) + { + return error.href && error.lineNo > 0; + }, + + hasErrorBreak: function(error) + { + return fbs.hasErrorBreakpoint(error.href, error.lineNo); + }, + + getMessage: function(message) + { + var re = /\[Exception... "(.*?)" nsresult:/; + var m = re.exec(message); + return m ? m[1] : message; + }, + + getLine: function(error) + { + if (error.category == "js") + { + if (error.source) + return cropString(error.source, 80); + else if (error.href && error.href.indexOf("XPCSafeJSObjectWrapper") == -1) + return cropString(error.getSourceLine(), 80); + } + }, + + getSourceLink: function(error) + { + var ext = error.category == "css" ? "css" : "js"; + return error.lineNo ? new SourceLink(error.href, error.lineNo, ext) : null; + }, + + getSourceType: function(error) + { + // Errors occurring inside of HTML event handlers look like "foo.html (line 1)" + // so let's try to skip those + if (error.source) + return "syntax"; + else if (error.lineNo == 1 && getFileExtension(error.href) != "js") + return "none"; + else if (error.category == "css") + return "none"; + else if (!error.href || !error.lineNo) + return "none"; + else + return "exec"; + }, + + onToggleError: function(event) + { + var target = event.currentTarget; + if (hasClass(event.target, "errorBreak")) + { + this.breakOnThisError(target.repObject); + } + else if (hasClass(event.target, "errorSource")) + { + var panel = Firebug.getElementPanel(event.target); + this.inspectObject(target.repObject, panel.context); + } + else if (hasClass(event.target, "errorTitle")) + { + var traceBox = target.childNodes[1]; + toggleClass(target, "opened"); + event.target.setAttribute('aria-checked', hasClass(target, "opened")); + if (hasClass(target, "opened")) + { + if (target.stackTrace) + var node = FirebugReps.StackTrace.tag.append({object: target.stackTrace}, traceBox); + if (Firebug.A11yModel.enabled) + { + var panel = Firebug.getElementPanel(event.target); + dispatch([Firebug.A11yModel], "onLogRowContentCreated", [panel , traceBox]); + } + } + else + clearNode(traceBox); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + copyError: function(error) + { + var message = [ + this.getMessage(error.message), + error.href, + "Line " + error.lineNo + ]; + copyToClipboard(message.join("\n")); + }, + + breakOnThisError: function(error) + { + if (this.hasErrorBreak(error)) + Firebug.Debugger.clearErrorBreakpoint(error.href, error.lineNo); + else + Firebug.Debugger.setErrorBreakpoint(error.href, error.lineNo); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "errorMessage", + inspectable: false, + + supportsObject: function(object) + { + return object instanceof ErrorMessage; + }, + + inspectObject: function(error, context) + { + var sourceLink = this.getSourceLink(error); + FirebugReps.SourceLink.inspectObject(sourceLink, context); + }, + + getContextMenuItems: function(error, target, context) + { + var breakOnThisError = this.hasErrorBreak(error); + + var items = [ + {label: "CopyError", command: bindFixed(this.copyError, this, error) } + ]; + + if (error.category == "css") + { + items.push( + "-", + {label: "BreakOnThisError", type: "checkbox", checked: breakOnThisError, + command: bindFixed(this.breakOnThisError, this, error) }, + + optionMenu("BreakOnAllErrors", "breakOnErrors") + ); + } + + return items; + } +}); + +// ************************************************************************************************ + +this.Assert = domplate(Firebug.Rep, +{ + tag: + DIV( + DIV({"class": "errorTitle"}), + DIV({"class": "assertDescription"}) + ), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "assert", + + inspectObject: function(error, context) + { + var sourceLink = this.getSourceLink(error); + Firebug.chrome.select(sourceLink); + }, + + getContextMenuItems: function(error, target, context) + { + var breakOnThisError = this.hasErrorBreak(error); + + return [ + {label: "CopyError", command: bindFixed(this.copyError, this, error) }, + "-", + {label: "BreakOnThisError", type: "checkbox", checked: breakOnThisError, + command: bindFixed(this.breakOnThisError, this, error) }, + {label: "BreakOnAllErrors", type: "checkbox", checked: Firebug.breakOnErrors, + command: bindFixed(this.breakOnAllErrors, this, error) } + ]; + } +}); + +// ************************************************************************************************ + +this.SourceText = domplate(Firebug.Rep, +{ + tag: + DIV( + FOR("line", "$object|lineIterator", + DIV({"class": "sourceRow", role : "presentation"}, + SPAN({"class": "sourceLine", role : "presentation"}, "$line.lineNo"), + SPAN({"class": "sourceRowText", role : "presentation"}, "$line.text") + ) + ) + ), + + lineIterator: function(sourceText) + { + var maxLineNoChars = (sourceText.lines.length + "").length; + var list = []; + + for (var i = 0; i < sourceText.lines.length; ++i) + { + // Make sure all line numbers are the same width (with a fixed-width font) + var lineNo = (i+1) + ""; + while (lineNo.length < maxLineNoChars) + lineNo = " " + lineNo; + + list.push({lineNo: lineNo, text: sourceText.lines[i]}); + } + + return list; + }, + + getHTML: function(sourceText) + { + return getSourceLineRange(sourceText, 1, sourceText.lines.length); + } +}); + +//************************************************************************************************ +this.nsIDOMHistory = domplate(Firebug.Rep, +{ + tag:OBJECTBOX({onclick: "$showHistory"}, + OBJECTLINK("$object|summarizeHistory") + ), + + className: "nsIDOMHistory", + + summarizeHistory: function(history) + { + try + { + var items = history.length; + return items + " history entries"; + } + catch(exc) + { + return "object does not support history (nsIDOMHistory)"; + } + }, + + showHistory: function(history) + { + try + { + var items = history.length; // if this throws, then unsupported + Firebug.chrome.select(history); + } + catch (exc) + { + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + supportsObject: function(object, type) + { + return (object instanceof Ci.nsIDOMHistory); + } +}); + +// ************************************************************************************************ +this.ApplicationCache = domplate(Firebug.Rep, +{ + tag:OBJECTBOX({onclick: "$showApplicationCache"}, + OBJECTLINK("$object|summarizeCache") + ), + + summarizeCache: function(applicationCache) + { + try + { + return applicationCache.length + " items in offline cache"; + } + catch(exc) + { + return "https://bugzilla.mozilla.org/show_bug.cgi?id=422264"; + } + }, + + showApplicationCache: function(event) + { + openNewTab("https://bugzilla.mozilla.org/show_bug.cgi?id=422264"); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "applicationCache", + + supportsObject: function(object, type) + { + if (Ci.nsIDOMOfflineResourceList) + return (object instanceof Ci.nsIDOMOfflineResourceList); + } + +}); + +this.Storage = domplate(Firebug.Rep, +{ + tag: OBJECTBOX({onclick: "$show"}, OBJECTLINK("$object|summarize")), + + summarize: function(storage) + { + return storage.length +" items in Storage"; + }, + show: function(storage) + { + openNewTab("http://dev.w3.org/html5/webstorage/#storage-0"); + }, + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "Storage", + + supportsObject: function(object, type) + { + return (object instanceof Storage); + } + +}); + +// ************************************************************************************************ +Firebug.registerRep( + //this.nsIDOMHistory, // make this early to avoid exceptions + this.Undefined, + this.Null, + this.Number, + this.String, + this.Window, + //this.ApplicationCache, // must come before Arr (array) else exceptions. + //this.ErrorMessage, + this.Element, + //this.TextNode, + this.Document, + this.StyleSheet, + this.Event, + //this.SourceLink, + //this.SourceFile, + //this.StackTrace, + //this.StackFrame, + //this.jsdStackFrame, + //this.jsdScript, + //this.NetFile, + this.Property, + this.Except, + this.Arr +); + +Firebug.setDefaultReps(this.Func, this.Obj); + +}}); + +// ************************************************************************************************ +/* + * The following is http://developer.yahoo.com/yui/license.txt and applies to only code labeled "Yahoo BSD Source" + * in only this file reps.js. John J. Barton June 2007. + * +Software License Agreement (BSD License) + +Copyright (c) 2006, Yahoo! Inc. +All rights reserved. + +Redistribution and use of this software in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of Yahoo! Inc. nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of Yahoo! Inc. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * / + */ + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// Constants + +var saveTimeout = 400; +var pageAmount = 10; + +// ************************************************************************************************ +// Globals + +var currentTarget = null; +var currentGroup = null; +var currentPanel = null; +var currentEditor = null; + +var defaultEditor = null; + +var originalClassName = null; + +var originalValue = null; +var defaultValue = null; +var previousValue = null; + +var invalidEditor = false; +var ignoreNextInput = false; + +// ************************************************************************************************ + +Firebug.Editor = extend(Firebug.Module, +{ + supportsStopEvent: true, + + dispatchName: "editor", + tabCharacter: " ", + + startEditing: function(target, value, editor) + { + this.stopEditing(); + + if (hasClass(target, "insertBefore") || hasClass(target, "insertAfter")) + return; + + var panel = Firebug.getElementPanel(target); + if (!panel.editable) + return; + + if (FBTrace.DBG_EDITOR) + FBTrace.sysout("editor.startEditing " + value, target); + + defaultValue = target.getAttribute("defaultValue"); + if (value == undefined) + { + var textContent = isIE ? "innerText" : "textContent"; + value = target[textContent]; + if (value == defaultValue) + value = ""; + } + + originalValue = previousValue = value; + + invalidEditor = false; + currentTarget = target; + currentPanel = panel; + currentGroup = getAncestorByClass(target, "editGroup"); + + currentPanel.editing = true; + + var panelEditor = currentPanel.getEditor(target, value); + currentEditor = editor ? editor : panelEditor; + if (!currentEditor) + currentEditor = getDefaultEditor(currentPanel); + + var inlineParent = getInlineParent(target); + var targetSize = getOffsetSize(inlineParent); + + setClass(panel.panelNode, "editing"); + setClass(target, "editing"); + if (currentGroup) + setClass(currentGroup, "editing"); + + currentEditor.show(target, currentPanel, value, targetSize); + //dispatch(this.fbListeners, "onBeginEditing", [currentPanel, currentEditor, target, value]); + currentEditor.beginEditing(target, value); + if (FBTrace.DBG_EDITOR) + FBTrace.sysout("Editor start panel "+currentPanel.name); + this.attachListeners(currentEditor, panel.context); + }, + + stopEditing: function(cancel) + { + if (!currentTarget) + return; + + if (FBTrace.DBG_EDITOR) + FBTrace.sysout("editor.stopEditing cancel:" + cancel+" saveTimeout: "+this.saveTimeout); + + clearTimeout(this.saveTimeout); + delete this.saveTimeout; + + this.detachListeners(currentEditor, currentPanel.context); + + removeClass(currentPanel.panelNode, "editing"); + removeClass(currentTarget, "editing"); + if (currentGroup) + removeClass(currentGroup, "editing"); + + var value = currentEditor.getValue(); + if (value == defaultValue) + value = ""; + + var removeGroup = currentEditor.endEditing(currentTarget, value, cancel); + + try + { + if (cancel) + { + //dispatch([Firebug.A11yModel], 'onInlineEditorClose', [currentPanel, currentTarget, removeGroup && !originalValue]); + if (value != originalValue) + this.saveEditAndNotifyListeners(currentTarget, originalValue, previousValue); + + if (removeGroup && !originalValue && currentGroup) + currentGroup.parentNode.removeChild(currentGroup); + } + else if (!value) + { + this.saveEditAndNotifyListeners(currentTarget, null, previousValue); + + if (removeGroup && currentGroup) + currentGroup.parentNode.removeChild(currentGroup); + } + else + this.save(value); + } + catch (exc) + { + //throw exc.message; + //ERROR(exc); + } + + currentEditor.hide(); + currentPanel.editing = false; + + //dispatch(this.fbListeners, "onStopEdit", [currentPanel, currentEditor, currentTarget]); + //if (FBTrace.DBG_EDITOR) + // FBTrace.sysout("Editor stop panel "+currentPanel.name); + + currentTarget = null; + currentGroup = null; + currentPanel = null; + currentEditor = null; + originalValue = null; + invalidEditor = false; + + return value; + }, + + cancelEditing: function() + { + return this.stopEditing(true); + }, + + update: function(saveNow) + { + if (this.saveTimeout) + clearTimeout(this.saveTimeout); + + invalidEditor = true; + + currentEditor.layout(); + + if (saveNow) + this.save(); + else + { + var context = currentPanel.context; + this.saveTimeout = context.setTimeout(bindFixed(this.save, this), saveTimeout); + if (FBTrace.DBG_EDITOR) + FBTrace.sysout("editor.update saveTimeout: "+this.saveTimeout); + } + }, + + save: function(value) + { + if (!invalidEditor) + return; + + if (value == undefined) + value = currentEditor.getValue(); + if (FBTrace.DBG_EDITOR) + FBTrace.sysout("editor.save saveTimeout: "+this.saveTimeout+" currentPanel: "+(currentPanel?currentPanel.name:"null")); + try + { + this.saveEditAndNotifyListeners(currentTarget, value, previousValue); + + previousValue = value; + invalidEditor = false; + } + catch (exc) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("editor.save FAILS "+exc, exc); + } + }, + + saveEditAndNotifyListeners: function(currentTarget, value, previousValue) + { + currentEditor.saveEdit(currentTarget, value, previousValue); + //dispatch(this.fbListeners, "onSaveEdit", [currentPanel, currentEditor, currentTarget, value, previousValue]); + }, + + setEditTarget: function(element) + { + if (!element) + { + dispatch([Firebug.A11yModel], 'onInlineEditorClose', [currentPanel, currentTarget, true]); + this.stopEditing(); + } + else if (hasClass(element, "insertBefore")) + this.insertRow(element, "before"); + else if (hasClass(element, "insertAfter")) + this.insertRow(element, "after"); + else + this.startEditing(element); + }, + + tabNextEditor: function() + { + if (!currentTarget) + return; + + var value = currentEditor.getValue(); + var nextEditable = currentTarget; + do + { + nextEditable = !value && currentGroup + ? getNextOutsider(nextEditable, currentGroup) + : getNextByClass(nextEditable, "editable"); + } + while (nextEditable && !nextEditable.offsetHeight); + + this.setEditTarget(nextEditable); + }, + + tabPreviousEditor: function() + { + if (!currentTarget) + return; + + var value = currentEditor.getValue(); + var prevEditable = currentTarget; + do + { + prevEditable = !value && currentGroup + ? getPreviousOutsider(prevEditable, currentGroup) + : getPreviousByClass(prevEditable, "editable"); + } + while (prevEditable && !prevEditable.offsetHeight); + + this.setEditTarget(prevEditable); + }, + + insertRow: function(relative, insertWhere) + { + var group = + relative || getAncestorByClass(currentTarget, "editGroup") || currentTarget; + var value = this.stopEditing(); + + currentPanel = Firebug.getElementPanel(group); + + currentEditor = currentPanel.getEditor(group, value); + if (!currentEditor) + currentEditor = getDefaultEditor(currentPanel); + + currentGroup = currentEditor.insertNewRow(group, insertWhere); + if (!currentGroup) + return; + + var editable = hasClass(currentGroup, "editable") + ? currentGroup + : getNextByClass(currentGroup, "editable"); + + if (editable) + this.setEditTarget(editable); + }, + + insertRowForObject: function(relative) + { + var container = getAncestorByClass(relative, "insertInto"); + if (container) + { + relative = getChildByClass(container, "insertBefore"); + if (relative) + this.insertRow(relative, "before"); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + attachListeners: function(editor, context) + { + var win = isIE ? + currentTarget.ownerDocument.parentWindow : + currentTarget.ownerDocument.defaultView; + + addEvent(win, "resize", this.onResize); + addEvent(win, "blur", this.onBlur); + + var chrome = Firebug.chrome; + + this.listeners = [ + chrome.keyCodeListen("ESCAPE", null, bind(this.cancelEditing, this)) + ]; + + if (editor.arrowCompletion) + { + this.listeners.push( + chrome.keyCodeListen("UP", null, bindFixed(editor.completeValue, editor, -1)), + chrome.keyCodeListen("DOWN", null, bindFixed(editor.completeValue, editor, 1)), + chrome.keyCodeListen("PAGE_UP", null, bindFixed(editor.completeValue, editor, -pageAmount)), + chrome.keyCodeListen("PAGE_DOWN", null, bindFixed(editor.completeValue, editor, pageAmount)) + ); + } + + if (currentEditor.tabNavigation) + { + this.listeners.push( + chrome.keyCodeListen("RETURN", null, bind(this.tabNextEditor, this)), + chrome.keyCodeListen("RETURN", isControl, bind(this.insertRow, this, null, "after")), + chrome.keyCodeListen("TAB", null, bind(this.tabNextEditor, this)), + chrome.keyCodeListen("TAB", isShift, bind(this.tabPreviousEditor, this)) + ); + } + else if (currentEditor.multiLine) + { + this.listeners.push( + chrome.keyCodeListen("TAB", null, insertTab) + ); + } + else + { + this.listeners.push( + chrome.keyCodeListen("RETURN", null, bindFixed(this.stopEditing, this)) + ); + + if (currentEditor.tabCompletion) + { + this.listeners.push( + chrome.keyCodeListen("TAB", null, bind(editor.completeValue, editor, 1)), + chrome.keyCodeListen("TAB", isShift, bind(editor.completeValue, editor, -1)) + ); + } + } + }, + + detachListeners: function(editor, context) + { + if (!this.listeners) + return; + + var win = isIE ? + currentTarget.ownerDocument.parentWindow : + currentTarget.ownerDocument.defaultView; + + removeEvent(win, "resize", this.onResize); + removeEvent(win, "blur", this.onBlur); + + var chrome = Firebug.chrome; + if (chrome) + { + for (var i = 0; i < this.listeners.length; ++i) + chrome.keyIgnore(this.listeners[i]); + } + + delete this.listeners; + }, + + onResize: function(event) + { + currentEditor.layout(true); + }, + + onBlur: function(event) + { + if (currentEditor.enterOnBlur && isAncestor(event.target, currentEditor.box)) + this.stopEditing(); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Module + + initialize: function() + { + Firebug.Module.initialize.apply(this, arguments); + + this.onResize = bindFixed(this.onResize, this); + this.onBlur = bind(this.onBlur, this); + }, + + disable: function() + { + this.stopEditing(); + }, + + showContext: function(browser, context) + { + this.stopEditing(); + }, + + showPanel: function(browser, panel) + { + this.stopEditing(); + } +}); + +// ************************************************************************************************ +// BaseEditor + +Firebug.BaseEditor = extend(Firebug.MeasureBox, +{ + getValue: function() + { + }, + + setValue: function(value) + { + }, + + show: function(target, panel, value, textSize, targetSize) + { + }, + + hide: function() + { + }, + + layout: function(forceAll) + { + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Support for context menus within inline editors. + + getContextMenuItems: function(target) + { + var items = []; + items.push({label: "Cut", commandID: "cmd_cut"}); + items.push({label: "Copy", commandID: "cmd_copy"}); + items.push({label: "Paste", commandID: "cmd_paste"}); + return items; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Editor Module listeners will get "onBeginEditing" just before this call + + beginEditing: function(target, value) + { + }, + + // Editor Module listeners will get "onSaveEdit" just after this call + saveEdit: function(target, value, previousValue) + { + }, + + endEditing: function(target, value, cancel) + { + // Remove empty groups by default + return true; + }, + + insertNewRow: function(target, insertWhere) + { + } +}); + +// ************************************************************************************************ +// InlineEditor + +// basic inline editor attributes +var inlineEditorAttributes = { + "class": "textEditorInner", + + type: "text", + spellcheck: "false", + + onkeypress: "$onKeyPress", + + onoverflow: "$onOverflow", + oncontextmenu: "$onContextMenu" +}; + +// IE does not support the oninput event, so we're using the onkeydown to signalize +// the relevant keyboard events, and the onpropertychange to actually handle the +// input event, which should happen after the onkeydown event is fired and after the +// value of the input is updated, but before the onkeyup and before the input (with the +// new value) is rendered +if (isIE) +{ + inlineEditorAttributes.onpropertychange = "$onInput"; + inlineEditorAttributes.onkeydown = "$onKeyDown"; +} +// for other browsers we use the oninput event +else +{ + inlineEditorAttributes.oninput = "$onInput"; +} + +Firebug.InlineEditor = function(doc) +{ + this.initializeInline(doc); +}; + +Firebug.InlineEditor.prototype = domplate(Firebug.BaseEditor, +{ + enterOnBlur: true, + outerMargin: 8, + shadowExpand: 7, + + tag: + DIV({"class": "inlineEditor"}, + DIV({"class": "textEditorTop1"}, + DIV({"class": "textEditorTop2"}) + ), + DIV({"class": "textEditorInner1"}, + DIV({"class": "textEditorInner2"}, + INPUT( + inlineEditorAttributes + ) + ) + ), + DIV({"class": "textEditorBottom1"}, + DIV({"class": "textEditorBottom2"}) + ) + ), + + inputTag : + INPUT({"class": "textEditorInner", type: "text", + /*oninput: "$onInput",*/ onkeypress: "$onKeyPress", onoverflow: "$onOverflow"} + ), + + expanderTag: + IMG({"class": "inlineExpander", src: "blank.gif"}), + + initialize: function() + { + this.fixedWidth = false; + this.completeAsYouType = true; + this.tabNavigation = true; + this.multiLine = false; + this.tabCompletion = false; + this.arrowCompletion = true; + this.noWrap = true; + this.numeric = false; + }, + + destroy: function() + { + this.destroyInput(); + }, + + initializeInline: function(doc) + { + if (FBTrace.DBG_EDITOR) + FBTrace.sysout("Firebug.InlineEditor initializeInline()"); + + //this.box = this.tag.replace({}, doc, this); + this.box = this.tag.append({}, doc.body, this); + + //this.input = this.box.childNodes[1].firstChild.firstChild; // XXXjjb childNode[1] required + this.input = this.box.getElementsByTagName("input")[0]; + + if (isIElt8) + { + this.input.style.top = "-8px"; + } + + this.expander = this.expanderTag.replace({}, doc, this); + this.initialize(); + }, + + destroyInput: function() + { + // XXXjoe Need to remove input/keypress handlers to avoid leaks + }, + + getValue: function() + { + return this.input.value; + }, + + setValue: function(value) + { + // It's only a one-line editor, so new lines shouldn't be allowed + return this.input.value = stripNewLines(value); + }, + + show: function(target, panel, value, targetSize) + { + //dispatch([Firebug.A11yModel], "onInlineEditorShow", [panel, this]); + this.target = target; + this.panel = panel; + + this.targetSize = targetSize; + + // TODO: xxxpedro editor + //this.targetOffset = getClientOffset(target); + + // Some browsers (IE, Google Chrome and Safari) will have problem trying to get the + // offset values of invisible elements, or empty elements. So, in order to get the + // correct values, we temporary inject a character in the innerHTML of the empty element, + // then we get the offset values, and next, we restore the original innerHTML value. + var innerHTML = target.innerHTML; + var isEmptyElement = !innerHTML; + if (isEmptyElement) + target.innerHTML = "."; + + // Get the position of the target element (that is about to be edited) + this.targetOffset = + { + x: target.offsetLeft, + y: target.offsetTop + }; + + // Restore the original innerHTML value of the empty element + if (isEmptyElement) + target.innerHTML = innerHTML; + + this.originalClassName = this.box.className; + + var classNames = target.className.split(" "); + for (var i = 0; i < classNames.length; ++i) + setClass(this.box, "editor-" + classNames[i]); + + // Make the editor match the target's font style + copyTextStyles(target, this.box); + + this.setValue(value); + + if (this.fixedWidth) + this.updateLayout(true); + else + { + this.startMeasuring(target); + this.textSize = this.measureInputText(value); + + // Correct the height of the box to make the funky CSS drop-shadow line up + var parent = this.input.parentNode; + if (hasClass(parent, "textEditorInner2")) + { + var yDiff = this.textSize.height - this.shadowExpand; + + // IE6 height offset + if (isIE6) + yDiff -= 2; + + parent.style.height = yDiff + "px"; + parent.parentNode.style.height = yDiff + "px"; + } + + this.updateLayout(true); + } + + this.getAutoCompleter().reset(); + + if (isIElt8) + panel.panelNode.appendChild(this.box); + else + target.offsetParent.appendChild(this.box); + + //console.log(target); + //this.input.select(); // it's called bellow, with setTimeout + + if (isIE) + { + // reset input style + this.input.style.fontFamily = "Monospace"; + this.input.style.fontSize = "11px"; + } + + // Insert the "expander" to cover the target element with white space + if (!this.fixedWidth) + { + copyBoxStyles(target, this.expander); + + target.parentNode.replaceChild(this.expander, target); + collapse(target, true); + this.expander.parentNode.insertBefore(target, this.expander); + } + + //TODO: xxxpedro + //scrollIntoCenterView(this.box, null, true); + + // Display the editor after change its size and position to avoid flickering + this.box.style.display = "block"; + + // we need to call input.focus() and input.select() with a timeout, + // otherwise it won't work on all browsers due to timing issues + var self = this; + setTimeout(function(){ + self.input.focus(); + self.input.select(); + },0); + }, + + hide: function() + { + this.box.className = this.originalClassName; + + if (!this.fixedWidth) + { + this.stopMeasuring(); + + collapse(this.target, false); + + if (this.expander.parentNode) + this.expander.parentNode.removeChild(this.expander); + } + + if (this.box.parentNode) + { + ///setSelectionRange(this.input, 0, 0); + this.input.blur(); + + this.box.parentNode.removeChild(this.box); + } + + delete this.target; + delete this.panel; + }, + + layout: function(forceAll) + { + if (!this.fixedWidth) + this.textSize = this.measureInputText(this.input.value); + + if (forceAll) + this.targetOffset = getClientOffset(this.expander); + + this.updateLayout(false, forceAll); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + beginEditing: function(target, value) + { + }, + + saveEdit: function(target, value, previousValue) + { + }, + + endEditing: function(target, value, cancel) + { + // Remove empty groups by default + return true; + }, + + insertNewRow: function(target, insertWhere) + { + }, + + advanceToNext: function(target, charCode) + { + return false; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getAutoCompleteRange: function(value, offset) + { + }, + + getAutoCompleteList: function(preExpr, expr, postExpr) + { + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getAutoCompleter: function() + { + if (!this.autoCompleter) + { + this.autoCompleter = new Firebug.AutoCompleter(null, + bind(this.getAutoCompleteRange, this), bind(this.getAutoCompleteList, this), + true, false); + } + + return this.autoCompleter; + }, + + completeValue: function(amt) + { + //console.log("completeValue"); + + var selectRangeCallback = this.getAutoCompleter().complete(currentPanel.context, this.input, true, amt < 0); + + if (selectRangeCallback) + { + Firebug.Editor.update(true); + + // We need to select the editor text after calling update in Safari/Chrome, + // otherwise the text won't be selected + if (isSafari) + setTimeout(selectRangeCallback,0); + else + selectRangeCallback(); + } + else + this.incrementValue(amt); + }, + + incrementValue: function(amt) + { + var value = this.input.value; + + // TODO: xxxpedro editor + if (isIE) + var start = getInputSelectionStart(this.input), end = start; + else + var start = this.input.selectionStart, end = this.input.selectionEnd; + + //debugger; + var range = this.getAutoCompleteRange(value, start); + if (!range || range.type != "int") + range = {start: 0, end: value.length-1}; + + var expr = value.substr(range.start, range.end-range.start+1); + preExpr = value.substr(0, range.start); + postExpr = value.substr(range.end+1); + + // See if the value is an integer, and if so increment it + var intValue = parseInt(expr); + if (!!intValue || intValue == 0) + { + var m = /\d+/.exec(expr); + var digitPost = expr.substr(m.index+m[0].length); + + var completion = intValue-amt; + this.input.value = preExpr + completion + digitPost + postExpr; + + setSelectionRange(this.input, start, end); + + Firebug.Editor.update(true); + + return true; + } + else + return false; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + onKeyPress: function(event) + { + //console.log("onKeyPress", event); + if (event.keyCode == 27 && !this.completeAsYouType) + { + var reverted = this.getAutoCompleter().revert(this.input); + if (reverted) + cancelEvent(event); + } + else if (event.charCode && this.advanceToNext(this.target, event.charCode)) + { + Firebug.Editor.tabNextEditor(); + cancelEvent(event); + } + else + { + if (this.numeric && event.charCode && (event.charCode < 48 || event.charCode > 57) + && event.charCode != 45 && event.charCode != 46) + FBL.cancelEvent(event); + else + { + // If the user backspaces, don't autocomplete after the upcoming input event + this.ignoreNextInput = event.keyCode == 8; + } + } + }, + + onOverflow: function() + { + this.updateLayout(false, false, 3); + }, + + onKeyDown: function(event) + { + //console.log("onKeyDown", event.keyCode); + if (event.keyCode > 46 || event.keyCode == 32 || event.keyCode == 8) + { + this.keyDownPressed = true; + } + }, + + onInput: function(event) + { + //debugger; + + // skip not relevant onpropertychange calls on IE + if (isIE) + { + if (event.propertyName != "value" || !isVisible(this.input) || !this.keyDownPressed) + return; + + this.keyDownPressed = false; + } + + //console.log("onInput", event); + //console.trace(); + + var selectRangeCallback; + + if (this.ignoreNextInput) + { + this.ignoreNextInput = false; + this.getAutoCompleter().reset(); + } + else if (this.completeAsYouType) + selectRangeCallback = this.getAutoCompleter().complete(currentPanel.context, this.input, false); + else + this.getAutoCompleter().reset(); + + Firebug.Editor.update(); + + if (selectRangeCallback) + { + // We need to select the editor text after calling update in Safari/Chrome, + // otherwise the text won't be selected + if (isSafari) + setTimeout(selectRangeCallback,0); + else + selectRangeCallback(); + } + }, + + onContextMenu: function(event) + { + cancelEvent(event); + + var popup = $("fbInlineEditorPopup"); + FBL.eraseNode(popup); + + var target = event.target || event.srcElement; + var menu = this.getContextMenuItems(target); + if (menu) + { + for (var i = 0; i < menu.length; ++i) + FBL.createMenuItem(popup, menu[i]); + } + + if (!popup.firstChild) + return false; + + popup.openPopupAtScreen(event.screenX, event.screenY, true); + return true; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + updateLayout: function(initial, forceAll, extraWidth) + { + if (this.fixedWidth) + { + this.box.style.left = (this.targetOffset.x) + "px"; + this.box.style.top = (this.targetOffset.y) + "px"; + + var w = this.target.offsetWidth; + var h = this.target.offsetHeight; + this.input.style.width = w + "px"; + this.input.style.height = (h-3) + "px"; + } + else + { + if (initial || forceAll) + { + this.box.style.left = this.targetOffset.x + "px"; + this.box.style.top = this.targetOffset.y + "px"; + } + + var approxTextWidth = this.textSize.width; + var maxWidth = (currentPanel.panelNode.scrollWidth - this.targetOffset.x) + - this.outerMargin; + + var wrapped = initial + ? this.noWrap && this.targetSize.height > this.textSize.height+3 + : this.noWrap && approxTextWidth > maxWidth; + + if (wrapped) + { + var style = isIE ? + this.target.currentStyle : + this.target.ownerDocument.defaultView.getComputedStyle(this.target, ""); + + targetMargin = parseInt(style.marginLeft) + parseInt(style.marginRight); + + // Make the width fit the remaining x-space from the offset to the far right + approxTextWidth = maxWidth - targetMargin; + + this.input.style.width = "100%"; + this.box.style.width = approxTextWidth + "px"; + } + else + { + // Make the input one character wider than the text value so that + // typing does not ever cause the textbox to scroll + var charWidth = this.measureInputText('m').width; + + // Sometimes we need to make the editor a little wider, specifically when + // an overflow happens, otherwise it will scroll off some text on the left + if (extraWidth) + charWidth *= extraWidth; + + var inputWidth = approxTextWidth + charWidth; + + if (initial) + { + if (isIE) + { + // TODO: xxxpedro + var xDiff = 13; + this.box.style.width = (inputWidth + xDiff) + "px"; + } + else + this.box.style.width = "auto"; + } + else + { + // TODO: xxxpedro + var xDiff = isIE ? 13: this.box.scrollWidth - this.input.offsetWidth; + this.box.style.width = (inputWidth + xDiff) + "px"; + } + + this.input.style.width = inputWidth + "px"; + } + + this.expander.style.width = approxTextWidth + "px"; + this.expander.style.height = Math.max(this.textSize.height-3,0) + "px"; + } + + if (forceAll) + scrollIntoCenterView(this.box, null, true); + } +}); + +// ************************************************************************************************ +// Autocompletion + +Firebug.AutoCompleter = function(getExprOffset, getRange, evaluator, selectMode, caseSensitive) +{ + var candidates = null; + var originalValue = null; + var originalOffset = -1; + var lastExpr = null; + var lastOffset = -1; + var exprOffset = 0; + var lastIndex = 0; + var preParsed = null; + var preExpr = null; + var postExpr = null; + + this.revert = function(textBox) + { + if (originalOffset != -1) + { + textBox.value = originalValue; + + setSelectionRange(textBox, originalOffset, originalOffset); + + this.reset(); + return true; + } + else + { + this.reset(); + return false; + } + }; + + this.reset = function() + { + candidates = null; + originalValue = null; + originalOffset = -1; + lastExpr = null; + lastOffset = 0; + exprOffset = 0; + }; + + this.complete = function(context, textBox, cycle, reverse) + { + //console.log("complete", context, textBox, cycle, reverse); + // TODO: xxxpedro important port to firebug (variable leak) + //var value = lastValue = textBox.value; + var value = textBox.value; + + //var offset = textBox.selectionStart; + var offset = getInputSelectionStart(textBox); + + // The result of selectionStart() in Safari/Chrome is 1 unit less than the result + // in Firefox. Therefore, we need to manually adjust the value here. + if (isSafari && !cycle && offset >= 0) offset++; + + if (!selectMode && originalOffset != -1) + offset = originalOffset; + + if (!candidates || !cycle || offset != lastOffset) + { + originalOffset = offset; + originalValue = value; + + // Find the part of the string that will be parsed + var parseStart = getExprOffset ? getExprOffset(value, offset, context) : 0; + preParsed = value.substr(0, parseStart); + var parsed = value.substr(parseStart); + + // Find the part of the string that is being completed + var range = getRange ? getRange(parsed, offset-parseStart, context) : null; + if (!range) + range = {start: 0, end: parsed.length-1 }; + + var expr = parsed.substr(range.start, range.end-range.start+1); + preExpr = parsed.substr(0, range.start); + postExpr = parsed.substr(range.end+1); + exprOffset = parseStart + range.start; + + if (!cycle) + { + if (!expr) + return; + else if (lastExpr && lastExpr.indexOf(expr) != 0) + { + candidates = null; + } + else if (lastExpr && lastExpr.length >= expr.length) + { + candidates = null; + lastExpr = expr; + return; + } + } + + lastExpr = expr; + lastOffset = offset; + + var searchExpr; + + // Check if the cursor is at the very right edge of the expression, or + // somewhere in the middle of it + if (expr && offset != parseStart+range.end+1) + { + if (cycle) + { + // We are in the middle of the expression, but we can + // complete by cycling to the next item in the values + // list after the expression + offset = range.start; + searchExpr = expr; + expr = ""; + } + else + { + // We can't complete unless we are at the ridge edge + return; + } + } + + var values = evaluator(preExpr, expr, postExpr, context); + if (!values) + return; + + if (expr) + { + // Filter the list of values to those which begin with expr. We + // will then go on to complete the first value in the resulting list + candidates = []; + + if (caseSensitive) + { + for (var i = 0; i < values.length; ++i) + { + var name = values[i]; + if (name.indexOf && name.indexOf(expr) == 0) + candidates.push(name); + } + } + else + { + var lowerExpr = caseSensitive ? expr : expr.toLowerCase(); + for (var i = 0; i < values.length; ++i) + { + var name = values[i]; + if (name.indexOf && name.toLowerCase().indexOf(lowerExpr) == 0) + candidates.push(name); + } + } + + lastIndex = reverse ? candidates.length-1 : 0; + } + else if (searchExpr) + { + var searchIndex = -1; + + // Find the first instance of searchExpr in the values list. We + // will then complete the string that is found + if (caseSensitive) + { + searchIndex = values.indexOf(expr); + } + else + { + var lowerExpr = searchExpr.toLowerCase(); + for (var i = 0; i < values.length; ++i) + { + var name = values[i]; + if (name && name.toLowerCase().indexOf(lowerExpr) == 0) + { + searchIndex = i; + break; + } + } + } + + // Nothing found, so there's nothing to complete to + if (searchIndex == -1) + return this.reset(); + + expr = searchExpr; + candidates = cloneArray(values); + lastIndex = searchIndex; + } + else + { + expr = ""; + candidates = []; + for (var i = 0; i < values.length; ++i) + { + if (values[i].substr) + candidates.push(values[i]); + } + lastIndex = -1; + } + } + + if (cycle) + { + expr = lastExpr; + lastIndex += reverse ? -1 : 1; + } + + if (!candidates.length) + return; + + if (lastIndex >= candidates.length) + lastIndex = 0; + else if (lastIndex < 0) + lastIndex = candidates.length-1; + + var completion = candidates[lastIndex]; + var preCompletion = expr.substr(0, offset-exprOffset); + var postCompletion = completion.substr(offset-exprOffset); + + textBox.value = preParsed + preExpr + preCompletion + postCompletion + postExpr; + var offsetEnd = preParsed.length + preExpr.length + completion.length; + + // TODO: xxxpedro remove the following commented code, if the lib.setSelectionRange() + // is working well. + /* + if (textBox.setSelectionRange) + { + // we must select the range with a timeout, otherwise the text won't + // be properly selected (because after this function executes, the editor's + // input will be resized to fit the whole text) + setTimeout(function(){ + if (selectMode) + textBox.setSelectionRange(offset, offsetEnd); + else + textBox.setSelectionRange(offsetEnd, offsetEnd); + },0); + } + /**/ + + // we must select the range with a timeout, otherwise the text won't + // be properly selected (because after this function executes, the editor's + // input will be resized to fit the whole text) + /* + setTimeout(function(){ + if (selectMode) + setSelectionRange(textBox, offset, offsetEnd); + else + setSelectionRange(textBox, offsetEnd, offsetEnd); + },0); + + return true; + /**/ + + // The editor text should be selected only after calling the editor.update() + // in Safari/Chrome, otherwise the text won't be selected. So, we're returning + // a function to be called later (in the proper time for all browsers). + // + // TODO: xxxpedro see if we can move the editor.update() calls to here, and avoid + // returning a closure. the complete() function seems to be called only twice in + // editor.js. See if this function is called anywhere else (like css.js for example). + return function(){ + //console.log("autocomplete ", textBox, offset, offsetEnd); + + if (selectMode) + setSelectionRange(textBox, offset, offsetEnd); + else + setSelectionRange(textBox, offsetEnd, offsetEnd); + }; + /**/ + }; +}; + +// ************************************************************************************************ +// Local Helpers + +var getDefaultEditor = function getDefaultEditor(panel) +{ + if (!defaultEditor) + { + var doc = panel.document; + defaultEditor = new Firebug.InlineEditor(doc); + } + + return defaultEditor; +} + +/** + * An outsider is the first element matching the stepper element that + * is not an child of group. Elements tagged with insertBefore or insertAfter + * classes are also excluded from these results unless they are the sibling + * of group, relative to group's parent editGroup. This allows for the proper insertion + * rows when groups are nested. + */ +var getOutsider = function getOutsider(element, group, stepper) +{ + var parentGroup = getAncestorByClass(group.parentNode, "editGroup"); + var next; + do + { + next = stepper(next || element); + } + while (isAncestor(next, group) || isGroupInsert(next, parentGroup)); + + return next; +} + +var isGroupInsert = function isGroupInsert(next, group) +{ + return (!group || isAncestor(next, group)) + && (hasClass(next, "insertBefore") || hasClass(next, "insertAfter")); +} + +var getNextOutsider = function getNextOutsider(element, group) +{ + return getOutsider(element, group, bind(getNextByClass, FBL, "editable")); +} + +var getPreviousOutsider = function getPreviousOutsider(element, group) +{ + return getOutsider(element, group, bind(getPreviousByClass, FBL, "editable")); +} + +var getInlineParent = function getInlineParent(element) +{ + var lastInline = element; + for (; element; element = element.parentNode) + { + //var s = element.ownerDocument.defaultView.getComputedStyle(element, ""); + var s = isIE ? + element.currentStyle : + element.ownerDocument.defaultView.getComputedStyle(element, ""); + + if (s.display != "inline") + return lastInline; + else + lastInline = element; + } + return null; +} + +var insertTab = function insertTab() +{ + insertTextIntoElement(currentEditor.input, Firebug.Editor.tabCharacter); +} + +// ************************************************************************************************ + +Firebug.registerModule(Firebug.Editor); + +// ************************************************************************************************ + +}}); + + +/* 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(); + + 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" ? FirebugChrome.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 + + + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +// next-generation Console Panel (will override consoje.js) +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +// Constants + +/* +const Cc = Components.classes; +const Ci = Components.interfaces; +const nsIPrefBranch2 = Ci.nsIPrefBranch2; +const PrefService = Cc["@mozilla.org/preferences-service;1"]; +const prefs = PrefService.getService(nsIPrefBranch2); +/**/ +/* + +// new offline message handler +o = {x:1,y:2}; + +r = Firebug.getRep(o); + +r.tag.tag.compile(); + +outputs = []; +html = r.tag.renderHTML({object:o}, outputs); + + +// finish rendering the template (the DOM part) +target = $("build"); +target.innerHTML = html; +root = target.firstChild; + +domArgs = [root, r.tag.context, 0]; +domArgs.push.apply(domArgs, r.tag.domArgs); +domArgs.push.apply(domArgs, outputs); +r.tag.tag.renderDOM.apply(self ? self : r.tag.subject, domArgs); + + + */ +var consoleQueue = []; +var lastHighlightedObject; +var FirebugContext = Env.browser; + +// ************************************************************************************************ + +var maxQueueRequests = 500; + +// ************************************************************************************************ + +Firebug.ConsoleBase = +{ + log: function(object, context, className, rep, noThrottle, sourceLink) + { + //dispatch(this.fbListeners,"log",[context, object, className, sourceLink]); + return this.logRow(appendObject, object, context, className, rep, sourceLink, noThrottle); + }, + + logFormatted: function(objects, context, className, noThrottle, sourceLink) + { + //dispatch(this.fbListeners,"logFormatted",[context, objects, className, sourceLink]); + return this.logRow(appendFormatted, objects, context, className, null, sourceLink, noThrottle); + }, + + openGroup: function(objects, context, className, rep, noThrottle, sourceLink, noPush) + { + return this.logRow(appendOpenGroup, objects, context, className, rep, sourceLink, noThrottle); + }, + + closeGroup: function(context, noThrottle) + { + return this.logRow(appendCloseGroup, null, context, null, null, null, noThrottle, true); + }, + + logRow: function(appender, objects, context, className, rep, sourceLink, noThrottle, noRow) + { + // TODO: xxxpedro console console2 + noThrottle = true; // xxxpedro forced because there is no TabContext yet + + if (!context) + context = FirebugContext; + + if (FBTrace.DBG_ERRORS && !context) + FBTrace.sysout("Console.logRow has no context, skipping objects", objects); + + if (!context) + return; + + if (noThrottle || !context) + { + var panel = this.getPanel(context); + if (panel) + { + var row = panel.append(appender, objects, className, rep, sourceLink, noRow); + var container = panel.panelNode; + + // TODO: xxxpedro what is this? console console2 + /* + var template = Firebug.NetMonitor.NetLimit; + + while (container.childNodes.length > maxQueueRequests + 1) + { + clearDomplate(container.firstChild.nextSibling); + container.removeChild(container.firstChild.nextSibling); + panel.limit.limitInfo.totalCount++; + template.updateCounter(panel.limit); + } + dispatch([Firebug.A11yModel], "onLogRowCreated", [panel , row]); + /**/ + return row; + } + else + { + consoleQueue.push([appender, objects, context, className, rep, sourceLink, noThrottle, noRow]); + } + } + else + { + if (!context.throttle) + { + //FBTrace.sysout("console.logRow has not context.throttle! "); + return; + } + var args = [appender, objects, context, className, rep, sourceLink, true, noRow]; + context.throttle(this.logRow, this, args); + } + }, + + appendFormatted: function(args, row, context) + { + if (!context) + context = FirebugContext; + + var panel = this.getPanel(context); + panel.appendFormatted(args, row); + }, + + clear: function(context) + { + if (!context) + //context = FirebugContext; + context = Firebug.context; + + /* + if (context) + Firebug.Errors.clear(context); + /**/ + + var panel = this.getPanel(context, true); + if (panel) + { + panel.clear(); + } + }, + + // Override to direct output to your panel + getPanel: function(context, noCreate) + { + //return context.getPanel("console", noCreate); + // TODO: xxxpedro console console2 + return Firebug.chrome ? Firebug.chrome.getPanel("Console") : null; + } + +}; + +// ************************************************************************************************ + +//TODO: xxxpedro +//var ActivableConsole = extend(Firebug.ActivableModule, Firebug.ConsoleBase); +var ActivableConsole = extend(Firebug.ConsoleBase, +{ + isAlwaysEnabled: function() + { + return true; + } +}); + +Firebug.Console = Firebug.Console = extend(ActivableConsole, +//Firebug.Console = extend(ActivableConsole, +{ + dispatchName: "console", + + error: function() + { + Firebug.Console.logFormatted(arguments, Firebug.browser, "error"); + }, + + flush: function() + { + dispatch(this.fbListeners,"flush",[]); + + for (var i=0, length=consoleQueue.length; i objects.length) // then too few parameters for format, assume unformatted. + { + format = ""; + objIndex = -1; + parts.length = 0; + break; + } + } + + } + for (var i = 0; i < parts.length; ++i) + { + var part = parts[i]; + if (part && typeof(part) == "object") + { + var object = objects[++objIndex]; + if (typeof(object) != "undefined") + this.appendObject(object, row, part.rep); + else + this.appendObject(part.type, row, FirebugReps.Text); + } + else + FirebugReps.Text.tag.append({object: part}, row); + } + + for (var i = objIndex+1; i < objects.length; ++i) + { + logText(" ", row); + var object = objects[i]; + if (typeof(object) == "string") + FirebugReps.Text.tag.append({object: object}, row); + else + this.appendObject(object, row); + } + }, + + appendOpenGroup: function(objects, row, rep) + { + if (!this.groups) + this.groups = []; + + setClass(row, "logGroup"); + setClass(row, "opened"); + + var innerRow = this.createRow("logRow"); + setClass(innerRow, "logGroupLabel"); + if (rep) + rep.tag.replace({"objects": objects}, innerRow); + else + this.appendFormatted(objects, innerRow, rep); + row.appendChild(innerRow); + //dispatch([Firebug.A11yModel], 'onLogRowCreated', [this, innerRow]); + var groupBody = this.createRow("logGroupBody"); + row.appendChild(groupBody); + groupBody.setAttribute('role', 'group'); + this.groups.push(groupBody); + + addEvent(innerRow, "mousedown", function(event) + { + if (isLeftClick(event)) + { + //console.log(event.currentTarget == event.target); + + var target = event.target || event.srcElement; + + target = getAncestorByClass(target, "logGroupLabel"); + + var groupRow = target.parentNode; + + if (hasClass(groupRow, "opened")) + { + removeClass(groupRow, "opened"); + target.setAttribute('aria-expanded', 'false'); + } + else + { + setClass(groupRow, "opened"); + target.setAttribute('aria-expanded', 'true'); + } + } + }); + }, + + appendCloseGroup: function(object, row, rep) + { + if (this.groups) + this.groups.pop(); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // TODO: xxxpedro console2 + onMouseMove: function(event) + { + var target = event.srcElement || event.target; + + var object = getAncestorByClass(target, "objectLink-element"); + object = object ? object.repObject : null; + + if(object && instanceOf(object, "Element") && object.nodeType == 1) + { + if(object != lastHighlightedObject) + { + Firebug.Inspector.drawBoxModel(object); + object = lastHighlightedObject; + } + } + else + Firebug.Inspector.hideBoxModel(); + + }, + + onMouseDown: function(event) + { + var target = event.srcElement || event.target; + + var object = getAncestorByClass(target, "objectLink"); + var repObject = object ? object.repObject : null; + + if (!repObject) + { + return; + } + + if (hasClass(object, "objectLink-object")) + { + Firebug.chrome.selectPanel("DOM"); + Firebug.chrome.getPanel("DOM").select(repObject, true); + } + else if (hasClass(object, "objectLink-element")) + { + Firebug.chrome.selectPanel("HTML"); + Firebug.chrome.getPanel("HTML").select(repObject, true); + } + + /* + if(object && instanceOf(object, "Element") && object.nodeType == 1) + { + if(object != lastHighlightedObject) + { + Firebug.Inspector.drawBoxModel(object); + object = lastHighlightedObject; + } + } + else + Firebug.Inspector.hideBoxModel(); + /**/ + + }, + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "Console", + title: "Console", + //searchable: true, + //breakable: true, + //editable: false, + + options: + { + hasCommandLine: true, + hasToolButtons: true, + isPreRendered: true + }, + + create: function() + { + Firebug.Panel.create.apply(this, arguments); + + this.context = Firebug.browser.window; + this.document = Firebug.chrome.document; + this.onMouseMove = bind(this.onMouseMove, this); + this.onMouseDown = bind(this.onMouseDown, this); + + this.clearButton = new Button({ + element: $("fbConsole_btClear"), + owner: Firebug.Console, + onClick: Firebug.Console.clear + }); + }, + + initialize: function() + { + Firebug.Panel.initialize.apply(this, arguments); // loads persisted content + //Firebug.ActivablePanel.initialize.apply(this, arguments); // loads persisted content + + if (!this.persistedContent && Firebug.Console.isAlwaysEnabled()) + { + this.insertLogLimit(this.context); + + // Initialize log limit and listen for changes. + this.updateMaxLimit(); + + if (this.context.consoleReloadWarning) // we have not yet injected the console + this.insertReloadWarning(); + } + + //Firebug.Console.injector.install(Firebug.browser.window); + + addEvent(this.panelNode, "mouseover", this.onMouseMove); + addEvent(this.panelNode, "mousedown", this.onMouseDown); + + this.clearButton.initialize(); + + //consolex.trace(); + //TODO: xxxpedro remove this + /* + Firebug.Console.openGroup(["asd"], null, "group", null, false); + Firebug.Console.log("asd"); + Firebug.Console.log("asd"); + Firebug.Console.log("asd"); + /**/ + + //TODO: xxxpedro preferences prefs + //prefs.addObserver(Firebug.prefDomain, this, false); + }, + + initializeNode : function() + { + //dispatch([Firebug.A11yModel], 'onInitializeNode', [this]); + if (FBTrace.DBG_CONSOLE) + { + this.onScroller = bind(this.onScroll, this); + addEvent(this.panelNode, "scroll", this.onScroller); + } + + this.onResizer = bind(this.onResize, this); + this.resizeEventTarget = Firebug.chrome.$('fbContentBox'); + addEvent(this.resizeEventTarget, "resize", this.onResizer); + }, + + destroyNode : function() + { + //dispatch([Firebug.A11yModel], 'onDestroyNode', [this]); + if (this.onScroller) + removeEvent(this.panelNode, "scroll", this.onScroller); + + //removeEvent(this.resizeEventTarget, "resize", this.onResizer); + }, + + shutdown: function() + { + //TODO: xxxpedro console console2 + this.clearButton.shutdown(); + + removeEvent(this.panelNode, "mousemove", this.onMouseMove); + removeEvent(this.panelNode, "mousedown", this.onMouseDown); + + this.destroyNode(); + + Firebug.Panel.shutdown.apply(this, arguments); + + //TODO: xxxpedro preferences prefs + //prefs.removeObserver(Firebug.prefDomain, this, false); + }, + + ishow: function(state) + { + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("Console.panel show; " + this.context.getName(), state); + + var enabled = Firebug.Console.isAlwaysEnabled(); + if (enabled) + { + Firebug.Console.disabledPanelPage.hide(this); + this.showCommandLine(true); + this.showToolbarButtons("fbConsoleButtons", true); + Firebug.chrome.setGlobalAttribute("cmd_togglePersistConsole", "checked", this.persistContent); + + if (state && state.wasScrolledToBottom) + { + this.wasScrolledToBottom = state.wasScrolledToBottom; + delete state.wasScrolledToBottom; + } + + if (this.wasScrolledToBottom) + scrollToBottom(this.panelNode); + + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.show ------------------ wasScrolledToBottom: " + + this.wasScrolledToBottom + ", " + this.context.getName()); + } + else + { + this.hide(state); + Firebug.Console.disabledPanelPage.show(this); + } + }, + + ihide: function(state) + { + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("Console.panel hide; " + this.context.getName(), state); + + this.showToolbarButtons("fbConsoleButtons", false); + this.showCommandLine(false); + + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.hide ------------------ wasScrolledToBottom: " + + this.wasScrolledToBottom + ", " + this.context.getName()); + }, + + destroy: function(state) + { + if (this.panelNode.offsetHeight) + this.wasScrolledToBottom = isScrolledToBottom(this.panelNode); + + if (state) + state.wasScrolledToBottom = this.wasScrolledToBottom; + + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.destroy ------------------ wasScrolledToBottom: " + + this.wasScrolledToBottom + ", " + this.context.getName()); + }, + + shouldBreakOnNext: function() + { + // xxxHonza: shouldn't the breakOnErrors be context related? + // xxxJJB, yes, but we can't support it because we can't yet tell + // which window the error is on. + return Firebug.getPref(Firebug.servicePrefDomain, "breakOnErrors"); + }, + + getBreakOnNextTooltip: function(enabled) + { + return (enabled ? $STR("console.Disable Break On All Errors") : + $STR("console.Break On All Errors")); + }, + + enablePanel: function(module) + { + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.ConsolePanel.enablePanel; " + this.context.getName()); + + Firebug.ActivablePanel.enablePanel.apply(this, arguments); + + this.showCommandLine(true); + + if (this.wasScrolledToBottom) + scrollToBottom(this.panelNode); + }, + + disablePanel: function(module) + { + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.ConsolePanel.disablePanel; " + this.context.getName()); + + Firebug.ActivablePanel.disablePanel.apply(this, arguments); + + this.showCommandLine(false); + }, + + getOptionsMenuItems: function() + { + return [ + optionMenu("ShowJavaScriptErrors", "showJSErrors"), + optionMenu("ShowJavaScriptWarnings", "showJSWarnings"), + optionMenu("ShowCSSErrors", "showCSSErrors"), + optionMenu("ShowXMLErrors", "showXMLErrors"), + optionMenu("ShowXMLHttpRequests", "showXMLHttpRequests"), + optionMenu("ShowChromeErrors", "showChromeErrors"), + optionMenu("ShowChromeMessages", "showChromeMessages"), + optionMenu("ShowExternalErrors", "showExternalErrors"), + optionMenu("ShowNetworkErrors", "showNetworkErrors"), + this.getShowStackTraceMenuItem(), + this.getStrictOptionMenuItem(), + "-", + optionMenu("LargeCommandLine", "largeCommandLine") + ]; + }, + + getShowStackTraceMenuItem: function() + { + var menuItem = serviceOptionMenu("ShowStackTrace", "showStackTrace"); + if (FirebugContext && !Firebug.Debugger.isAlwaysEnabled()) + menuItem.disabled = true; + return menuItem; + }, + + getStrictOptionMenuItem: function() + { + var strictDomain = "javascript.options"; + var strictName = "strict"; + var strictValue = prefs.getBoolPref(strictDomain+"."+strictName); + return {label: "JavascriptOptionsStrict", type: "checkbox", checked: strictValue, + command: bindFixed(Firebug.setPref, Firebug, strictDomain, strictName, !strictValue) }; + }, + + getBreakOnMenuItems: function() + { + //xxxHonza: no BON options for now. + /*return [ + optionMenu("console.option.Persist Break On Error", "persistBreakOnError") + ];*/ + return []; + }, + + search: function(text) + { + if (!text) + return; + + // Make previously visible nodes invisible again + if (this.matchSet) + { + for (var i in this.matchSet) + removeClass(this.matchSet[i], "matched"); + } + + this.matchSet = []; + + function findRow(node) { return getAncestorByClass(node, "logRow"); } + var search = new TextSearch(this.panelNode, findRow); + + var logRow = search.find(text); + if (!logRow) + { + dispatch([Firebug.A11yModel], 'onConsoleSearchMatchFound', [this, text, []]); + return false; + } + for (; logRow; logRow = search.findNext()) + { + setClass(logRow, "matched"); + this.matchSet.push(logRow); + } + dispatch([Firebug.A11yModel], 'onConsoleSearchMatchFound', [this, text, this.matchSet]); + return true; + }, + + breakOnNext: function(breaking) + { + Firebug.setPref(Firebug.servicePrefDomain, "breakOnErrors", breaking); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // private + + createRow: function(rowName, className) + { + var elt = this.document.createElement("div"); + elt.className = rowName + (className ? " " + rowName + "-" + className : ""); + return elt; + }, + + getTopContainer: function() + { + if (this.groups && this.groups.length) + return this.groups[this.groups.length-1]; + else + return this.panelNode; + }, + + filterLogRow: function(logRow, scrolledToBottom) + { + if (this.searchText) + { + setClass(logRow, "matching"); + setClass(logRow, "matched"); + + // Search after a delay because we must wait for a frame to be created for + // the new logRow so that the finder will be able to locate it + setTimeout(bindFixed(function() + { + if (this.searchFilter(this.searchText, logRow)) + this.matchSet.push(logRow); + else + removeClass(logRow, "matched"); + + removeClass(logRow, "matching"); + + if (scrolledToBottom) + scrollToBottom(this.panelNode); + }, this), 100); + } + }, + + searchFilter: function(text, logRow) + { + var count = this.panelNode.childNodes.length; + var searchRange = this.document.createRange(); + searchRange.setStart(this.panelNode, 0); + searchRange.setEnd(this.panelNode, count); + + var startPt = this.document.createRange(); + startPt.setStartBefore(logRow); + + var endPt = this.document.createRange(); + endPt.setStartAfter(logRow); + + return finder.Find(text, searchRange, startPt, endPt) != null; + }, + + // nsIPrefObserver + observe: function(subject, topic, data) + { + // We're observing preferences only. + if (topic != "nsPref:changed") + return; + + // xxxHonza check this out. + var prefDomain = "Firebug.extension."; + var prefName = data.substr(prefDomain.length); + if (prefName == "console.logLimit") + this.updateMaxLimit(); + }, + + updateMaxLimit: function() + { + var value = 1000; + //TODO: xxxpedro preferences log limit? + //var value = Firebug.getPref(Firebug.prefDomain, "console.logLimit"); + maxQueueRequests = value ? value : maxQueueRequests; + }, + + showCommandLine: function(shouldShow) + { + //TODO: xxxpedro show command line important + return; + + if (shouldShow) + { + collapse(Firebug.chrome.$("fbCommandBox"), false); + Firebug.CommandLine.setMultiLine(Firebug.largeCommandLine, Firebug.chrome); + } + else + { + // Make sure that entire content of the Console panel is hidden when + // the panel is disabled. + Firebug.CommandLine.setMultiLine(false, Firebug.chrome, Firebug.largeCommandLine); + collapse(Firebug.chrome.$("fbCommandBox"), true); + } + }, + + onScroll: function(event) + { + // Update the scroll position flag if the position changes. + this.wasScrolledToBottom = FBL.isScrolledToBottom(this.panelNode); + + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.onScroll ------------------ wasScrolledToBottom: " + + this.wasScrolledToBottom + ", wasScrolledToBottom: " + + this.context.getName(), event); + }, + + onResize: function(event) + { + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.onResize ------------------ wasScrolledToBottom: " + + this.wasScrolledToBottom + ", offsetHeight: " + this.panelNode.offsetHeight + + ", scrollTop: " + this.panelNode.scrollTop + ", scrollHeight: " + + this.panelNode.scrollHeight + ", " + this.context.getName(), event); + + if (this.wasScrolledToBottom) + scrollToBottom(this.panelNode); + } +}); + +// ************************************************************************************************ + +function parseFormat(format) +{ + var parts = []; + if (format.length <= 0) + return parts; + + var reg = /((^%|.%)(\d+)?(\.)([a-zA-Z]))|((^%|.%)([a-zA-Z]))/; + for (var m = reg.exec(format); m; m = reg.exec(format)) + { + if (m[0].substr(0, 2) == "%%") + { + parts.push(format.substr(0, m.index)); + parts.push(m[0].substr(1)); + } + else + { + var type = m[8] ? m[8] : m[5]; + var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0); + + var rep = null; + switch (type) + { + case "s": + rep = FirebugReps.Text; + break; + case "f": + case "i": + case "d": + rep = FirebugReps.Number; + break; + case "o": + rep = null; + break; + } + + parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1)); + parts.push({rep: rep, precision: precision, type: ("%" + type)}); + } + + format = format.substr(m.index+m[0].length); + } + + parts.push(format); + return parts; +} + +// ************************************************************************************************ + +var appendObject = Firebug.ConsolePanel.prototype.appendObject; +var appendFormatted = Firebug.ConsolePanel.prototype.appendFormatted; +var appendOpenGroup = Firebug.ConsolePanel.prototype.appendOpenGroup; +var appendCloseGroup = Firebug.ConsolePanel.prototype.appendCloseGroup; + +// ************************************************************************************************ + +//Firebug.registerActivableModule(Firebug.Console); +Firebug.registerModule(Firebug.Console); +Firebug.registerPanel(Firebug.ConsolePanel); + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// Constants + +//const Cc = Components.classes; +//const Ci = Components.interfaces; + +var frameCounters = {}; +var traceRecursion = 0; + +Firebug.Console.injector = +{ + install: function(context) + { + var win = context.window; + + var consoleHandler = new FirebugConsoleHandler(context, win); + + var properties = + [ + "log", + "debug", + "info", + "warn", + "error", + "assert", + "dir", + "dirxml", + "group", + "groupCollapsed", + "groupEnd", + "time", + "timeEnd", + "count", + "trace", + "profile", + "profileEnd", + "clear", + "open", + "close" + ]; + + var Handler = function(name) + { + var c = consoleHandler; + var f = consoleHandler[name]; + return function(){return f.apply(c,arguments)}; + }; + + var installer = function(c) + { + for (var i=0, l=properties.length; i 1) + { + traceRecursion--; + return; + } + + var frames = []; + + for (var fn = arguments.callee.caller.caller; fn; fn = fn.caller) + { + if (wasVisited(fn)) break; + + var args = []; + + for (var i = 0, l = fn.arguments.length; i < l; ++i) + { + args.push({value: fn.arguments[i]}); + } + + frames.push({fn: fn, name: getFuncName(fn), args: args}); + } + + + // **************************************************************************************** + + try + { + (0)(); + } + catch(e) + { + var result = e; + + var stack = + result.stack || // Firefox / Google Chrome + result.stacktrace || // Opera + ""; + + stack = stack.replace(/\n\r|\r\n/g, "\n"); // normalize line breaks + var items = stack.split(/[\n\r]/); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Google Chrome + if (FBL.isSafari) + { + //var reChromeStackItem = /^\s+at\s+([^\(]+)\s\((.*)\)$/; + //var reChromeStackItem = /^\s+at\s+(.*)((?:http|https|ftp|file):\/\/.*)$/; + var reChromeStackItem = /^\s+at\s+(.*)((?:http|https|ftp|file):\/\/.*)$/; + + var reChromeStackItemName = /\s*\($/; + var reChromeStackItemValue = /^(.+)\:(\d+\:\d+)\)?$/; + + var framePos = 0; + for (var i=4, length=items.length; i 1) + { + objects = [errorObject]; + for (var i = 1; i < args.length; i++) + objects.push(args[i]); + } + + var row = Firebug.Console.log(objects, context, "errorMessage", null, true); // noThrottle + row.scrollIntoView(); + } + + function getComponentsStackDump() + { + // Starting with our stack, walk back to the user-level code + var frame = Components.stack; + var userURL = win.location.href.toString(); + + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("consoleInjector.getComponentsStackDump initial stack for userURL "+userURL, frame); + + // Drop frames until we get into user code. + while (frame && FBL.isSystemURL(frame.filename) ) + frame = frame.caller; + + // Drop two more frames, the injected console function and firebugAppendConsole() + if (frame) + frame = frame.caller; + if (frame) + frame = frame.caller; + + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("consoleInjector.getComponentsStackDump final stack for userURL "+userURL, frame); + + return frame; + } + + function getStackLink() + { + // TODO: xxxpedro console2 + return; + //return FBL.getFrameSourceLink(getComponentsStackDump()); + } + + function getJSDUserStack() + { + var trace = FBL.getCurrentStackTrace(context); + + var frames = trace ? trace.frames : null; + if (frames && (frames.length > 0) ) + { + var oldest = frames.length - 1; // 6 - 1 = 5 + for (var i = 0; i < frames.length; i++) + { + if (frames[oldest - i].href.indexOf("chrome:") == 0) break; + var fn = frames[oldest - i].fn + ""; + if (fn && (fn.indexOf("_firebugEvalEvent") != -1) ) break; // command line + } + FBTrace.sysout("consoleInjector getJSDUserStack: "+frames.length+" oldest: "+oldest+" i: "+i+" i - oldest + 2: "+(i - oldest + 2), trace); + trace.frames = trace.frames.slice(2 - i); // take the oldest frames, leave 2 behind they are injection code + + return trace; + } + else + return "Firebug failed to get stack trace with any frames"; + } +} + +// ************************************************************************************************ +// Register console namespace + +FBL.registerConsole = function() +{ + //TODO: xxxpedro console options override + //if (Env.Options.overrideConsole) + var win = Env.browser.window; + Firebug.Console.injector.install(win); +}; + +registerConsole(); + +}}); + + +/* 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) +{ + commandHistory.push(command); + commandPointer = 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(); + + 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 (commandPointer > 0 && commandHistory.length > 0) + this.element.value = commandHistory[--commandPointer]; + }, + + nextCommand: function() + { + var element = this.element; + + var limit = commandHistory.length -1; + var i = commandPointer; + + if (i < limit) + element.value = commandHistory[++commandPointer]; + + else if (i == limit) + { + ++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; + + // TODO: xxxpedro html3 + ///Firebug.Console.log(o, Firebug.context, "dirxml", Firebug.HTMLPanel.SoloElement); + var div = Firebug.Console.log(o, Firebug.context, "dirxml"); + var html = []; + Firebug.Reps.appendNode(o, html); + div.innerHTML = html.join(""); + + } +}; + +// ************************************************************************************************ + +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]; + } +}; + +// ************************************************************************************************ +}}); + +/* 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(); + }; +} + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var reIgnore = /about:|javascript:|resource:|chrome:|jar:/; +var layoutInterval = 300; +var indentWidth = 18; + +var cacheSession = null; +var contexts = new Array(); +var panelName = "net"; +var maxQueueRequests = 500; +//var panelBar1 = $("fbPanelBar1"); // chrome not available at startup +var activeRequests = []; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var mimeExtensionMap = +{ + "txt": "text/plain", + "html": "text/html", + "htm": "text/html", + "xhtml": "text/html", + "xml": "text/xml", + "css": "text/css", + "js": "application/x-javascript", + "jss": "application/x-javascript", + "jpg": "image/jpg", + "jpeg": "image/jpeg", + "gif": "image/gif", + "png": "image/png", + "bmp": "image/bmp", + "swf": "application/x-shockwave-flash", + "flv": "video/x-flv" +}; + +var fileCategories = +{ + "undefined": 1, + "html": 1, + "css": 1, + "js": 1, + "xhr": 1, + "image": 1, + "flash": 1, + "txt": 1, + "bin": 1 +}; + +var textFileCategories = +{ + "txt": 1, + "html": 1, + "xhr": 1, + "css": 1, + "js": 1 +}; + +var binaryFileCategories = +{ + "bin": 1, + "flash": 1 +}; + +var mimeCategoryMap = +{ + "text/plain": "txt", + "application/octet-stream": "bin", + "text/html": "html", + "text/xml": "html", + "text/css": "css", + "application/x-javascript": "js", + "text/javascript": "js", + "application/javascript" : "js", + "image/jpeg": "image", + "image/jpg": "image", + "image/gif": "image", + "image/png": "image", + "image/bmp": "image", + "application/x-shockwave-flash": "flash", + "video/x-flv": "flash" +}; + +var binaryCategoryMap = +{ + "image": 1, + "flash" : 1 +}; + +// ************************************************************************************************ + +/** + * @module Represents a module object for the Net panel. This object is derived + * from Firebug.ActivableModule in order to support activation (enable/disable). + * This allows to avoid (performance) expensive features if the functionality is not necessary + * for the user. + */ +Firebug.NetMonitor = extend(Firebug.ActivableModule, +{ + dispatchName: "netMonitor", + + clear: function(context) + { + // The user pressed a Clear button so, remove content of the panel... + var panel = context.getPanel(panelName, true); + if (panel) + panel.clear(); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Module + + initialize: function() + { + return; + + this.panelName = panelName; + + Firebug.ActivableModule.initialize.apply(this, arguments); + + if (Firebug.TraceModule) + Firebug.TraceModule.addListener(this.TraceListener); + + // HTTP observer must be registered now (and not in monitorContext, since if a + // page is opened in a new tab the top document request would be missed otherwise. + NetHttpObserver.registerObserver(); + NetHttpActivityObserver.registerObserver(); + + Firebug.Debugger.addListener(this.DebuggerListener); + }, + + shutdown: function() + { + return; + + prefs.removeObserver(Firebug.prefDomain, this, false); + if (Firebug.TraceModule) + Firebug.TraceModule.removeListener(this.TraceListener); + + NetHttpObserver.unregisterObserver(); + NetHttpActivityObserver.unregisterObserver(); + + Firebug.Debugger.removeListener(this.DebuggerListener); + } +}); + + +/** + * @domplate Represents a template that is used to reneder detailed info about a request. + * This template is rendered when a request is expanded. + */ +Firebug.NetMonitor.NetInfoBody = domplate(Firebug.Rep, new Firebug.Listener(), +{ + tag: + DIV({"class": "netInfoBody", _repObject: "$file"}, + TAG("$infoTabs", {file: "$file"}), + TAG("$infoBodies", {file: "$file"}) + ), + + infoTabs: + DIV({"class": "netInfoTabs focusRow subFocusRow", "role": "tablist"}, + A({"class": "netInfoParamsTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Params", + $collapsed: "$file|hideParams"}, + $STR("URLParameters") + ), + A({"class": "netInfoHeadersTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Headers"}, + $STR("Headers") + ), + A({"class": "netInfoPostTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Post", + $collapsed: "$file|hidePost"}, + $STR("Post") + ), + A({"class": "netInfoPutTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Put", + $collapsed: "$file|hidePut"}, + $STR("Put") + ), + A({"class": "netInfoResponseTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Response", + $collapsed: "$file|hideResponse"}, + $STR("Response") + ), + A({"class": "netInfoCacheTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Cache", + $collapsed: "$file|hideCache"}, + $STR("Cache") + ), + A({"class": "netInfoHtmlTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Html", + $collapsed: "$file|hideHtml"}, + $STR("HTML") + ) + ), + + infoBodies: + DIV({"class": "netInfoBodies outerFocusRow"}, + TABLE({"class": "netInfoParamsText netInfoText netInfoParamsTable", "role": "tabpanel", + cellpadding: 0, cellspacing: 0}, TBODY()), + DIV({"class": "netInfoHeadersText netInfoText", "role": "tabpanel"}), + DIV({"class": "netInfoPostText netInfoText", "role": "tabpanel"}), + DIV({"class": "netInfoPutText netInfoText", "role": "tabpanel"}), + PRE({"class": "netInfoResponseText netInfoText", "role": "tabpanel"}), + DIV({"class": "netInfoCacheText netInfoText", "role": "tabpanel"}, + TABLE({"class": "netInfoCacheTable", cellpadding: 0, cellspacing: 0, "role": "presentation"}, + TBODY({"role": "list", "aria-label": $STR("Cache")}) + ) + ), + DIV({"class": "netInfoHtmlText netInfoText", "role": "tabpanel"}, + IFRAME({"class": "netInfoHtmlPreview", "role": "document"}) + ) + ), + + headerDataTag: + FOR("param", "$headers", + TR({"role": "listitem"}, + TD({"class": "netInfoParamName", "role": "presentation"}, + TAG("$param|getNameTag", {param: "$param"}) + ), + TD({"class": "netInfoParamValue", "role": "list", "aria-label": "$param.name"}, + FOR("line", "$param|getParamValueIterator", + CODE({"class": "focusRow subFocusRow", "role": "listitem"}, "$line") + ) + ) + ) + ), + + customTab: + A({"class": "netInfo$tabId\\Tab netInfoTab", onclick: "$onClickTab", view: "$tabId", "role": "tab"}, + "$tabTitle" + ), + + customBody: + DIV({"class": "netInfo$tabId\\Text netInfoText", "role": "tabpanel"}), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + nameTag: + SPAN("$param|getParamName"), + + nameWithTooltipTag: + SPAN({title: "$param.name"}, "$param|getParamName"), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getNameTag: function(param) + { + return (this.getParamName(param) == param.name) ? this.nameTag : this.nameWithTooltipTag; + }, + + getParamName: function(param) + { + var limit = 25; + var name = param.name; + if (name.length > limit) + name = name.substr(0, limit) + "..."; + return name; + }, + + getParamTitle: function(param) + { + var limit = 25; + var name = param.name; + if (name.length > limit) + return name; + return ""; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + hideParams: function(file) + { + return !file.urlParams || !file.urlParams.length; + }, + + hidePost: function(file) + { + return file.method.toUpperCase() != "POST"; + }, + + hidePut: function(file) + { + return file.method.toUpperCase() != "PUT"; + }, + + hideResponse: function(file) + { + return false; + //return file.category in binaryFileCategories; + }, + + hideCache: function(file) + { + return true; + //xxxHonza: I don't see any reason why not to display the cache also info for images. + return !file.cacheEntry; // || file.category=="image"; + }, + + hideHtml: function(file) + { + return (file.mimeType != "text/html") && (file.mimeType != "application/xhtml+xml"); + }, + + onClickTab: function(event) + { + this.selectTab(event.currentTarget || event.srcElement); + }, + + getParamValueIterator: function(param) + { + // TODO: xxxpedro console2 + return param.value; + + // This value is inserted into CODE element and so, make sure the HTML isn't escaped (1210). + // This is why the second parameter is true. + // The CODE (with style white-space:pre) element preserves whitespaces so they are + // displayed the same, as they come from the server (1194). + // In case of a long header values of post parameters the value must be wrapped (2105). + return wrapText(param.value, true); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + appendTab: function(netInfoBox, tabId, tabTitle) + { + // Create new tab and body. + var args = {tabId: tabId, tabTitle: tabTitle}; + ///this.customTab.append(args, netInfoBox.getElementsByClassName("netInfoTabs").item(0)); + ///this.customBody.append(args, netInfoBox.getElementsByClassName("netInfoBodies").item(0)); + this.customTab.append(args, $$(".netInfoTabs", netInfoBox)[0]); + this.customBody.append(args, $$(".netInfoBodies", netInfoBox)[0]); + }, + + selectTabByName: function(netInfoBox, tabName) + { + var tab = getChildByClass(netInfoBox, "netInfoTabs", "netInfo"+tabName+"Tab"); + if (tab) + this.selectTab(tab); + }, + + selectTab: function(tab) + { + var view = tab.getAttribute("view"); + + var netInfoBox = getAncestorByClass(tab, "netInfoBody"); + + var selectedTab = netInfoBox.selectedTab; + + if (selectedTab) + { + //netInfoBox.selectedText.removeAttribute("selected"); + removeClass(netInfoBox.selectedText, "netInfoTextSelected"); + + removeClass(selectedTab, "netInfoTabSelected"); + //selectedTab.removeAttribute("selected"); + selectedTab.setAttribute("aria-selected", "false"); + } + + var textBodyName = "netInfo" + view + "Text"; + + selectedTab = netInfoBox.selectedTab = tab; + + netInfoBox.selectedText = $$("."+textBodyName, netInfoBox)[0]; + //netInfoBox.selectedText = netInfoBox.getElementsByClassName(textBodyName).item(0); + + //netInfoBox.selectedText.setAttribute("selected", "true"); + setClass(netInfoBox.selectedText, "netInfoTextSelected"); + + setClass(selectedTab, "netInfoTabSelected"); + selectedTab.setAttribute("selected", "true"); + selectedTab.setAttribute("aria-selected", "true"); + + var file = Firebug.getRepObject(netInfoBox); + + //var context = Firebug.getElementPanel(netInfoBox).context; + var context = Firebug.chrome; + + this.updateInfo(netInfoBox, file, context); + }, + + updateInfo: function(netInfoBox, file, context) + { + if (FBTrace.DBG_NET) + FBTrace.sysout("net.updateInfo; file", file); + + if (!netInfoBox) + { + if (FBTrace.DBG_NET || FBTrace.DBG_ERRORS) + FBTrace.sysout("net.updateInfo; ERROR netInfo == null " + file.href, file); + return; + } + + var tab = netInfoBox.selectedTab; + + if (hasClass(tab, "netInfoParamsTab")) + { + if (file.urlParams && !netInfoBox.urlParamsPresented) + { + netInfoBox.urlParamsPresented = true; + this.insertHeaderRows(netInfoBox, file.urlParams, "Params"); + } + } + + else if (hasClass(tab, "netInfoHeadersTab")) + { + var headersText = $$(".netInfoHeadersText", netInfoBox)[0]; + //var headersText = netInfoBox.getElementsByClassName("netInfoHeadersText").item(0); + + if (file.responseHeaders && !netInfoBox.responseHeadersPresented) + { + netInfoBox.responseHeadersPresented = true; + NetInfoHeaders.renderHeaders(headersText, file.responseHeaders, "ResponseHeaders"); + } + + if (file.requestHeaders && !netInfoBox.requestHeadersPresented) + { + netInfoBox.requestHeadersPresented = true; + NetInfoHeaders.renderHeaders(headersText, file.requestHeaders, "RequestHeaders"); + } + } + + else if (hasClass(tab, "netInfoPostTab")) + { + if (!netInfoBox.postPresented) + { + netInfoBox.postPresented = true; + //var postText = netInfoBox.getElementsByClassName("netInfoPostText").item(0); + var postText = $$(".netInfoPostText", netInfoBox)[0]; + NetInfoPostData.render(context, postText, file); + } + } + + else if (hasClass(tab, "netInfoPutTab")) + { + if (!netInfoBox.putPresented) + { + netInfoBox.putPresented = true; + //var putText = netInfoBox.getElementsByClassName("netInfoPutText").item(0); + var putText = $$(".netInfoPutText", netInfoBox)[0]; + NetInfoPostData.render(context, putText, file); + } + } + + else if (hasClass(tab, "netInfoResponseTab") && file.loaded && !netInfoBox.responsePresented) + { + ///var responseTextBox = netInfoBox.getElementsByClassName("netInfoResponseText").item(0); + var responseTextBox = $$(".netInfoResponseText", netInfoBox)[0]; + if (file.category == "image") + { + netInfoBox.responsePresented = true; + + var responseImage = netInfoBox.ownerDocument.createElement("img"); + responseImage.src = file.href; + + clearNode(responseTextBox); + responseTextBox.appendChild(responseImage, responseTextBox); + } + else ///if (!(binaryCategoryMap.hasOwnProperty(file.category))) + { + this.setResponseText(file, netInfoBox, responseTextBox, context); + } + } + + else if (hasClass(tab, "netInfoCacheTab") && file.loaded && !netInfoBox.cachePresented) + { + var responseTextBox = netInfoBox.getElementsByClassName("netInfoCacheText").item(0); + if (file.cacheEntry) { + netInfoBox.cachePresented = true; + this.insertHeaderRows(netInfoBox, file.cacheEntry, "Cache"); + } + } + + else if (hasClass(tab, "netInfoHtmlTab") && file.loaded && !netInfoBox.htmlPresented) + { + netInfoBox.htmlPresented = true; + + var text = Utils.getResponseText(file, context); + + ///var iframe = netInfoBox.getElementsByClassName("netInfoHtmlPreview").item(0); + var iframe = $$(".netInfoHtmlPreview", netInfoBox)[0]; + + ///iframe.contentWindow.document.body.innerHTML = text; + + // TODO: xxxpedro net - remove scripts + var reScript = //gi; + + text = text.replace(reScript, ""); + + iframe.contentWindow.document.write(text); + iframe.contentWindow.document.close(); + } + + // Notify listeners about update so, content of custom tabs can be updated. + dispatch(NetInfoBody.fbListeners, "updateTabBody", [netInfoBox, file, context]); + }, + + setResponseText: function(file, netInfoBox, responseTextBox, context) + { + //********************************************** + //********************************************** + //********************************************** + netInfoBox.responsePresented = true; + // line breaks somehow are different in IE + // make this only once in the initialization? we don't have net panels and modules yet. + if (isIE) + responseTextBox.style.whiteSpace = "nowrap"; + + responseTextBox[ + typeof responseTextBox.textContent != "undefined" ? + "textContent" : + "innerText" + ] = file.responseText; + + return; + //********************************************** + //********************************************** + //********************************************** + + // Get response text and make sure it doesn't exceed the max limit. + var text = Utils.getResponseText(file, context); + var limit = Firebug.netDisplayedResponseLimit + 15; + var limitReached = text ? (text.length > limit) : false; + if (limitReached) + text = text.substr(0, limit) + "..."; + + // Insert the response into the UI. + if (text) + insertWrappedText(text, responseTextBox); + else + insertWrappedText("", responseTextBox); + + // Append a message informing the user that the response isn't fully displayed. + if (limitReached) + { + var object = { + text: $STR("net.responseSizeLimitMessage"), + onClickLink: function() { + var panel = context.getPanel("net", true); + panel.openResponseInTab(file); + } + }; + Firebug.NetMonitor.ResponseSizeLimit.append(object, responseTextBox); + } + + netInfoBox.responsePresented = true; + + if (FBTrace.DBG_NET) + FBTrace.sysout("net.setResponseText; response text updated"); + }, + + insertHeaderRows: function(netInfoBox, headers, tableName, rowName) + { + if (!headers.length) + return; + + var headersTable = $$(".netInfo"+tableName+"Table", netInfoBox)[0]; + //var headersTable = netInfoBox.getElementsByClassName("netInfo"+tableName+"Table").item(0); + var tbody = getChildByClass(headersTable, "netInfo" + rowName + "Body"); + if (!tbody) + tbody = headersTable.firstChild; + var titleRow = getChildByClass(tbody, "netInfo" + rowName + "Title"); + + this.headerDataTag.insertRows({headers: headers}, titleRow ? titleRow : tbody); + removeClass(titleRow, "collapsed"); + } +}); + +var NetInfoBody = Firebug.NetMonitor.NetInfoBody; + +// ************************************************************************************************ + +/** + * @domplate Used within the Net panel to display raw source of request and response headers + * as well as pretty-formatted summary of these headers. + */ +Firebug.NetMonitor.NetInfoHeaders = domplate(Firebug.Rep, //new Firebug.Listener(), +{ + tag: + DIV({"class": "netInfoHeadersTable", "role": "tabpanel"}, + DIV({"class": "netInfoHeadersGroup netInfoResponseHeadersTitle"}, + SPAN($STR("ResponseHeaders")), + SPAN({"class": "netHeadersViewSource response collapsed", onclick: "$onViewSource", + _sourceDisplayed: false, _rowName: "ResponseHeaders"}, + $STR("net.headers.view source") + ) + ), + TABLE({cellpadding: 0, cellspacing: 0}, + TBODY({"class": "netInfoResponseHeadersBody", "role": "list", + "aria-label": $STR("ResponseHeaders")}) + ), + DIV({"class": "netInfoHeadersGroup netInfoRequestHeadersTitle"}, + SPAN($STR("RequestHeaders")), + SPAN({"class": "netHeadersViewSource request collapsed", onclick: "$onViewSource", + _sourceDisplayed: false, _rowName: "RequestHeaders"}, + $STR("net.headers.view source") + ) + ), + TABLE({cellpadding: 0, cellspacing: 0}, + TBODY({"class": "netInfoRequestHeadersBody", "role": "list", + "aria-label": $STR("RequestHeaders")}) + ) + ), + + sourceTag: + TR({"role": "presentation"}, + TD({colspan: 2, "role": "presentation"}, + PRE({"class": "source"}) + ) + ), + + onViewSource: function(event) + { + var target = event.target; + var requestHeaders = (target.rowName == "RequestHeaders"); + + var netInfoBox = getAncestorByClass(target, "netInfoBody"); + var file = netInfoBox.repObject; + + if (target.sourceDisplayed) + { + var headers = requestHeaders ? file.requestHeaders : file.responseHeaders; + this.insertHeaderRows(netInfoBox, headers, target.rowName); + target.innerHTML = $STR("net.headers.view source"); + } + else + { + var source = requestHeaders ? file.requestHeadersText : file.responseHeadersText; + this.insertSource(netInfoBox, source, target.rowName); + target.innerHTML = $STR("net.headers.pretty print"); + } + + target.sourceDisplayed = !target.sourceDisplayed; + + cancelEvent(event); + }, + + insertSource: function(netInfoBox, source, rowName) + { + // This breaks copy to clipboard. + //if (source) + // source = source.replace(/\r\n/gm, "\\r\\n\r\n"); + + ///var tbody = netInfoBox.getElementsByClassName("netInfo" + rowName + "Body").item(0); + var tbody = $$(".netInfo" + rowName + "Body", netInfoBox)[0]; + var node = this.sourceTag.replace({}, tbody); + ///var sourceNode = node.getElementsByClassName("source").item(0); + var sourceNode = $$(".source", node)[0]; + sourceNode.innerHTML = source; + }, + + insertHeaderRows: function(netInfoBox, headers, rowName) + { + var headersTable = $$(".netInfoHeadersTable", netInfoBox)[0]; + var tbody = $$(".netInfo" + rowName + "Body", headersTable)[0]; + + //var headersTable = netInfoBox.getElementsByClassName("netInfoHeadersTable").item(0); + //var tbody = headersTable.getElementsByClassName("netInfo" + rowName + "Body").item(0); + + clearNode(tbody); + + if (!headers.length) + return; + + NetInfoBody.headerDataTag.insertRows({headers: headers}, tbody); + + var titleRow = getChildByClass(headersTable, "netInfo" + rowName + "Title"); + removeClass(titleRow, "collapsed"); + }, + + init: function(parent) + { + var rootNode = this.tag.append({}, parent); + + var netInfoBox = getAncestorByClass(parent, "netInfoBody"); + var file = netInfoBox.repObject; + + var viewSource; + + viewSource = $$(".request", rootNode)[0]; + //viewSource = rootNode.getElementsByClassName("netHeadersViewSource request").item(0); + if (file.requestHeadersText) + removeClass(viewSource, "collapsed"); + + viewSource = $$(".response", rootNode)[0]; + //viewSource = rootNode.getElementsByClassName("netHeadersViewSource response").item(0); + if (file.responseHeadersText) + removeClass(viewSource, "collapsed"); + }, + + renderHeaders: function(parent, headers, rowName) + { + if (!parent.firstChild) + this.init(parent); + + this.insertHeaderRows(parent, headers, rowName); + } +}); + +var NetInfoHeaders = Firebug.NetMonitor.NetInfoHeaders; + +// ************************************************************************************************ + +/** + * @domplate Represents posted data within request info (the info, which is visible when + * a request entry is expanded. This template renders content of the Post tab. + */ +Firebug.NetMonitor.NetInfoPostData = domplate(Firebug.Rep, /*new Firebug.Listener(),*/ +{ + // application/x-www-form-urlencoded + paramsTable: + TABLE({"class": "netInfoPostParamsTable", cellpadding: 0, cellspacing: 0, "role": "presentation"}, + TBODY({"role": "list", "aria-label": $STR("net.label.Parameters")}, + TR({"class": "netInfoPostParamsTitle", "role": "presentation"}, + TD({colspan: 3, "role": "presentation"}, + DIV({"class": "netInfoPostParams"}, + $STR("net.label.Parameters"), + SPAN({"class": "netInfoPostContentType"}, + "application/x-www-form-urlencoded" + ) + ) + ) + ) + ) + ), + + // multipart/form-data + partsTable: + TABLE({"class": "netInfoPostPartsTable", cellpadding: 0, cellspacing: 0, "role": "presentation"}, + TBODY({"role": "list", "aria-label": $STR("net.label.Parts")}, + TR({"class": "netInfoPostPartsTitle", "role": "presentation"}, + TD({colspan: 2, "role":"presentation" }, + DIV({"class": "netInfoPostParams"}, + $STR("net.label.Parts"), + SPAN({"class": "netInfoPostContentType"}, + "multipart/form-data" + ) + ) + ) + ) + ) + ), + + // application/json + jsonTable: + TABLE({"class": "netInfoPostJSONTable", cellpadding: 0, cellspacing: 0, "role": "presentation"}, + ///TBODY({"role": "list", "aria-label": $STR("jsonviewer.tab.JSON")}, + TBODY({"role": "list", "aria-label": $STR("JSON")}, + TR({"class": "netInfoPostJSONTitle", "role": "presentation"}, + TD({"role": "presentation" }, + DIV({"class": "netInfoPostParams"}, + ///$STR("jsonviewer.tab.JSON") + $STR("JSON") + ) + ) + ), + TR( + TD({"class": "netInfoPostJSONBody"}) + ) + ) + ), + + // application/xml + xmlTable: + TABLE({"class": "netInfoPostXMLTable", cellpadding: 0, cellspacing: 0, "role": "presentation"}, + TBODY({"role": "list", "aria-label": $STR("xmlviewer.tab.XML")}, + TR({"class": "netInfoPostXMLTitle", "role": "presentation"}, + TD({"role": "presentation" }, + DIV({"class": "netInfoPostParams"}, + $STR("xmlviewer.tab.XML") + ) + ) + ), + TR( + TD({"class": "netInfoPostXMLBody"}) + ) + ) + ), + + sourceTable: + TABLE({"class": "netInfoPostSourceTable", cellpadding: 0, cellspacing: 0, "role": "presentation"}, + TBODY({"role": "list", "aria-label": $STR("net.label.Source")}, + TR({"class": "netInfoPostSourceTitle", "role": "presentation"}, + TD({colspan: 2, "role": "presentation"}, + DIV({"class": "netInfoPostSource"}, + $STR("net.label.Source") + ) + ) + ) + ) + ), + + sourceBodyTag: + TR({"role": "presentation"}, + TD({colspan: 2, "role": "presentation"}, + FOR("line", "$param|getParamValueIterator", + CODE({"class":"focusRow subFocusRow" , "role": "listitem"},"$line") + ) + ) + ), + + getParamValueIterator: function(param) + { + return NetInfoBody.getParamValueIterator(param); + }, + + render: function(context, parentNode, file) + { + //debugger; + var spy = getAncestorByClass(parentNode, "spyHead"); + var spyObject = spy.repObject; + var data = spyObject.data; + + ///var contentType = Utils.findHeader(file.requestHeaders, "content-type"); + var contentType = file.mimeType; + + ///var text = Utils.getPostText(file, context, true); + ///if (text == undefined) + /// return; + + ///if (Utils.isURLEncodedRequest(file, context)) + // fake Utils.isURLEncodedRequest identification + if (contentType && contentType == "application/x-www-form-urlencoded" || + data && data.indexOf("=") != -1) + { + ///var lines = text.split("\n"); + ///var params = parseURLEncodedText(lines[lines.length-1]); + var params = parseURLEncodedTextArray(data); + if (params) + this.insertParameters(parentNode, params); + } + + ///if (Utils.isMultiPartRequest(file, context)) + ///{ + /// var data = this.parseMultiPartText(file, context); + /// if (data) + /// this.insertParts(parentNode, data); + ///} + + // moved to the top + ///var contentType = Utils.findHeader(file.requestHeaders, "content-type"); + + ///if (Firebug.JSONViewerModel.isJSON(contentType)) + var jsonData = { + responseText: data + }; + + if (Firebug.JSONViewerModel.isJSON(contentType, data)) + ///this.insertJSON(parentNode, file, context); + this.insertJSON(parentNode, jsonData, context); + + ///if (Firebug.XMLViewerModel.isXML(contentType)) + /// this.insertXML(parentNode, file, context); + + ///var postText = Utils.getPostText(file, context); + ///postText = Utils.formatPostText(postText); + var postText = data; + if (postText) + this.insertSource(parentNode, postText); + }, + + insertParameters: function(parentNode, params) + { + if (!params || !params.length) + return; + + var paramTable = this.paramsTable.append({object:{}}, parentNode); + var row = $$(".netInfoPostParamsTitle", paramTable)[0]; + //var paramTable = this.paramsTable.append(null, parentNode); + //var row = paramTable.getElementsByClassName("netInfoPostParamsTitle").item(0); + + var tbody = paramTable.getElementsByTagName("tbody")[0]; + + NetInfoBody.headerDataTag.insertRows({headers: params}, row); + }, + + insertParts: function(parentNode, data) + { + if (!data.params || !data.params.length) + return; + + var partsTable = this.partsTable.append({object:{}}, parentNode); + var row = $$(".netInfoPostPartsTitle", paramTable)[0]; + //var partsTable = this.partsTable.append(null, parentNode); + //var row = partsTable.getElementsByClassName("netInfoPostPartsTitle").item(0); + + NetInfoBody.headerDataTag.insertRows({headers: data.params}, row); + }, + + insertJSON: function(parentNode, file, context) + { + ///var text = Utils.getPostText(file, context); + var text = file.responseText; + ///var data = parseJSONString(text, "http://" + file.request.originalURI.host); + var data = parseJSONString(text); + if (!data) + return; + + ///var jsonTable = this.jsonTable.append(null, parentNode); + var jsonTable = this.jsonTable.append({}, parentNode); + ///var jsonBody = jsonTable.getElementsByClassName("netInfoPostJSONBody").item(0); + var jsonBody = $$(".netInfoPostJSONBody", jsonTable)[0]; + + if (!this.toggles) + this.toggles = {}; + + Firebug.DOMPanel.DirTable.tag.replace( + {object: data, toggles: this.toggles}, jsonBody); + }, + + insertXML: function(parentNode, file, context) + { + var text = Utils.getPostText(file, context); + + var jsonTable = this.xmlTable.append(null, parentNode); + ///var jsonBody = jsonTable.getElementsByClassName("netInfoPostXMLBody").item(0); + var jsonBody = $$(".netInfoPostXMLBody", jsonTable)[0]; + + Firebug.XMLViewerModel.insertXML(jsonBody, text); + }, + + insertSource: function(parentNode, text) + { + var sourceTable = this.sourceTable.append({object:{}}, parentNode); + var row = $$(".netInfoPostSourceTitle", sourceTable)[0]; + //var sourceTable = this.sourceTable.append(null, parentNode); + //var row = sourceTable.getElementsByClassName("netInfoPostSourceTitle").item(0); + + var param = {value: [text]}; + this.sourceBodyTag.insertRows({param: param}, row); + }, + + parseMultiPartText: function(file, context) + { + var text = Utils.getPostText(file, context); + if (text == undefined) + return null; + + FBTrace.sysout("net.parseMultiPartText; boundary: ", text); + + var boundary = text.match(/\s*boundary=\s*(.*)/)[1]; + + var divider = "\r\n\r\n"; + var bodyStart = text.indexOf(divider); + var body = text.substr(bodyStart + divider.length); + + var postData = {}; + postData.mimeType = "multipart/form-data"; + postData.params = []; + + var parts = body.split("--" + boundary); + for (var i=0; i 1) ? m[1] : "", + value: trim(part[1]) + }); + } + + return postData; + } +}); + +var NetInfoPostData = Firebug.NetMonitor.NetInfoPostData; + +// ************************************************************************************************ + + +// TODO: xxxpedro net i18n +var $STRP = function(a){return a;}; + +Firebug.NetMonitor.NetLimit = domplate(Firebug.Rep, +{ + collapsed: true, + + tableTag: + DIV( + TABLE({width: "100%", cellpadding: 0, cellspacing: 0}, + TBODY() + ) + ), + + limitTag: + TR({"class": "netRow netLimitRow", $collapsed: "$isCollapsed"}, + TD({"class": "netCol netLimitCol", colspan: 6}, + TABLE({cellpadding: 0, cellspacing: 0}, + TBODY( + TR( + TD( + SPAN({"class": "netLimitLabel"}, + $STRP("plural.Limit_Exceeded", [0]) + ) + ), + TD({style: "width:100%"}), + TD( + BUTTON({"class": "netLimitButton", title: "$limitPrefsTitle", + onclick: "$onPreferences"}, + $STR("LimitPrefs") + ) + ), + TD(" ") + ) + ) + ) + ) + ), + + isCollapsed: function() + { + return this.collapsed; + }, + + onPreferences: function(event) + { + openNewTab("about:config"); + }, + + updateCounter: function(row) + { + removeClass(row, "collapsed"); + + // Update info within the limit row. + var limitLabel = row.getElementsByClassName("netLimitLabel").item(0); + limitLabel.firstChild.nodeValue = $STRP("plural.Limit_Exceeded", [row.limitInfo.totalCount]); + }, + + createTable: function(parent, limitInfo) + { + var table = this.tableTag.replace({}, parent); + var row = this.createRow(table.firstChild.firstChild, limitInfo); + return [table, row]; + }, + + createRow: function(parent, limitInfo) + { + var row = this.limitTag.insertRows(limitInfo, parent, this)[0]; + row.limitInfo = limitInfo; + return row; + }, + + // nsIPrefObserver + observe: function(subject, topic, data) + { + // We're observing preferences only. + if (topic != "nsPref:changed") + return; + + if (data.indexOf("net.logLimit") != -1) + this.updateMaxLimit(); + }, + + updateMaxLimit: function() + { + var value = Firebug.getPref(Firebug.prefDomain, "net.logLimit"); + maxQueueRequests = value ? value : maxQueueRequests; + } +}); + +var NetLimit = Firebug.NetMonitor.NetLimit; + +// ************************************************************************************************ + +Firebug.NetMonitor.ResponseSizeLimit = domplate(Firebug.Rep, +{ + tag: + DIV({"class": "netInfoResponseSizeLimit"}, + SPAN("$object.beforeLink"), + A({"class": "objectLink", onclick: "$onClickLink"}, + "$object.linkText" + ), + SPAN("$object.afterLink") + ), + + reLink: /^(.*)(.*)<\/a>(.*$)/, + append: function(obj, parent) + { + var m = obj.text.match(this.reLink); + return this.tag.append({onClickLink: obj.onClickLink, + object: { + beforeLink: m[1], + linkText: m[2], + afterLink: m[3] + }}, parent, this); + } +}); + +// ************************************************************************************************ +// ************************************************************************************************ + +Firebug.NetMonitor.Utils = +{ + findHeader: function(headers, name) + { + if (!headers) + return null; + + name = name.toLowerCase(); + for (var i = 0; i < headers.length; ++i) + { + var headerName = headers[i].name.toLowerCase(); + if (headerName == name) + return headers[i].value; + } + }, + + formatPostText: function(text) + { + if (text instanceof XMLDocument) + return getElementXML(text.documentElement); + else + return text; + }, + + getPostText: function(file, context, noLimit) + { + if (!file.postText) + { + file.postText = readPostTextFromRequest(file.request, context); + + if (!file.postText && context) + file.postText = readPostTextFromPage(file.href, context); + } + + if (!file.postText) + return file.postText; + + var limit = Firebug.netDisplayedPostBodyLimit; + if (file.postText.length > limit && !noLimit) + { + return cropString(file.postText, limit, + "\n\n... " + $STR("net.postDataSizeLimitMessage") + " ...\n\n"); + } + + return file.postText; + }, + + getResponseText: function(file, context) + { + // The response can be also empty string so, check agains "undefined". + return (typeof(file.responseText) != "undefined")? file.responseText : + context.sourceCache.loadText(file.href, file.method, file); + }, + + isURLEncodedRequest: function(file, context) + { + var text = Utils.getPostText(file, context); + if (text && text.toLowerCase().indexOf("content-type: application/x-www-form-urlencoded") == 0) + return true; + + // The header value doesn't have to be always exactly "application/x-www-form-urlencoded", + // there can be even charset specified. So, use indexOf rather than just "==". + var headerValue = Utils.findHeader(file.requestHeaders, "content-type"); + if (headerValue && headerValue.indexOf("application/x-www-form-urlencoded") == 0) + return true; + + return false; + }, + + isMultiPartRequest: function(file, context) + { + var text = Utils.getPostText(file, context); + if (text && text.toLowerCase().indexOf("content-type: multipart/form-data") == 0) + return true; + return false; + }, + + getMimeType: function(mimeType, uri) + { + if (!mimeType || !(mimeCategoryMap.hasOwnProperty(mimeType))) + { + var ext = getFileExtension(uri); + if (!ext) + return mimeType; + else + { + var extMimeType = mimeExtensionMap[ext.toLowerCase()]; + return extMimeType ? extMimeType : mimeType; + } + } + else + return mimeType; + }, + + getDateFromSeconds: function(s) + { + var d = new Date(); + d.setTime(s*1000); + return d; + }, + + getHttpHeaders: function(request, file) + { + try + { + var http = QI(request, Ci.nsIHttpChannel); + file.status = request.responseStatus; + + // xxxHonza: is there any problem to do this in requestedFile method? + file.method = http.requestMethod; + file.urlParams = parseURLParams(file.href); + file.mimeType = Utils.getMimeType(request.contentType, request.name); + + if (!file.responseHeaders && Firebug.collectHttpHeaders) + { + var requestHeaders = [], responseHeaders = []; + + http.visitRequestHeaders({ + visitHeader: function(name, value) + { + requestHeaders.push({name: name, value: value}); + } + }); + http.visitResponseHeaders({ + visitHeader: function(name, value) + { + responseHeaders.push({name: name, value: value}); + } + }); + + file.requestHeaders = requestHeaders; + file.responseHeaders = responseHeaders; + } + } + catch (exc) + { + // An exception can be throwed e.g. when the request is aborted and + // request.responseStatus is accessed. + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("net.getHttpHeaders FAILS " + file.href, exc); + } + }, + + isXHR: function(request) + { + try + { + var callbacks = request.notificationCallbacks; + var xhrRequest = callbacks ? callbacks.getInterface(Ci.nsIXMLHttpRequest) : null; + if (FBTrace.DBG_NET) + FBTrace.sysout("net.isXHR; " + (xhrRequest != null) + ", " + safeGetName(request)); + + return (xhrRequest != null); + } + catch (exc) + { + } + + return false; + }, + + getFileCategory: function(file) + { + if (file.category) + { + if (FBTrace.DBG_NET) + FBTrace.sysout("net.getFileCategory; current: " + file.category + " for: " + file.href, file); + return file.category; + } + + if (file.isXHR) + { + if (FBTrace.DBG_NET) + FBTrace.sysout("net.getFileCategory; XHR for: " + file.href, file); + return file.category = "xhr"; + } + + if (!file.mimeType) + { + var ext = getFileExtension(file.href); + if (ext) + file.mimeType = mimeExtensionMap[ext.toLowerCase()]; + } + + /*if (FBTrace.DBG_NET) + FBTrace.sysout("net.getFileCategory; " + mimeCategoryMap[file.mimeType] + + ", mimeType: " + file.mimeType + " for: " + file.href, file);*/ + + if (!file.mimeType) + return ""; + + // Solve cases when charset is also specified, eg "text/html; charset=UTF-8". + var mimeType = file.mimeType; + if (mimeType) + mimeType = mimeType.split(";")[0]; + + return (file.category = mimeCategoryMap[mimeType]); + } +}; + +var Utils = Firebug.NetMonitor.Utils; + +// ************************************************************************************************ + +//Firebug.registerRep(Firebug.NetMonitor.NetRequestTable); +//Firebug.registerActivableModule(Firebug.NetMonitor); +//Firebug.registerPanel(NetPanel); + +Firebug.registerModule(Firebug.NetMonitor); +//Firebug.registerRep(Firebug.NetMonitor.BreakpointRep); + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// Constants + +//const Cc = Components.classes; +//const Ci = Components.interfaces; + +// List of contexts with XHR spy attached. +var contexts = []; + +// ************************************************************************************************ +// Spy Module + +/** + * @module Represents a XHR Spy module. The main purpose of the XHR Spy feature is to monitor + * XHR activity of the current page and create appropriate log into the Console panel. + * This feature can be controlled by an option Show XMLHttpRequests (from within the + * console panel). + * + * The module is responsible for attaching/detaching a HTTP Observers when Firebug is + * activated/deactivated for a site. + */ +Firebug.Spy = extend(Firebug.Module, +/** @lends Firebug.Spy */ +{ + dispatchName: "spy", + + initialize: function() + { + if (Firebug.TraceModule) + Firebug.TraceModule.addListener(this.TraceListener); + + Firebug.Module.initialize.apply(this, arguments); + }, + + shutdown: function() + { + Firebug.Module.shutdown.apply(this, arguments); + + if (Firebug.TraceModule) + Firebug.TraceModule.removeListener(this.TraceListener); + }, + + initContext: function(context) + { + context.spies = []; + + if (Firebug.showXMLHttpRequests && Firebug.Console.isAlwaysEnabled()) + this.attachObserver(context, context.window); + + if (FBTrace.DBG_SPY) + FBTrace.sysout("spy.initContext " + contexts.length + " ", context.getName()); + }, + + destroyContext: function(context) + { + // For any spies that are in progress, remove our listeners so that they don't leak + this.detachObserver(context, null); + + if (FBTrace.DBG_SPY && context.spies.length) + FBTrace.sysout("spy.destroyContext; ERROR There are leaking Spies (" + + context.spies.length + ") " + context.getName()); + + delete context.spies; + + if (FBTrace.DBG_SPY) + FBTrace.sysout("spy.destroyContext " + contexts.length + " ", context.getName()); + }, + + watchWindow: function(context, win) + { + if (Firebug.showXMLHttpRequests && Firebug.Console.isAlwaysEnabled()) + this.attachObserver(context, win); + }, + + unwatchWindow: function(context, win) + { + try + { + // This make sure that the existing context is properly removed from "contexts" array. + this.detachObserver(context, win); + } + catch (ex) + { + // Get exceptions here sometimes, so let's just ignore them + // since the window is going away anyhow + ERROR(ex); + } + }, + + updateOption: function(name, value) + { + // XXXjjb Honza, if Console.isEnabled(context) false, then this can't be called, + // but somehow seems not correct + if (name == "showXMLHttpRequests") + { + var tach = value ? this.attachObserver : this.detachObserver; + for (var i = 0; i < TabWatcher.contexts.length; ++i) + { + var context = TabWatcher.contexts[i]; + iterateWindows(context.window, function(win) + { + tach.apply(this, [context, win]); + }); + } + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Attaching Spy to XHR requests. + + /** + * Returns false if Spy should not be attached to XHRs executed by the specified window. + */ + skipSpy: function(win) + { + if (!win) + return true; + + // Don't attach spy to chrome. + var uri = safeGetWindowLocation(win); + if (uri && (uri.indexOf("about:") == 0 || uri.indexOf("chrome:") == 0)) + return true; + }, + + attachObserver: function(context, win) + { + if (Firebug.Spy.skipSpy(win)) + return; + + for (var i=0; insIHttpChannel. + * Returns null if the request doesn't represent XHR. + */ + getXHR: function(request) + { + // Does also query-interface for nsIHttpChannel. + if (!(request instanceof Ci.nsIHttpChannel)) + return null; + + try + { + var callbacks = request.notificationCallbacks; + return (callbacks ? callbacks.getInterface(Ci.nsIXMLHttpRequest) : null); + } + catch (exc) + { + if (exc.name == "NS_NOINTERFACE") + { + if (FBTrace.DBG_SPY) + FBTrace.sysout("spy.getXHR; Request is not nsIXMLHttpRequest: " + + safeGetRequestName(request)); + } + } + + return null; + } +}); + + + + + +// ************************************************************************************************ + +/* +function getSpyForXHR(request, xhrRequest, context, noCreate) +{ + var spy = null; + + // Iterate all existing spy objects in this context and look for one that is + // already created for this request. + var length = context.spies.length; + for (var i=0; i= 3) + { + var netInfoBox = getChildByClass(spy.logRow, "spyHead", "netInfoBody"); + if (netInfoBox) + { + netInfoBox.htmlPresented = false; + netInfoBox.responsePresented = false; + } + } + + // If the request is loading update the end time. + if (spy.xhrRequest.readyState == 3) + { + spy.responseTime = spy.endTime - spy.sendTime; + updateTime(spy); + } + + // Request loaded. Get all the info from the request now, just in case the + // XHR would be aborted in the original onReadyStateChange handler. + if (spy.xhrRequest.readyState == 4) + { + // Cumulate response so, multipart response content is properly displayed. + if (SpyHttpActivityObserver.getActivityDistributor()) + spy.responseText += spy.xhrRequest.responseText; + else + { + // xxxHonza: remove from FB 1.6 + if (!spy.responseText) + spy.responseText = spy.xhrRequest.responseText; + } + + // The XHR is loaded now (used also by the activity observer). + spy.loaded = true; + + // Update UI. + updateHttpSpyInfo(spy); + + // Notify Net pane about a request beeing loaded. + // xxxHonza: I don't think this is necessary. + var netProgress = spy.context.netProgress; + if (netProgress) + netProgress.post(netProgress.stopFile, [spy.request, spy.endTime, spy.postText, spy.responseText]); + + // Notify registered listeners about finish of the XHR. + dispatch(Firebug.Spy.fbListeners, "onLoad", [spy.context, spy]); + } + + // Pass the event to the original page handler. + callPageHandler(spy, event, originalHandler); +} + +function onHTTPSpyLoad(spy) +{ + if (FBTrace.DBG_SPY) + FBTrace.sysout("spy.onHTTPSpyLoad: " + spy.href, spy); + + // Detach must be done in onLoad (not in onreadystatechange) otherwise + // onAbort would not be handled. + spy.detach(); + + // xxxHonza: Still needed for Fx 3.5 (#502959) + if (!SpyHttpActivityObserver.getActivityDistributor()) + onHTTPSpyReadyStateChange(spy, null); +} + +function onHTTPSpyError(spy) +{ + if (FBTrace.DBG_SPY) + FBTrace.sysout("spy.onHTTPSpyError; " + spy.href, spy); + + spy.detach(); + spy.loaded = true; + + if (spy.logRow) + { + removeClass(spy.logRow, "loading"); + setClass(spy.logRow, "error"); + } +} + +function onHTTPSpyAbort(spy) +{ + if (FBTrace.DBG_SPY) + FBTrace.sysout("spy.onHTTPSpyAbort: " + spy.href, spy); + + spy.detach(); + spy.loaded = true; + + if (spy.logRow) + { + removeClass(spy.logRow, "loading"); + setClass(spy.logRow, "error"); + } + + spy.statusText = "Aborted"; + updateLogRow(spy); + + // Notify Net pane about a request beeing aborted. + // xxxHonza: the net panel shoud find out this itself. + var netProgress = spy.context.netProgress; + if (netProgress) + netProgress.post(netProgress.abortFile, [spy.request, spy.endTime, spy.postText, spy.responseText]); +} +/**/ + +// ************************************************************************************************ + +/** + * @domplate Represents a template for XHRs logged in the Console panel. The body of the + * log (displayed when expanded) is rendered using {@link Firebug.NetMonitor.NetInfoBody}. + */ + +Firebug.Spy.XHR = domplate(Firebug.Rep, +/** @lends Firebug.Spy.XHR */ + +{ + tag: + DIV({"class": "spyHead", _repObject: "$object"}, + TABLE({"class": "spyHeadTable focusRow outerFocusRow", cellpadding: 0, cellspacing: 0, + "role": "listitem", "aria-expanded": "false"}, + TBODY({"role": "presentation"}, + TR({"class": "spyRow"}, + TD({"class": "spyTitleCol spyCol", onclick: "$onToggleBody"}, + DIV({"class": "spyTitle"}, + "$object|getCaption" + ), + DIV({"class": "spyFullTitle spyTitle"}, + "$object|getFullUri" + ) + ), + TD({"class": "spyCol"}, + DIV({"class": "spyStatus"}, "$object|getStatus") + ), + TD({"class": "spyCol"}, + SPAN({"class": "spyIcon"}) + ), + TD({"class": "spyCol"}, + SPAN({"class": "spyTime"}) + ), + TD({"class": "spyCol"}, + TAG(FirebugReps.SourceLink.tag, {object: "$object.sourceLink"}) + ) + ) + ) + ) + ), + + getCaption: function(spy) + { + return spy.method.toUpperCase() + " " + cropString(spy.getURL(), 100); + }, + + getFullUri: function(spy) + { + return spy.method.toUpperCase() + " " + spy.getURL(); + }, + + getStatus: function(spy) + { + var text = ""; + if (spy.statusCode) + text += spy.statusCode + " "; + + if (spy.statusText) + return text += spy.statusText; + + return text; + }, + + onToggleBody: function(event) + { + var target = event.currentTarget || event.srcElement; + var logRow = getAncestorByClass(target, "logRow-spy"); + + if (isLeftClick(event)) + { + toggleClass(logRow, "opened"); + + var spy = getChildByClass(logRow, "spyHead").repObject; + var spyHeadTable = getAncestorByClass(target, "spyHeadTable"); + + if (hasClass(logRow, "opened")) + { + updateHttpSpyInfo(spy, logRow); + if (spyHeadTable) + spyHeadTable.setAttribute('aria-expanded', 'true'); + } + else + { + //var netInfoBox = getChildByClass(spy.logRow, "spyHead", "netInfoBody"); + //dispatch(Firebug.NetMonitor.NetInfoBody.fbListeners, "destroyTabBody", [netInfoBox, spy]); + //if (spyHeadTable) + // spyHeadTable.setAttribute('aria-expanded', 'false'); + } + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + copyURL: function(spy) + { + copyToClipboard(spy.getURL()); + }, + + copyParams: function(spy) + { + var text = spy.postText; + if (!text) + return; + + var url = reEncodeURL(spy, text, true); + copyToClipboard(url); + }, + + copyResponse: function(spy) + { + copyToClipboard(spy.responseText); + }, + + openInTab: function(spy) + { + openNewTab(spy.getURL(), spy.postText); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + supportsObject: function(object) + { + // TODO: xxxpedro spy xhr + return false; + + return object instanceof Firebug.Spy.XMLHttpRequestSpy; + }, + + browseObject: function(spy, context) + { + var url = spy.getURL(); + openNewTab(url); + return true; + }, + + getRealObject: function(spy, context) + { + return spy.xhrRequest; + }, + + getContextMenuItems: function(spy) + { + var items = [ + {label: "CopyLocation", command: bindFixed(this.copyURL, this, spy) } + ]; + + if (spy.postText) + { + items.push( + {label: "CopyLocationParameters", command: bindFixed(this.copyParams, this, spy) } + ); + } + + items.push( + {label: "CopyResponse", command: bindFixed(this.copyResponse, this, spy) }, + "-", + {label: "OpenInTab", command: bindFixed(this.openInTab, this, spy) } + ); + + return items; + } +}); + +// ************************************************************************************************ + +function updateTime(spy) +{ + var timeBox = spy.logRow.getElementsByClassName("spyTime").item(0); + if (spy.responseTime) + timeBox.textContent = " " + formatTime(spy.responseTime); +} + +function updateLogRow(spy) +{ + updateTime(spy); + + var statusBox = spy.logRow.getElementsByClassName("spyStatus").item(0); + statusBox.textContent = Firebug.Spy.XHR.getStatus(spy); + + removeClass(spy.logRow, "loading"); + setClass(spy.logRow, "loaded"); + + try + { + var errorRange = Math.floor(spy.xhrRequest.status/100); + if (errorRange == 4 || errorRange == 5) + setClass(spy.logRow, "error"); + } + catch (exc) + { + } +} + +var updateHttpSpyInfo = function updateHttpSpyInfo(spy, logRow) +{ + if (!spy.logRow && logRow) + spy.logRow = logRow; + + if (!spy.logRow || !hasClass(spy.logRow, "opened")) + return; + + if (!spy.params) + //spy.params = parseURLParams(spy.href+""); + spy.params = parseURLParams(spy.href+""); + + if (!spy.requestHeaders) + spy.requestHeaders = getRequestHeaders(spy); + + if (!spy.responseHeaders && spy.loaded) + spy.responseHeaders = getResponseHeaders(spy); + + var template = Firebug.NetMonitor.NetInfoBody; + var netInfoBox = getChildByClass(spy.logRow, "spyHead", "netInfoBody"); + if (!netInfoBox) + { + var head = getChildByClass(spy.logRow, "spyHead"); + netInfoBox = template.tag.append({"file": spy}, head); + dispatch(template.fbListeners, "initTabBody", [netInfoBox, spy]); + template.selectTabByName(netInfoBox, "Response"); + } + else + { + template.updateInfo(netInfoBox, spy, spy.context); + } +}; + + + +// ************************************************************************************************ + +function getRequestHeaders(spy) +{ + var headers = []; + + var channel = spy.xhrRequest.channel; + if (channel instanceof Ci.nsIHttpChannel) + { + channel.visitRequestHeaders({ + visitHeader: function(name, value) + { + headers.push({name: name, value: value}); + } + }); + } + + return headers; +} + +function getResponseHeaders(spy) +{ + var headers = []; + + try + { + var channel = spy.xhrRequest.channel; + if (channel instanceof Ci.nsIHttpChannel) + { + channel.visitResponseHeaders({ + visitHeader: function(name, value) + { + headers.push({name: name, value: value}); + } + }); + } + } + catch (exc) + { + if (FBTrace.DBG_SPY || FBTrace.DBG_ERRORS) + FBTrace.sysout("spy.getResponseHeaders; EXCEPTION " + + safeGetRequestName(spy.request), exc); + } + + return headers; +} + +// ************************************************************************************************ +// Registration + +Firebug.registerModule(Firebug.Spy); +//Firebug.registerRep(Firebug.Spy.XHR); + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ + +// List of JSON content types. +var contentTypes = +{ + "text/plain": 1, + "text/javascript": 1, + "text/x-javascript": 1, + "text/json": 1, + "text/x-json": 1, + "application/json": 1, + "application/x-json": 1, + "application/javascript": 1, + "application/x-javascript": 1, + "application/json-rpc": 1 +}; + +// ************************************************************************************************ +// Model implementation + +Firebug.JSONViewerModel = extend(Firebug.Module, +{ + dispatchName: "jsonViewer", + initialize: function() + { + Firebug.NetMonitor.NetInfoBody.addListener(this); + + // Used by Firebug.DOMPanel.DirTable domplate. + this.toggles = {}; + }, + + shutdown: function() + { + Firebug.NetMonitor.NetInfoBody.removeListener(this); + }, + + initTabBody: function(infoBox, file) + { + if (FBTrace.DBG_JSONVIEWER) + FBTrace.sysout("jsonviewer.initTabBody", infoBox); + + // Let listeners to parse the JSON. + dispatch(this.fbListeners, "onParseJSON", [file]); + + // The JSON is still no there, try to parse most common cases. + if (!file.jsonObject) + { + ///if (this.isJSON(safeGetContentType(file.request), file.responseText)) + if (this.isJSON(file.mimeType, file.responseText)) + file.jsonObject = this.parseJSON(file); + } + + // The jsonObject is created so, the JSON tab can be displayed. + if (file.jsonObject && hasProperties(file.jsonObject)) + { + Firebug.NetMonitor.NetInfoBody.appendTab(infoBox, "JSON", + ///$STR("jsonviewer.tab.JSON")); + $STR("JSON")); + + if (FBTrace.DBG_JSONVIEWER) + FBTrace.sysout("jsonviewer.initTabBody; JSON object available " + + (typeof(file.jsonObject) != "undefined"), file.jsonObject); + } + }, + + isJSON: function(contentType, data) + { + // Workaround for JSON responses without proper content type + // Let's consider all responses starting with "{" as JSON. In the worst + // case there will be an exception when parsing. This means that no-JSON + // responses (and post data) (with "{") can be parsed unnecessarily, + // which represents a little overhead, but this happens only if the request + // is actually expanded by the user in the UI (Net & Console panels). + + ///var responseText = data ? trimLeft(data) : null; + ///if (responseText && responseText.indexOf("{") == 0) + /// return true; + var responseText = data ? trim(data) : null; + if (responseText && responseText.indexOf("{") == 0) + return true; + + if (!contentType) + return false; + + contentType = contentType.split(";")[0]; + contentType = trim(contentType); + return contentTypes[contentType]; + }, + + // Update listener for TabView + updateTabBody: function(infoBox, file, context) + { + var tab = infoBox.selectedTab; + ///var tabBody = infoBox.getElementsByClassName("netInfoJSONText").item(0); + var tabBody = $$(".netInfoJSONText", infoBox)[0]; + if (!hasClass(tab, "netInfoJSONTab") || tabBody.updated) + return; + + tabBody.updated = true; + + if (file.jsonObject) { + Firebug.DOMPanel.DirTable.tag.replace( + {object: file.jsonObject, toggles: this.toggles}, tabBody); + } + }, + + parseJSON: function(file) + { + var jsonString = new String(file.responseText); + ///return parseJSONString(jsonString, "http://" + file.request.originalURI.host); + return parseJSONString(jsonString); + } +}); + +// ************************************************************************************************ +// Registration + +Firebug.registerModule(Firebug.JSONViewerModel); + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// Constants + +// List of XML related content types. +var xmlContentTypes = +[ + "text/xml", + "application/xml", + "application/xhtml+xml", + "application/rss+xml", + "application/atom+xml",, + "application/vnd.mozilla.maybe.feed", + "application/rdf+xml", + "application/vnd.mozilla.xul+xml" +]; + +// ************************************************************************************************ +// Model implementation + +/** + * @module Implements viewer for XML based network responses. In order to create a new + * tab wihin network request detail, a listener is registered into + * Firebug.NetMonitor.NetInfoBody object. + */ +Firebug.XMLViewerModel = extend(Firebug.Module, +{ + dispatchName: "xmlViewer", + + initialize: function() + { + ///Firebug.ActivableModule.initialize.apply(this, arguments); + Firebug.Module.initialize.apply(this, arguments); + Firebug.NetMonitor.NetInfoBody.addListener(this); + }, + + shutdown: function() + { + ///Firebug.ActivableModule.shutdown.apply(this, arguments); + Firebug.Module.shutdown.apply(this, arguments); + Firebug.NetMonitor.NetInfoBody.removeListener(this); + }, + + /** + * Check response's content-type and if it's a XML, create a new tab with XML preview. + */ + initTabBody: function(infoBox, file) + { + if (FBTrace.DBG_XMLVIEWER) + FBTrace.sysout("xmlviewer.initTabBody", infoBox); + + // If the response is XML let's display a pretty preview. + ///if (this.isXML(safeGetContentType(file.request))) + if (this.isXML(file.mimeType, file.responseText)) + { + Firebug.NetMonitor.NetInfoBody.appendTab(infoBox, "XML", + ///$STR("xmlviewer.tab.XML")); + $STR("XML")); + + if (FBTrace.DBG_XMLVIEWER) + FBTrace.sysout("xmlviewer.initTabBody; XML response available"); + } + }, + + isXML: function(contentType) + { + if (!contentType) + return false; + + // Look if the response is XML based. + for (var i=0; i\s*/, ""); + + var div = parentNode.ownerDocument.createElement("div"); + div.innerHTML = xmlText; + + var root = div.getElementsByTagName("*")[0]; + + /*** + var parser = CCIN("@mozilla.org/xmlextras/domparser;1", "nsIDOMParser"); + var doc = parser.parseFromString(text, "text/xml"); + var root = doc.documentElement; + + // Error handling + var nsURI = "http://www.mozilla.org/newlayout/xml/parsererror.xml"; + if (root.namespaceURI == nsURI && root.nodeName == "parsererror") + { + this.ParseError.tag.replace({error: { + message: root.firstChild.nodeValue, + source: root.lastChild.textContent + }}, parentNode); + return; + } + /**/ + + if (FBTrace.DBG_XMLVIEWER) + FBTrace.sysout("xmlviewer.updateTabBody; XML response parsed", doc); + + // Override getHidden in these templates. The parsed XML documen is + // hidden, but we want to display it using 'visible' styling. + /* + var templates = [ + Firebug.HTMLPanel.CompleteElement, + Firebug.HTMLPanel.Element, + Firebug.HTMLPanel.TextElement, + Firebug.HTMLPanel.EmptyElement, + Firebug.HTMLPanel.XEmptyElement, + ]; + + var originals = []; + for (var i=0; iFirebug.XMLViewerModel. + */ +Firebug.XMLViewerModel.ParseError = domplate(Firebug.Rep, +{ + tag: + DIV({"class": "xmlInfoError"}, + DIV({"class": "xmlInfoErrorMsg"}, "$error.message"), + PRE({"class": "xmlInfoErrorSource"}, "$error|getSource") + ), + + getSource: function(error) + { + var parts = error.source.split("\n"); + if (parts.length != 2) + return error.source; + + var limit = 50; + var column = parts[1].length; + if (column >= limit) { + parts[0] = "..." + parts[0].substr(column - limit); + parts[1] = "..." + parts[1].substr(column - limit); + } + + if (parts[0].length > 80) + parts[0] = parts[0].substr(0, 80) + "..."; + + return parts.join("\n"); + } +}); + +// ************************************************************************************************ +// Registration + +Firebug.registerModule(Firebug.XMLViewerModel); + +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +// Globals + +var ElementCache = Firebug.Lite.Cache.Element; +var cacheID = Firebug.Lite.Cache.ID; + +var ignoreHTMLProps = +{ + // ignores the attributes injected by Sizzle, otherwise it will + // be visible on IE (when enumerating element.attributes) + sizcache: 1, + sizset: 1 +}; + +// ignores also the cache property injected by firebug +ignoreHTMLProps[cacheID] = 1; + + +// ************************************************************************************************ +// HTML Module + +Firebug.HTML = extend(Firebug.Module, +{ + appendTreeNode: function(nodeArray, html) + { + var reTrim = /^\s+|\s+$/g; + + if (!nodeArray.length) nodeArray = [nodeArray]; + + for (var n=0, node; node=nodeArray[n]; n++) + { + if (node.nodeType == 1) + { + if (Firebug.ignoreFirebugElements && node.firebugIgnore) continue; + + var uid = ElementCache(node); + var child = node.childNodes; + var childLength = child.length; + + var nodeName = node.nodeName.toLowerCase(); + + var nodeVisible = isVisible(node); + + var hasSingleTextChild = childLength == 1 && node.firstChild.nodeType == 3 && + nodeName != "script" && nodeName != "style"; + + var nodeControl = !hasSingleTextChild && childLength > 0 ? + ('
      ') : ''; + + 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 || 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; + + 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; + + 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: true, + 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.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.HTML.selectTreeNode(ElementCache(Firebug.browser.document.body)); + } + + // 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(FirebugChrome.selectedHTMLElementId) + Firebug.HTML.selectTreeNode(FirebugChrome.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"; + + selectedElement = e; + + FirebugChrome.selectedHTMLElementId = e.id; + + var target = ElementCache.get(e.id); + var selectedSidePanel = Firebug.chrome.getPanel("HTML").sidePanelBar.selectedPanel; + + var stack = FirebugChrome.htmlSelectionStack; + + stack.unshift(target); + + if (stack.length > 2) + stack.pop(); + + var lazySelect = function() + { + selectedSidePanelTS = new Date().getTime(); + + 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') + { + 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(' ]'); + } + +}; + + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +/* + +Hack: +Firebug.chrome.currentPanel = Firebug.chrome.selectedPanel; +Firebug.showInfoTips = true; +Firebug.InfoTip.initializeBrowser(Firebug.chrome); + +/**/ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// Constants + +var maxWidth = 100, maxHeight = 80; +var infoTipMargin = 10; +var infoTipWindowPadding = 25; + +// ************************************************************************************************ + +Firebug.InfoTip = extend(Firebug.Module, +{ + dispatchName: "infoTip", + tags: domplate( + { + infoTipTag: DIV({"class": "infoTip"}), + + colorTag: + DIV({style: "background: $rgbValue; width: 100px; height: 40px"}, " "), + + imgTag: + DIV({"class": "infoTipImageBox infoTipLoading"}, + IMG({"class": "infoTipImage", src: "$urlValue", repeat: "$repeat", + onload: "$onLoadImage"}), + IMG({"class": "infoTipBgImage", collapsed: true, src: "blank.gif"}), + DIV({"class": "infoTipCaption"}) + ), + + onLoadImage: function(event) + { + var img = event.currentTarget || event.srcElement; + ///var bgImg = img.nextSibling; + ///if (!bgImg) + /// return; // Sometimes gets called after element is dead + + ///var caption = bgImg.nextSibling; + var innerBox = img.parentNode; + + /// TODO: xxxpedro infoTip hack + var caption = getElementByClass(innerBox, "infoTipCaption"); + var bgImg = getElementByClass(innerBox, "infoTipBgImage"); + if (!bgImg) + return; // Sometimes gets called after element is dead + + // TODO: xxxpedro infoTip IE and timing issue + // TODO: use offline document to avoid flickering + if (isIE) + removeClass(innerBox, "infoTipLoading"); + + var updateInfoTip = function(){ + + var w = img.naturalWidth || img.width || 10, + h = img.naturalHeight || img.height || 10; + + var repeat = img.getAttribute("repeat"); + + if (repeat == "repeat-x" || (w == 1 && h > 1)) + { + collapse(img, true); + collapse(bgImg, false); + bgImg.style.background = "url(" + img.src + ") repeat-x"; + bgImg.style.width = maxWidth + "px"; + if (h > maxHeight) + bgImg.style.height = maxHeight + "px"; + else + bgImg.style.height = h + "px"; + } + else if (repeat == "repeat-y" || (h == 1 && w > 1)) + { + collapse(img, true); + collapse(bgImg, false); + bgImg.style.background = "url(" + img.src + ") repeat-y"; + bgImg.style.height = maxHeight + "px"; + if (w > maxWidth) + bgImg.style.width = maxWidth + "px"; + else + bgImg.style.width = w + "px"; + } + else if (repeat == "repeat" || (w == 1 && h == 1)) + { + collapse(img, true); + collapse(bgImg, false); + bgImg.style.background = "url(" + img.src + ") repeat"; + bgImg.style.width = maxWidth + "px"; + bgImg.style.height = maxHeight + "px"; + } + else + { + if (w > maxWidth || h > maxHeight) + { + if (w > h) + { + img.style.width = maxWidth + "px"; + img.style.height = Math.round((h / w) * maxWidth) + "px"; + } + else + { + img.style.width = Math.round((w / h) * maxHeight) + "px"; + img.style.height = maxHeight + "px"; + } + } + } + + //caption.innerHTML = $STRF("Dimensions", [w, h]); + caption.innerHTML = $STRF(w + " x " + h); + + + }; + + if (isIE) + setTimeout(updateInfoTip, 0); + else + { + updateInfoTip(); + removeClass(innerBox, "infoTipLoading"); + } + + /// + } + + /* + /// onLoadImage original + onLoadImage: function(event) + { + var img = event.currentTarget; + var bgImg = img.nextSibling; + if (!bgImg) + return; // Sometimes gets called after element is dead + + var caption = bgImg.nextSibling; + var innerBox = img.parentNode; + + var w = img.naturalWidth, h = img.naturalHeight; + var repeat = img.getAttribute("repeat"); + + if (repeat == "repeat-x" || (w == 1 && h > 1)) + { + collapse(img, true); + collapse(bgImg, false); + bgImg.style.background = "url(" + img.src + ") repeat-x"; + bgImg.style.width = maxWidth + "px"; + if (h > maxHeight) + bgImg.style.height = maxHeight + "px"; + else + bgImg.style.height = h + "px"; + } + else if (repeat == "repeat-y" || (h == 1 && w > 1)) + { + collapse(img, true); + collapse(bgImg, false); + bgImg.style.background = "url(" + img.src + ") repeat-y"; + bgImg.style.height = maxHeight + "px"; + if (w > maxWidth) + bgImg.style.width = maxWidth + "px"; + else + bgImg.style.width = w + "px"; + } + else if (repeat == "repeat" || (w == 1 && h == 1)) + { + collapse(img, true); + collapse(bgImg, false); + bgImg.style.background = "url(" + img.src + ") repeat"; + bgImg.style.width = maxWidth + "px"; + bgImg.style.height = maxHeight + "px"; + } + else + { + if (w > maxWidth || h > maxHeight) + { + if (w > h) + { + img.style.width = maxWidth + "px"; + img.style.height = Math.round((h / w) * maxWidth) + "px"; + } + else + { + img.style.width = Math.round((w / h) * maxHeight) + "px"; + img.style.height = maxHeight + "px"; + } + } + } + + caption.innerHTML = $STRF("Dimensions", [w, h]); + + removeClass(innerBox, "infoTipLoading"); + } + /**/ + + }), + + initializeBrowser: function(browser) + { + browser.onInfoTipMouseOut = bind(this.onMouseOut, this, browser); + browser.onInfoTipMouseMove = bind(this.onMouseMove, this, browser); + + ///var doc = browser.contentDocument; + var doc = browser.document; + if (!doc) + return; + + ///doc.addEventListener("mouseover", browser.onInfoTipMouseMove, true); + ///doc.addEventListener("mouseout", browser.onInfoTipMouseOut, true); + ///doc.addEventListener("mousemove", browser.onInfoTipMouseMove, true); + addEvent(doc, "mouseover", browser.onInfoTipMouseMove); + addEvent(doc, "mouseout", browser.onInfoTipMouseOut); + addEvent(doc, "mousemove", browser.onInfoTipMouseMove); + + return browser.infoTip = this.tags.infoTipTag.append({}, getBody(doc)); + }, + + uninitializeBrowser: function(browser) + { + if (browser.infoTip) + { + ///var doc = browser.contentDocument; + var doc = browser.document; + ///doc.removeEventListener("mouseover", browser.onInfoTipMouseMove, true); + ///doc.removeEventListener("mouseout", browser.onInfoTipMouseOut, true); + ///doc.removeEventListener("mousemove", browser.onInfoTipMouseMove, true); + removeEvent(doc, "mouseover", browser.onInfoTipMouseMove); + removeEvent(doc, "mouseout", browser.onInfoTipMouseOut); + removeEvent(doc, "mousemove", browser.onInfoTipMouseMove); + + browser.infoTip.parentNode.removeChild(browser.infoTip); + delete browser.infoTip; + delete browser.onInfoTipMouseMove; + } + }, + + showInfoTip: function(infoTip, panel, target, x, y, rangeParent, rangeOffset) + { + if (!Firebug.showInfoTips) + return; + + var scrollParent = getOverflowParent(target); + var scrollX = x + (scrollParent ? scrollParent.scrollLeft : 0); + + if (panel.showInfoTip(infoTip, target, scrollX, y, rangeParent, rangeOffset)) + { + var htmlElt = infoTip.ownerDocument.documentElement; + var panelWidth = htmlElt.clientWidth; + var panelHeight = htmlElt.clientHeight; + + if (x+infoTip.offsetWidth+infoTipMargin > panelWidth) + { + infoTip.style.left = Math.max(0, panelWidth-(infoTip.offsetWidth+infoTipMargin)) + "px"; + infoTip.style.right = "auto"; + } + else + { + infoTip.style.left = (x+infoTipMargin) + "px"; + infoTip.style.right = "auto"; + } + + if (y+infoTip.offsetHeight+infoTipMargin > panelHeight) + { + infoTip.style.top = Math.max(0, panelHeight-(infoTip.offsetHeight+infoTipMargin)) + "px"; + infoTip.style.bottom = "auto"; + } + else + { + infoTip.style.top = (y+infoTipMargin) + "px"; + infoTip.style.bottom = "auto"; + } + + if (FBTrace.DBG_INFOTIP) + FBTrace.sysout("infotip.showInfoTip; top: " + infoTip.style.top + + ", left: " + infoTip.style.left + ", bottom: " + infoTip.style.bottom + + ", right:" + infoTip.style.right + ", offsetHeight: " + infoTip.offsetHeight + + ", offsetWidth: " + infoTip.offsetWidth + + ", x: " + x + ", panelWidth: " + panelWidth + + ", y: " + y + ", panelHeight: " + panelHeight); + + infoTip.setAttribute("active", "true"); + } + else + this.hideInfoTip(infoTip); + }, + + hideInfoTip: function(infoTip) + { + if (infoTip) + infoTip.removeAttribute("active"); + }, + + onMouseOut: function(event, browser) + { + if (!event.relatedTarget) + this.hideInfoTip(browser.infoTip); + }, + + onMouseMove: function(event, browser) + { + // Ignore if the mouse is moving over the existing info tip. + if (getAncestorByClass(event.target, "infoTip")) + return; + + if (browser.currentPanel) + { + var x = event.clientX, y = event.clientY, target = event.target || event.srcElement; + this.showInfoTip(browser.infoTip, browser.currentPanel, target, x, y, event.rangeParent, event.rangeOffset); + } + else + this.hideInfoTip(browser.infoTip); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + populateColorInfoTip: function(infoTip, color) + { + this.tags.colorTag.replace({rgbValue: color}, infoTip); + return true; + }, + + populateImageInfoTip: function(infoTip, url, repeat) + { + if (!repeat) + repeat = "no-repeat"; + + this.tags.imgTag.replace({urlValue: url, repeat: repeat}, infoTip); + + return true; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Module + + disable: function() + { + // XXXjoe For each browser, call uninitializeBrowser + }, + + showPanel: function(browser, panel) + { + if (panel) + { + var infoTip = panel.panelBrowser.infoTip; + if (!infoTip) + infoTip = this.initializeBrowser(panel.panelBrowser); + this.hideInfoTip(infoTip); + } + + }, + + showSidePanel: function(browser, panel) + { + this.showPanel(browser, panel); + } +}); + +// ************************************************************************************************ + +Firebug.registerModule(Firebug.InfoTip); + +// ************************************************************************************************ + +}}); + + +/* See license.txt for terms of usage */ + +// move to FBL +(function() { + +// ************************************************************************************************ +// XPath + +/** + * Gets an XPath for an element which describes its hierarchical location. + */ +this.getElementXPath = function(element) +{ + if (element && element.id) + return '//*[@id="' + element.id + '"]'; + else + return this.getElementTreeXPath(element); +}; + +this.getElementTreeXPath = function(element) +{ + var paths = []; + + for (; element && element.nodeType == 1; element = element.parentNode) + { + var index = 0; + for (var sibling = element.previousSibling; sibling; sibling = sibling.previousSibling) + { + if (sibling.nodeName == element.nodeName) + ++index; + } + + var tagName = element.nodeName.toLowerCase(); + var pathIndex = (index ? "[" + (index+1) + "]" : ""); + paths.splice(0, 0, tagName + pathIndex); + } + + return paths.length ? "/" + paths.join("/") : null; +}; + +this.getElementsByXPath = function(doc, xpath) +{ + var nodes = []; + + try { + var result = doc.evaluate(xpath, doc, null, XPathResult.ANY_TYPE, null); + for (var item = result.iterateNext(); item; item = result.iterateNext()) + nodes.push(item); + } + catch (exc) + { + // Invalid xpath expressions make their way here sometimes. If that happens, + // we still want to return an empty set without an exception. + } + + return nodes; +}; + +this.getRuleMatchingElements = function(rule, doc) +{ + var css = rule.selectorText; + var xpath = this.cssToXPath(css); + return this.getElementsByXPath(doc, xpath); +}; + + +}).call(FBL); + + + + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ + +var toCamelCase = function toCamelCase(s) +{ + return s.replace(reSelectorCase, toCamelCaseReplaceFn); +}; + +var toSelectorCase = function toSelectorCase(s) +{ + return s.replace(reCamelCase, "-$1").toLowerCase(); + +}; + +var reCamelCase = /([A-Z])/g; +var reSelectorCase = /\-(.)/g; +var toCamelCaseReplaceFn = function toCamelCaseReplaceFn(m,g) +{ + return g.toUpperCase(); +}; + + + + + +// ************************************************************************************************ + +var ElementCache = Firebug.Lite.Cache.Element; +var StyleSheetCache = Firebug.Lite.Cache.StyleSheet; + +var globalCSSRuleIndex; + +var externalStyleSheetURLs = []; +var 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") + ) +}); + + +var processAllStyleSheetsTimeout = null; +var loadExternalStylesheet = function(doc, styleSheetIterator, styleSheet) +{ + var url = styleSheet.href; + styleSheet.firebugIgnore = true; + + var source = Firebug.Lite.Proxy.load(url); + + // TODO: check for null and error responses + + + // remove comments + //var reMultiComment = /(\/\*([^\*]|\*(?!\/))*\*\/)/g; + //source = source.replace(reMultiComment, ""); + + // convert relative addresses to absolute ones + source = source.replace(/url\(([^\)]+)\)/g, function(a,name){ + + var hasDomain = /\w+:\/\/./.test(name); + + if (!hasDomain) + { + name = name.replace(/^(["'])(.+)\1$/, "$2"); + var first = name.charAt(0); + + // relative path, based on root + if (first == "/") + { + // TODO: xxxpedro move to lib or Firebug.Lite.something + // getURLRoot + var m = /^([^:]+:\/{1,3}[^\/]+)/.exec(url); + + return m ? + "url(" + m[1] + name + ")" : + "url(" + name + ")"; + } + // relative path, based on current location + else + { + // TODO: xxxpedro move to lib or Firebug.Lite.something + // getURLPath + var path = url.replace(/[^\/]+\.[\w\d]+(\?.+|#.+)?$/g, ""); + + path = path + name; + + var reBack = /[^\/]+\/\.\.\//; + while(reBack.test(path)) + { + path = path.replace(reBack, ""); + } + + //console.log("url(" + path + ")"); + + return "url(" + path + ")"; + } + } + + // if it is an absolute path, there is nothing to do + return a; + }); + + var oldStyle = styleSheet.ownerNode; + + if (!oldStyle) return; + + if (!oldStyle.parentNode) return; + + var style = createGlobalElement("style"); + style.setAttribute("charset","utf-8"); + style.setAttribute("type", "text/css"); + style.innerHTML = source; + + //debugger; + oldStyle.parentNode.insertBefore(style, oldStyle.nextSibling); + oldStyle.parentNode.removeChild(oldStyle); + + + //doc.getElementsByTagName("head")[0].appendChild(style); + + doc.styleSheets[doc.styleSheets.length-1].externalURL = url; + + console.log(url, "call " + externalStyleSheetURLs.length, source); + + externalStyleSheetURLs.pop(); + + if (processAllStyleSheetsTimeout) + { + clearTimeout(processAllStyleSheetsTimeout); + } + + processAllStyleSheetsTimeout = setTimeout(function(){ + console.log("processing"); + FBL.processAllStyleSheets(doc, styleSheetIterator); + processAllStyleSheetsTimeout = null; + },200); + +}; + + +FBL.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 maxSpecificity) + { + maxSpecificity = spec; + mostSpecificSelector = sel; + } + } + } + + rule.specificity = maxSpecificity; + } + } + + rules.sort(sortElementRules); + //rules.sort(solveRulesTied); + + return rules; +}; + +var sortElementRules = function(a, b) +{ + var ruleA = CSSRuleMap[a]; + var ruleB = CSSRuleMap[b]; + + var specificityA = ruleA.specificity; + var specificityB = ruleB.specificity; + + if (specificityA > specificityB) + return 1; + + else if (specificityA < specificityB) + return -1; + + else + return ruleA.order > ruleB.order ? 1 : -1; +}; + +var solveRulesTied = function(a, b) +{ + var ruleA = CSSRuleMap[a]; + var ruleB = CSSRuleMap[b]; + + if (ruleA.specificity == ruleB.specificity) + return ruleA.order > ruleB.order ? 1 : -1; + + return null; +}; + +var reSelectorTag = /(^|\s)(?:\w+)/g; +var reSelectorClass = /\.[\w\d_-]+/g; +var reSelectorId = /#[\w\d_-]+/g; + +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; +}; + +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ + + +// ************************************************************************************************ +// Constants + +//const Cc = Components.classes; +//const Ci = Components.interfaces; +//const nsIDOMCSSStyleRule = Ci.nsIDOMCSSStyleRule; +//const nsIInterfaceRequestor = Ci.nsIInterfaceRequestor; +//const nsISelectionDisplay = Ci.nsISelectionDisplay; +//const nsISelectionController = Ci.nsISelectionController; + +// See: http://mxr.mozilla.org/mozilla1.9.2/source/content/events/public/nsIEventStateManager.h#153 +//const STATE_ACTIVE = 0x01; +//const STATE_FOCUS = 0x02; +//const STATE_HOVER = 0x04; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +Firebug.SourceBoxPanel = Firebug.Panel; + +var domUtils = null; + +var textContent = isIE ? "innerText" : "textContent"; +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var CSSDomplateBase = { + isEditable: function(rule) + { + return !rule.isSystemSheet; + }, + isSelectorEditable: function(rule) + { + return rule.isSelectorEditable && this.isEditable(rule); + } +}; + +var CSSPropTag = domplate(CSSDomplateBase, { + tag: DIV({"class": "cssProp focusRow", $disabledStyle: "$prop.disabled", + $editGroup: "$rule|isEditable", + $cssOverridden: "$prop.overridden", role : "option"}, + A({"class": "cssPropDisable"}, "  "), + SPAN({"class": "cssPropName", $editable: "$rule|isEditable"}, "$prop.name"), + SPAN({"class": "cssColon"}, ":"), + SPAN({"class": "cssPropValue", $editable: "$rule|isEditable"}, "$prop.value$prop.important"), + SPAN({"class": "cssSemi"}, ";") + ) +}); + +var CSSRuleTag = + TAG("$rule.tag", {rule: "$rule"}); + +var CSSImportRuleTag = domplate({ + tag: DIV({"class": "cssRule insertInto focusRow importRule", _repObject: "$rule.rule"}, + "@import "", + A({"class": "objectLink", _repObject: "$rule.rule.styleSheet"}, "$rule.rule.href"), + "";" + ) +}); + +var CSSStyleRuleTag = domplate(CSSDomplateBase, { + tag: DIV({"class": "cssRule insertInto", + $cssEditableRule: "$rule|isEditable", + $editGroup: "$rule|isSelectorEditable", + _repObject: "$rule.rule", + "ruleId": "$rule.id", role : 'presentation'}, + DIV({"class": "cssHead focusRow", role : 'listitem'}, + SPAN({"class": "cssSelector", $editable: "$rule|isSelectorEditable"}, "$rule.selector"), " {" + ), + DIV({role : 'group'}, + DIV({"class": "cssPropertyListBox", role : 'listbox'}, + FOR("prop", "$rule.props", + TAG(CSSPropTag.tag, {rule: "$rule", prop: "$prop"}) + ) + ) + ), + DIV({"class": "editable insertBefore", role:"presentation"}, "}") + ) +}); + +var reSplitCSS = /(url\("?[^"\)]+?"?\))|(rgb\(.*?\))|(#[\dA-Fa-f]+)|(-?\d+(\.\d+)?(%|[a-z]{1,2})?)|([^,\s]+)|"(.*?)"/; + +var reURL = /url\("?([^"\)]+)?"?\)/; + +var reRepeat = /no-repeat|repeat-x|repeat-y|repeat/; + +//const sothinkInstalled = !!$("swfcatcherKey_sidebar"); +var sothinkInstalled = false; +var styleGroups = +{ + text: [ + "font-family", + "font-size", + "font-weight", + "font-style", + "color", + "text-transform", + "text-decoration", + "letter-spacing", + "word-spacing", + "line-height", + "text-align", + "vertical-align", + "direction", + "column-count", + "column-gap", + "column-width" + ], + + background: [ + "background-color", + "background-image", + "background-repeat", + "background-position", + "background-attachment", + "opacity" + ], + + box: [ + "width", + "height", + "top", + "right", + "bottom", + "left", + "margin-top", + "margin-right", + "margin-bottom", + "margin-left", + "padding-top", + "padding-right", + "padding-bottom", + "padding-left", + "border-top-width", + "border-right-width", + "border-bottom-width", + "border-left-width", + "border-top-color", + "border-right-color", + "border-bottom-color", + "border-left-color", + "border-top-style", + "border-right-style", + "border-bottom-style", + "border-left-style", + "-moz-border-top-radius", + "-moz-border-right-radius", + "-moz-border-bottom-radius", + "-moz-border-left-radius", + "outline-top-width", + "outline-right-width", + "outline-bottom-width", + "outline-left-width", + "outline-top-color", + "outline-right-color", + "outline-bottom-color", + "outline-left-color", + "outline-top-style", + "outline-right-style", + "outline-bottom-style", + "outline-left-style" + ], + + layout: [ + "position", + "display", + "visibility", + "z-index", + "overflow-x", // http://www.w3.org/TR/2002/WD-css3-box-20021024/#overflow + "overflow-y", + "overflow-clip", + "white-space", + "clip", + "float", + "clear", + "-moz-box-sizing" + ], + + other: [ + "cursor", + "list-style-image", + "list-style-position", + "list-style-type", + "marker-offset", + "user-focus", + "user-select", + "user-modify", + "user-input" + ] +}; + +var styleGroupTitles = +{ + text: "Text", + background: "Background", + box: "Box Model", + layout: "Layout", + other: "Other" +}; + +Firebug.CSSModule = extend(Firebug.Module, +{ + freeEdit: function(styleSheet, value) + { + if (!styleSheet.editStyleSheet) + { + var ownerNode = getStyleSheetOwnerNode(styleSheet); + styleSheet.disabled = true; + + var url = CCSV("@mozilla.org/network/standard-url;1", Components.interfaces.nsIURL); + url.spec = styleSheet.href; + + var editStyleSheet = ownerNode.ownerDocument.createElementNS( + "http://www.w3.org/1999/xhtml", + "style"); + unwrapObject(editStyleSheet).firebugIgnore = true; + editStyleSheet.setAttribute("type", "text/css"); + editStyleSheet.setAttributeNS( + "http://www.w3.org/XML/1998/namespace", + "base", + url.directory); + if (ownerNode.hasAttribute("media")) + { + editStyleSheet.setAttribute("media", ownerNode.getAttribute("media")); + } + + // Insert the edited stylesheet directly after the old one to ensure the styles + // cascade properly. + ownerNode.parentNode.insertBefore(editStyleSheet, ownerNode.nextSibling); + + styleSheet.editStyleSheet = editStyleSheet; + } + + styleSheet.editStyleSheet.innerHTML = value; + if (FBTrace.DBG_CSS) + FBTrace.sysout("css.saveEdit styleSheet.href:"+styleSheet.href+" got innerHTML:"+value+"\n"); + + dispatch(this.fbListeners, "onCSSFreeEdit", [styleSheet, value]); + }, + + insertRule: function(styleSheet, cssText, ruleIndex) + { + if (FBTrace.DBG_CSS) FBTrace.sysout("Insert: " + ruleIndex + " " + cssText); + var insertIndex = styleSheet.insertRule(cssText, ruleIndex); + + dispatch(this.fbListeners, "onCSSInsertRule", [styleSheet, cssText, ruleIndex]); + + return insertIndex; + }, + + deleteRule: function(styleSheet, ruleIndex) + { + if (FBTrace.DBG_CSS) FBTrace.sysout("deleteRule: " + ruleIndex + " " + styleSheet.cssRules.length, styleSheet.cssRules); + dispatch(this.fbListeners, "onCSSDeleteRule", [styleSheet, ruleIndex]); + + styleSheet.deleteRule(ruleIndex); + }, + + setProperty: function(rule, propName, propValue, propPriority) + { + var style = rule.style || rule; + + // Record the original CSS text for the inline case so we can reconstruct at a later + // point for diffing purposes + var baseText = style.cssText; + + // good browsers + if (style.getPropertyValue) + { + var prevValue = style.getPropertyValue(propName); + var prevPriority = style.getPropertyPriority(propName); + + // XXXjoe Gecko bug workaround: Just changing priority doesn't have any effect + // unless we remove the property first + style.removeProperty(propName); + + style.setProperty(propName, propValue, propPriority); + } + // sad browsers + else + { + // TODO: xxxpedro parse CSS rule to find property priority in IE? + //console.log(propName, propValue); + style[toCamelCase(propName)] = propValue; + } + + if (propName) { + dispatch(this.fbListeners, "onCSSSetProperty", [style, propName, propValue, propPriority, prevValue, prevPriority, rule, baseText]); + } + }, + + removeProperty: function(rule, propName, parent) + { + var style = rule.style || rule; + + // Record the original CSS text for the inline case so we can reconstruct at a later + // point for diffing purposes + var baseText = style.cssText; + + if (style.getPropertyValue) + { + + var prevValue = style.getPropertyValue(propName); + var prevPriority = style.getPropertyPriority(propName); + + style.removeProperty(propName); + } + else + { + style[toCamelCase(propName)] = ""; + } + + if (propName) { + dispatch(this.fbListeners, "onCSSRemoveProperty", [style, propName, prevValue, prevPriority, rule, baseText]); + } + }/*, + + cleanupSheets: function(doc, context) + { + // Due to the manner in which the layout engine handles multiple + // references to the same sheet we need to kick it a little bit. + // The injecting a simple stylesheet then removing it will force + // Firefox to regenerate it's CSS hierarchy. + // + // WARN: This behavior was determined anecdotally. + // See http://code.google.com/p/fbug/issues/detail?id=2440 + var style = doc.createElementNS("http://www.w3.org/1999/xhtml", "style"); + style.setAttribute("charset","utf-8"); + unwrapObject(style).firebugIgnore = true; + style.setAttribute("type", "text/css"); + style.innerHTML = "#fbIgnoreStyleDO_NOT_USE {}"; + addStyleSheet(doc, style); + style.parentNode.removeChild(style); + + // https://bugzilla.mozilla.org/show_bug.cgi?id=500365 + // This voodoo touches each style sheet to force some Firefox internal change to allow edits. + var styleSheets = getAllStyleSheets(context); + for(var i = 0; i < styleSheets.length; i++) + { + try + { + var rules = styleSheets[i].cssRules; + if (rules.length > 0) + var touch = rules[0]; + if (FBTrace.DBG_CSS && touch) + FBTrace.sysout("css.show() touch "+typeof(touch)+" in "+(styleSheets[i].href?styleSheets[i].href:context.getName())); + } + catch(e) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("css.show: sheet.cssRules FAILS for "+(styleSheets[i]?styleSheets[i].href:"null sheet")+e, e); + } + } + }, + cleanupSheetHandler: function(event, context) + { + var target = event.target || event.srcElement, + tagName = (target.tagName || "").toLowerCase(); + if (tagName == "link") + { + this.cleanupSheets(target.ownerDocument, context); + } + }, + watchWindow: function(context, win) + { + var cleanupSheets = bind(this.cleanupSheets, this), + cleanupSheetHandler = bind(this.cleanupSheetHandler, this, context), + doc = win.document; + + //doc.addEventListener("DOMAttrModified", cleanupSheetHandler, false); + //doc.addEventListener("DOMNodeInserted", cleanupSheetHandler, false); + }, + loadedContext: function(context) + { + var self = this; + iterateWindows(context.browser.contentWindow, function(subwin) + { + self.cleanupSheets(subwin.document, context); + }); + } + /**/ +}); + +// ************************************************************************************************ + +Firebug.CSSStyleSheetPanel = function() {}; + +Firebug.CSSStyleSheetPanel.prototype = extend(Firebug.SourceBoxPanel, +{ + template: domplate( + { + tag: + DIV({"class": "cssSheet insertInto a11yCSSView"}, + FOR("rule", "$rules", + CSSRuleTag + ), + DIV({"class": "cssSheet editable insertBefore"}, "") + ) + }), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + refresh: function() + { + if (this.location) + this.updateLocation(this.location); + else if (this.selection) + this.updateSelection(this.selection); + }, + + toggleEditing: function() + { + if (!this.stylesheetEditor) + this.stylesheetEditor = new StyleSheetEditor(this.document); + + if (this.editing) + Firebug.Editor.stopEditing(); + else + { + if (!this.location) + return; + + var styleSheet = this.location.editStyleSheet + ? this.location.editStyleSheet.sheet + : this.location; + + var css = getStyleSheetCSS(styleSheet, this.context); + //var topmost = getTopmostRuleLine(this.panelNode); + + this.stylesheetEditor.styleSheet = this.location; + Firebug.Editor.startEditing(this.panelNode, css, this.stylesheetEditor); + //this.stylesheetEditor.scrollToLine(topmost.line, topmost.offset); + } + }, + + getStylesheetURL: function(rule) + { + if (this.location.href) + return this.location.href; + else + return this.context.window.location.href; + }, + + getRuleByLine: function(styleSheet, line) + { + if (!domUtils) + return null; + + var cssRules = styleSheet.cssRules; + for (var i = 0; i < cssRules.length; ++i) + { + var rule = cssRules[i]; + if (rule instanceof CSSStyleRule) + { + var ruleLine = domUtils.getRuleLine(rule); + if (ruleLine >= line) + return rule; + } + } + }, + + highlightRule: function(rule) + { + var ruleElement = Firebug.getElementByRepObject(this.panelNode.firstChild, rule); + if (ruleElement) + { + scrollIntoCenterView(ruleElement, this.panelNode); + setClassTimed(ruleElement, "jumpHighlight", this.context); + } + }, + + getStyleSheetRules: function(context, styleSheet) + { + var isSystemSheet = isSystemStyleSheet(styleSheet); + + function appendRules(cssRules) + { + for (var i = 0; i < cssRules.length; ++i) + { + var rule = cssRules[i]; + + // TODO: xxxpedro opera instanceof stylesheet remove the following comments when + // the issue with opera and style sheet Classes has been solved. + + //if (rule instanceof CSSStyleRule) + if (instanceOf(rule, "CSSStyleRule")) + { + var props = this.getRuleProperties(context, rule); + //var line = domUtils.getRuleLine(rule); + var line = null; + + var selector = rule.selectorText; + + if (isIE) + { + selector = selector.replace(reSelectorTag, + function(s){return s.toLowerCase();}); + } + + var ruleId = rule.selectorText+"/"+line; + rules.push({tag: CSSStyleRuleTag.tag, rule: rule, id: ruleId, + selector: selector, props: props, + isSystemSheet: isSystemSheet, + isSelectorEditable: true}); + } + //else if (rule instanceof CSSImportRule) + else if (instanceOf(rule, "CSSImportRule")) + rules.push({tag: CSSImportRuleTag.tag, rule: rule}); + //else if (rule instanceof CSSMediaRule) + else if (instanceOf(rule, "CSSMediaRule")) + appendRules.apply(this, [rule.cssRules]); + else + { + if (FBTrace.DBG_ERRORS || FBTrace.DBG_CSS) + FBTrace.sysout("css getStyleSheetRules failed to classify a rule ", rule); + } + } + } + + var rules = []; + appendRules.apply(this, [styleSheet.cssRules || styleSheet.rules]); + return rules; + }, + + parseCSSProps: function(style, inheritMode) + { + var props = []; + + if (Firebug.expandShorthandProps) + { + var count = style.length-1, + index = style.length; + while (index--) + { + var propName = style.item(count - index); + this.addProperty(propName, style.getPropertyValue(propName), !!style.getPropertyPriority(propName), false, inheritMode, props); + } + } + else + { + var lines = style.cssText.match(/(?:[^;\(]*(?:\([^\)]*?\))?[^;\(]*)*;?/g); + var propRE = /\s*([^:\s]*)\s*:\s*(.*?)\s*(! important)?;?$/; + var line,i=0; + // TODO: xxxpedro port to firebug: variable leaked into global namespace + var m; + + while(line=lines[i++]){ + m = propRE.exec(line); + if(!m) + continue; + //var name = m[1], value = m[2], important = !!m[3]; + if (m[2]) + this.addProperty(m[1], m[2], !!m[3], false, inheritMode, props); + }; + } + + return props; + }, + + getRuleProperties: function(context, rule, inheritMode) + { + var props = this.parseCSSProps(rule.style, inheritMode); + + // TODO: xxxpedro port to firebug: variable leaked into global namespace + //var line = domUtils.getRuleLine(rule); + var line; + var ruleId = rule.selectorText+"/"+line; + this.addOldProperties(context, ruleId, inheritMode, props); + sortProperties(props); + + return props; + }, + + addOldProperties: function(context, ruleId, inheritMode, props) + { + if (context.selectorMap && context.selectorMap.hasOwnProperty(ruleId) ) + { + var moreProps = context.selectorMap[ruleId]; + for (var i = 0; i < moreProps.length; ++i) + { + var prop = moreProps[i]; + this.addProperty(prop.name, prop.value, prop.important, true, inheritMode, props); + } + } + }, + + addProperty: function(name, value, important, disabled, inheritMode, props) + { + name = name.toLowerCase(); + + if (inheritMode && !inheritedStyleNames[name]) + return; + + name = this.translateName(name, value); + if (name) + { + value = stripUnits(rgbToHex(value)); + important = important ? " !important" : ""; + + var prop = {name: name, value: value, important: important, disabled: disabled}; + props.push(prop); + } + }, + + translateName: function(name, value) + { + // Don't show these proprietary Mozilla properties + if ((value == "-moz-initial" + && (name == "-moz-background-clip" || name == "-moz-background-origin" + || name == "-moz-background-inline-policy")) + || (value == "physical" + && (name == "margin-left-ltr-source" || name == "margin-left-rtl-source" + || name == "margin-right-ltr-source" || name == "margin-right-rtl-source")) + || (value == "physical" + && (name == "padding-left-ltr-source" || name == "padding-left-rtl-source" + || name == "padding-right-ltr-source" || name == "padding-right-rtl-source"))) + return null; + + // Translate these back to the form the user probably expects + if (name == "margin-left-value") + return "margin-left"; + else if (name == "margin-right-value") + return "margin-right"; + else if (name == "margin-top-value") + return "margin-top"; + else if (name == "margin-bottom-value") + return "margin-bottom"; + else if (name == "padding-left-value") + return "padding-left"; + else if (name == "padding-right-value") + return "padding-right"; + else if (name == "padding-top-value") + return "padding-top"; + else if (name == "padding-bottom-value") + return "padding-bottom"; + // XXXjoe What about border! + else + return name; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + editElementStyle: function() + { + ///var rulesBox = this.panelNode.getElementsByClassName("cssElementRuleContainer")[0]; + var rulesBox = $$(".cssElementRuleContainer", this.panelNode)[0]; + var styleRuleBox = rulesBox && Firebug.getElementByRepObject(rulesBox, this.selection); + if (!styleRuleBox) + { + var rule = {rule: this.selection, inherited: false, selector: "element.style", props: []}; + if (!rulesBox) + { + // The element did not have any displayed styles. We need to create the whole tree and remove + // the no styles message + styleRuleBox = this.template.cascadedTag.replace({ + rules: [rule], inherited: [], inheritLabel: "Inherited from" // $STR("InheritedFrom") + }, this.panelNode); + + ///styleRuleBox = styleRuleBox.getElementsByClassName("cssElementRuleContainer")[0]; + styleRuleBox = $$(".cssElementRuleContainer", styleRuleBox)[0]; + } + else + styleRuleBox = this.template.ruleTag.insertBefore({rule: rule}, rulesBox); + + ///styleRuleBox = styleRuleBox.getElementsByClassName("insertInto")[0]; + styleRuleBox = $$(".insertInto", styleRuleBox)[0]; + } + + Firebug.Editor.insertRowForObject(styleRuleBox); + }, + + insertPropertyRow: function(row) + { + Firebug.Editor.insertRowForObject(row); + }, + + insertRule: function(row) + { + var location = getAncestorByClass(row, "cssRule"); + if (!location) + { + location = getChildByClass(this.panelNode, "cssSheet"); + Firebug.Editor.insertRowForObject(location); + } + else + { + Firebug.Editor.insertRow(location, "before"); + } + }, + + editPropertyRow: function(row) + { + var propValueBox = getChildByClass(row, "cssPropValue"); + Firebug.Editor.startEditing(propValueBox); + }, + + deletePropertyRow: function(row) + { + var rule = Firebug.getRepObject(row); + var propName = getChildByClass(row, "cssPropName")[textContent]; + Firebug.CSSModule.removeProperty(rule, propName); + + // Remove the property from the selector map, if it was disabled + var ruleId = Firebug.getRepNode(row).getAttribute("ruleId"); + if ( this.context.selectorMap && this.context.selectorMap.hasOwnProperty(ruleId) ) + { + var map = this.context.selectorMap[ruleId]; + for (var i = 0; i < map.length; ++i) + { + if (map[i].name == propName) + { + map.splice(i, 1); + break; + } + } + } + if (this.name == "stylesheet") + dispatch([Firebug.A11yModel], 'onInlineEditorClose', [this, row.firstChild, true]); + row.parentNode.removeChild(row); + + this.markChange(this.name == "stylesheet"); + }, + + disablePropertyRow: function(row) + { + toggleClass(row, "disabledStyle"); + + var rule = Firebug.getRepObject(row); + var propName = getChildByClass(row, "cssPropName")[textContent]; + + if (!this.context.selectorMap) + this.context.selectorMap = {}; + + // XXXjoe Generate unique key for elements too + var ruleId = Firebug.getRepNode(row).getAttribute("ruleId"); + if (!(this.context.selectorMap.hasOwnProperty(ruleId))) + this.context.selectorMap[ruleId] = []; + + var map = this.context.selectorMap[ruleId]; + var propValue = getChildByClass(row, "cssPropValue")[textContent]; + var parsedValue = parsePriority(propValue); + if (hasClass(row, "disabledStyle")) + { + Firebug.CSSModule.removeProperty(rule, propName); + + map.push({"name": propName, "value": parsedValue.value, + "important": parsedValue.priority}); + } + else + { + Firebug.CSSModule.setProperty(rule, propName, parsedValue.value, parsedValue.priority); + + var index = findPropByName(map, propName); + map.splice(index, 1); + } + + this.markChange(this.name == "stylesheet"); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + onMouseDown: function(event) + { + //console.log("onMouseDown", event.target || event.srcElement, event); + + // xxxpedro adjusting coordinates because the panel isn't a window yet + var offset = event.clientX - this.panelNode.parentNode.offsetLeft; + + // XXjoe Hack to only allow clicking on the checkbox + if (!isLeftClick(event) || offset > 20) + return; + + var target = event.target || event.srcElement; + if (hasClass(target, "textEditor")) + return; + + var row = getAncestorByClass(target, "cssProp"); + if (row && hasClass(row, "editGroup")) + { + this.disablePropertyRow(row); + cancelEvent(event); + } + }, + + onDoubleClick: function(event) + { + //console.log("onDoubleClick", event.target || event.srcElement, event); + + // xxxpedro adjusting coordinates because the panel isn't a window yet + var offset = event.clientX - this.panelNode.parentNode.offsetLeft; + + if (!isLeftClick(event) || offset <= 20) + return; + + var target = event.target || event.srcElement; + + //console.log("ok", target, hasClass(target, "textEditorInner"), !isLeftClick(event), offset <= 20); + + // if the inline editor was clicked, don't insert a new rule + if (hasClass(target, "textEditorInner")) + return; + + var row = getAncestorByClass(target, "cssRule"); + if (row && !getAncestorByClass(target, "cssPropName") + && !getAncestorByClass(target, "cssPropValue")) + { + this.insertPropertyRow(row); + cancelEvent(event); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "stylesheet", + title: "CSS", + parentPanel: null, + searchable: true, + dependents: ["css", "stylesheet", "dom", "domSide", "layout"], + + options: + { + hasToolButtons: true + }, + + create: function() + { + Firebug.Panel.create.apply(this, arguments); + + this.onMouseDown = bind(this.onMouseDown, this); + this.onDoubleClick = bind(this.onDoubleClick, this); + + if (this.name == "stylesheet") + { + this.onChangeSelect = bind(this.onChangeSelect, this); + + var doc = Firebug.browser.document; + var selectNode = this.selectNode = createElement("select"); + + processAllStyleSheets(doc, function(doc, styleSheet) + { + var key = StyleSheetCache.key(styleSheet); + var fileName = getFileName(styleSheet.href) || getFileName(doc.location.href); + var option = createElement("option", {value: key}); + + option.appendChild(Firebug.chrome.document.createTextNode(fileName)); + selectNode.appendChild(option); + }); + + this.toolButtonsNode.appendChild(selectNode); + } + /**/ + }, + + onChangeSelect: function(event) + { + event = event || window.event; + var target = event.srcElement || event.currentTarget; + var key = target.value; + var styleSheet = StyleSheetCache.get(key); + + this.updateLocation(styleSheet); + }, + + initialize: function() + { + Firebug.Panel.initialize.apply(this, arguments); + + //if (!domUtils) + //{ + // try { + // domUtils = CCSV("@mozilla.org/inspector/dom-utils;1", "inIDOMUtils"); + // } catch (exc) { + // if (FBTrace.DBG_ERRORS) + // FBTrace.sysout("@mozilla.org/inspector/dom-utils;1 FAILED to load: "+exc, exc); + // } + //} + + //TODO: xxxpedro + this.context = Firebug.chrome; // TODO: xxxpedro css2 + this.document = Firebug.chrome.document; // TODO: xxxpedro css2 + + this.initializeNode(); + + if (this.name == "stylesheet") + { + var styleSheets = Firebug.browser.document.styleSheets; + + if (styleSheets.length > 0) + { + addEvent(this.selectNode, "change", this.onChangeSelect); + + this.updateLocation(styleSheets[0]); + } + } + + //Firebug.SourceBoxPanel.initialize.apply(this, arguments); + }, + + shutdown: function() + { + // must destroy the editor when we leave the panel to avoid problems (Issue 2981) + Firebug.Editor.stopEditing(); + + if (this.name == "stylesheet") + { + removeEvent(this.selectNode, "change", this.onChangeSelect); + } + + this.destroyNode(); + + Firebug.Panel.shutdown.apply(this, arguments); + }, + + destroy: function(state) + { + //state.scrollTop = this.panelNode.scrollTop ? this.panelNode.scrollTop : this.lastScrollTop; + + //persistObjects(this, state); + + // xxxpedro we are stopping the editor in the shutdown method already + //Firebug.Editor.stopEditing(); + Firebug.Panel.destroy.apply(this, arguments); + }, + + initializeNode: function(oldPanelNode) + { + addEvent(this.panelNode, "mousedown", this.onMouseDown); + addEvent(this.panelNode, "dblclick", this.onDoubleClick); + //Firebug.SourceBoxPanel.initializeNode.apply(this, arguments); + //dispatch([Firebug.A11yModel], 'onInitializeNode', [this, 'css']); + }, + + destroyNode: function() + { + removeEvent(this.panelNode, "mousedown", this.onMouseDown); + removeEvent(this.panelNode, "dblclick", this.onDoubleClick); + //Firebug.SourceBoxPanel.destroyNode.apply(this, arguments); + //dispatch([Firebug.A11yModel], 'onDestroyNode', [this, 'css']); + }, + + ishow: function(state) + { + Firebug.Inspector.stopInspecting(true); + + this.showToolbarButtons("fbCSSButtons", true); + + if (this.context.loaded && !this.location) // wait for loadedContext to restore the panel + { + restoreObjects(this, state); + + if (!this.location) + this.location = this.getDefaultLocation(); + + if (state && state.scrollTop) + this.panelNode.scrollTop = state.scrollTop; + } + }, + + ihide: function() + { + this.showToolbarButtons("fbCSSButtons", false); + + this.lastScrollTop = this.panelNode.scrollTop; + }, + + supportsObject: function(object) + { + if (object instanceof CSSStyleSheet) + return 1; + else if (object instanceof CSSStyleRule) + return 2; + else if (object instanceof CSSStyleDeclaration) + return 2; + else if (object instanceof SourceLink && object.type == "css" && reCSS.test(object.href)) + return 2; + else + return 0; + }, + + updateLocation: function(styleSheet) + { + if (!styleSheet) + return; + if (styleSheet.editStyleSheet) + styleSheet = styleSheet.editStyleSheet.sheet; + + // if it is a restricted stylesheet, show the warning message and abort the update process + if (styleSheet.restricted) + { + FirebugReps.Warning.tag.replace({object: "AccessRestricted"}, this.panelNode); + + // TODO: xxxpedro remove when there the external resource problem is fixed + externalStyleSheetWarning.tag.append({ + object: "The stylesheet could not be loaded due to access restrictions. ", + link: "more...", + href: "http://getfirebug.com/wiki/index.php/Firebug_Lite_FAQ#I_keep_seeing_.22Access_to_restricted_URI_denied.22" + }, this.panelNode); + + return; + } + + var rules = this.getStyleSheetRules(this.context, styleSheet); + + var result; + if (rules.length) + result = this.template.tag.replace({rules: rules}, this.panelNode); + else + result = FirebugReps.Warning.tag.replace({object: "EmptyStyleSheet"}, this.panelNode); + + // TODO: xxxpedro need to fix showToolbarButtons function + //this.showToolbarButtons("fbCSSButtons", !isSystemStyleSheet(this.location)); + + //dispatch([Firebug.A11yModel], 'onCSSRulesAdded', [this, this.panelNode]); + }, + + updateSelection: function(object) + { + this.selection = null; + + if (object instanceof CSSStyleDeclaration) { + object = object.parentRule; + } + + if (object instanceof CSSStyleRule) + { + this.navigate(object.parentStyleSheet); + this.highlightRule(object); + } + else if (object instanceof CSSStyleSheet) + { + this.navigate(object); + } + else if (object instanceof SourceLink) + { + try + { + var sourceLink = object; + + var sourceFile = getSourceFileByHref(sourceLink.href, this.context); + if (sourceFile) + { + clearNode(this.panelNode); // replace rendered stylesheets + this.showSourceFile(sourceFile); + + var lineNo = object.line; + if (lineNo) + this.scrollToLine(lineNo, this.jumpHighlightFactory(lineNo, this.context)); + } + else // XXXjjb we should not be taking this path + { + var stylesheet = getStyleSheetByHref(sourceLink.href, this.context); + if (stylesheet) + this.navigate(stylesheet); + else + { + if (FBTrace.DBG_CSS) + FBTrace.sysout("css.updateSelection no sourceFile for "+sourceLink.href, sourceLink); + } + } + } + catch(exc) { + if (FBTrace.DBG_CSS) + FBTrace.sysout("css.upDateSelection FAILS "+exc, exc); + } + } + }, + + updateOption: function(name, value) + { + if (name == "expandShorthandProps") + this.refresh(); + }, + + getLocationList: function() + { + var styleSheets = getAllStyleSheets(this.context); + return styleSheets; + }, + + getOptionsMenuItems: function() + { + return [ + {label: "Expand Shorthand Properties", type: "checkbox", checked: Firebug.expandShorthandProps, + command: bindFixed(Firebug.togglePref, Firebug, "expandShorthandProps") }, + "-", + {label: "Refresh", command: bind(this.refresh, this) } + ]; + }, + + getContextMenuItems: function(style, target) + { + var items = []; + + if (this.infoTipType == "color") + { + items.push( + {label: "CopyColor", + command: bindFixed(copyToClipboard, FBL, this.infoTipObject) } + ); + } + else if (this.infoTipType == "image") + { + items.push( + {label: "CopyImageLocation", + command: bindFixed(copyToClipboard, FBL, this.infoTipObject) }, + {label: "OpenImageInNewTab", + command: bindFixed(openNewTab, FBL, this.infoTipObject) } + ); + } + + ///if (this.selection instanceof Element) + if (isElement(this.selection)) + { + items.push( + //"-", + {label: "EditStyle", + command: bindFixed(this.editElementStyle, this) } + ); + } + else if (!isSystemStyleSheet(this.selection)) + { + items.push( + //"-", + {label: "NewRule", + command: bindFixed(this.insertRule, this, target) } + ); + } + + var cssRule = getAncestorByClass(target, "cssRule"); + if (cssRule && hasClass(cssRule, "cssEditableRule")) + { + items.push( + "-", + {label: "NewProp", + command: bindFixed(this.insertPropertyRow, this, target) } + ); + + var propRow = getAncestorByClass(target, "cssProp"); + if (propRow) + { + var propName = getChildByClass(propRow, "cssPropName")[textContent]; + var isDisabled = hasClass(propRow, "disabledStyle"); + + items.push( + {label: $STRF("EditProp", [propName]), nol10n: true, + command: bindFixed(this.editPropertyRow, this, propRow) }, + {label: $STRF("DeleteProp", [propName]), nol10n: true, + command: bindFixed(this.deletePropertyRow, this, propRow) }, + {label: $STRF("DisableProp", [propName]), nol10n: true, + type: "checkbox", checked: isDisabled, + command: bindFixed(this.disablePropertyRow, this, propRow) } + ); + } + } + + items.push( + "-", + {label: "Refresh", command: bind(this.refresh, this) } + ); + + return items; + }, + + browseObject: function(object) + { + if (this.infoTipType == "image") + { + openNewTab(this.infoTipObject); + return true; + } + }, + + showInfoTip: function(infoTip, target, x, y) + { + var propValue = getAncestorByClass(target, "cssPropValue"); + if (propValue) + { + var offset = getClientOffset(propValue); + var offsetX = x-offset.x; + + var text = propValue[textContent]; + var charWidth = propValue.offsetWidth/text.length; + var charOffset = Math.floor(offsetX/charWidth); + + var cssValue = parseCSSValue(text, charOffset); + if (cssValue) + { + if (cssValue.value == this.infoTipValue) + return true; + + this.infoTipValue = cssValue.value; + + if (cssValue.type == "rgb" || (!cssValue.type && isColorKeyword(cssValue.value))) + { + this.infoTipType = "color"; + this.infoTipObject = cssValue.value; + + return Firebug.InfoTip.populateColorInfoTip(infoTip, cssValue.value); + } + else if (cssValue.type == "url") + { + ///var propNameNode = target.parentNode.getElementsByClassName("cssPropName").item(0); + var propNameNode = getElementByClass(target.parentNode, "cssPropName"); + if (propNameNode && isImageRule(propNameNode[textContent])) + { + var rule = Firebug.getRepObject(target); + var baseURL = this.getStylesheetURL(rule); + var relURL = parseURLValue(cssValue.value); + var absURL = isDataURL(relURL) ? relURL:absoluteURL(relURL, baseURL); + var repeat = parseRepeatValue(text); + + this.infoTipType = "image"; + this.infoTipObject = absURL; + + return Firebug.InfoTip.populateImageInfoTip(infoTip, absURL, repeat); + } + } + } + } + + delete this.infoTipType; + delete this.infoTipValue; + delete this.infoTipObject; + }, + + getEditor: function(target, value) + { + if (target == this.panelNode + || hasClass(target, "cssSelector") || hasClass(target, "cssRule") + || hasClass(target, "cssSheet")) + { + if (!this.ruleEditor) + this.ruleEditor = new CSSRuleEditor(this.document); + + return this.ruleEditor; + } + else + { + if (!this.editor) + this.editor = new CSSEditor(this.document); + + return this.editor; + } + }, + + getDefaultLocation: function() + { + try + { + var styleSheets = this.context.window.document.styleSheets; + if (styleSheets.length) + { + var sheet = styleSheets[0]; + return (Firebug.filterSystemURLs && isSystemURL(getURLForStyleSheet(sheet))) ? null : sheet; + } + } + catch (exc) + { + if (FBTrace.DBG_LOCATIONS) + FBTrace.sysout("css.getDefaultLocation FAILS "+exc, exc); + } + }, + + getObjectDescription: function(styleSheet) + { + var url = getURLForStyleSheet(styleSheet); + var instance = getInstanceForStyleSheet(styleSheet); + + var baseDescription = splitURLBase(url); + if (instance) { + baseDescription.name = baseDescription.name + " #" + (instance + 1); + } + return baseDescription; + }, + + search: function(text, reverse) + { + var curDoc = this.searchCurrentDoc(!Firebug.searchGlobal, text, reverse); + if (!curDoc && Firebug.searchGlobal) + { + return this.searchOtherDocs(text, reverse); + } + return curDoc; + }, + + searchOtherDocs: function(text, reverse) + { + var scanRE = Firebug.Search.getTestingRegex(text); + function scanDoc(styleSheet) { + // we don't care about reverse here as we are just looking for existence, + // if we do have a result we will handle the reverse logic on display + for (var i = 0; i < styleSheet.cssRules.length; i++) + { + if (scanRE.test(styleSheet.cssRules[i].cssText)) + { + return true; + } + } + } + + if (this.navigateToNextDocument(scanDoc, reverse)) + { + return this.searchCurrentDoc(true, text, reverse); + } + }, + + searchCurrentDoc: function(wrapSearch, text, reverse) + { + if (!text) + { + delete this.currentSearch; + return false; + } + + var row; + if (this.currentSearch && text == this.currentSearch.text) + { + row = this.currentSearch.findNext(wrapSearch, false, reverse, Firebug.Search.isCaseSensitive(text)); + } + else + { + if (this.editing) + { + this.currentSearch = new TextSearch(this.stylesheetEditor.box); + row = this.currentSearch.find(text, reverse, Firebug.Search.isCaseSensitive(text)); + + if (row) + { + var sel = this.document.defaultView.getSelection(); + sel.removeAllRanges(); + sel.addRange(this.currentSearch.range); + scrollSelectionIntoView(this); + return true; + } + else + return false; + } + else + { + function findRow(node) { return node.nodeType == 1 ? node : node.parentNode; } + this.currentSearch = new TextSearch(this.panelNode, findRow); + row = this.currentSearch.find(text, reverse, Firebug.Search.isCaseSensitive(text)); + } + } + + if (row) + { + this.document.defaultView.getSelection().selectAllChildren(row); + scrollIntoCenterView(row, this.panelNode); + dispatch([Firebug.A11yModel], 'onCSSSearchMatchFound', [this, text, row]); + return true; + } + else + { + dispatch([Firebug.A11yModel], 'onCSSSearchMatchFound', [this, text, null]); + return false; + } + }, + + getSearchOptionsMenuItems: function() + { + return [ + Firebug.Search.searchOptionMenu("search.Case_Sensitive", "searchCaseSensitive"), + Firebug.Search.searchOptionMenu("search.Multiple_Files", "searchGlobal") + ]; + } +}); +/**/ +// ************************************************************************************************ + +function CSSElementPanel() {} + +CSSElementPanel.prototype = extend(Firebug.CSSStyleSheetPanel.prototype, +{ + template: domplate( + { + cascadedTag: + DIV({"class": "a11yCSSView", role : 'presentation'}, + DIV({role : 'list', 'aria-label' : $STR('aria.labels.style rules') }, + FOR("rule", "$rules", + TAG("$ruleTag", {rule: "$rule"}) + ) + ), + DIV({role : "list", 'aria-label' :$STR('aria.labels.inherited style rules')}, + FOR("section", "$inherited", + H1({"class": "cssInheritHeader groupHeader focusRow", role : 'listitem' }, + SPAN({"class": "cssInheritLabel"}, "$inheritLabel"), + TAG(FirebugReps.Element.shortTag, {object: "$section.element"}) + ), + DIV({role : 'group'}, + FOR("rule", "$section.rules", + TAG("$ruleTag", {rule: "$rule"}) + ) + ) + ) + ) + ), + + ruleTag: + isIE ? + // IE needs the sourceLink first, otherwise it will be rendered outside the panel + DIV({"class": "cssElementRuleContainer"}, + TAG(FirebugReps.SourceLink.tag, {object: "$rule.sourceLink"}), + TAG(CSSStyleRuleTag.tag, {rule: "$rule"}) + ) + : + // other browsers need the sourceLink last, otherwise it will cause an extra space + // before the rule representation + DIV({"class": "cssElementRuleContainer"}, + TAG(CSSStyleRuleTag.tag, {rule: "$rule"}), + TAG(FirebugReps.SourceLink.tag, {object: "$rule.sourceLink"}) + ) + }), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + updateCascadeView: function(element) + { + //dispatch([Firebug.A11yModel], 'onBeforeCSSRulesAdded', [this]); + var rules = [], sections = [], usedProps = {}; + this.getInheritedRules(element, sections, usedProps); + this.getElementRules(element, rules, usedProps); + + if (rules.length || sections.length) + { + var inheritLabel = "Inherited from"; // $STR("InheritedFrom"); + var result = this.template.cascadedTag.replace({rules: rules, inherited: sections, + inheritLabel: inheritLabel}, this.panelNode); + //dispatch([Firebug.A11yModel], 'onCSSRulesAdded', [this, result]); + } + else + { + var result = FirebugReps.Warning.tag.replace({object: "EmptyElementCSS"}, this.panelNode); + //dispatch([Firebug.A11yModel], 'onCSSRulesAdded', [this, result]); + } + + // TODO: xxxpedro remove when there the external resource problem is fixed + if (externalStyleSheetURLs.length > 0) + externalStyleSheetWarning.tag.append({ + object: "The results here may be inaccurate because some " + + "stylesheets could not be loaded due to access restrictions. ", + link: "more...", + href: "http://getfirebug.com/wiki/index.php/Firebug_Lite_FAQ#I_keep_seeing_.22This_element_has_no_style_rules.22" + }, this.panelNode); + }, + + getStylesheetURL: function(rule) + { + // if the parentStyleSheet.href is null, CSS std says its inline style. + // TODO: xxxpedro IE doesn't have rule.parentStyleSheet so we must fall back to the doc.location + if (rule && rule.parentStyleSheet && rule.parentStyleSheet.href) + return rule.parentStyleSheet.href; + else + return this.selection.ownerDocument.location.href; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getInheritedRules: function(element, sections, usedProps) + { + var parent = element.parentNode; + if (parent && parent.nodeType == 1) + { + this.getInheritedRules(parent, sections, usedProps); + + var rules = []; + this.getElementRules(parent, rules, usedProps, true); + + if (rules.length) + sections.splice(0, 0, {element: parent, rules: rules}); + } + }, + + getElementRules: function(element, rules, usedProps, inheritMode) + { + var inspectedRules, displayedRules = {}; + + // TODO: xxxpedro remove document specificity issue + //var eid = ElementCache(element); + //inspectedRules = ElementCSSRulesMap[eid]; + + inspectedRules = getElementCSSRules(element); + + if (inspectedRules) + { + for (var i = 0, length=inspectedRules.length; i < length; ++i) + { + var ruleId = inspectedRules[i]; + var ruleData = CSSRuleMap[ruleId]; + var rule = ruleData.rule; + + var ssid = ruleData.styleSheetId; + var parentStyleSheet = StyleSheetCache.get(ssid); + + var href = parentStyleSheet.externalURL ? parentStyleSheet.externalURL : parentStyleSheet.href; // Null means inline + + var instance = null; + //var instance = getInstanceForStyleSheet(rule.parentStyleSheet, element.ownerDocument); + + var isSystemSheet = false; + //var isSystemSheet = isSystemStyleSheet(rule.parentStyleSheet); + + if (!Firebug.showUserAgentCSS && isSystemSheet) // This removes user agent rules + continue; + + if (!href) + href = element.ownerDocument.location.href; // http://code.google.com/p/fbug/issues/detail?id=452 + + var props = this.getRuleProperties(this.context, rule, inheritMode); + if (inheritMode && !props.length) + continue; + + // + //var line = domUtils.getRuleLine(rule); + var line; + + var ruleId = rule.selectorText+"/"+line; + var sourceLink = new SourceLink(href, line, "css", rule, instance); + + this.markOverridenProps(props, usedProps, inheritMode); + + rules.splice(0, 0, {rule: rule, id: ruleId, + selector: ruleData.selector, sourceLink: sourceLink, + props: props, inherited: inheritMode, + isSystemSheet: isSystemSheet}); + } + } + + if (element.style) + this.getStyleProperties(element, rules, usedProps, inheritMode); + + if (FBTrace.DBG_CSS) + FBTrace.sysout("getElementRules "+rules.length+" rules for "+getElementXPath(element), rules); + }, + /* + getElementRules: function(element, rules, usedProps, inheritMode) + { + var inspectedRules, displayedRules = {}; + try + { + inspectedRules = domUtils ? domUtils.getCSSStyleRules(element) : null; + } catch (exc) {} + + if (inspectedRules) + { + for (var i = 0; i < inspectedRules.Count(); ++i) + { + var rule = QI(inspectedRules.GetElementAt(i), nsIDOMCSSStyleRule); + + var href = rule.parentStyleSheet.href; // Null means inline + + var instance = getInstanceForStyleSheet(rule.parentStyleSheet, element.ownerDocument); + + var isSystemSheet = isSystemStyleSheet(rule.parentStyleSheet); + if (!Firebug.showUserAgentCSS && isSystemSheet) // This removes user agent rules + continue; + if (!href) + href = element.ownerDocument.location.href; // http://code.google.com/p/fbug/issues/detail?id=452 + + var props = this.getRuleProperties(this.context, rule, inheritMode); + if (inheritMode && !props.length) + continue; + + var line = domUtils.getRuleLine(rule); + var ruleId = rule.selectorText+"/"+line; + var sourceLink = new SourceLink(href, line, "css", rule, instance); + + this.markOverridenProps(props, usedProps, inheritMode); + + rules.splice(0, 0, {rule: rule, id: ruleId, + selector: rule.selectorText, sourceLink: sourceLink, + props: props, inherited: inheritMode, + isSystemSheet: isSystemSheet}); + } + } + + if (element.style) + this.getStyleProperties(element, rules, usedProps, inheritMode); + + if (FBTrace.DBG_CSS) + FBTrace.sysout("getElementRules "+rules.length+" rules for "+getElementXPath(element), rules); + }, + /**/ + markOverridenProps: function(props, usedProps, inheritMode) + { + for (var i = 0; i < props.length; ++i) + { + var prop = props[i]; + if ( usedProps.hasOwnProperty(prop.name) ) + { + var deadProps = usedProps[prop.name]; // all previous occurrences of this property + for (var j = 0; j < deadProps.length; ++j) + { + var deadProp = deadProps[j]; + if (!deadProp.disabled && !deadProp.wasInherited && deadProp.important && !prop.important) + prop.overridden = true; // new occurrence overridden + else if (!prop.disabled) + deadProp.overridden = true; // previous occurrences overridden + } + } + else + usedProps[prop.name] = []; + + prop.wasInherited = inheritMode ? true : false; + usedProps[prop.name].push(prop); // all occurrences of a property seen so far, by name + } + }, + + getStyleProperties: function(element, rules, usedProps, inheritMode) + { + var props = this.parseCSSProps(element.style, inheritMode); + this.addOldProperties(this.context, getElementXPath(element), inheritMode, props); + + sortProperties(props); + this.markOverridenProps(props, usedProps, inheritMode); + + if (props.length) + rules.splice(0, 0, + {rule: element, id: getElementXPath(element), + selector: "element.style", props: props, inherited: inheritMode}); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "css", + title: "Style", + parentPanel: "HTML", + order: 0, + + initialize: function() + { + this.context = Firebug.chrome; // TODO: xxxpedro css2 + this.document = Firebug.chrome.document; // TODO: xxxpedro css2 + + Firebug.CSSStyleSheetPanel.prototype.initialize.apply(this, arguments); + + // TODO: xxxpedro css2 + var selection = ElementCache.get(FirebugChrome.selectedHTMLElementId); + if (selection) + this.select(selection, true); + + //this.updateCascadeView(document.getElementsByTagName("h1")[0]); + //this.updateCascadeView(document.getElementById("build")); + + /* + this.onStateChange = bindFixed(this.contentStateCheck, this); + this.onHoverChange = bindFixed(this.contentStateCheck, this, STATE_HOVER); + this.onActiveChange = bindFixed(this.contentStateCheck, this, STATE_ACTIVE); + /**/ + }, + + ishow: function(state) + { + }, + + watchWindow: function(win) + { + if (domUtils) + { + // Normally these would not be required, but in order to update after the state is set + // using the options menu we need to monitor these global events as well + var doc = win.document; + ///addEvent(doc, "mouseover", this.onHoverChange); + ///addEvent(doc, "mousedown", this.onActiveChange); + } + }, + unwatchWindow: function(win) + { + var doc = win.document; + ///removeEvent(doc, "mouseover", this.onHoverChange); + ///removeEvent(doc, "mousedown", this.onActiveChange); + + if (isAncestor(this.stateChangeEl, doc)) + { + this.removeStateChangeHandlers(); + } + }, + + supportsObject: function(object) + { + return object instanceof Element ? 1 : 0; + }, + + updateView: function(element) + { + this.updateCascadeView(element); + if (domUtils) + { + this.contentState = safeGetContentState(element); + this.addStateChangeHandlers(element); + } + }, + + updateSelection: function(element) + { + if ( !instanceOf(element , "Element") ) // html supports SourceLink + return; + + if (sothinkInstalled) + { + FirebugReps.Warning.tag.replace({object: "SothinkWarning"}, this.panelNode); + return; + } + + /* + if (!domUtils) + { + FirebugReps.Warning.tag.replace({object: "DOMInspectorWarning"}, this.panelNode); + return; + } + /**/ + + if (!element) + return; + + this.updateView(element); + }, + + updateOption: function(name, value) + { + if (name == "showUserAgentCSS" || name == "expandShorthandProps") + this.refresh(); + }, + + getOptionsMenuItems: function() + { + var ret = [ + {label: "Show User Agent CSS", type: "checkbox", checked: Firebug.showUserAgentCSS, + command: bindFixed(Firebug.togglePref, Firebug, "showUserAgentCSS") }, + {label: "Expand Shorthand Properties", type: "checkbox", checked: Firebug.expandShorthandProps, + command: bindFixed(Firebug.togglePref, Firebug, "expandShorthandProps") } + ]; + if (domUtils && this.selection) + { + var state = safeGetContentState(this.selection); + + ret.push("-"); + ret.push({label: ":active", type: "checkbox", checked: state & STATE_ACTIVE, + command: bindFixed(this.updateContentState, this, STATE_ACTIVE, state & STATE_ACTIVE)}); + ret.push({label: ":hover", type: "checkbox", checked: state & STATE_HOVER, + command: bindFixed(this.updateContentState, this, STATE_HOVER, state & STATE_HOVER)}); + } + return ret; + }, + + updateContentState: function(state, remove) + { + domUtils.setContentState(remove ? this.selection.ownerDocument.documentElement : this.selection, state); + this.refresh(); + }, + + addStateChangeHandlers: function(el) + { + this.removeStateChangeHandlers(); + + /* + addEvent(el, "focus", this.onStateChange); + addEvent(el, "blur", this.onStateChange); + addEvent(el, "mouseup", this.onStateChange); + addEvent(el, "mousedown", this.onStateChange); + addEvent(el, "mouseover", this.onStateChange); + addEvent(el, "mouseout", this.onStateChange); + /**/ + + this.stateChangeEl = el; + }, + + removeStateChangeHandlers: function() + { + var sel = this.stateChangeEl; + if (sel) + { + /* + removeEvent(sel, "focus", this.onStateChange); + removeEvent(sel, "blur", this.onStateChange); + removeEvent(sel, "mouseup", this.onStateChange); + removeEvent(sel, "mousedown", this.onStateChange); + removeEvent(sel, "mouseover", this.onStateChange); + removeEvent(sel, "mouseout", this.onStateChange); + /**/ + } + }, + + contentStateCheck: function(state) + { + if (!state || this.contentState & state) + { + var timeoutRunner = bindFixed(function() + { + var newState = safeGetContentState(this.selection); + if (newState != this.contentState) + { + this.context.invalidatePanels(this.name); + } + }, this); + + // Delay exec until after the event has processed and the state has been updated + setTimeout(timeoutRunner, 0); + } + } +}); + +function safeGetContentState(selection) +{ + try + { + return domUtils.getContentState(selection); + } + catch (e) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("css.safeGetContentState; EXCEPTION", e); + } +} + +// ************************************************************************************************ + +function CSSComputedElementPanel() {} + +CSSComputedElementPanel.prototype = extend(CSSElementPanel.prototype, +{ + template: domplate( + { + computedTag: + DIV({"class": "a11yCSSView", role : "list", "aria-label" : $STR('aria.labels.computed styles')}, + FOR("group", "$groups", + H1({"class": "cssInheritHeader groupHeader focusRow", role : "listitem"}, + SPAN({"class": "cssInheritLabel"}, "$group.title") + ), + TABLE({width: "100%", role : 'group'}, + TBODY({role : 'presentation'}, + FOR("prop", "$group.props", + TR({"class": 'focusRow computedStyleRow', role : 'listitem'}, + TD({"class": "stylePropName", role : 'presentation'}, "$prop.name"), + TD({"class": "stylePropValue", role : 'presentation'}, "$prop.value") + ) + ) + ) + ) + ) + ) + }), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + updateComputedView: function(element) + { + var win = isIE ? + element.ownerDocument.parentWindow : + element.ownerDocument.defaultView; + + var style = isIE ? + element.currentStyle : + win.getComputedStyle(element, ""); + + var groups = []; + + for (var groupName in styleGroups) + { + // TODO: xxxpedro i18n $STR + //var title = $STR("StyleGroup-" + groupName); + var title = styleGroupTitles[groupName]; + var group = {title: title, props: []}; + groups.push(group); + + var props = styleGroups[groupName]; + for (var i = 0; i < props.length; ++i) + { + var propName = props[i]; + var propValue = style.getPropertyValue ? + style.getPropertyValue(propName) : + ""+style[toCamelCase(propName)]; + + if (propValue === undefined || propValue === null) + continue; + + propValue = stripUnits(rgbToHex(propValue)); + if (propValue) + group.props.push({name: propName, value: propValue}); + } + } + + var result = this.template.computedTag.replace({groups: groups}, this.panelNode); + //dispatch([Firebug.A11yModel], 'onCSSRulesAdded', [this, result]); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "computed", + title: "Computed", + parentPanel: "HTML", + order: 1, + + updateView: function(element) + { + this.updateComputedView(element); + }, + + getOptionsMenuItems: function() + { + return [ + {label: "Refresh", command: bind(this.refresh, this) } + ]; + } +}); + +// ************************************************************************************************ +// CSSEditor + +function CSSEditor(doc) +{ + this.initializeInline(doc); +} + +CSSEditor.prototype = domplate(Firebug.InlineEditor.prototype, +{ + insertNewRow: function(target, insertWhere) + { + var rule = Firebug.getRepObject(target); + var emptyProp = + { + // TODO: xxxpedro - uses charCode(255) to force the element being rendered, + // allowing webkit to get the correct position of the property name "span", + // when inserting a new CSS rule? + name: "", + value: "", + important: "" + }; + + if (insertWhere == "before") + return CSSPropTag.tag.insertBefore({prop: emptyProp, rule: rule}, target); + else + return CSSPropTag.tag.insertAfter({prop: emptyProp, rule: rule}, target); + }, + + saveEdit: function(target, value, previousValue) + { + // We need to check the value first in order to avoid a problem in IE8 + // See Issue 3038: Empty (null) styles when adding CSS styles in Firebug Lite + if (!value) return; + + target.innerHTML = escapeForCss(value); + + var row = getAncestorByClass(target, "cssProp"); + if (hasClass(row, "disabledStyle")) + toggleClass(row, "disabledStyle"); + + var rule = Firebug.getRepObject(target); + + if (hasClass(target, "cssPropName")) + { + if (value && previousValue != value) // name of property has changed. + { + var propValue = getChildByClass(row, "cssPropValue")[textContent]; + var parsedValue = parsePriority(propValue); + + if (propValue && propValue != "undefined") { + if (FBTrace.DBG_CSS) + FBTrace.sysout("CSSEditor.saveEdit : "+previousValue+"->"+value+" = "+propValue+"\n"); + if (previousValue) + Firebug.CSSModule.removeProperty(rule, previousValue); + Firebug.CSSModule.setProperty(rule, value, parsedValue.value, parsedValue.priority); + } + } + else if (!value) // name of the property has been deleted, so remove the property. + Firebug.CSSModule.removeProperty(rule, previousValue); + } + else if (getAncestorByClass(target, "cssPropValue")) + { + var propName = getChildByClass(row, "cssPropName")[textContent]; + var propValue = getChildByClass(row, "cssPropValue")[textContent]; + + if (FBTrace.DBG_CSS) + { + FBTrace.sysout("CSSEditor.saveEdit propName=propValue: "+propName +" = "+propValue+"\n"); + // FBTrace.sysout("CSSEditor.saveEdit BEFORE style:",style); + } + + if (value && value != "null") + { + var parsedValue = parsePriority(value); + Firebug.CSSModule.setProperty(rule, propName, parsedValue.value, parsedValue.priority); + } + else if (previousValue && previousValue != "null") + Firebug.CSSModule.removeProperty(rule, propName); + } + + this.panel.markChange(this.panel.name == "stylesheet"); + }, + + advanceToNext: function(target, charCode) + { + if (charCode == 58 /*":"*/ && hasClass(target, "cssPropName")) + return true; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getAutoCompleteRange: function(value, offset) + { + if (hasClass(this.target, "cssPropName")) + return {start: 0, end: value.length-1}; + else + return parseCSSValue(value, offset); + }, + + getAutoCompleteList: function(preExpr, expr, postExpr) + { + if (hasClass(this.target, "cssPropName")) + { + return getCSSPropertyNames(); + } + else + { + var row = getAncestorByClass(this.target, "cssProp"); + var propName = getChildByClass(row, "cssPropName")[textContent]; + return getCSSKeywordsByProperty(propName); + } + } +}); + +//************************************************************************************************ +//CSSRuleEditor + +function CSSRuleEditor(doc) +{ + this.initializeInline(doc); + this.completeAsYouType = false; +} +CSSRuleEditor.uniquifier = 0; +CSSRuleEditor.prototype = domplate(Firebug.InlineEditor.prototype, +{ + insertNewRow: function(target, insertWhere) + { + var emptyRule = { + selector: "", + id: "", + props: [], + isSelectorEditable: true + }; + + if (insertWhere == "before") + return CSSStyleRuleTag.tag.insertBefore({rule: emptyRule}, target); + else + return CSSStyleRuleTag.tag.insertAfter({rule: emptyRule}, target); + }, + + saveEdit: function(target, value, previousValue) + { + if (FBTrace.DBG_CSS) + FBTrace.sysout("CSSRuleEditor.saveEdit: '" + value + "' '" + previousValue + "'", target); + + target.innerHTML = escapeForCss(value); + + if (value === previousValue) return; + + var row = getAncestorByClass(target, "cssRule"); + var styleSheet = this.panel.location; + styleSheet = styleSheet.editStyleSheet ? styleSheet.editStyleSheet.sheet : styleSheet; + + var cssRules = styleSheet.cssRules; + var rule = Firebug.getRepObject(target), oldRule = rule; + var ruleIndex = cssRules.length; + if (rule || Firebug.getRepObject(row.nextSibling)) + { + var searchRule = rule || Firebug.getRepObject(row.nextSibling); + for (ruleIndex=0; ruleIndex b.name ? 1 : -1; + }); +} + +function getTopmostRuleLine(panelNode) +{ + for (var child = panelNode.firstChild; child; child = child.nextSibling) + { + if (child.offsetTop+child.offsetHeight > panelNode.scrollTop) + { + var rule = child.repObject; + if (rule) + return { + line: domUtils.getRuleLine(rule), + offset: panelNode.scrollTop-child.offsetTop + }; + } + } + return 0; +} + +function getStyleSheetCSS(sheet, context) +{ + if (sheet.ownerNode instanceof HTMLStyleElement) + return sheet.ownerNode.innerHTML; + else + return context.sourceCache.load(sheet.href).join(""); +} + +function getStyleSheetOwnerNode(sheet) { + for (; sheet && !sheet.ownerNode; sheet = sheet.parentStyleSheet); + + return sheet.ownerNode; +} + +function scrollSelectionIntoView(panel) +{ + var selCon = getSelectionController(panel); + selCon.scrollSelectionIntoView( + nsISelectionController.SELECTION_NORMAL, + nsISelectionController.SELECTION_FOCUS_REGION, true); +} + +function getSelectionController(panel) +{ + var browser = Firebug.chrome.getPanelBrowser(panel); + return browser.docShell.QueryInterface(nsIInterfaceRequestor) + .getInterface(nsISelectionDisplay) + .QueryInterface(nsISelectionController); +} + +// ************************************************************************************************ + +Firebug.registerModule(Firebug.CSSModule); +Firebug.registerPanel(Firebug.CSSStyleSheetPanel); +Firebug.registerPanel(CSSElementPanel); +Firebug.registerPanel(CSSComputedElementPanel); + +// ************************************************************************************************ + +}}); + + +/* 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 (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; +}; + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var ElementCache = Firebug.Lite.Cache.Element; + +var insertSliceSize = 18; +var insertInterval = 40; + +var ignoreVars = +{ + "__firebug__": 1, + "eval": 1, + + // We are forced to ignore Java-related variables, because + // trying to access them causes browser freeze + "java": 1, + "sun": 1, + "Packages": 1, + "JavaArray": 1, + "JavaMember": 1, + "JavaObject": 1, + "JavaClass": 1, + "JavaPackage": 1, + "_firebug": 1, + "_FirebugConsole": 1, + "_FirebugCommandLine": 1 +}; + +if (Firebug.ignoreFirebugElements) + ignoreVars[Firebug.Lite.Cache.ID] = 1; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var memberPanelRep = + isIE6 ? + {"class": "memberLabel $member.type\\Label", href: "javacript:void(0)"} + : + {"class": "memberLabel $member.type\\Label"}; + +var RowTag = + TR({"class": "memberRow $member.open $member.type\\Row", $hasChildren: "$member.hasChildren", role : 'presentation', + level: "$member.level"}, + TD({"class": "memberLabelCell", style: "padding-left: $member.indent\\px", role : 'presentation'}, + A(memberPanelRep, + SPAN({}, "$member.name") + ) + ), + TD({"class": "memberValueCell", role : 'presentation'}, + TAG("$member.tag", {object: "$member.value"}) + ) + ); + +var WatchRowTag = + TR({"class": "watchNewRow", level: 0}, + TD({"class": "watchEditCell", colspan: 2}, + DIV({"class": "watchEditBox a11yFocusNoTab", role: "button", 'tabindex' : '0', + 'aria-label' : $STR('press enter to add new watch expression')}, + $STR("NewWatch") + ) + ) + ); + +var SizerRow = + TR({role : 'presentation'}, + TD({width: "30%"}), + TD({width: "70%"}) + ); + +var domTableClass = isIElt8 ? "domTable domTableIE" : "domTable"; +var DirTablePlate = domplate(Firebug.Rep, +{ + tag: + TABLE({"class": domTableClass, cellpadding: 0, cellspacing: 0, onclick: "$onClick", role :"tree"}, + TBODY({role: 'presentation'}, + SizerRow, + FOR("member", "$object|memberIterator", RowTag) + ) + ), + + watchTag: + TABLE({"class": domTableClass, cellpadding: 0, cellspacing: 0, + _toggles: "$toggles", _domPanel: "$domPanel", onclick: "$onClick", role : 'tree'}, + TBODY({role : 'presentation'}, + SizerRow, + WatchRowTag + ) + ), + + tableTag: + TABLE({"class": domTableClass, cellpadding: 0, cellspacing: 0, + _toggles: "$toggles", _domPanel: "$domPanel", onclick: "$onClick", role : 'tree'}, + TBODY({role : 'presentation'}, + SizerRow + ) + ), + + rowTag: + FOR("member", "$members", RowTag), + + memberIterator: function(object, level) + { + return getMembers(object, level); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + onClick: function(event) + { + if (!isLeftClick(event)) + return; + + var target = event.target || event.srcElement; + + var row = getAncestorByClass(target, "memberRow"); + var label = getAncestorByClass(target, "memberLabel"); + if (label && hasClass(row, "hasChildren")) + { + var row = label.parentNode.parentNode; + this.toggleRow(row); + } + else + { + var object = Firebug.getRepObject(target); + if (typeof(object) == "function") + { + Firebug.chrome.select(object, "script"); + cancelEvent(event); + } + else if (event.detail == 2 && !object) + { + var panel = row.parentNode.parentNode.domPanel; + if (panel) + { + var rowValue = panel.getRowPropertyValue(row); + if (typeof(rowValue) == "boolean") + panel.setPropertyValue(row, !rowValue); + else + panel.editProperty(row); + + cancelEvent(event); + } + } + } + + return false; + }, + + toggleRow: function(row) + { + var level = parseInt(row.getAttribute("level")); + var toggles = row.parentNode.parentNode.toggles; + + if (hasClass(row, "opened")) + { + removeClass(row, "opened"); + + if (toggles) + { + var path = getPath(row); + + // Remove the path from the toggle tree + for (var i = 0; i < path.length; ++i) + { + if (i == path.length-1) + delete toggles[path[i]]; + else + toggles = toggles[path[i]]; + } + } + + var rowTag = this.rowTag; + var tbody = row.parentNode; + + setTimeout(function() + { + for (var firstRow = row.nextSibling; firstRow; firstRow = row.nextSibling) + { + if (parseInt(firstRow.getAttribute("level")) <= level) + break; + + tbody.removeChild(firstRow); + } + }, row.insertTimeout ? row.insertTimeout : 0); + } + else + { + setClass(row, "opened"); + + if (toggles) + { + var path = getPath(row); + + // Mark the path in the toggle tree + for (var i = 0; i < path.length; ++i) + { + var name = path[i]; + if (toggles.hasOwnProperty(name)) + toggles = toggles[name]; + else + toggles = toggles[name] = {}; + } + } + + var value = row.lastChild.firstChild.repObject; + var members = getMembers(value, level+1); + + var rowTag = this.rowTag; + var lastRow = row; + + var delay = 0; + //var setSize = members.length; + //var rowCount = 1; + while (members.length) + { + with({slice: members.splice(0, insertSliceSize), isLast: !members.length}) + { + setTimeout(function() + { + if (lastRow.parentNode) + { + var result = rowTag.insertRows({members: slice}, lastRow); + lastRow = result[1]; + //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [null, result, rowCount, setSize]); + //rowCount += insertSliceSize; + } + if (isLast) + row.removeAttribute("insertTimeout"); + }, delay); + } + + delay += insertInterval; + } + + row.insertTimeout = delay; + } + } +}); + + + +// ************************************************************************************************ + +Firebug.DOMBasePanel = function() {} + +Firebug.DOMBasePanel.prototype = extend(Firebug.Panel, +{ + tag: DirTablePlate.tableTag, + + getRealObject: function(object) + { + // TODO: Move this to some global location + // TODO: Unwrapping should be centralized rather than sprinkling it around ad hoc. + // TODO: We might be able to make this check more authoritative with QueryInterface. + if (!object) return object; + if (object.wrappedJSObject) return object.wrappedJSObject; + return object; + }, + + rebuild: function(update, scrollTop) + { + //dispatch([Firebug.A11yModel], 'onBeforeDomUpdateSelection', [this]); + var members = getMembers(this.selection); + expandMembers(members, this.toggles, 0, 0); + + this.showMembers(members, update, scrollTop); + + //TODO: xxxpedro statusbar + if (!this.parentPanel) + updateStatusBar(this); + }, + + showMembers: function(members, update, scrollTop) + { + // If we are still in the midst of inserting rows, cancel all pending + // insertions here - this is a big speedup when stepping in the debugger + if (this.timeouts) + { + for (var i = 0; i < this.timeouts.length; ++i) + this.context.clearTimeout(this.timeouts[i]); + delete this.timeouts; + } + + if (!members.length) + return this.showEmptyMembers(); + + var panelNode = this.panelNode; + var priorScrollTop = scrollTop == undefined ? panelNode.scrollTop : scrollTop; + + // If we are asked to "update" the current view, then build the new table + // offscreen and swap it in when it's done + var offscreen = update && panelNode.firstChild; + var dest = offscreen ? panelNode.ownerDocument : panelNode; + + var table = this.tag.replace({domPanel: this, toggles: this.toggles}, dest); + var tbody = table.lastChild; + var rowTag = DirTablePlate.rowTag; + + // Insert the first slice immediately + //var slice = members.splice(0, insertSliceSize); + //var result = rowTag.insertRows({members: slice}, tbody.lastChild); + + //var setSize = members.length; + //var rowCount = 1; + + var panel = this; + var result; + + //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [panel, result, rowCount, setSize]); + var timeouts = []; + + var delay = 0; + + // enable to measure rendering performance + var renderStart = new Date().getTime(); + while (members.length) + { + with({slice: members.splice(0, insertSliceSize), isLast: !members.length}) + { + timeouts.push(this.context.setTimeout(function() + { + // TODO: xxxpedro can this be a timing error related to the + // "iteration number" approach insted of "duration time"? + // avoid error in IE8 + if (!tbody.lastChild) return; + + result = rowTag.insertRows({members: slice}, tbody.lastChild); + + //rowCount += insertSliceSize; + //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [panel, result, rowCount, setSize]); + + if ((panelNode.scrollHeight+panelNode.offsetHeight) >= priorScrollTop) + panelNode.scrollTop = priorScrollTop; + + + // enable to measure rendering performance + //if (isLast) alert(new Date().getTime() - renderStart + "ms"); + + + }, delay)); + + delay += insertInterval; + } + } + + if (offscreen) + { + timeouts.push(this.context.setTimeout(function() + { + if (panelNode.firstChild) + panelNode.replaceChild(table, panelNode.firstChild); + else + panelNode.appendChild(table); + + // Scroll back to where we were before + panelNode.scrollTop = priorScrollTop; + }, delay)); + } + else + { + timeouts.push(this.context.setTimeout(function() + { + panelNode.scrollTop = scrollTop == undefined ? 0 : scrollTop; + }, delay)); + } + this.timeouts = timeouts; + }, + + /* + // new + showMembers: function(members, update, scrollTop) + { + // If we are still in the midst of inserting rows, cancel all pending + // insertions here - this is a big speedup when stepping in the debugger + if (this.timeouts) + { + for (var i = 0; i < this.timeouts.length; ++i) + this.context.clearTimeout(this.timeouts[i]); + delete this.timeouts; + } + + if (!members.length) + return this.showEmptyMembers(); + + var panelNode = this.panelNode; + var priorScrollTop = scrollTop == undefined ? panelNode.scrollTop : scrollTop; + + // If we are asked to "update" the current view, then build the new table + // offscreen and swap it in when it's done + var offscreen = update && panelNode.firstChild; + var dest = offscreen ? panelNode.ownerDocument : panelNode; + + var table = this.tag.replace({domPanel: this, toggles: this.toggles}, dest); + var tbody = table.lastChild; + var rowTag = DirTablePlate.rowTag; + + // Insert the first slice immediately + //var slice = members.splice(0, insertSliceSize); + //var result = rowTag.insertRows({members: slice}, tbody.lastChild); + + //var setSize = members.length; + //var rowCount = 1; + + var panel = this; + var result; + + //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [panel, result, rowCount, setSize]); + var timeouts = []; + + var delay = 0; + var _insertSliceSize = insertSliceSize; + var _insertInterval = insertInterval; + + // enable to measure rendering performance + var renderStart = new Date().getTime(); + var lastSkip = renderStart, now; + + while (members.length) + { + with({slice: members.splice(0, _insertSliceSize), isLast: !members.length}) + { + var _tbody = tbody; + var _rowTag = rowTag; + var _panelNode = panelNode; + var _priorScrollTop = priorScrollTop; + + timeouts.push(this.context.setTimeout(function() + { + // TODO: xxxpedro can this be a timing error related to the + // "iteration number" approach insted of "duration time"? + // avoid error in IE8 + if (!_tbody.lastChild) return; + + result = _rowTag.insertRows({members: slice}, _tbody.lastChild); + + //rowCount += _insertSliceSize; + //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [panel, result, rowCount, setSize]); + + if ((_panelNode.scrollHeight + _panelNode.offsetHeight) >= _priorScrollTop) + _panelNode.scrollTop = _priorScrollTop; + + + // enable to measure rendering performance + //alert("gap: " + (new Date().getTime() - lastSkip)); + //lastSkip = new Date().getTime(); + + //if (isLast) alert("new: " + (new Date().getTime() - renderStart) + "ms"); + + }, delay)); + + delay += _insertInterval; + } + } + + if (offscreen) + { + timeouts.push(this.context.setTimeout(function() + { + if (panelNode.firstChild) + panelNode.replaceChild(table, panelNode.firstChild); + else + panelNode.appendChild(table); + + // Scroll back to where we were before + panelNode.scrollTop = priorScrollTop; + }, delay)); + } + else + { + timeouts.push(this.context.setTimeout(function() + { + panelNode.scrollTop = scrollTop == undefined ? 0 : scrollTop; + }, delay)); + } + this.timeouts = timeouts; + }, + /**/ + + showEmptyMembers: function() + { + FirebugReps.Warning.tag.replace({object: "NoMembersWarning"}, this.panelNode); + }, + + findPathObject: function(object) + { + var pathIndex = -1; + for (var i = 0; i < this.objectPath.length; ++i) + { + // IE needs === instead of == or otherwise some objects will + // be considered equal to different objects, returning the + // wrong index of the objectPath array + if (this.getPathObject(i) === object) + return i; + } + + return -1; + }, + + getPathObject: function(index) + { + var object = this.objectPath[index]; + + if (object instanceof Property) + return object.getObject(); + else + return object; + }, + + getRowObject: function(row) + { + var object = getRowOwnerObject(row); + return object ? object : this.selection; + }, + + getRowPropertyValue: function(row) + { + var object = this.getRowObject(row); + object = this.getRealObject(object); + if (object) + { + var propName = getRowName(row); + + if (object instanceof jsdIStackFrame) + return Firebug.Debugger.evaluate(propName, this.context); + else + return object[propName]; + } + }, + /* + copyProperty: function(row) + { + var value = this.getRowPropertyValue(row); + copyToClipboard(value); + }, + + editProperty: function(row, editValue) + { + if (hasClass(row, "watchNewRow")) + { + if (this.context.stopped) + Firebug.Editor.startEditing(row, ""); + else if (Firebug.Console.isAlwaysEnabled()) // not stopped in debugger, need command line + { + if (Firebug.CommandLine.onCommandLineFocus()) + Firebug.Editor.startEditing(row, ""); + else + row.innerHTML = $STR("warning.Command line blocked?"); + } + else + row.innerHTML = $STR("warning.Console must be enabled"); + } + else if (hasClass(row, "watchRow")) + Firebug.Editor.startEditing(row, getRowName(row)); + else + { + var object = this.getRowObject(row); + this.context.thisValue = object; + + if (!editValue) + { + var propValue = this.getRowPropertyValue(row); + + var type = typeof(propValue); + if (type == "undefined" || type == "number" || type == "boolean") + editValue = propValue; + else if (type == "string") + editValue = "\"" + escapeJS(propValue) + "\""; + else if (propValue == null) + editValue = "null"; + else if (object instanceof Window || object instanceof jsdIStackFrame) + editValue = getRowName(row); + else + editValue = "this." + getRowName(row); + } + + + Firebug.Editor.startEditing(row, editValue); + } + }, + + deleteProperty: function(row) + { + if (hasClass(row, "watchRow")) + this.deleteWatch(row); + else + { + var object = getRowOwnerObject(row); + if (!object) + object = this.selection; + object = this.getRealObject(object); + + if (object) + { + var name = getRowName(row); + try + { + delete object[name]; + } + catch (exc) + { + return; + } + + this.rebuild(true); + this.markChange(); + } + } + }, + + setPropertyValue: function(row, value) // value must be string + { + if(FBTrace.DBG_DOM) + { + FBTrace.sysout("row: "+row); + FBTrace.sysout("value: "+value+" type "+typeof(value), value); + } + + var name = getRowName(row); + if (name == "this") + return; + + var object = this.getRowObject(row); + object = this.getRealObject(object); + if (object && !(object instanceof jsdIStackFrame)) + { + // unwrappedJSObject.property = unwrappedJSObject + Firebug.CommandLine.evaluate(value, this.context, object, this.context.getGlobalScope(), + function success(result, context) + { + if (FBTrace.DBG_DOM) + FBTrace.sysout("setPropertyValue evaluate success object["+name+"]="+result+" type "+typeof(result), result); + object[name] = result; + }, + function failed(exc, context) + { + try + { + if (FBTrace.DBG_DOM) + FBTrace.sysout("setPropertyValue evaluate failed with exc:"+exc+" object["+name+"]="+value+" type "+typeof(value), exc); + // If the value doesn't parse, then just store it as a string. Some users will + // not realize they're supposed to enter a JavaScript expression and just type + // literal text + object[name] = String(value); // unwrappedJSobject.property = string + } + catch (exc) + { + return; + } + } + ); + } + else if (this.context.stopped) + { + try + { + Firebug.CommandLine.evaluate(name+"="+value, this.context); + } + catch (exc) + { + try + { + // See catch block above... + object[name] = String(value); // unwrappedJSobject.property = string + } + catch (exc) + { + return; + } + } + } + + this.rebuild(true); + this.markChange(); + }, + + highlightRow: function(row) + { + if (this.highlightedRow) + cancelClassTimed(this.highlightedRow, "jumpHighlight", this.context); + + this.highlightedRow = row; + + if (row) + setClassTimed(row, "jumpHighlight", this.context); + },/**/ + + onMouseMove: function(event) + { + var target = event.srcElement || event.target; + + var object = getAncestorByClass(target, "objectLink-element"); + object = object ? object.repObject : null; + + if(object && instanceOf(object, "Element") && object.nodeType == 1) + { + if(object != lastHighlightedObject) + { + Firebug.Inspector.drawBoxModel(object); + object = lastHighlightedObject; + } + } + else + Firebug.Inspector.hideBoxModel(); + + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + create: function() + { + // TODO: xxxpedro + this.context = Firebug.browser; + + this.objectPath = []; + this.propertyPath = []; + this.viewPath = []; + this.pathIndex = -1; + this.toggles = {}; + + Firebug.Panel.create.apply(this, arguments); + + this.panelNode.style.padding = "0 1px"; + }, + + initialize: function(){ + Firebug.Panel.initialize.apply(this, arguments); + + addEvent(this.panelNode, "mousemove", this.onMouseMove); + }, + + shutdown: function() + { + removeEvent(this.panelNode, "mousemove", this.onMouseMove); + + Firebug.Panel.shutdown.apply(this, arguments); + }, + + /* + destroy: function(state) + { + var view = this.viewPath[this.pathIndex]; + if (view && this.panelNode.scrollTop) + view.scrollTop = this.panelNode.scrollTop; + + if (this.pathIndex) + state.pathIndex = this.pathIndex; + if (this.viewPath) + state.viewPath = this.viewPath; + if (this.propertyPath) + state.propertyPath = this.propertyPath; + + if (this.propertyPath.length > 0 && !this.propertyPath[1]) + state.firstSelection = persistObject(this.getPathObject(1), this.context); + + Firebug.Panel.destroy.apply(this, arguments); + }, + /**/ + + ishow: function(state) + { + if (this.context.loaded && !this.selection) + { + if (!state) + { + this.select(null); + return; + } + if (state.viewPath) + this.viewPath = state.viewPath; + if (state.propertyPath) + this.propertyPath = state.propertyPath; + + var defaultObject = this.getDefaultSelection(this.context); + var selectObject = defaultObject; + + if (state.firstSelection) + { + var restored = state.firstSelection(this.context); + if (restored) + { + selectObject = restored; + this.objectPath = [defaultObject, restored]; + } + else + this.objectPath = [defaultObject]; + } + else + this.objectPath = [defaultObject]; + + if (this.propertyPath.length > 1) + { + for (var i = 1; i < this.propertyPath.length; ++i) + { + var name = this.propertyPath[i]; + if (!name) + continue; + + var object = selectObject; + try + { + selectObject = object[name]; + } + catch (exc) + { + selectObject = null; + } + + if (selectObject) + { + this.objectPath.push(new Property(object, name)); + } + else + { + // If we can't access a property, just stop + this.viewPath.splice(i); + this.propertyPath.splice(i); + this.objectPath.splice(i); + selectObject = this.getPathObject(this.objectPath.length-1); + break; + } + } + } + + var selection = state.pathIndex <= this.objectPath.length-1 + ? this.getPathObject(state.pathIndex) + : this.getPathObject(this.objectPath.length-1); + + this.select(selection); + } + }, + /* + hide: function() + { + var view = this.viewPath[this.pathIndex]; + if (view && this.panelNode.scrollTop) + view.scrollTop = this.panelNode.scrollTop; + }, + /**/ + + supportsObject: function(object) + { + if (object == null) + return 1000; + + if (typeof(object) == "undefined") + return 1000; + else if (object instanceof SourceLink) + return 0; + else + return 1; // just agree to support everything but not agressively. + }, + + refresh: function() + { + this.rebuild(true); + }, + + updateSelection: function(object) + { + var previousIndex = this.pathIndex; + var previousView = previousIndex == -1 ? null : this.viewPath[previousIndex]; + + var newPath = this.pathToAppend; + delete this.pathToAppend; + + var pathIndex = this.findPathObject(object); + if (newPath || pathIndex == -1) + { + this.toggles = {}; + + if (newPath) + { + // Remove everything after the point where we are inserting, so we + // essentially replace it with the new path + if (previousView) + { + if (this.panelNode.scrollTop) + previousView.scrollTop = this.panelNode.scrollTop; + + var start = previousIndex + 1, + // Opera needs the length argument in splice(), otherwise + // it will consider that only one element should be removed + length = this.objectPath.length - start; + + this.objectPath.splice(start, length); + this.propertyPath.splice(start, length); + this.viewPath.splice(start, length); + } + + var value = this.getPathObject(previousIndex); + if (!value) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("dom.updateSelection no pathObject for "+previousIndex+"\n"); + return; + } + + for (var i = 0, length = newPath.length; i < length; ++i) + { + var name = newPath[i]; + var object = value; + try + { + value = value[name]; + } + catch(exc) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("dom.updateSelection FAILS at path_i="+i+" for name:"+name+"\n"); + return; + } + + ++this.pathIndex; + this.objectPath.push(new Property(object, name)); + this.propertyPath.push(name); + this.viewPath.push({toggles: this.toggles, scrollTop: 0}); + } + } + else + { + this.toggles = {}; + + var win = Firebug.browser.window; + //var win = this.context.getGlobalScope(); + if (object === win) + { + this.pathIndex = 0; + this.objectPath = [win]; + this.propertyPath = [null]; + this.viewPath = [{toggles: this.toggles, scrollTop: 0}]; + } + else + { + this.pathIndex = 1; + this.objectPath = [win, object]; + this.propertyPath = [null, null]; + this.viewPath = [ + {toggles: {}, scrollTop: 0}, + {toggles: this.toggles, scrollTop: 0} + ]; + } + } + + this.panelNode.scrollTop = 0; + this.rebuild(); + } + else + { + this.pathIndex = pathIndex; + + var view = this.viewPath[pathIndex]; + this.toggles = view.toggles; + + // Persist the current scroll location + if (previousView && this.panelNode.scrollTop) + previousView.scrollTop = this.panelNode.scrollTop; + + this.rebuild(false, view.scrollTop); + } + }, + + getObjectPath: function(object) + { + return this.objectPath; + }, + + getDefaultSelection: function() + { + return Firebug.browser.window; + //return this.context.getGlobalScope(); + }/*, + + updateOption: function(name, value) + { + const optionMap = {showUserProps: 1, showUserFuncs: 1, showDOMProps: 1, + showDOMFuncs: 1, showDOMConstants: 1}; + if ( optionMap.hasOwnProperty(name) ) + this.rebuild(true); + }, + + getOptionsMenuItems: function() + { + return [ + optionMenu("ShowUserProps", "showUserProps"), + optionMenu("ShowUserFuncs", "showUserFuncs"), + optionMenu("ShowDOMProps", "showDOMProps"), + optionMenu("ShowDOMFuncs", "showDOMFuncs"), + optionMenu("ShowDOMConstants", "showDOMConstants"), + "-", + {label: "Refresh", command: bindFixed(this.rebuild, this, true) } + ]; + }, + + getContextMenuItems: function(object, target) + { + var row = getAncestorByClass(target, "memberRow"); + + var items = []; + + if (row) + { + var rowName = getRowName(row); + var rowObject = this.getRowObject(row); + var rowValue = this.getRowPropertyValue(row); + + var isWatch = hasClass(row, "watchRow"); + var isStackFrame = rowObject instanceof jsdIStackFrame; + + if (typeof(rowValue) == "string" || typeof(rowValue) == "number") + { + // Functions already have a copy item in their context menu + items.push( + "-", + {label: "CopyValue", + command: bindFixed(this.copyProperty, this, row) } + ); + } + + items.push( + "-", + {label: isWatch ? "EditWatch" : (isStackFrame ? "EditVariable" : "EditProperty"), + command: bindFixed(this.editProperty, this, row) } + ); + + if (isWatch || (!isStackFrame && !isDOMMember(rowObject, rowName))) + { + items.push( + {label: isWatch ? "DeleteWatch" : "DeleteProperty", + command: bindFixed(this.deleteProperty, this, row) } + ); + } + } + + items.push( + "-", + {label: "Refresh", command: bindFixed(this.rebuild, this, true) } + ); + + return items; + }, + + getEditor: function(target, value) + { + if (!this.editor) + this.editor = new DOMEditor(this.document); + + return this.editor; + }/**/ +}); + +// ************************************************************************************************ + +// TODO: xxxpedro statusbar +var updateStatusBar = function(panel) +{ + var path = panel.propertyPath; + var index = panel.pathIndex; + + var r = []; + + for (var i=0, l=path.length; i'); + r.push(i==0 ? "window" : path[i] || "Object"); + r.push('
      '); + + if(i < l-1) + r.push('>'); + } + panel.statusBarNode.innerHTML = r.join(""); +}; + + +var DOMMainPanel = Firebug.DOMPanel = function () {}; + +Firebug.DOMPanel.DirTable = DirTablePlate; + +DOMMainPanel.prototype = extend(Firebug.DOMBasePanel.prototype, +{ + onClickStatusBar: function(event) + { + var target = event.srcElement || event.target; + var element = getAncestorByClass(target, "fbHover"); + + if(element) + { + var pathIndex = element.getAttribute("pathIndex"); + + if(pathIndex) + { + this.select(this.getPathObject(pathIndex)); + } + } + }, + + selectRow: function(row, target) + { + if (!target) + target = row.lastChild.firstChild; + + if (!target || !target.repObject) + return; + + this.pathToAppend = getPath(row); + + // If the object is inside an array, look up its index + var valueBox = row.lastChild.firstChild; + if (hasClass(valueBox, "objectBox-array")) + { + var arrayIndex = FirebugReps.Arr.getItemIndex(target); + this.pathToAppend.push(arrayIndex); + } + + // Make sure we get a fresh status path for the object, since otherwise + // it might find the object in the existing path and not refresh it + //Firebug.chrome.clearStatusPath(); + + this.select(target.repObject, true); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + onClick: function(event) + { + var target = event.srcElement || event.target; + var repNode = Firebug.getRepNode(target); + if (repNode) + { + var row = getAncestorByClass(target, "memberRow"); + if (row) + { + this.selectRow(row, repNode); + cancelEvent(event); + } + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "DOM", + title: "DOM", + searchable: true, + statusSeparator: ">", + + options: { + hasToolButtons: true, + hasStatusBar: true + }, + + create: function() + { + Firebug.DOMBasePanel.prototype.create.apply(this, arguments); + + this.onClick = bind(this.onClick, this); + + //TODO: xxxpedro + this.onClickStatusBar = bind(this.onClickStatusBar, this); + + this.panelNode.style.padding = "0 1px"; + }, + + initialize: function(oldPanelNode) + { + //this.panelNode.addEventListener("click", this.onClick, false); + //dispatch([Firebug.A11yModel], 'onInitializeNode', [this, 'console']); + + Firebug.DOMBasePanel.prototype.initialize.apply(this, arguments); + + addEvent(this.panelNode, "click", this.onClick); + + // TODO: xxxpedro dom + this.ishow(); + + //TODO: xxxpedro + addEvent(this.statusBarNode, "click", this.onClickStatusBar); + }, + + shutdown: function() + { + //this.panelNode.removeEventListener("click", this.onClick, false); + //dispatch([Firebug.A11yModel], 'onDestroyNode', [this, 'console']); + + removeEvent(this.panelNode, "click", this.onClick); + + Firebug.DOMBasePanel.prototype.shutdown.apply(this, arguments); + }/*, + + search: function(text, reverse) + { + if (!text) + { + delete this.currentSearch; + this.highlightRow(null); + return false; + } + + var row; + if (this.currentSearch && text == this.currentSearch.text) + row = this.currentSearch.findNext(true, undefined, reverse, Firebug.searchCaseSensitive); + else + { + function findRow(node) { return getAncestorByClass(node, "memberRow"); } + this.currentSearch = new TextSearch(this.panelNode, findRow); + row = this.currentSearch.find(text, reverse, Firebug.searchCaseSensitive); + } + + if (row) + { + var sel = this.document.defaultView.getSelection(); + sel.removeAllRanges(); + sel.addRange(this.currentSearch.range); + + scrollIntoCenterView(row, this.panelNode); + + this.highlightRow(row); + dispatch([Firebug.A11yModel], 'onDomSearchMatchFound', [this, text, row]); + return true; + } + else + { + dispatch([Firebug.A11yModel], 'onDomSearchMatchFound', [this, text, null]); + return false; + } + }/**/ +}); + +Firebug.registerPanel(DOMMainPanel); + + +// ************************************************************************************************ + + + +// ************************************************************************************************ +// Local Helpers + +var getMembers = function getMembers(object, level) // we expect object to be user-level object wrapped in security blanket +{ + if (!level) + level = 0; + + var ordinals = [], userProps = [], userClasses = [], userFuncs = [], + domProps = [], domFuncs = [], domConstants = []; + + try + { + var domMembers = getDOMMembers(object); + //var domMembers = {}; // TODO: xxxpedro + //var domConstantMap = {}; // TODO: xxxpedro + + if (object.wrappedJSObject) + var insecureObject = object.wrappedJSObject; + else + var insecureObject = object; + + // IE function prototype is not listed in (for..in) + if (isIE && isFunction(object)) + addMember("user", userProps, "prototype", object.prototype, level); + + for (var name in insecureObject) // enumeration is safe + { + if (ignoreVars[name] == 1) // javascript.options.strict says ignoreVars is undefined. + continue; + + var val; + try + { + val = insecureObject[name]; // getter is safe + } + catch (exc) + { + // Sometimes we get exceptions trying to access certain members + if (FBTrace.DBG_ERRORS && FBTrace.DBG_DOM) + FBTrace.sysout("dom.getMembers cannot access "+name, exc); + } + + var ordinal = parseInt(name); + if (ordinal || ordinal == 0) + { + addMember("ordinal", ordinals, name, val, level); + } + else if (isFunction(val)) + { + if (isClassFunction(val) && !(name in domMembers)) + addMember("userClass", userClasses, name, val, level); + else if (name in domMembers) + addMember("domFunction", domFuncs, name, val, level, domMembers[name]); + else + addMember("userFunction", userFuncs, name, val, level); + } + else + { + //TODO: xxxpedro + /* + var getterFunction = insecureObject.__lookupGetter__(name), + setterFunction = insecureObject.__lookupSetter__(name), + prefix = ""; + + if(getterFunction && !setterFunction) + prefix = "get "; + /**/ + + var prefix = ""; + + if (name in domMembers && !(name in domConstantMap)) + addMember("dom", domProps, (prefix+name), val, level, domMembers[name]); + else if (name in domConstantMap) + addMember("dom", domConstants, (prefix+name), val, level); + else + addMember("user", userProps, (prefix+name), val, level); + } + } + } + catch (exc) + { + // Sometimes we get exceptions just from trying to iterate the members + // of certain objects, like StorageList, but don't let that gum up the works + throw exc; + if (FBTrace.DBG_ERRORS && FBTrace.DBG_DOM) + FBTrace.sysout("dom.getMembers FAILS: ", exc); + //throw exc; + } + + function sortName(a, b) { return a.name > b.name ? 1 : -1; } + function sortOrder(a, b) { return a.order > b.order ? 1 : -1; } + + var members = []; + + members.push.apply(members, ordinals); + + Firebug.showUserProps = true; // TODO: xxxpedro + Firebug.showUserFuncs = true; // TODO: xxxpedro + Firebug.showDOMProps = true; + Firebug.showDOMFuncs = true; + Firebug.showDOMConstants = true; + + if (Firebug.showUserProps) + { + userProps.sort(sortName); + members.push.apply(members, userProps); + } + + if (Firebug.showUserFuncs) + { + userClasses.sort(sortName); + members.push.apply(members, userClasses); + + userFuncs.sort(sortName); + members.push.apply(members, userFuncs); + } + + if (Firebug.showDOMProps) + { + domProps.sort(sortName); + members.push.apply(members, domProps); + } + + if (Firebug.showDOMFuncs) + { + domFuncs.sort(sortName); + members.push.apply(members, domFuncs); + } + + if (Firebug.showDOMConstants) + members.push.apply(members, domConstants); + + return members; +} + +function expandMembers(members, toggles, offset, level) // recursion starts with offset=0, level=0 +{ + var expanded = 0; + for (var i = offset; i < members.length; ++i) + { + var member = members[i]; + if (member.level > level) + break; + + if ( toggles.hasOwnProperty(member.name) ) + { + member.open = "opened"; // member.level <= level && member.name in toggles. + + var newMembers = getMembers(member.value, level+1); // sets newMembers.level to level+1 + + var args = [i+1, 0]; + args.push.apply(args, newMembers); + members.splice.apply(members, args); + + /* + if (FBTrace.DBG_DOM) + { + FBTrace.sysout("expandMembers member.name", member.name); + FBTrace.sysout("expandMembers toggles", toggles); + FBTrace.sysout("expandMembers toggles[member.name]", toggles[member.name]); + FBTrace.sysout("dom.expandedMembers level: "+level+" member", member); + } + /**/ + + expanded += newMembers.length; + i += newMembers.length + expandMembers(members, toggles[member.name], i+1, level+1); + } + } + + return expanded; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + +function isClassFunction(fn) +{ + try + { + for (var name in fn.prototype) + return true; + } catch (exc) {} + return false; +} + +var hasProperties = function hasProperties(ob) +{ + try + { + for (var name in ob) + return true; + } catch (exc) {} + + // IE function prototype is not listed in (for..in) + if (isFunction(ob)) return true; + + return false; +} + +FBL.ErrorCopy = function(message) +{ + this.message = message; +}; + +var addMember = function addMember(type, props, name, value, level, order) +{ + var rep = Firebug.getRep(value); // do this first in case a call to instanceof reveals contents + var tag = rep.shortTag ? rep.shortTag : rep.tag; + + var ErrorCopy = function(){}; //TODO: xxxpedro + + var valueType = typeof(value); + var hasChildren = hasProperties(value) && !(value instanceof ErrorCopy) && + (isFunction(value) || (valueType == "object" && value != null) + || (valueType == "string" && value.length > Firebug.stringCropLength)); + + props.push({ + name: name, + value: value, + type: type, + rowClass: "memberRow-"+type, + open: "", + order: order, + level: level, + indent: level*16, + hasChildren: hasChildren, + tag: tag + }); +} + +var getWatchRowIndex = function getWatchRowIndex(row) +{ + var index = -1; + for (; row && hasClass(row, "watchRow"); row = row.previousSibling) + ++index; + return index; +} + +var getRowName = function getRowName(row) +{ + var node = row.firstChild; + return node.textContent ? node.textContent : node.innerText; +} + +var getRowValue = function getRowValue(row) +{ + return row.lastChild.firstChild.repObject; +} + +var getRowOwnerObject = function getRowOwnerObject(row) +{ + var parentRow = getParentRow(row); + if (parentRow) + return getRowValue(parentRow); +} + +var getParentRow = function getParentRow(row) +{ + var level = parseInt(row.getAttribute("level"))-1; + for (row = row.previousSibling; row; row = row.previousSibling) + { + if (parseInt(row.getAttribute("level")) == level) + return row; + } +} + +var getPath = function getPath(row) +{ + var name = getRowName(row); + var path = [name]; + + var level = parseInt(row.getAttribute("level"))-1; + for (row = row.previousSibling; row; row = row.previousSibling) + { + if (parseInt(row.getAttribute("level")) == level) + { + var name = getRowName(row); + path.splice(0, 0, name); + + --level; + } + } + + return path; +} + +// ************************************************************************************************ + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + +// ************************************************************************************************ +// DOM Module + +Firebug.DOM = extend(Firebug.Module, +{ + getPanel: function() + { + return Firebug.chrome ? Firebug.chrome.getPanel("DOM") : null; + } +}); + +Firebug.registerModule(Firebug.DOM); + + +// ************************************************************************************************ +// DOM Panel + +var lastHighlightedObject; + +function DOMSidePanel(){}; + +DOMSidePanel.prototype = extend(Firebug.DOMBasePanel.prototype, +{ + selectRow: function(row, target) + { + if (!target) + target = row.lastChild.firstChild; + + if (!target || !target.repObject) + return; + + this.pathToAppend = getPath(row); + + // If the object is inside an array, look up its index + var valueBox = row.lastChild.firstChild; + if (hasClass(valueBox, "objectBox-array")) + { + var arrayIndex = FirebugReps.Arr.getItemIndex(target); + this.pathToAppend.push(arrayIndex); + } + + // Make sure we get a fresh status path for the object, since otherwise + // it might find the object in the existing path and not refresh it + //Firebug.chrome.clearStatusPath(); + + var object = target.repObject; + + if (instanceOf(object, "Element")) + { + Firebug.HTML.selectTreeNode(ElementCache(object)); + } + else + { + Firebug.chrome.selectPanel("DOM"); + Firebug.chrome.getPanel("DOM").select(object, true); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + onClick: function(event) + { + /* + var target = event.srcElement || event.target; + + var object = getAncestorByClass(target, "objectLink"); + object = object ? object.repObject : null; + + if(!object) return; + + if (instanceOf(object, "Element")) + { + Firebug.HTML.selectTreeNode(ElementCache(object)); + } + else + { + Firebug.chrome.selectPanel("DOM"); + Firebug.chrome.getPanel("DOM").select(object, true); + } + /**/ + + + var target = event.srcElement || event.target; + var repNode = Firebug.getRepNode(target); + if (repNode) + { + var row = getAncestorByClass(target, "memberRow"); + if (row) + { + this.selectRow(row, repNode); + cancelEvent(event); + } + } + /**/ + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "DOMSidePanel", + parentPanel: "HTML", + title: "DOM", + + options: { + hasToolButtons: true + }, + + isInitialized: false, + + create: function() + { + Firebug.DOMBasePanel.prototype.create.apply(this, arguments); + + this.onClick = bind(this.onClick, this); + }, + + initialize: function(){ + Firebug.DOMBasePanel.prototype.initialize.apply(this, arguments); + + addEvent(this.panelNode, "click", this.onClick); + + // TODO: xxxpedro css2 + var selection = ElementCache.get(FirebugChrome.selectedHTMLElementId); + if (selection) + this.select(selection, true); + }, + + shutdown: function() + { + removeEvent(this.panelNode, "click", this.onClick); + + Firebug.DOMBasePanel.prototype.shutdown.apply(this, arguments); + }, + + reattach: function(oldChrome) + { + //this.isInitialized = oldChrome.getPanel("DOM").isInitialized; + this.toggles = oldChrome.getPanel("DOMSidePanel").toggles; + } + +}); + +Firebug.registerPanel(DOMSidePanel); + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +FBL.FBTrace = {}; + +(function() { +// ************************************************************************************************ + +var traceOptions = { + DBG_TIMESTAMP: 1, + DBG_INITIALIZE: 1, + DBG_CHROME: 1, + DBG_ERRORS: 1, + DBG_DISPATCH: 1, + DBG_CSS: 1 +}; + +this.module = null; + +this.initialize = function() +{ + if (!this.messageQueue) + this.messageQueue = []; + + for (var name in traceOptions) + this[name] = traceOptions[name]; +}; + +// ************************************************************************************************ +// FBTrace API + +this.sysout = function() +{ + return this.logFormatted(arguments, ""); +}; + +this.dumpProperties = function(title, object) +{ + return this.logFormatted("dumpProperties() not supported.", "warning"); +}; + +this.dumpStack = function() +{ + return this.logFormatted("dumpStack() not supported.", "warning"); +}; + +this.flush = function(module) +{ + this.module = module; + + var queue = this.messageQueue; + this.messageQueue = []; + + for (var i = 0; i < queue.length; ++i) + this.writeMessage(queue[i][0], queue[i][1], queue[i][2]); +}; + +this.getPanel = function() +{ + return this.module ? this.module.getPanel() : null; +}; + +//************************************************************************************************* + +this.logFormatted = function(objects, className) +{ + var html = this.DBG_TIMESTAMP ? [getTimestamp(), " | "] : []; + var length = objects.length; + + for (var i = 0; i < length; ++i) + { + appendText(" ", html); + + var object = objects[i]; + + if (i == 0) + { + html.push(""); + 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); + +/* 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(); + } + +}); + +Firebug.registerPanel(TracePanel); + +// ************************************************************************************************ +}}); + +/* 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); + } + +}); + + + + +// ************************************************************************************************ +}}); + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +FirebugChrome.Skin = +{ + CSS: '.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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/textEditorBorders.png) repeat-y;_background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/textEditorBorders.gif) repeat-y;_overflow:hidden;}.textEditorInner2{position:relative;padding-right:2px;background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/textEditorBorders.png) repeat-y 100% 0;_background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/textEditorBorders.gif) repeat-y 100% 0;_position:fixed;}.textEditorTop1{background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/textEditorCorners.png) no-repeat 100% 0;margin-left:11px;height:10px;_background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/textEditorCorners.gif) no-repeat 100% 0;_overflow:hidden;}.textEditorTop2{position:relative;left:-11px;width:11px;height:10px;background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/textEditorCorners.png) no-repeat;_background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/textEditorCorners.gif) no-repeat;}.textEditorBottom1{position:relative;background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/textEditorCorners.png) no-repeat 100% 100%;margin-left:11px;height:12px;_background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/textEditorCorners.gif) no-repeat 100% 100%;}.textEditorBottom2{position:relative;left:-11px;width:11px;height:12px;background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/textEditorCorners.png) no-repeat 0 100%;_background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/disable.png) no-repeat 2px 1px;_background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/disable.gif) no-repeat 2px 1px;}.cssProp.editGroup.editing{background:none;}.cssProp.disabledStyle{background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/disableHover.png) no-repeat 2px 1px;_background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/chrome://firebug/skin/tableHeaderActive.gif) repeat-x;}.netHeaderSorted{background:#7D93B2 url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/chrome://firebug/skin/tableHeaderSorted.gif) repeat-x;}.netHeaderSorted > .netHeaderCellBox{border-right-color:#6B7C93;background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/chrome://firebug/skin/arrowDown.png) no-repeat right;}.netHeaderSorted.sortedAscending > .netHeaderCellBox{background-image:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/chrome://firebug/skin/arrowUp.png);}.netHeaderSorted:hover:active{background:#536B90 url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/chrome://firebug/skin/breakpoint.png);}.netRow[breakpoint="true"][disabledBreakpoint="true"] .netRowHeader{background-image:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/chrome://firebug/skin/netBarResolving.gif) repeat-x;z-index:60;}.netConnectingBar{position:absolute;left:0;top:0;bottom:0;background:#FFFFFF url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/chrome://firebug/skin/netBarConnecting.gif) repeat-x;z-index:50;}.netBlockingBar{position:absolute;left:0;top:0;bottom:0;background:#FFFFFF url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/chrome://firebug/skin/netBarWaiting.gif) repeat-x;z-index:40;}.netSendingBar{position:absolute;left:0;top:0;bottom:0;background:#FFFFFF url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/chrome://firebug/skin/netBarSending.gif) repeat-x;z-index:30;}.netWaitingBar{position:absolute;left:0;top:0;bottom:0;background:#FFFFFF url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/chrome://firebug/skin/netBarLoaded.gif) repeat-x;border-color:#B6B6B6;}.fromCache .netReceivingBar,.fromCache.netReceivingBar{background:#D6D6D6 url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/tabMenuTarget.png);}.fbTabMenuTarget:hover{background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/tabMenuTargetHover.png);}.fbShadow{float:left;background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/shadowAlpha.png) no-repeat bottom right !important;background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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;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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/tabMenuPin.png) no-repeat right 0;}.fbMenuGroup:hover{background:#316AC5 url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/tabMenuPin.png) no-repeat right -17px;}.fbMenuGroupSelected{color:#fff;background:#316AC5 url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/tabMenuPin.png) no-repeat right -17px;}.fbMenuChecked{background:transparent url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/tabMenuCheckbox.png) no-repeat 4px 0;}.fbMenuChecked:hover{background:#316AC5 url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/tabMenuCheckbox.png) no-repeat 4px -17px;}.fbMenuRadioSelected{background:transparent url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/tabMenuRadio.png) no-repeat 4px 0;}.fbMenuRadioSelected:hover{background:#316AC5 url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/search.png) no-repeat 4px 2px !important;background:#fff url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/errorIcon.png) no-repeat !important;background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/sprite.png) #f1f2ee 0 0;height:27px;font-size:11px;}#fbPanelBarBox{background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/sprite.png) #f1f2ee 0 0;}#fbPanelBar1{width:1024px; z-index:8;left:0;white-space:nowrap;background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/sprite.png) #dbd9c9 0 -27px;position:absolute;left:4px;}#fbPanelBar2Box{background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/down.png) no-repeat;position:absolute;right:2px;bottom:3px;z-index:99;}#fbSmallCommandLineIcon:hover{background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/up.png) no-repeat;position:absolute;right:1px;bottom:1px;z-index:10;}#fbLargeCommandLineIcon:hover{background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/min.png);}#fbWindow_btClose:hover{background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/minHover.png);}#fbWindow_btDetach{background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/detach.png);}#fbWindow_btDetach:hover{background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/detachHover.png);}#fbWindow_btDeactivate{background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/off.png);}#fbWindow_btDeactivate:hover{background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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;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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/sprite.png) 0 -73px;}a.fbTab:hover .fbTabL{background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/sprite.png) -16px -96px;}a.fbTab:hover .fbTabR{background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/sprite.png) -24px -96px;}.fbSelectedTab{background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/sprite.png) #f1f2ee 0 -50px !important;color:#000;}.fbSelectedTab .fbTabL{background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/sprite.png) 0 -96px !important;}.fbSelectedTab .fbTabR{background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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 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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/tree_open.gif);_float:none;_display:inline;_position:absolute;}div.nodeMaximized{background:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/infoIcon.png) !important;background-image:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/infoIcon.gif);}.logRow-warn{background-color:cyan;background-image:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/warningIcon.png) !important;background-image:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/warningIcon.gif);}.logRow-error{background-color:LightYellow;background-image:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/skin/xp/errorIcon.png) !important;background-image:url(chrome-extension://mdaojmoeahmmokaflgbannaopagamgoj/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;}', + HTML: '
       
       
      >>>
      2 errors' +}; + +// ************************************************************************************************ +}}); + +// ************************************************************************************************ +FBL.initialize(); +// ************************************************************************************************ + +})(); \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/firebug.jpg b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/firebug.jpg new file mode 100755 index 0000000000000000000000000000000000000000..2a18aa0dff623b9f5a346a18c34fae9dac9e384c GIT binary patch literal 34998 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/firebug128.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/firebug128.png new file mode 100755 index 0000000000000000000000000000000000000000..dbca545fe4fab491dd38e1f5e52bf28ad9de5759 GIT binary patch literal 19240 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 P00000NkvXXu0mjfAQ^>n literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/firebug16.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/firebug16.png new file mode 100755 index 0000000000000000000000000000000000000000..d8d0c249060e3e485fca290fbf53e9aaeb115972 GIT binary patch literal 1053 zcmV+&1mgRNP)K^D zBF6baiEKtTjn&8pD`C>DLm)1cE;8iBbz4d4*0HrKx3w+3y)Qo3Y5d@Maz31s=Q%m& zJpUhaXnz|tV;BZ3%V1#G2OUo!$?EE{qt^PywG#8M^-z=797iIwIz}!=j5&KYX#lJYqS{Ll^J?=kuEZ-5La!&;igDxhde=e`Hc9pFwt*0Fi(`UO_ zRb`;Lc36hV2gmZfp2ydY8BAXhYQL%VnGlT);ZuM5NQbT2e{mG!lb0~*{Vg6(DVtcr ziqLZ+Ou7uRjmmq@!I>$U=*nX%zx%|NJ8#%*)-hDsZCIAj+3Uc^FE_zEe*QW!pzXlZ z>tke}?LN$me}`t@=*&vIvUOR((T8rpu>Y}Gx+ZO<=ai( znso-Fv2xGDmXojA3OcyJE#W7FPRARwn4!*!kn8;k)ApLw6b?RV#<8IwJn2##eJmfr zg$uWya~He=Mf@y5MYq7@P7b;j6*ie)_)4Eg?A}@s`zUZzv?p%NVSj@jUCt<6nQ9zq z5K$gAX5)r9JO9*NOiNTuaP!r(e9t85^ta%Y~k1fX9RN5F@yixUjhsO XvjU95kpgPJ00000NkvXXu0mjf$Qk(5 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/firebug24.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/firebug24.png new file mode 100755 index 0000000000000000000000000000000000000000..f50ff926c93d8b400eb513e480ac92002da6e991 GIT binary patch literal 1949 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/firebug48.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/firebug48.png new file mode 100755 index 0000000000000000000000000000000000000000..b44313276a3415fcdf62612e4de7cb66bb0da66d GIT binary patch literal 4096 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 HDWM4fu+KD3 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/buttonBgHover.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/buttonBgHover.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/detach.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/detach.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/disable.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/disable.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/disableHover.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/disableHover.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/disableHover.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/disableHover.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/downActive.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/downActive.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/downHover.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/downHover.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/errorIcon-sm.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/errorIcon-sm.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/firebug-1.3a2.css b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/firebug-1.3a2.css new file mode 100755 index 0000000..b5dd5dd --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/firebug.IE6.css b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/firebug.IE6.css new file mode 100755 index 0000000..14f8aa8 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/firebug.css b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/firebug.css new file mode 100755 index 0000000..decd591 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/firebug.css @@ -0,0 +1,3056 @@ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/* 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: 0 10px 0 0; + font-family: Lucida Grande, Tahoma, sans-serif; + font-weight: bold; + vertical-align: top; + text-align: right; + white-space: nowrap; +} + +.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; +} + +.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: 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; + 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: 49px; +} + +#fbToolbar { + background: url(sprite.png) #f1f2ee 0 0; + height: 27px; + font-size: 11px; +} + +#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; + 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 Monaco, monospace; + position: absolute; + top: 0; + left: 0; + margin: 0; + padding: 0 5px 0 20px; + 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-warning { + 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-warning { + 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/firebug.html b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/firebug.html new file mode 100755 index 0000000..4432a32 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/firebug.html @@ -0,0 +1,213 @@ + + + + +Firebug Lite + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      +   +   +   +
      + + +
      +
      + + + +   + + + + + + + + + Inspect + + + + + Clear + + + + + + + + + + + + + +
      + +
      + + + + + +
       
      + +
      +
      +
      +
      +
      +
      + + +
       
      + + +
      + + +
      +
      +
      + +
      + + + + + +
      + Run + Clear + + +
      + +
      +
      +
      >>>
      + + +
      +
      + + + + 2 errors + + + + + \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/firebug.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/firebug.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/infoIcon.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/infoIcon.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/min.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/min.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/off.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/off.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/search.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/search.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/search.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/search.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/shadow.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/shadow.gif new file mode 100755 index 0000000000000000000000000000000000000000..af7f537e391f08327e417c7be6323c917d5d3788 GIT binary patch literal 4364 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 mNRx4)$-Se2KGVRJG=-nEko^8U73WMVE8{ literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/shadow2.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/shadow2.gif new file mode 100755 index 0000000000000000000000000000000000000000..099cbf35d455e13d49010e736c40bab22c3d1a23 GIT binary patch literal 3093 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/shadowAlpha.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/shadowAlpha.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/sprite.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/sprite.png new file mode 100755 index 0000000000000000000000000000000000000000..33d2c4d4649ec35b7771213977d7c83180907ccd GIT binary patch literal 40027 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabHoverMid.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabHoverMid.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabHoverRight.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabHoverRight.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabMenuCheckbox.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabMenuCheckbox.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabMenuPin.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabMenuPin.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabMenuRadio.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabMenuRadio.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabMenuTarget.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabMenuTarget.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabMenuTargetHover.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabMenuTargetHover.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabRight.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tabRight.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/textEditorBorders.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/textEditorBorders.gif new file mode 100755 index 0000000000000000000000000000000000000000..0ee5497874cec4a5599e562dd7c00b8c57bc5a44 GIT binary patch literal 117 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 L`)q75=;;3dF|oR- literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/textEditorCorners.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/textEditorCorners.png new file mode 100755 index 0000000000000000000000000000000000000000..a0f839dc598edd80d093e1cf954134a916db5af0 GIT binary patch literal 3960 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/titlebarMid.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/titlebarMid.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tree_close.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tree_close.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tree_open.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/tree_open.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/up.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/up.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/warningIcon.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/warningIcon.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/warningIcon.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension-beta/skin/xp/warningIcon.png new file mode 100755 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 +/* See license.txt for terms of usage */ + +// ************************************************************************************************* + +//var bookmarlet = "javascript:(typeof Firebug!='undefined')?Firebug.chrome.toggle():(function(F,i,r,e,b,u,g,L,I,T,E){if(F.getElementById(b))return;E=F.documentElement.namespaceURI;E=E?F[i+'NS'](E,'script'):F[i]('script');E=F[i]('script');E[r]('id',b);E[r]('src',I+g+T);E[r](b,u);(F[e]('head')[0]||F[e]('body')[0]).appendChild(E);E=new Image;E[r]('src',I+L);})(document,'createElement','setAttribute','getElementsByTagName','FirebugLiteBookmarlet','1.3.0.1','firebug.jgz','skin/xp/sprite.png','https://getfirebug.com/releases/lite/beta/','#startOpened,showIconWhenHidden=false');"; +var firebugVersion = "Firebug Lite 1.3.2"; +var extensionURL = chrome.extension.getURL(""); +var isActive = false; + +// ************************************************************************************************* + +function handleIconClick(tab) +{ + if (tab.url.indexOf("https://chrome.google.com/extensions") == 0 || + tab.url.indexOf("chrome://") == 0) + { + alert("For security reasons extensions cannot run content scripts at this page, and therefore, Firebug Lite can't work here."); + + return; + } + + var isContentScriptActive = false; + + chrome.tabs.sendRequest( tab.id, {name: "FB_isActive"}, + + function(response) + { + isContentScriptActive = true; + + if (response.value == "true") + { + chrome.tabs.update(tab.id, {url: "javascript:Firebug.chrome.toggle()"}); + } + else + { + setActivationStorage(tab); + chrome.tabs.sendRequest(tab.id, {name: "FB_loadFirebug"}); + } + } + ); + /* + setTimeout(function(){ + + if (!isContentScriptActive) + { + //chrome.tabs.update(tab.id, {url: bookmarlet}); + //enableBrowserActionIcon(); + //setActivationStorage(tab); + + //alert("Firebug Lite can't open because this page was open before it was installed. Please reload this page."); + + setActivationStorage(tab); + if (confirm("Firebug Lite can't complete its activation because this page was open before the extension itself was enabled. The process will complete when you reload the page.\n\nPress ok to reload the page now, or cancel to reload it later.")) + { + chrome.tabs.update(tab.id, {url: "javascript:window.location.reload()"}); + } + } + + },500);/**/ +}; + +chrome.browserAction.onClicked.addListener(handleIconClick); + +// ************************************************************************************************* + +function handleTabChange(tabId, selectInfo) +{ + var isUpdated = false; + + chrome.tabs.sendRequest(tabId, {name: "FB_isActive"}, + + function(response) + { + isUpdated = true; + + if (response.value == "true") + { + enableBrowserActionIcon(); + isActive = true; + } + else + { + disableBrowserActionIcon(); + isActive = false; + } + } + ); + + setTimeout(function(){ + + chrome.tabs.get(tabId, function(tab){ + + var title = tab.title || ""; + if (!isUpdated && !title.indexOf("Firebug Lite") == 0) + { + disableBrowserActionIcon(); + isActive = false; + } + + }); + + },100); +}; + +// ************************************************************************************************* + +chrome.tabs.onSelectionChanged.addListener(handleTabChange); + +// ************************************************************************************************* + +function handleUpdateTab(tabId, updateInfo, tab) +{ + if (updateInfo.status == "complete") return; + + handleTabChange(tabId, updateInfo); +} + +// memory leaking here +//chrome.tabs.onUpdated.addListener(handleUpdateTab); + +// ************************************************************************************************* + +chrome.extension.onRequest.addListener +( + function(request, sender, sendResponse) + { + if (request.name == "FB_enableIcon") + enableBrowserActionIcon(); + + else if (request.name == "FB_disableIcon") + disableBrowserActionIcon(); + + else if (request.name == "FB_deactivate") + { + disableBrowserActionIcon(); + chrome.tabs.getSelected(null, function(tab){ + unsetActivationStorage(tab); + + chrome.tabs.sendRequest(tab.id, {name: "FB_deactivate"}); + }); + } + + sendResponse({}); // snub them. + } +); + +// ************************************************************************************************* + +chrome.contextMenus.create({ + title: "Inspect with Firebug Lite", + "contexts": ["all"], + onclick: function(info, tab) { + chrome.tabs.sendRequest(tab.id, {name: "FB_contextMenuClick"}); + } +}); + +// ************************************************************************************************* + +function enableBrowserActionIcon() +{ + chrome.browserAction.setTitle({title: firebugVersion + " (On)"}); + chrome.browserAction.setIcon({path:"firebug24.png"}); +}; + +function disableBrowserActionIcon() +{ + chrome.browserAction.setTitle({title: firebugVersion + " (Off)"}); + chrome.browserAction.setIcon({path:"firebug24_disabled.png"}); +}; + +// ************************************************************************************************* + +function setActivationStorage(tab) +{ + chrome.tabs.update(tab.id, {url: "javascript:localStorage.setItem('Firebug','1,1,"+extensionURL+"')"}); + isActive = true; +}; + +function unsetActivationStorage(tab) +{ + chrome.tabs.update(tab.id, {url: "javascript:localStorage.removeItem('Firebug')"}); + isActive = false; +}; + +// ************************************************************************************************* + \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/contentScript.js b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/contentScript.js new file mode 100755 index 0000000..90b3730 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/contentScript.js @@ -0,0 +1,378 @@ +// ************************************************************************************************* + +var isActive = false; +var isOpen = false; +var extensionURL = null; + +var contextMenuElementXPath = null; +var isListeningKeyboardActivation = false; + +// ************************************************************************************************* + +// restore Firebug Lite state +var loadStateData = function() +{ + var FirebugData = localStorage.getItem("Firebug"); + + isActive = false; + isOpen = false; + extensionURL = chrome.extension.getURL(""); + + if (FirebugData) + { + FirebugData = FirebugData.split(","); + isActive = FirebugData[0] == "1"; + isOpen = FirebugData[1] == "1"; + } +} + +// ************************************************************************************************* + +// load Firebug Lite application +var loadFirebug = function() +{ + document.documentElement.setAttribute("debug", isOpen); + + injectScriptText("("+listenConsoleCalls+")()"); + + // TODO: xxxpedro - change to XHR when Issue 41024 is solved + // Issue 41024: XHR using file: and chrome-extension: protocols not working. + // http://code.google.com/p/chromium/issues/detail?id=41024 + injectFirebugScript(); +} + +// TODO: think a better solution than using the stateData parameter, required +// by the keyboard activation. +var loadFirebugAndWait = function(callback, stateData) +{ + stateData = stateData || ('1,1,'+extensionURL); + localStorage.setItem('Firebug', stateData); + loadStateData(); + chrome.extension.sendRequest({name: isActive ? "FB_enableIcon" : "FB_disableIcon"}); + + document.documentElement.setAttribute("debug", isOpen); + + injectFirebugScript(); + + setTimeout(function(){ + waitFirebug(callback); + },0); +}; + +var waitFirebug = function(callback) +{ + if (document && document.getElementById("FirebugChannel")) + { + stopListeningKeyboardActivation(); + callback(); + } + else + setTimeout(function(){ waitFirebug(callback); }, 100); + +}; + +// ************************************************************************************************* + +// inject Firebug Lite script into the page +var injectFirebugScript = function(url) +{ + scriptElement = document.getElementById("FirebugLite"); + if (scriptElement) + { + firebugDispatch("FB_toggle"); + } + else + { + var script = document.createElement("script"); + + script.src = extensionURL + "firebug-lite.js"; + script.setAttribute("id", "FirebugLite"); + script.setAttribute("firebugIgnore", "true"); + script.setAttribute("extension", "Chrome"); + document.documentElement.appendChild(script); + + script.onload = function() { + // TODO: xxxpedro remove this files when deploy the new structure + script = document.createElement("script"); + script.src = extensionURL + "googleChrome.js"; + document.documentElement.appendChild(script); + }; + } +} + +// inject a script into the page +var injectScriptText = function(text) +{ + var script = document.createElement("script"); + var parent = document.documentElement; + + script.text = text; + script.setAttribute("id", "FirebugLite"); + script.setAttribute("firebugIgnore", "true"); + script.setAttribute("extension", "Chrome"); + parent.appendChild(script); + parent.removeChild(script); +} + +// ************************************************************************************************* + +// communication with the background page +chrome.extension.onRequest.addListener +( + function(request, sender, sendResponse) + { + // check if Firebug Lite is active + if (request.name == "FB_isActive") + { + loadStateData(); + sendResponse({value: ""+isActive}); + } + // load Firebug Lite application + else if (request.name == "FB_loadFirebug") + { + setTimeout(function(){ + + loadStateData(); + + //loadFirebug(); + loadFirebugAndWait(function(){ + + isActive = true; + var message = isActive ? "FB_enableIcon" : "FB_disableIcon"; + chrome.extension.sendRequest({name: message}); + + loadChannel(); + }); + + },0); + + sendResponse({}); + } + // handle context menu click by sending "FB_contextMenuClick" message + // to Firebug Lite application + else if (request.name == "FB_contextMenuClick") + { + // TODO: if not active, activate first, wait the activation to complete + // and only then dispatch the event to Firebug Lite application + if (isActive) + firebugDispatch("FB_contextMenuClick,"+contextMenuElementXPath); + else + loadFirebugAndWait(function(){ + firebugDispatch("FB_contextMenuClick,"+contextMenuElementXPath); + }); + } + else if (request.name == "FB_deactivate") + { + listenKeyboardActivation(); + } + else + sendResponse({}); // snub them. + } +); + +// ************************************************************************************************* + +// communication with the page +var channel = null; +var channelEvent; + +var onFirebugChannelEvent = function() +{ + channel = document.getElementById("FirebugChannel"); + + if (channel) + { + chrome.extension.sendRequest({name: channel.innerText}); + } +}; + +var loadChannel = function() +{ + channel = document.getElementById("FirebugChannel"); + + if (channel) + { + channel.addEventListener("FirebugChannelEvent", onFirebugChannelEvent); + channelEvent = document.createEvent("Event"); + channelEvent.initEvent("FirebugChannelEvent", true, true); + } +} + +var firebugDispatch = function(data) +{ + if (!channel) + loadChannel(); + + channel.innerText = data; + channel.dispatchEvent(channelEvent); +}; + +// ************************************************************************************************* + +var onContextMenu = function(event) +{ + contextMenuElementXPath = getElementXPath(event.target); +}; + +var loadListeners = function() +{ + window.addEventListener("contextmenu", onContextMenu); + window.addEventListener("unload", unloadListeners); +}; + +var unloadListeners = function() +{ + if (channel) + { + channel.removeEventListener("FirebugChannelEvent", onFirebugChannelEvent); + } + + window.removeEventListener("contextmenu", onContextMenu); + window.removeEventListener("unload", unloadListeners); +}; + +// ************************************************************************************************* + +// listen to console calls before Firebug Lite finishes to load +var listenConsoleCalls = function() +{ + // TODO: xxxpedro add all console functions + var fns = ["log", "info", "warn", "error"]; + + var listener = {consoleQueue: ["chromeConsoleQueueHack"]}; + var queue = listener.consoleQueue; + + for (var i=0, l=fns.length; i 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}"}; + } + + 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; + + // 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 + 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; + } + } + } + + // 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) + return ob + ""; + + 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, ""); + + if (elt.offsetLeft) + coords.x += elt.offsetLeft + parseInt(style.borderLeftWidth); + if (elt.offsetTop) + coords.y += elt.offsetTop + parseInt(style.borderTopWidth); + + if (p) + { + if (p.nodeType == 1) + addOffset(p, coords, view); + } + else + { + var otherView = isIE ? elt.ownerDocument.parentWindow : elt.ownerDocument.defaultView; + if (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; + + return toString.call(object) === "[object Function]" || + this.isIE && typeof object != "string" && reFunction.test(""+object); +}; + + +// ************************************************************************************************ +// 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 = this.getXHRObject(); + }, + + 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); + +/* See license.txt for terms of usage */ + +FBL.ns( /** @scope ns-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; +}; + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +FBL.ns( /** @scope ns-firebug */ function() { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +// Globals + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Internals + +var modules = []; +var panelTypes = []; +var panelTypeMap = {}; +var reps = []; + +var parentPanelMap = {}; + + +// ************************************************************************************************ +// Firebug + +/** + * @namespace describe Firebug + * @exports window.Firebug as Firebug + */ +window.Firebug = FBL.Firebug = +{ + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + version: "Firebug Lite 1.3.2", + revision: "$Revision: 9759 $", + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + 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; + + // Document must be cached before chrome initialization + cacheDocument(); + + if (Firebug.Inspector) + Firebug.Inspector.create(); + + if (FBL.processAllStyleSheets) + processAllStyleSheets(Firebug.browser.document); + + FirebugChrome.initialize(); + + dispatch(modules, "initialize", []); + + if (Env.onLoad) + { + var onLoad = Env.onLoad; + delete Env.onLoad; + + setTimeout(onLoad, 200); + } + }, + + shutdown: function() + { + if (Firebug.Inspector) + Firebug.Inspector.destroy(); + + dispatch(modules, "shutdown", []); + + var chromeMap = FirebugChrome.chromeMap; + + for (var name in chromeMap) + { + if (chromeMap.hasOwnProperty(name)) + { + chromeMap[name].destroy(); + } + } + + 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; + + this.savePrefs(); + }, + + setPrefs: function(prefs) + { + for (var name in prefs) + { + if (prefs.hasOwnProperty(name)) + Firebug[name] = prefs[name]; + } + + this.savePrefs(); + }, + + restorePrefs: function() + { + var Options = Env.Options; + + for (var name in Options) + { + Firebug[name] = Options[name]; + } + }, + + loadPrefs: function(prefs) + { + this.restorePrefs(); + + prefs = prefs || eval("(" + readCookie("FirebugLite") + ")"); + + for (var name in prefs) + { + if (prefs.hasOwnProperty(name)) + Firebug[name] = prefs[name]; + } + }, + + savePrefs: function() + { + var json = ['{'], jl = 0; + var Options = Env.Options; + + for (var name in Options) + { + if (Options.hasOwnProperty(name)) + { + var value = Firebug[name]; + + json[++jl] = '"'; + json[++jl] = name; + + var type = typeof value; + if (type == "boolean" || type == "number") + { + json[++jl] = '":'; + json[++jl] = value; + json[++jl] = ','; + } + else + { + json[++jl] = '":"'; + json[++jl] = value; + json[++jl] = '",'; + } + } + } + + json.length = jl--; + json[++jl] = '}'; + + createCookie("FirebugLite", json.join("")); + }, + + erasePrefs: function() + { + removeCookie("FirebugLite"); + } +}; + +Firebug.restorePrefs(); + +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; + Firebug.InfoTip.initializeBrowser(Firebug.chrome); + }, + + shutdown: function() + { + if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.Panel.shutdown", this.name); + + /// TODO: xxxpedro infoTip Hack + 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.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"; + } +}); + +// ************************************************************************************************ + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +FBL.ns( /** @scope ns-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) + FirebugChrome.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 width || el.scrollHeight > height)) + { + width = el.scrollWidth; + height = el.scrollHeight; + } + + return {width: width, height: height}; + }, + + getWindowScrollPosition: function() + { + var top=0, left=0, el; + + if(typeof this.window.pageYOffset == "number") + { + top = this.window.pageYOffset; + left = this.window.pageXOffset; + } + else if((el=this.document.body) && (el.scrollTop || el.scrollLeft)) + { + top = el.scrollTop; + left = el.scrollLeft; + } + else if((el=this.document.documentElement) && (el.scrollTop || el.scrollLeft)) + { + top = el.scrollTop; + left = el.scrollLeft; + } + + return {top:top, left:left}; + }, + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Element Methods + + getElementFromPoint: function(x, y) + { + if (shouldFixElementFromPoint) + { + var scroll = this.getWindowScrollPosition(); + return this.document.elementFromPoint(x + scroll.left, y + scroll.top); + } + else + return this.document.elementFromPoint(x, y); + }, + + getElementPosition: function(el) + { + var left = 0 + var top = 0; + + do + { + left += el.offsetLeft; + top += el.offsetTop; + } + while (el = el.offsetParent); + + return {left:left, top:top}; + }, + + getElementBox: function(el) + { + var result = {}; + + if (el.getBoundingClientRect) + { + var rect = el.getBoundingClientRect(); + + // fix IE problem with offset when not in fullscreen mode + var offset = isIE ? this.document.body.clientTop || this.document.documentElement.clientTop: 0; + + var scroll = this.getWindowScrollPosition(); + + result.top = Math.round(rect.top - offset + scroll.top); + result.left = Math.round(rect.left - offset + scroll.left); + result.height = Math.round(rect.bottom - rect.top); + result.width = Math.round(rect.right - rect.left); + } + else + { + var position = this.getElementPosition(el); + + result.top = position.top; + result.left = position.left; + result.height = el.offsetHeight; + result.width = el.offsetWidth; + } + + return result; + }, + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Measurement Methods + + getMeasurement: function(el, name) + { + var result = {value: 0, unit: "px"}; + + var cssValue = this.getStyle(el, name); + + if (!cssValue) return result; + if (cssValue.toLowerCase() == "auto") return result; + + var reMeasure = /(\d+\.?\d*)(.*)/; + var m = cssValue.match(reMeasure); + + if (m) + { + result.value = m[1]-0; + result.unit = m[2].toLowerCase(); + } + + return result; + }, + + getMeasurementInPixels: function(el, name) + { + if (!el) return null; + + var m = this.getMeasurement(el, name); + var value = m.value; + var unit = m.unit; + + if (unit == "px") + return value; + + else if (unit == "pt") + return this.pointsToPixels(name, value); + + if (unit == "em") + return this.emToPixels(el, value); + + else if (unit == "%") + return this.percentToPixels(el, value); + }, + + getMeasurementBox1: function(el, name) + { + var sufixes = ["Top", "Left", "Bottom", "Right"]; + var result = []; + + for(var i=0, sufix; sufix=sufixes[i]; i++) + result[i] = Math.round(this.getMeasurementInPixels(el, name + sufix)); + + return {top:result[0], left:result[1], bottom:result[2], right:result[3]}; + }, + + getMeasurementBox: function(el, name) + { + var result = []; + var sufixes = name == "border" ? + ["TopWidth", "LeftWidth", "BottomWidth", "RightWidth"] : + ["Top", "Left", "Bottom", "Right"]; + + if (isIE) + { + var propName, cssValue; + var autoMargin = null; + + for(var i=0, sufix; sufix=sufixes[i]; i++) + { + propName = name + sufix; + + cssValue = el.currentStyle[propName] || el.style[propName]; + + if (cssValue == "auto") + { + if (!autoMargin) + autoMargin = this.getCSSAutoMarginBox(el); + + result[i] = autoMargin[sufix.toLowerCase()]; + } + else + result[i] = this.getMeasurementInPixels(el, propName); + + } + + } + else + { + for(var i=0, sufix; sufix=sufixes[i]; i++) + result[i] = this.getMeasurementInPixels(el, name + sufix); + } + + return {top:result[0], left:result[1], bottom:result[2], right:result[3]}; + }, + + getCSSAutoMarginBox: function(el) + { + if (isIE && " meta title input script link a ".indexOf(" "+el.nodeName.toLowerCase()+" ") != -1) + return {top:0, left:0, bottom:0, right:0}; + /**/ + + if (isIE && " h1 h2 h3 h4 h5 h6 h7 ul p ".indexOf(" "+el.nodeName.toLowerCase()+" ") == -1) + return {top:0, left:0, bottom:0, right:0}; + /**/ + + var offsetTop = 0; + if (false && isIEStantandMode) + { + var scrollSize = Firebug.browser.getWindowScrollSize(); + offsetTop = scrollSize.height; + } + + var box = this.document.createElement("div"); + //box.style.cssText = "margin:0; padding:1px; border: 0; position:static; overflow:hidden; visibility: hidden;"; + box.style.cssText = "margin:0; padding:1px; border: 0; visibility: hidden;"; + + var clone = el.cloneNode(false); + var text = this.document.createTextNode(" "); + clone.appendChild(text); + + box.appendChild(clone); + + this.document.body.appendChild(box); + + var marginTop = clone.offsetTop - box.offsetTop - 1; + var marginBottom = box.offsetHeight - clone.offsetHeight - 2 - marginTop; + + var marginLeft = clone.offsetLeft - box.offsetLeft - 1; + var marginRight = box.offsetWidth - clone.offsetWidth - 2 - marginLeft; + + this.document.body.removeChild(box); + + return {top:marginTop+offsetTop, left:marginLeft, bottom:marginBottom-offsetTop, right:marginRight}; + }, + + getFontSizeInPixels: function(el) + { + var size = this.getMeasurement(el, "fontSize"); + + if (size.unit == "px") return size.value; + + // get font size, the dirty way + var computeDirtyFontSize = function(el, calibration) + { + var div = this.document.createElement("div"); + var divStyle = offscreenStyle; + + if (calibration) + divStyle += " font-size:"+calibration+"px;"; + + div.style.cssText = divStyle; + div.innerHTML = "A"; + el.appendChild(div); + + var value = div.offsetHeight; + el.removeChild(div); + return value; + } + + /* + var calibrationBase = 200; + var calibrationValue = computeDirtyFontSize(el, calibrationBase); + var rate = calibrationBase / calibrationValue; + /**/ + + // the "dirty technique" fails in some environments, so we're using a static value + // based in some tests. + var rate = 200 / 225; + + var value = computeDirtyFontSize(el); + + return value * rate; + }, + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Unit Funtions + + pointsToPixels: function(name, value, returnFloat) + { + var axis = /Top$|Bottom$/.test(name) ? "y" : "x"; + + var result = value * pixelsPerInch[axis] / 72; + + return returnFloat ? result : Math.round(result); + }, + + emToPixels: function(el, value) + { + if (!el) return null; + + var fontSize = this.getFontSizeInPixels(el); + + return Math.round(value * fontSize); + }, + + exToPixels: function(el, value) + { + if (!el) return null; + + // get ex value, the dirty way + var div = this.document.createElement("div"); + div.style.cssText = offscreenStyle + "width:"+value + "ex;"; + + el.appendChild(div); + var value = div.offsetWidth; + el.removeChild(div); + + return value; + }, + + percentToPixels: function(el, value) + { + if (!el) return null; + + // get % value, the dirty way + var div = this.document.createElement("div"); + div.style.cssText = offscreenStyle + "width:"+value + "%;"; + + el.appendChild(div); + var value = div.offsetWidth; + el.removeChild(div); + + return value; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getStyle: isIE ? function(el, name) + { + return el.currentStyle[name] || el.style[name] || undefined; + } + : function(el, name) + { + return this.document.defaultView.getComputedStyle(el,null)[name] + || el.style[name] || undefined; + } + +}; + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +FBL.ns( /**@scope ns-chrome*/ function() { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +// Globals + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Window Options + +var WindowDefaultOptions = + { + type: "frame", + id: "FirebugUI", + height: 250 + }, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Instantiated objects + + commandLine, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Interface Elements Cache + + fbTop, + fbContent, + fbContentStyle, + fbBottom, + fbBtnInspect, + + fbToolbar, + + fbPanelBox1, + fbPanelBox1Style, + fbPanelBox2, + fbPanelBox2Style, + fbPanelBar2Box, + fbPanelBar2BoxStyle, + + fbHSplitter, + fbVSplitter, + fbVSplitterStyle, + + fbPanel1, + fbPanel1Style, + fbPanel2, + fbPanel2Style, + + fbConsole, + fbConsoleStyle, + fbHTML, + + fbCommandLine, + fbLargeCommandLine, + fbLargeCommandButtons, + +//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Cached size values + + topHeight, + topPartialHeight, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + chromeRedrawSkipRate = isIE ? 75 : isOpera ? 80 : 75, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + lastSelectedPanelName, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + focusCommandLineState = 0, + lastFocusedPanelName, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + lastHSplitterMouseMove = 0, + onHSplitterMouseMoveBuffer = null, + onHSplitterMouseMoveTimer = null, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + lastVSplitterMouseMove = 0; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + +// ************************************************************************************************ +// FirebugChrome + +/**@namespace*/ +FBL.FirebugChrome = +{ + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + isOpen: false, + height: 250, + sidePanelWidth: 350, + + selectedPanelName: "Console", + selectedHTMLElementId: null, + + chromeMap: {}, + + htmlSelectionStack: [], + consoleMessageQueue: [], + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + create: function() + { + if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("FirebugChrome.create", "creating chrome window"); + + createChromeWindow(); + }, + + initialize: function() + { + if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("FirebugChrome.initialize", "initializing chrome window"); + + if (Env.chrome.type == "frame" || Env.chrome.type == "div") + ChromeMini.create(Env.chrome); + + var chrome = Firebug.chrome = new Chrome(Env.chrome); + FirebugChrome.chromeMap[chrome.type] = chrome; + + addGlobalEvent("keydown", onGlobalKeyDown); + + if (Env.Options.enablePersistent && chrome.type == "popup") + { + // TODO: xxxpedro persist - revise chrome synchronization when in persistent mode + var frame = FirebugChrome.chromeMap.frame; + if (frame) + frame.close(); + + //chrome.reattach(frame, chrome); + //TODO: xxxpedro persist synchronize? + chrome.initialize(); + } + }, + + clone: function(FBChrome) + { + for (var name in FBChrome) + { + var prop = FBChrome[name]; + if (FBChrome.hasOwnProperty(name) && !isFunction(prop)) + { + this[name] = prop; + } + } + } +}; + + + +// ************************************************************************************************ +// Chrome Window Creation + +var createChromeWindow = function(options) +{ + options = extend(WindowDefaultOptions, options || {}); + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Locals + + var chrome = {}, + + context = options.context || Env.browser, + + type = chrome.type = Env.Options.enablePersistent ? + "popup" : + options.type, + + isChromeFrame = type == "frame", + + useLocalSkin = Env.useLocalSkin, + + url = useLocalSkin ? + Env.Location.skin : + "about:blank", + + // document.body not available in XML+XSL documents in Firefox + body = context.document.getElementsByTagName("body")[0], + + formatNode = function(node) + { + if (!Env.isDebugMode) + { + node.firebugIgnore = true; + } + + node.style.border = "0"; + node.style.visibility = "hidden"; + node.style.zIndex = "2147483647"; // MAX z-index = 2147483647 + node.style.position = noFixedPosition ? "absolute" : "fixed"; + node.style.width = "100%"; // "102%"; IE auto margin bug + node.style.left = "0"; + node.style.bottom = noFixedPosition ? "-1px" : "0"; + node.style.height = options.height + "px"; + + // avoid flickering during chrome rendering + if (isFirefox) + node.style.display = "none"; + }, + + createChromeDiv = function() + { + //Firebug.Console.warn("Firebug Lite GUI is working in 'windowless mode'. It may behave slower and receive interferences from the page in which it is installed."); + + var node = chrome.node = createGlobalElement("div"), + style = createGlobalElement("style"), + + css = FirebugChrome.Skin.CSS + /* + .replace(/;/g, " !important;") + .replace(/!important\s!important/g, "!important") + .replace(/display\s*:\s*(\w+)\s*!important;/g, "display:$1;")*/, + + // reset some styles to minimize interference from the main page's style + rules = ".fbBody *{margin:0;padding:0;font-size:11px;line-height:13px;color:inherit;}" + + // load the chrome styles + css + + // adjust some remaining styles + ".fbBody #fbHSplitter{position:absolute !important;} .fbBody #fbHTML span{line-height:14px;} .fbBody .lineNo div{line-height:inherit !important;}"; + /* + if (isIE) + { + // IE7 CSS bug (FbChrome table bigger than its parent div) + rules += ".fbBody table.fbChrome{position: static !important;}"; + }/**/ + + style.type = "text/css"; + + if (style.styleSheet) + style.styleSheet.cssText = rules; + else + style.appendChild(context.document.createTextNode(rules)); + + document.getElementsByTagName("head")[0].appendChild(style); + + node.className = "fbBody"; + node.style.overflow = "hidden"; + node.innerHTML = getChromeDivTemplate(); + + if (isIE) + { + // IE7 CSS bug (FbChrome table bigger than its parent div) + setTimeout(function(){ + node.firstChild.style.height = "1px"; + node.firstChild.style.position = "static"; + },0); + /**/ + } + + formatNode(node); + + body.appendChild(node); + + chrome.window = window; + chrome.document = document; + onChromeLoad(chrome); + }; + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + try + { + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // create the Chrome as a "div" (windowless mode) + if (type == "div") + { + createChromeDiv(); + return; + } + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // cretate the Chrome as an "iframe" + else if (isChromeFrame) + { + // Create the Chrome Frame + var node = chrome.node = createGlobalElement("iframe"); + node.setAttribute("src", url); + node.setAttribute("frameBorder", "0"); + + formatNode(node); + + body.appendChild(node); + + // must set the id after appending to the document, otherwise will cause an + // strange error in IE, making the iframe load the page in which the bookmarklet + // was created (like getfirebug.com), before loading the injected UI HTML, + // generating an "Access Denied" error. + node.id = options.id; + } + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // create the Chrome as a "popup" + else + { + var height = FirebugChrome.height || options.height, + + options = [ + "true,top=", + Math.max(screen.availHeight - height - 61 /* Google Chrome bug */, 0), + ",left=0,height=", + height, + ",width=", + screen.availWidth-10, // Opera opens popup in a new tab if it's too big! + ",resizable" + ].join(""), + + node = chrome.node = context.window.open( + url, + "popup", + options + ); + + if (node) + { + try + { + node.focus(); + } + catch(E) + { + alert("Firebug Error: Firebug popup was blocked."); + return; + } + } + else + { + alert("Firebug Error: Firebug popup was blocked."); + return; + } + } + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Inject the interface HTML if it is not using the local skin + + if (!useLocalSkin) + { + var tpl = getChromeTemplate(!isChromeFrame), + doc = isChromeFrame ? node.contentWindow.document : node.document; + + doc.write(tpl); + doc.close(); + } + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Wait the Window to be loaded + + var win, + + waitDelay = useLocalSkin ? isChromeFrame ? 200 : 300 : 100, + + waitForWindow = function() + { + if ( // Frame loaded... OR + isChromeFrame && (win=node.contentWindow) && + node.contentWindow.document.getElementById("fbCommandLine") || + + // Popup loaded + !isChromeFrame && (win=node.window) && node.document && + node.document.getElementById("fbCommandLine") ) + { + chrome.window = win.window; + chrome.document = win.document; + + // Prevent getting the wrong chrome height in FF when opening a popup + setTimeout(function(){ + onChromeLoad(chrome); + },0); + } + else + setTimeout(waitForWindow, waitDelay); + }; + + waitForWindow(); + } + catch(e) + { + var msg = e.message || e; + + if (/access/i.test(msg)) + { + // Firebug Lite could not create a window for its Graphical User Interface due to + // a access restriction. This happens in some pages, when loading via bookmarklet. + // In such cases, the only way is to load the GUI in a "windowless mode". + + if (isChromeFrame) + body.removeChild(node); + else if(type == "popup") + node.close(); + + // Load the GUI in a "windowless mode" + createChromeDiv(); + } + else + { + alert("Firebug Error: Firebug GUI could not be created."); + } + } +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var onChromeLoad = function onChromeLoad(chrome) +{ + Env.chrome = chrome; + + if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Chrome onChromeLoad", "chrome window loaded"); + + if (Env.Options.enablePersistent) + { + // TODO: xxxpedro persist - make better chrome synchronization when in persistent mode + Env.FirebugChrome = FirebugChrome; + + chrome.window.Firebug = chrome.window.Firebug || {}; + chrome.window.Firebug.SharedEnv = Env; + + if (Env.isDevelopmentMode) + { + Env.browser.window.FBDev.loadChromeApplication(chrome); + } + else + { + var doc = chrome.document; + var script = doc.createElement("script"); + script.src = Env.Location.app + "#remote,persist"; + doc.getElementsByTagName("head")[0].appendChild(script); + } + } + else + { + if (chrome.type == "frame" || chrome.type == "div") + { + // initialize the chrome application + setTimeout(function(){ + FBL.Firebug.initialize(); + },0); + } + else if (chrome.type == "popup") + { + var oldChrome = FirebugChrome.chromeMap.frame; + + var newChrome = new Chrome(chrome); + + // TODO: xxxpedro sync detach reattach attach + dispatch(newChrome.panelMap, "detach", [oldChrome, newChrome]); + + if (oldChrome) + oldChrome.close(); + + newChrome.reattach(oldChrome, newChrome); + } + } +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var getChromeDivTemplate = function() +{ + return FirebugChrome.Skin.HTML; +}; + +var getChromeTemplate = function(isPopup) +{ + var tpl = FirebugChrome.Skin; + var r = [], i = -1; + + r[++i] = ''; + r[++i] = ''; + r[++i] = Firebug.version; + + /* + r[++i] = ''; + /**/ + + r[++i] = ''; + /**/ + + r[++i] = ''; + r[++i] = tpl.HTML; + r[++i] = ''; + + return r.join(""); +}; + + +// ************************************************************************************************ +// Chrome Class + +/**@class*/ +var Chrome = function Chrome(chrome) +{ + var type = chrome.type; + var Base = type == "frame" || type == "div" ? ChromeFrameBase : ChromePopupBase; + + append(this, Base); // inherit from base class (ChromeFrameBase or ChromePopupBase) + append(this, chrome); // inherit chrome window properties + append(this, new Context(chrome.window)); // inherit from Context class + + FirebugChrome.chromeMap[type] = this; + Firebug.chrome = this; + Env.chrome = chrome.window; + + this.commandLineVisible = false; + this.sidePanelVisible = false; + + this.create(); + + return this; +}; + +// ************************************************************************************************ +// ChromeBase + +/** + * @namespace + * @extends FBL.Controller + * @extends FBL.PanelBar + **/ +var ChromeBase = {}; +append(ChromeBase, Controller); +append(ChromeBase, PanelBar); +append(ChromeBase, +/**@extend ns-chrome-ChromeBase*/ +{ + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // inherited properties + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // inherited from createChrome function + + node: null, + type: null, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // inherited from Context.prototype + + document: null, + window: null, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // value properties + + sidePanelVisible: false, + commandLineVisible: false, + largeCommandLineVisible: false, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // object properties + + inspectButton: null, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + create: function() + { + PanelBar.create.call(this); + + if (Firebug.Inspector) + this.inspectButton = new Button({ + type: "toggle", + element: $("fbChrome_btInspect"), + owner: Firebug.Inspector, + + onPress: Firebug.Inspector.startInspecting, + onUnpress: Firebug.Inspector.stopInspecting + }); + }, + + destroy: function() + { + if(Firebug.Inspector) + this.inspectButton.destroy(); + + PanelBar.destroy.call(this); + + this.shutdown(); + }, + + testMenu: function() + { + var firebugMenu = new Menu( + { + id: "fbFirebugMenu", + + items: + [ + { + label: "Open Firebug", + type: "shortcut", + key: isFirefox ? "Shift+F12" : "F12", + checked: true, + command: "toggleChrome" + }, + { + label: "Open Firebug in New Window", + type: "shortcut", + key: isFirefox ? "Ctrl+Shift+F12" : "Ctrl+F12", + command: "openPopup" + }, + { + label: "Inspect Element", + type: "shortcut", + key: "Ctrl+Shift+C", + command: "toggleInspect" + }, + { + label: "Command Line", + type: "shortcut", + key: "Ctrl+Shift+L", + command: "focusCommandLine" + }, + "-", + { + label: "Options", + type: "group", + child: "fbFirebugOptionsMenu" + }, + "-", + { + label: "Firebug Lite Website...", + command: "visitWebsite" + }, + { + label: "Discussion Group...", + command: "visitDiscussionGroup" + }, + { + label: "Issue Tracker...", + command: "visitIssueTracker" + } + ], + + onHide: function() + { + iconButton.restore(); + }, + + toggleChrome: function() + { + Firebug.chrome.toggle(); + }, + + openPopup: function() + { + Firebug.chrome.toggle(true, true); + }, + + toggleInspect: function() + { + Firebug.Inspector.toggleInspect(); + }, + + focusCommandLine: function() + { + Firebug.chrome.focusCommandLine(); + }, + + visitWebsite: function() + { + this.visit("http://getfirebug.com/lite.html"); + }, + + visitDiscussionGroup: function() + { + this.visit("http://groups.google.com/group/firebug"); + }, + + visitIssueTracker: function() + { + this.visit("http://code.google.com/p/fbug/issues/list"); + }, + + visit: function(url) + { + window.open(url); + } + + }); + + /**@private*/ + var firebugOptionsMenu = + { + id: "fbFirebugOptionsMenu", + + getItems: function() + { + var cookiesDisabled = !Firebug.saveCookies; + + return [ + { + label: "Save Options in Cookies", + type: "checkbox", + value: "saveCookies", + checked: Firebug.saveCookies, + command: "saveOptions" + }, + "-", + { + label: "Start Opened", + type: "checkbox", + value: "startOpened", + checked: Firebug.startOpened, + disabled: cookiesDisabled + }, + { + label: "Start in New Window", + type: "checkbox", + value: "startInNewWindow", + checked: Firebug.startInNewWindow, + disabled: cookiesDisabled + }, + { + label: "Show Icon When Hidden", + type: "checkbox", + value: "showIconWhenHidden", + checked: Firebug.showIconWhenHidden, + disabled: cookiesDisabled + }, + { + label: "Override Console Object", + type: "checkbox", + value: "overrideConsole", + checked: Firebug.overrideConsole, + disabled: cookiesDisabled + }, + { + label: "Ignore Firebug Elements", + type: "checkbox", + value: "ignoreFirebugElements", + checked: Firebug.ignoreFirebugElements, + disabled: cookiesDisabled + }, + { + label: "Disable When Firebug Active", + type: "checkbox", + value: "disableWhenFirebugActive", + checked: Firebug.disableWhenFirebugActive, + disabled: cookiesDisabled + }, + { + label: "Disable XHR Listener", + type: "checkbox", + value: "disableXHRListener", + checked: Firebug.disableXHRListener, + disabled: cookiesDisabled + }, + { + label: "Enable Trace Mode", + type: "checkbox", + value: "enableTrace", + checked: Firebug.enableTrace, + disabled: cookiesDisabled + }, + { + label: "Enable Persistent Mode (experimental)", + type: "checkbox", + value: "enablePersistent", + checked: Firebug.enablePersistent, + disabled: cookiesDisabled + }, + "-", + { + label: "Reset All Firebug Options", + command: "restorePrefs", + disabled: cookiesDisabled + } + ]; + }, + + onCheck: function(target, value, checked) + { + Firebug.setPref(value, checked); + }, + + saveOptions: function(target) + { + var saveEnabled = target.getAttribute("checked"); + + if (!saveEnabled) this.restorePrefs(); + + this.updateMenu(target); + + return false; + }, + + restorePrefs: function(target) + { + Firebug.restorePrefs(); + + if(Firebug.saveCookies) + Firebug.savePrefs(); + else + Firebug.erasePrefs(); + + if (target) + this.updateMenu(target); + + return false; + }, + + updateMenu: function(target) + { + var options = getElementsByClass(target.parentNode, "fbMenuOption"); + + var firstOption = options[0]; + var enabled = Firebug.saveCookies; + if (enabled) + Menu.check(firstOption); + else + Menu.uncheck(firstOption); + + if (enabled) + Menu.check(options[0]); + else + Menu.uncheck(options[0]); + + for (var i = 1, length = options.length; i < length; i++) + { + var option = options[i]; + + var value = option.getAttribute("value"); + var pref = Firebug[value]; + + if (pref) + Menu.check(option); + else + Menu.uncheck(option); + + if (enabled) + Menu.enable(option); + else + Menu.disable(option); + } + } + }; + + Menu.register(firebugOptionsMenu); + + var menu = firebugMenu; + + var testMenuClick = function(event) + { + //console.log("testMenuClick"); + cancelEvent(event, true); + + var target = event.target || event.srcElement; + + if (menu.isVisible) + menu.hide(); + else + { + var offsetLeft = isIE6 ? 1 : -4, // IE6 problem with fixed position + + chrome = Firebug.chrome, + + box = chrome.getElementBox(target), + + offset = chrome.type == "div" ? + chrome.getElementPosition(chrome.node) : + {top: 0, left: 0}; + + menu.show( + box.left + offsetLeft - offset.left, + box.top + box.height -5 - offset.top + ); + } + + return false; + }; + + var iconButton = new IconButton({ + type: "toggle", + element: $("fbFirebugButton"), + + onClick: testMenuClick + }); + + iconButton.initialize(); + + //addEvent($("fbToolbarIcon"), "click", testMenuClick); + }, + + initialize: function() + { + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + if (Env.bookmarkletOutdated) + Firebug.Console.logFormatted([ + "A new bookmarklet version is available. " + + "Please visit http://getfirebug.com/firebuglite#Install and update it." + ], Firebug.context, "warn"); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + if (Firebug.Console) + Firebug.Console.flush(); + + if (Firebug.Trace) + FBTrace.flush(Firebug.Trace); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.chrome.initialize", "initializing chrome application"); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // initialize inherited classes + Controller.initialize.call(this); + PanelBar.initialize.call(this); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // create the interface elements cache + + fbTop = $("fbTop"); + fbContent = $("fbContent"); + fbContentStyle = fbContent.style; + fbBottom = $("fbBottom"); + fbBtnInspect = $("fbBtnInspect"); + + fbToolbar = $("fbToolbar"); + + fbPanelBox1 = $("fbPanelBox1"); + fbPanelBox1Style = fbPanelBox1.style; + fbPanelBox2 = $("fbPanelBox2"); + fbPanelBox2Style = fbPanelBox2.style; + fbPanelBar2Box = $("fbPanelBar2Box"); + fbPanelBar2BoxStyle = fbPanelBar2Box.style; + + fbHSplitter = $("fbHSplitter"); + fbVSplitter = $("fbVSplitter"); + fbVSplitterStyle = fbVSplitter.style; + + fbPanel1 = $("fbPanel1"); + fbPanel1Style = fbPanel1.style; + fbPanel2 = $("fbPanel2"); + fbPanel2Style = fbPanel2.style; + + fbConsole = $("fbConsole"); + fbConsoleStyle = fbConsole.style; + fbHTML = $("fbHTML"); + + fbCommandLine = $("fbCommandLine"); + fbLargeCommandLine = $("fbLargeCommandLine"); + fbLargeCommandButtons = $("fbLargeCommandButtons"); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // static values cache + topHeight = fbTop.offsetHeight; + topPartialHeight = fbToolbar.offsetHeight; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + disableTextSelection($("fbToolbar")); + disableTextSelection($("fbPanelBarBox")); + disableTextSelection($("fbPanelBar1")); + disableTextSelection($("fbPanelBar2")); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Add the "javascript:void(0)" href attributes used to make the hover effect in IE6 + if (isIE6 && Firebug.Selector) + { + // TODO: xxxpedro change to getElementsByClass + var as = $$(".fbHover"); + for (var i=0, a; a=as[i]; i++) + { + a.setAttribute("href", "javascript:void(0)"); + } + } + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // initialize all panels + /* + var panelMap = Firebug.panelTypes; + for (var i=0, p; p=panelMap[i]; i++) + { + if (!p.parentPanel) + { + this.addPanel(p.prototype.name); + } + } + /**/ + + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + + if(Firebug.Inspector) + this.inspectButton.initialize(); + + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + + this.addController( + [$("fbLargeCommandLineIcon"), "click", this.showLargeCommandLine] + ); + + // ************************************************************************************************ + + // Select the first registered panel + // TODO: BUG IE7 + var self = this; + setTimeout(function(){ + self.selectPanel(FirebugChrome.selectedPanelName); + + if (FirebugChrome.selectedPanelName == "Console" && Firebug.CommandLine) + Firebug.chrome.focusCommandLine(); + },0); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + //this.draw(); + + + + + + + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + var onPanelMouseDown = function onPanelMouseDown(event) + { + //console.log("onPanelMouseDown", event.target || event.srcElement, event); + + var target = event.target || event.srcElement; + + if (FBL.isLeftClick(event)) + { + var editable = FBL.getAncestorByClass(target, "editable"); + + // if an editable element has been clicked then start editing + if (editable) + { + Firebug.Editor.startEditing(editable); + FBL.cancelEvent(event); + } + // if any other element has been clicked then stop editing + else + { + if (!hasClass(target, "textEditorInner")) + Firebug.Editor.stopEditing(); + } + } + else if (FBL.isMiddleClick(event) && Firebug.getRepNode(target)) + { + // Prevent auto-scroll when middle-clicking a rep object + FBL.cancelEvent(event); + } + }; + + Firebug.getElementPanel = function(element) + { + var panelNode = getAncestorByClass(element, "fbPanel"); + var id = panelNode.id.substr(2); + + var panel = Firebug.chrome.panelMap[id]; + + if (!panel) + { + if (Firebug.chrome.selectedPanel.sidePanelBar) + panel = Firebug.chrome.selectedPanel.sidePanelBar.panelMap[id]; + } + + return panel; + }; + + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + // TODO: xxxpedro port to Firebug + + // Improved window key code event listener. Only one "keydown" event will be attached + // to the window, and the onKeyCodeListen() function will delegate which listeners + // should be called according to the event.keyCode fired. + var onKeyCodeListenersMap = []; + var onKeyCodeListen = function(event) + { + for (var keyCode in onKeyCodeListenersMap) + { + var listeners = onKeyCodeListenersMap[keyCode]; + + for (var i = 0, listener; listener = listeners[i]; i++) + { + var filter = listener.filter || FBL.noKeyModifiers; + + if (event.keyCode == keyCode && (!filter || filter(event))) + { + listener.listener(); + FBL.cancelEvent(event, true); + return false; + } + } + } + }; + + addEvent(Firebug.chrome.document, "keydown", onKeyCodeListen); + + /** + * @name keyCodeListen + * @memberOf FBL.FirebugChrome + */ + Firebug.chrome.keyCodeListen = function(key, filter, listener, capture) + { + var keyCode = KeyEvent["DOM_VK_"+key]; + + if (!onKeyCodeListenersMap[keyCode]) + onKeyCodeListenersMap[keyCode] = []; + + onKeyCodeListenersMap[keyCode].push({ + filter: filter, + listener: listener + }); + + return keyCode; + }; + + /** + * @name keyIgnore + * @memberOf FBL.FirebugChrome + */ + Firebug.chrome.keyIgnore = function(keyCode) + { + onKeyCodeListenersMap[keyCode] = null; + delete onKeyCodeListenersMap[keyCode]; + }; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + /**/ + // move to shutdown + //removeEvent(Firebug.chrome.document, "keydown", listener[0]); + + + /* + Firebug.chrome.keyCodeListen = function(key, filter, listener, capture) + { + if (!filter) + filter = FBL.noKeyModifiers; + + var keyCode = KeyEvent["DOM_VK_"+key]; + + var fn = function fn(event) + { + if (event.keyCode == keyCode && (!filter || filter(event))) + { + listener(); + FBL.cancelEvent(event, true); + return false; + } + } + + addEvent(Firebug.chrome.document, "keydown", fn); + + return [fn, capture]; + }; + + Firebug.chrome.keyIgnore = function(listener) + { + removeEvent(Firebug.chrome.document, "keydown", listener[0]); + }; + /**/ + + + this.addController( + [fbPanel1, "mousedown", onPanelMouseDown], + [fbPanel2, "mousedown", onPanelMouseDown] + ); +/**/ + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + + // menus can be used without domplate + if (FBL.domplate) + this.testMenu(); + /**/ + + //test XHR + /* + setTimeout(function(){ + + FBL.Ajax.request({url: "../content/firebug/boot.js"}); + FBL.Ajax.request({url: "../content/firebug/boot.js.invalid"}); + + },1000); + /**/ + }, + + shutdown: function() + { + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + + if(Firebug.Inspector) + this.inspectButton.shutdown(); + + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + // remove disableTextSelection event handlers + restoreTextSelection($("fbToolbar")); + restoreTextSelection($("fbPanelBarBox")); + restoreTextSelection($("fbPanelBar1")); + restoreTextSelection($("fbPanelBar2")); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // shutdown inherited classes + Controller.shutdown.call(this); + PanelBar.shutdown.call(this); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Remove the interface elements cache (this must happen after calling + // the shutdown method of all dependent components to avoid errors) + + fbTop = null; + fbContent = null; + fbContentStyle = null; + fbBottom = null; + fbBtnInspect = null; + + fbToolbar = null; + + fbPanelBox1 = null; + fbPanelBox1Style = null; + fbPanelBox2 = null; + fbPanelBox2Style = null; + fbPanelBar2Box = null; + fbPanelBar2BoxStyle = null; + + fbHSplitter = null; + fbVSplitter = null; + fbVSplitterStyle = null; + + fbPanel1 = null; + fbPanel1Style = null; + fbPanel2 = null; + + fbConsole = null; + fbConsoleStyle = null; + fbHTML = null; + + fbCommandLine = null; + fbLargeCommandLine = null; + fbLargeCommandButtons = null; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // static values cache + + topHeight = null; + topPartialHeight = null; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + toggle: function(forceOpen, popup) + { + if(popup) + { + this.detach(); + } + else + { + if (isOpera && Firebug.chrome.type == "popup" && Firebug.chrome.node.closed) + { + var frame = FirebugChrome.chromeMap.frame; + frame.reattach(); + + FirebugChrome.chromeMap.popup = null; + + frame.open(); + + return; + } + + // If the context is a popup, ignores the toggle process + if (Firebug.chrome.type == "popup") return; + + var shouldOpen = forceOpen || !FirebugChrome.isOpen; + + if(shouldOpen) + this.open(); + else + this.close(); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + detach: function() + { + if(!FirebugChrome.chromeMap.popup) + { + createChromeWindow({type: "popup"}); + } + }, + + reattach: function(oldChrome, newChrome) + { + Firebug.browser.window.Firebug = Firebug; + + // chrome synchronization + var newPanelMap = newChrome.panelMap; + var oldPanelMap = oldChrome.panelMap; + + var panel; + for(var name in newPanelMap) + { + // TODO: xxxpedro innerHTML + panel = newPanelMap[name]; + if (panel.options.innerHTMLSync) + panel.panelNode.innerHTML = oldPanelMap[name].panelNode.innerHTML; + } + + Firebug.chrome = newChrome; + + // TODO: xxxpedro sync detach reattach attach + //dispatch(Firebug.chrome.panelMap, "detach", [oldChrome, newChrome]); + + if (newChrome.type == "popup") + { + newChrome.initialize(); + //dispatch(Firebug.modules, "initialize", []); + } + else + { + // TODO: xxxpedro only needed in persistent + // should use FirebugChrome.clone, but popup FBChrome + // isn't acessible + FirebugChrome.selectedPanelName = oldChrome.selectedPanel.name; + } + + dispatch(newPanelMap, "reattach", [oldChrome, newChrome]); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + draw: function() + { + var size = this.getSize(); + + // Height related values + var commandLineHeight = Firebug.chrome.commandLineVisible ? fbCommandLine.offsetHeight : 0, + + y = Math.max(size.height /* chrome height */, topHeight), + + heightValue = Math.max(y - topHeight - commandLineHeight /* fixed height */, 0), + + height = heightValue + "px", + + // Width related values + sideWidthValue = Firebug.chrome.sidePanelVisible ? FirebugChrome.sidePanelWidth : 0, + + width = Math.max(size.width /* chrome width */ - sideWidthValue, 0) + "px"; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Height related rendering + fbPanelBox1Style.height = height; + fbPanel1Style.height = height; + + if (isIE || isOpera) + { + // Fix IE and Opera problems with auto resizing the verticall splitter + fbVSplitterStyle.height = Math.max(y - topPartialHeight - commandLineHeight, 0) + "px"; + } + //xxxpedro FF2 only? + /* + else if (isFirefox) + { + // Fix Firefox problem with table rows with 100% height (fit height) + fbContentStyle.maxHeight = Math.max(y - fixedHeight, 0)+ "px"; + }/**/ + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Width related rendering + fbPanelBox1Style.width = width; + fbPanel1Style.width = width; + + // SidePanel rendering + if (Firebug.chrome.sidePanelVisible) + { + sideWidthValue = Math.max(sideWidthValue - 6, 0); + + var sideWidth = sideWidthValue + "px"; + + fbPanelBox2Style.width = sideWidth; + + fbVSplitterStyle.right = sideWidth; + + if (Firebug.chrome.largeCommandLineVisible) + { + fbLargeCommandLine = $("fbLargeCommandLine"); + + fbLargeCommandLine.style.height = heightValue - 4 + "px"; + fbLargeCommandLine.style.width = sideWidthValue - 2 + "px"; + + fbLargeCommandButtons = $("fbLargeCommandButtons"); + fbLargeCommandButtons.style.width = sideWidth; + } + else + { + fbPanel2Style.height = height; + fbPanel2Style.width = sideWidth; + + fbPanelBar2BoxStyle.width = sideWidth; + } + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getSize: function() + { + return this.type == "div" ? + { + height: this.node.offsetHeight, + width: this.node.offsetWidth + } + : + this.getWindowSize(); + }, + + resize: function() + { + var self = this; + + // avoid partial resize when maximizing window + setTimeout(function(){ + self.draw(); + + if (noFixedPosition && (self.type == "frame" || self.type == "div")) + self.fixIEPosition(); + }, 0); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + layout: function(panel) + { + if (FBTrace.DBG_CHROME) FBTrace.sysout("Chrome.layout", ""); + + var options = panel.options; + + changeCommandLineVisibility(options.hasCommandLine); + changeSidePanelVisibility(panel.hasSidePanel); + + Firebug.chrome.draw(); + }, + + showLargeCommandLine: function(hideToggleIcon) + { + var chrome = Firebug.chrome; + + if (!chrome.largeCommandLineVisible) + { + chrome.largeCommandLineVisible = true; + + if (chrome.selectedPanel.options.hasCommandLine) + { + if (Firebug.CommandLine) + Firebug.CommandLine.blur(); + + changeCommandLineVisibility(false); + } + + changeSidePanelVisibility(true); + + fbLargeCommandLine.style.display = "block"; + fbLargeCommandButtons.style.display = "block"; + + fbPanel2Style.display = "none"; + fbPanelBar2BoxStyle.display = "none"; + + chrome.draw(); + + fbLargeCommandLine.focus(); + + if (Firebug.CommandLine) + Firebug.CommandLine.setMultiLine(true); + } + }, + + hideLargeCommandLine: function() + { + if (Firebug.chrome.largeCommandLineVisible) + { + Firebug.chrome.largeCommandLineVisible = false; + + if (Firebug.CommandLine) + Firebug.CommandLine.setMultiLine(false); + + fbLargeCommandLine.blur(); + + fbPanel2Style.display = "block"; + fbPanelBar2BoxStyle.display = "block"; + + fbLargeCommandLine.style.display = "none"; + fbLargeCommandButtons.style.display = "none"; + + changeSidePanelVisibility(false); + + if (Firebug.chrome.selectedPanel.options.hasCommandLine) + changeCommandLineVisibility(true); + + Firebug.chrome.draw(); + + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + focusCommandLine: function() + { + var selectedPanelName = this.selectedPanel.name, panelToSelect; + + if (focusCommandLineState == 0 || selectedPanelName != "Console") + { + focusCommandLineState = 0; + lastFocusedPanelName = selectedPanelName; + + panelToSelect = "Console"; + } + if (focusCommandLineState == 1) + { + panelToSelect = lastFocusedPanelName; + } + + this.selectPanel(panelToSelect); + + try + { + if (Firebug.CommandLine) + { + if (panelToSelect == "Console") + Firebug.CommandLine.focus(); + else + Firebug.CommandLine.blur(); + } + } + catch(e) + { + //TODO: xxxpedro trace error + } + + focusCommandLineState = ++focusCommandLineState % 2; + } + +}); + +// ************************************************************************************************ +// ChromeFrameBase + +/** + * @namespace + * @extends ns-chrome-ChromeBase + */ +var ChromeFrameBase = extend(ChromeBase, +/**@extend ns-chrome-ChromeFrameBase*/ +{ + create: function() + { + ChromeBase.create.call(this); + + // restore display for the anti-flicker trick + if (isFirefox) + this.node.style.display = "block"; + + if (Env.Options.startInNewWindow) + { + this.close(); + this.toggle(true, true); + return; + } + + if (Env.Options.startOpened) + this.open(); + else + this.close(); + }, + + destroy: function() + { + removeGlobalEvent("keydown", onGlobalKeyDown); + + ChromeBase.destroy.call(this); + + this.document = null; + delete this.document; + + this.window = null; + delete this.window; + + this.node.parentNode.removeChild(this.node); + this.node = null; + delete this.node; + }, + + initialize: function() + { + //FBTrace.sysout("Frame", "initialize();") + ChromeBase.initialize.call(this); + + this.addController( + [Firebug.browser.window, "resize", this.resize], + [$("fbWindow_btClose"), "click", this.close], + [$("fbWindow_btDetach"), "click", this.detach], + [$("fbWindow_btDeactivate"), "click", this.deactivate] + ); + + if (!Env.Options.enablePersistent) + this.addController([Firebug.browser.window, "unload", Firebug.shutdown]); + + if (noFixedPosition) + { + this.addController( + [Firebug.browser.window, "scroll", this.fixIEPosition] + ); + } + + fbVSplitter.onmousedown = onVSplitterMouseDown; + fbHSplitter.onmousedown = onHSplitterMouseDown; + + this.isInitialized = true; + }, + + shutdown: function() + { + fbVSplitter.onmousedown = null; + fbHSplitter.onmousedown = null; + + ChromeBase.shutdown.apply(this); + + this.isInitialized = false; + }, + + reattach: function() + { + var frame = FirebugChrome.chromeMap.frame; + + ChromeBase.reattach(FirebugChrome.chromeMap.popup, this); + }, + + open: function() + { + if (!FirebugChrome.isOpen) + { + FirebugChrome.isOpen = true; + + if (Env.isChromeExtension) + localStorage.setItem("Firebug", "1,1"); + + var node = this.node; + + node.style.visibility = "hidden"; // Avoid flickering + + if (Firebug.showIconWhenHidden) + { + if (ChromeMini.isInitialized) + { + ChromeMini.shutdown(); + } + + } + else + node.style.display = "block"; + + var main = $("fbChrome"); + + // IE6 throws an error when setting this property! why? + //main.style.display = "table"; + main.style.display = ""; + + var self = this; + setTimeout(function(){ + node.style.visibility = "visible"; + + //dispatch(Firebug.modules, "initialize", []); + self.initialize(); + + if (noFixedPosition) + self.fixIEPosition(); + + self.draw(); + + }, 10); + } + }, + + close: function() + { + if (FirebugChrome.isOpen || !this.isInitialized) + { + if (this.isInitialized) + { + //dispatch(Firebug.modules, "shutdown", []); + this.shutdown(); + } + + FirebugChrome.isOpen = false; + + if (Env.isChromeExtension) + localStorage.setItem("Firebug", "1,0"); + + var node = this.node; + + if (Firebug.showIconWhenHidden) + { + node.style.visibility = "hidden"; // Avoid flickering + + // TODO: xxxpedro - persist IE fixed? + var main = $("fbChrome", FirebugChrome.chromeMap.frame.document); + main.style.display = "none"; + + ChromeMini.initialize(); + + node.style.visibility = "visible"; + } + else + node.style.display = "none"; + } + }, + + deactivate: function() + { + // if it is running as a Chrome extension, dispatch a message to the extension signaling + // that Firebug should be deactivated for the current tab + if (Env.isChromeExtension) + { + localStorage.removeItem("Firebug"); + Firebug.GoogleChrome.dispatch("FB_deactivate"); + + // xxxpedro problem here regarding Chrome extension. We can't deactivate the whole + // app, otherwise it won't be able to be reactivated without reloading the page. + // but we need to stop listening global keys, otherwise the key activation won't work. + Firebug.chrome.close(); + } + else + { + Firebug.shutdown(); + } + }, + + fixIEPosition: function() + { + // fix IE problem with offset when not in fullscreen mode + var doc = this.document; + var offset = isIE ? doc.body.clientTop || doc.documentElement.clientTop: 0; + + var size = Firebug.browser.getWindowSize(); + var scroll = Firebug.browser.getWindowScrollPosition(); + var maxHeight = size.height; + var height = this.node.offsetHeight; + + var bodyStyle = doc.body.currentStyle; + + this.node.style.top = maxHeight - height + scroll.top + "px"; + + if ((this.type == "frame" || this.type == "div") && + (bodyStyle.marginLeft || bodyStyle.marginRight)) + { + this.node.style.width = size.width + "px"; + } + + if (fbVSplitterStyle) + fbVSplitterStyle.right = FirebugChrome.sidePanelWidth + "px"; + + this.draw(); + } + +}); + + +// ************************************************************************************************ +// ChromeMini + +/** + * @namespace + * @extends FBL.Controller + */ +var ChromeMini = extend(Controller, +/**@extend ns-chrome-ChromeMini*/ +{ + create: function(chrome) + { + append(this, chrome); + this.type = "mini"; + }, + + initialize: function() + { + Controller.initialize.apply(this); + + var doc = FirebugChrome.chromeMap.frame.document; + + var mini = $("fbMiniChrome", doc); + mini.style.display = "block"; + + var miniIcon = $("fbMiniIcon", doc); + var width = miniIcon.offsetWidth + 10; + miniIcon.title = "Open " + Firebug.version; + + var errors = $("fbMiniErrors", doc); + if (errors.offsetWidth) + width += errors.offsetWidth + 10; + + var node = this.node; + node.style.height = "27px"; + node.style.width = width + "px"; + node.style.left = ""; + node.style.right = 0; + + if (this.node.nodeName.toLowerCase() == "iframe") + { + node.setAttribute("allowTransparency", "true"); + this.document.body.style.backgroundColor = "transparent"; + } + else + node.style.background = "transparent"; + + if (noFixedPosition) + this.fixIEPosition(); + + this.addController( + [$("fbMiniIcon", doc), "click", onMiniIconClick] + ); + + if (noFixedPosition) + { + this.addController( + [Firebug.browser.window, "scroll", this.fixIEPosition] + ); + } + + this.isInitialized = true; + }, + + shutdown: function() + { + var node = this.node; + node.style.height = FirebugChrome.height + "px"; + node.style.width = "100%"; + node.style.left = 0; + node.style.right = ""; + + if (this.node.nodeName.toLowerCase() == "iframe") + { + node.setAttribute("allowTransparency", "false"); + this.document.body.style.backgroundColor = "#fff"; + } + else + node.style.background = "#fff"; + + if (noFixedPosition) + this.fixIEPosition(); + + var doc = FirebugChrome.chromeMap.frame.document; + + var mini = $("fbMiniChrome", doc); + mini.style.display = "none"; + + Controller.shutdown.apply(this); + + this.isInitialized = false; + }, + + draw: function() + { + + }, + + fixIEPosition: ChromeFrameBase.fixIEPosition + +}); + + +// ************************************************************************************************ +// ChromePopupBase + +/** + * @namespace + * @extends ns-chrome-ChromeBase + */ +var ChromePopupBase = extend(ChromeBase, +/**@extend ns-chrome-ChromePopupBase*/ +{ + + initialize: function() + { + setClass(this.document.body, "FirebugPopup"); + + ChromeBase.initialize.call(this); + + this.addController( + [Firebug.chrome.window, "resize", this.resize], + [Firebug.chrome.window, "unload", this.destroy] + ); + + if (Env.Options.enablePersistent) + { + this.persist = bind(this.persist, this); + addEvent(Firebug.browser.window, "unload", this.persist); + } + else + this.addController( + [Firebug.browser.window, "unload", this.close] + ); + + fbVSplitter.onmousedown = onVSplitterMouseDown; + }, + + destroy: function() + { + // TODO: xxxpedro sync detach reattach attach + var frame = FirebugChrome.chromeMap.frame; + + if(frame) + { + dispatch(frame.panelMap, "detach", [this, frame]); + + frame.reattach(this, frame); + } + + if (Env.Options.enablePersistent) + { + removeEvent(Firebug.browser.window, "unload", this.persist); + } + + ChromeBase.destroy.apply(this); + + FirebugChrome.chromeMap.popup = null; + + this.node.close(); + }, + + persist: function() + { + persistTimeStart = new Date().getTime(); + + removeEvent(Firebug.browser.window, "unload", this.persist); + + Firebug.Inspector.destroy(); + Firebug.browser.window.FirebugOldBrowser = true; + + var persistTimeStart = new Date().getTime(); + + var waitMainWindow = function() + { + var doc, head; + + try + { + if (window.opener && !window.opener.FirebugOldBrowser && (doc = window.opener.document)/* && + doc.documentElement && (head = doc.documentElement.firstChild)*/) + { + + try + { + // exposes the FBL to the global namespace when in debug mode + if (Env.isDebugMode) + { + window.FBL = FBL; + } + + window.Firebug = Firebug; + window.opener.Firebug = Firebug; + + Env.browser = window.opener; + Firebug.browser = Firebug.context = new Context(Env.browser); + + registerConsole(); + + // the delay time should be calculated right after registering the + // console, once right after the console registration, call log messages + // will be properly handled + var persistDelay = new Date().getTime() - persistTimeStart; + + var chrome = Firebug.chrome; + addEvent(Firebug.browser.window, "unload", chrome.persist); + + FBL.cacheDocument(); + Firebug.Inspector.create(); + + var htmlPanel = chrome.getPanel("HTML"); + htmlPanel.createUI(); + + Firebug.Console.logFormatted( + ["Firebug could not capture console calls during " + + persistDelay + "ms"], + Firebug.context, + "info" + ); + } + catch(pE) + { + alert("persist error: " + (pE.message || pE)); + } + + } + else + { + window.setTimeout(waitMainWindow, 0); + } + + } catch (E) { + window.close(); + } + }; + + waitMainWindow(); + }, + + close: function() + { + this.destroy(); + } + +}); + + +//************************************************************************************************ +// UI helpers + +var changeCommandLineVisibility = function changeCommandLineVisibility(visibility) +{ + var last = Firebug.chrome.commandLineVisible; + var visible = Firebug.chrome.commandLineVisible = + typeof visibility == "boolean" ? visibility : !Firebug.chrome.commandLineVisible; + + if (visible != last) + { + if (visible) + { + fbBottom.className = ""; + + if (Firebug.CommandLine) + Firebug.CommandLine.activate(); + } + else + { + if (Firebug.CommandLine) + Firebug.CommandLine.deactivate(); + + fbBottom.className = "hide"; + } + } +}; + +var changeSidePanelVisibility = function changeSidePanelVisibility(visibility) +{ + var last = Firebug.chrome.sidePanelVisible; + Firebug.chrome.sidePanelVisible = + typeof visibility == "boolean" ? visibility : !Firebug.chrome.sidePanelVisible; + + if (Firebug.chrome.sidePanelVisible != last) + { + fbPanelBox2.className = Firebug.chrome.sidePanelVisible ? "" : "hide"; + fbPanelBar2Box.className = Firebug.chrome.sidePanelVisible ? "" : "hide"; + } +}; + + +// ************************************************************************************************ +// F12 Handler + +var onGlobalKeyDown = function onGlobalKeyDown(event) +{ + var keyCode = event.keyCode; + var shiftKey = event.shiftKey; + var ctrlKey = event.ctrlKey; + + if (keyCode == 123 /* F12 */ && (!isFirefox && !shiftKey || shiftKey && isFirefox)) + { + Firebug.chrome.toggle(false, ctrlKey); + cancelEvent(event, true); + + // TODO: xxxpedro replace with a better solution. we're doing this + // to allow reactivating with the F12 key after being deactivated + if (Env.isChromeExtension) + { + Firebug.GoogleChrome.dispatch("FB_enableIcon"); + } + } + else if (keyCode == 67 /* C */ && ctrlKey && shiftKey) + { + Firebug.Inspector.toggleInspect(); + cancelEvent(event, true); + } + else if (keyCode == 76 /* L */ && ctrlKey && shiftKey) + { + Firebug.chrome.focusCommandLine(); + cancelEvent(event, true); + } +}; + +var onMiniIconClick = function onMiniIconClick(event) +{ + Firebug.chrome.toggle(false, event.ctrlKey); + cancelEvent(event, true); +}; + + +// ************************************************************************************************ +// Horizontal Splitter Handling + +var onHSplitterMouseDown = function onHSplitterMouseDown(event) +{ + addGlobalEvent("mousemove", onHSplitterMouseMove); + addGlobalEvent("mouseup", onHSplitterMouseUp); + + if (isIE) + addEvent(Firebug.browser.document.documentElement, "mouseleave", onHSplitterMouseUp); + + fbHSplitter.className = "fbOnMovingHSplitter"; + + return false; +}; + +var onHSplitterMouseMove = function onHSplitterMouseMove(event) +{ + cancelEvent(event, true); + + var clientY = event.clientY; + var win = isIE + ? event.srcElement.ownerDocument.parentWindow + : event.target.ownerDocument && event.target.ownerDocument.defaultView; + + if (!win) + return; + + if (win != win.parent) + { + var frameElement = win.frameElement; + if (frameElement) + { + var framePos = Firebug.browser.getElementPosition(frameElement).top; + clientY += framePos; + + if (frameElement.style.position != "fixed") + clientY -= Firebug.browser.getWindowScrollPosition().top; + } + } + + if (isOpera && isQuiksMode && win.frameElement.id == "FirebugUI") + { + clientY = Firebug.browser.getWindowSize().height - win.frameElement.offsetHeight + clientY; + } + /* + console.log( + typeof win.FBL != "undefined" ? "no-Chrome" : "Chrome", + //win.frameElement.id, + event.target, + clientY + );/**/ + + onHSplitterMouseMoveBuffer = clientY; // buffer + + if (new Date().getTime() - lastHSplitterMouseMove > chromeRedrawSkipRate) // frame skipping + { + lastHSplitterMouseMove = new Date().getTime(); + handleHSplitterMouseMove(); + } + else + if (!onHSplitterMouseMoveTimer) + onHSplitterMouseMoveTimer = setTimeout(handleHSplitterMouseMove, chromeRedrawSkipRate); + + // improving the resizing performance by canceling the mouse event. + // canceling events will prevent the page to receive such events, which would imply + // in more processing being expended. + cancelEvent(event, true); + return false; +}; + +var handleHSplitterMouseMove = function() +{ + if (onHSplitterMouseMoveTimer) + { + clearTimeout(onHSplitterMouseMoveTimer); + onHSplitterMouseMoveTimer = null; + } + + var clientY = onHSplitterMouseMoveBuffer; + + var windowSize = Firebug.browser.getWindowSize(); + var scrollSize = Firebug.browser.getWindowScrollSize(); + + // compute chrome fixed size (top bar and command line) + var commandLineHeight = Firebug.chrome.commandLineVisible ? fbCommandLine.offsetHeight : 0; + var fixedHeight = topHeight + commandLineHeight; + var chromeNode = Firebug.chrome.node; + + var scrollbarSize = !isIE && (scrollSize.width > windowSize.width) ? 17 : 0; + + //var height = !isOpera ? chromeNode.offsetTop + chromeNode.clientHeight : windowSize.height; + var height = windowSize.height; + + // compute the min and max size of the chrome + var chromeHeight = Math.max(height - clientY + 5 - scrollbarSize, fixedHeight); + chromeHeight = Math.min(chromeHeight, windowSize.height - scrollbarSize); + + FirebugChrome.height = chromeHeight; + chromeNode.style.height = chromeHeight + "px"; + + if (noFixedPosition) + Firebug.chrome.fixIEPosition(); + + Firebug.chrome.draw(); +}; + +var onHSplitterMouseUp = function onHSplitterMouseUp(event) +{ + removeGlobalEvent("mousemove", onHSplitterMouseMove); + removeGlobalEvent("mouseup", onHSplitterMouseUp); + + if (isIE) + removeEvent(Firebug.browser.document.documentElement, "mouseleave", onHSplitterMouseUp); + + fbHSplitter.className = ""; + + Firebug.chrome.draw(); + + // avoid text selection in IE when returning to the document + // after the mouse leaves the document during the resizing + return false; +}; + + +// ************************************************************************************************ +// Vertical Splitter Handling + +var onVSplitterMouseDown = function onVSplitterMouseDown(event) +{ + addGlobalEvent("mousemove", onVSplitterMouseMove); + addGlobalEvent("mouseup", onVSplitterMouseUp); + + return false; +}; + +var onVSplitterMouseMove = function onVSplitterMouseMove(event) +{ + if (new Date().getTime() - lastVSplitterMouseMove > chromeRedrawSkipRate) // frame skipping + { + var target = event.target || event.srcElement; + if (target && target.ownerDocument) // avoid error when cursor reaches out of the chrome + { + var clientX = event.clientX; + var win = document.all + ? event.srcElement.ownerDocument.parentWindow + : event.target.ownerDocument.defaultView; + + if (win != win.parent) + clientX += win.frameElement ? win.frameElement.offsetLeft : 0; + + var size = Firebug.chrome.getSize(); + var x = Math.max(size.width - clientX + 3, 6); + + FirebugChrome.sidePanelWidth = x; + Firebug.chrome.draw(); + } + + lastVSplitterMouseMove = new Date().getTime(); + } + + cancelEvent(event, true); + return false; +}; + +var onVSplitterMouseUp = function onVSplitterMouseUp(event) +{ + removeGlobalEvent("mousemove", onVSplitterMouseMove); + removeGlobalEvent("mouseup", onVSplitterMouseUp); + + Firebug.chrome.draw(); +}; + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +Firebug.Lite = +{ +}; + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + + +Firebug.Lite.Browser = function(window) +{ + this.contentWindow = window; + this.contentDocument = window.document; + this.currentURI = + { + spec: window.location.href + }; +}; + +Firebug.Lite.Browser.prototype = +{ + toString: function() + { + return "Firebug.Lite.Browser"; + } +}; + + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +Firebug.Lite.Cache = +{ + ID: "firebug" + new Date().getTime() +}; + +// ************************************************************************************************ + +/** + * TODO: if a cached element is cloned, the expando property will be cloned too in IE + * which will result in a bug. Firebug Lite will think the new cloned node is the old + * one. + * + * TODO: Investigate a possibility of cache validation, to be customized by each + * kind of cache. For ElementCache it should validate if the element still is + * inserted at the DOM. + */ +var cacheUID = 0; +var createCache = function() +{ + var map = {}; + var 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 = element[CID]; + + if (!id) + { + id = ++cacheUID; + element[CID] = id; + } + + if (!map.hasOwnProperty(id)) + { + map[id] = element; + } + + return id; + }, + + unset: function(element) + { + var id = element[CID]; + + if (supportsDeleteExpando) + { + delete element[CID]; + } + else if (element.removeAttribute) + { + element.removeAttribute(CID); + } + + delete map[id]; + + }, + + key: function(element) + { + return element[CID]; + }, + + has: function(element) + { + return map.hasOwnProperty(element[CID]); + }, + + clear: function() + { + for (var id in map) + { + var element = map[id]; + cacheAPI.unset(element); + } + } + }; + + 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(); + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + + +Firebug.Lite.Proxy = +{ + // jsonp callbacks + _callbacks: {}, + + /** + * Load a resource, either locally (directly) or externally (via proxy) using + * synchronous XHR calls. Loading external resources requires the proxy plugin to + * be installed and configured (see /plugin/proxy/proxy.php). + */ + load: function(url) + { + var resourceDomain = getDomain(url); + var isLocalResource = + // empty domain means local URL + !resourceDomain || + // same domain means local too + resourceDomain == Firebug.context.window.location.host; // TODO: xxxpedro context + + return isLocalResource ? fetchResource(url) : fetchProxyResource(url); + }, + + /** + * Load a resource using JSONP technique. + */ + loadJSONP: function(url, callback) + { + var script = createGlobalElement("script"), + doc = Firebug.context.document, + + uid = "" + new Date().getTime(), + callbackName = "callback=Firebug.Lite.Proxy._callbacks." + uid, + + jsonpURL = url.indexOf("?") != -1 ? + url + "&" + callbackName : + url + "?" + callbackName; + + Firebug.Lite.Proxy._callbacks[uid] = function(data) + { + if (callback) + callback(data); + + script.parentNode.removeChild(script); + delete Firebug.Lite.Proxy._callbacks[uid]; + }; + + script.src = jsonpURL; + + if (doc.documentElement) + doc.documentElement.appendChild(script); + }, + + /** + * Load a resource using YQL (not reliable). + */ + YQL: function(url, callback) + { + var yql = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22" + + encodeURIComponent(url) + "%22&format=xml"; + + this.loadJSONP(yql, function(data) + { + var source = data.results[0]; + + // clean up YQL bogus elements + var match = /\s+

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

      "; + + // Safari can't handle uppercase or unicode characters when + // in quirks mode. + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function(query, context, extra, seed){ + context = context || document; + + // Only use querySelectorAll on non-XML documents + // (ID selectors don't work in non-HTML documents) + if ( !seed && context.nodeType === 9 && !isXML(context) ) { + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(e){} + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; + } + + div = null; // release memory in IE +})(); + +if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){ + var div = document.createElement("div"); + div.innerHTML = "
      "; + + // Opera can't find a second classname (in 9.6) + if ( div.getElementsByClassName("e").length === 0 ) + return; + + // Safari caches class attributes, doesn't catch changes (in 3.2) + div.lastChild.className = "e"; + + if ( div.getElementsByClassName("e").length === 1 ) + return; + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS = function(match, context, isXML) { + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { + return context.getElementsByClassName(match[1]); + } + }; + + div = null; // release memory in IE +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + var sibDir = dir == "previousSibling" && !isXML; + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + if ( elem ) { + if ( sibDir && elem.nodeType === 1 ){ + elem.sizcache = doneName; + elem.sizset = i; + } + elem = elem[dir]; + var match = false; + + while ( elem ) { + if ( elem.sizcache === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem.sizcache = doneName; + elem.sizset = i; + } + + if ( elem.nodeName === cur ) { + match = elem; + break; + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + var sibDir = dir == "previousSibling" && !isXML; + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + if ( elem ) { + if ( sibDir && elem.nodeType === 1 ) { + elem.sizcache = doneName; + elem.sizset = i; + } + elem = elem[dir]; + var match = false; + + while ( elem ) { + if ( elem.sizcache === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem.sizcache = doneName; + elem.sizset = i; + } + if ( typeof cur !== "string" ) { + if ( elem === cur ) { + match = true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match = elem; + break; + } + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +var contains = document.compareDocumentPosition ? function(a, b){ + return a.compareDocumentPosition(b) & 16; +} : function(a, b){ + return a !== b && (a.contains ? a.contains(b) : true); +}; + +var isXML = function(elem){ + return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" || + !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML"; +}; + +var posProcess = function(selector, context){ + var tmpSet = [], later = "", match, + root = context.nodeType ? [context] : context; + + // Position selectors must be done after the filter + // And so must :not(positional) so we move all PSEUDOs to the end + while ( (match = Expr.match.PSEUDO.exec( selector )) ) { + later += match[0]; + selector = selector.replace( Expr.match.PSEUDO, "" ); + } + + selector = Expr.relative[selector] ? selector + "*" : selector; + + for ( var i = 0, l = root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE + +Firebug.Selector = Sizzle; + +/**#@-*/ + +// ************************************************************************************************ +}}); + +// Problems in IE +// FIXED - eval return +// FIXED - addEventListener problem in IE +// FIXED doc.createRange? +// +// class reserved word +// test all honza examples in IE6 and IE7 + + +/* See license.txt for terms of usage */ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +function DomplateTag(tagName) +{ + this.tagName = tagName; +} + +function DomplateEmbed() +{ +} + +function DomplateLoop() +{ +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +( /** @scope ns-domplate */ function() { + +var womb = null; + +var domplate = FBL.domplate = function() +{ + var lastSubject; + for (var i = 0; i < arguments.length; ++i) + lastSubject = lastSubject ? copyObject(lastSubject, arguments[i]) : arguments[i]; + + for (var name in lastSubject) + { + var val = lastSubject[name]; + if (isTag(val)) + val.tag.subject = lastSubject; + } + + return lastSubject; +}; + +domplate.context = function(context, fn) +{ + var lastContext = domplate.lastContext; + domplate.topContext = context; + fn.apply(context); + domplate.topContext = lastContext; +}; + +FBL.TAG = function() +{ + var embed = new DomplateEmbed(); + return embed.merge(arguments); +}; + +FBL.FOR = function() +{ + var loop = new DomplateLoop(); + return loop.merge(arguments); +}; + +DomplateTag.prototype = +{ + merge: function(args, oldTag) + { + if (oldTag) + this.tagName = oldTag.tagName; + + this.context = oldTag ? oldTag.context : null; + this.subject = oldTag ? oldTag.subject : null; + this.attrs = oldTag ? copyObject(oldTag.attrs) : {}; + this.classes = oldTag ? copyObject(oldTag.classes) : {}; + this.props = oldTag ? copyObject(oldTag.props) : null; + this.listeners = oldTag ? copyArray(oldTag.listeners) : null; + this.children = oldTag ? copyArray(oldTag.children) : []; + this.vars = oldTag ? copyArray(oldTag.vars) : []; + + var attrs = args.length ? args[0] : null; + var hasAttrs = typeof(attrs) == "object" && !isTag(attrs); + + this.children = []; + + if (domplate.topContext) + this.context = domplate.topContext; + + if (args.length) + parseChildren(args, hasAttrs ? 1 : 0, this.vars, this.children); + + if (hasAttrs) + this.parseAttrs(attrs); + + return creator(this, DomplateTag); + }, + + parseAttrs: function(args) + { + for (var name in args) + { + var val = parseValue(args[name]); + readPartNames(val, this.vars); + + if (name.indexOf("on") == 0) + { + var eventName = name.substr(2); + if (!this.listeners) + this.listeners = []; + this.listeners.push(eventName, val); + } + else if (name.indexOf("_") == 0) + { + var propName = name.substr(1); + if (!this.props) + this.props = {}; + this.props[propName] = val; + } + else if (name.indexOf("$") == 0) + { + var className = name.substr(1); + if (!this.classes) + this.classes = {}; + this.classes[className] = val; + } + else + { + if (name == "class" && this.attrs.hasOwnProperty(name) ) + this.attrs[name] += " " + val; + else + this.attrs[name] = val; + } + } + }, + + compile: function() + { + if (this.renderMarkup) + return; + + this.compileMarkup(); + this.compileDOM(); + + //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate renderMarkup: ", this.renderMarkup); + //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate renderDOM:", this.renderDOM); + //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate domArgs:", this.domArgs); + }, + + compileMarkup: function() + { + this.markupArgs = []; + var topBlock = [], topOuts = [], blocks = [], info = {args: this.markupArgs, argIndex: 0}; + + this.generateMarkup(topBlock, topOuts, blocks, info); + this.addCode(topBlock, topOuts, blocks); + + var fnBlock = ['r=(function (__code__, __context__, __in__, __out__']; + for (var i = 0; i < info.argIndex; ++i) + fnBlock.push(', s', i); + fnBlock.push(') {'); + + if (this.subject) + fnBlock.push('with (this) {'); + if (this.context) + fnBlock.push('with (__context__) {'); + fnBlock.push('with (__in__) {'); + + fnBlock.push.apply(fnBlock, blocks); + + if (this.subject) + fnBlock.push('}'); + if (this.context) + fnBlock.push('}'); + + fnBlock.push('}})'); + + function __link__(tag, code, outputs, args) + { + if (!tag || !tag.tag) + return; + + tag.tag.compile(); + + var tagOutputs = []; + var markupArgs = [code, tag.tag.context, args, tagOutputs]; + markupArgs.push.apply(markupArgs, tag.tag.markupArgs); + tag.tag.renderMarkup.apply(tag.tag.subject, markupArgs); + + outputs.push(tag); + outputs.push(tagOutputs); + } + + function __escape__(value) + { + function replaceChars(ch) + { + switch (ch) + { + case "<": + return "<"; + case ">": + return ">"; + case "&": + return "&"; + case "'": + return "'"; + case '"': + return """; + } + return "?"; + }; + return String(value).replace(/[<>&"']/g, replaceChars); + } + + function __loop__(iter, outputs, fn) + { + var iterOuts = []; + outputs.push(iterOuts); + + if (iter instanceof Array) + iter = new ArrayIterator(iter); + + try + { + while (1) + { + var value = iter.next(); + var itemOuts = [0,0]; + iterOuts.push(itemOuts); + fn.apply(this, [value, itemOuts]); + } + } + catch (exc) + { + if (exc != StopIteration) + throw exc; + } + } + + var js = fnBlock.join(""); + var r = null; + eval(js); + this.renderMarkup = r; + }, + + getVarNames: function(args) + { + if (this.vars) + args.push.apply(args, this.vars); + + for (var i = 0; i < this.children.length; ++i) + { + var child = this.children[i]; + if (isTag(child)) + child.tag.getVarNames(args); + else if (child instanceof Parts) + { + for (var i = 0; i < child.parts.length; ++i) + { + if (child.parts[i] instanceof Variable) + { + var name = child.parts[i].name; + var names = name.split("."); + args.push(names[0]); + } + } + } + } + }, + + generateMarkup: function(topBlock, topOuts, blocks, info) + { + topBlock.push(',"<', this.tagName, '"'); + + for (var name in this.attrs) + { + if (name != "class") + { + var val = this.attrs[name]; + topBlock.push(', " ', name, '=\\""'); + addParts(val, ',', topBlock, info, true); + topBlock.push(', "\\""'); + } + } + + if (this.listeners) + { + for (var i = 0; i < this.listeners.length; i += 2) + readPartNames(this.listeners[i+1], topOuts); + } + + if (this.props) + { + for (var name in this.props) + readPartNames(this.props[name], topOuts); + } + + if ( this.attrs.hasOwnProperty("class") || this.classes) + { + topBlock.push(', " class=\\""'); + if (this.attrs.hasOwnProperty("class")) + addParts(this.attrs["class"], ',', topBlock, info, true); + topBlock.push(', " "'); + for (var name in this.classes) + { + topBlock.push(', ('); + addParts(this.classes[name], '', topBlock, info); + topBlock.push(' ? "', name, '" + " " : "")'); + } + topBlock.push(', "\\""'); + } + topBlock.push(',">"'); + + this.generateChildMarkup(topBlock, topOuts, blocks, info); + topBlock.push(',""'); + }, + + generateChildMarkup: function(topBlock, topOuts, blocks, info) + { + for (var i = 0; i < this.children.length; ++i) + { + var child = this.children[i]; + if (isTag(child)) + child.tag.generateMarkup(topBlock, topOuts, blocks, info); + else + addParts(child, ',', topBlock, info, true); + } + }, + + addCode: function(topBlock, topOuts, blocks) + { + if (topBlock.length) + blocks.push('__code__.push(""', topBlock.join(""), ');'); + if (topOuts.length) + blocks.push('__out__.push(', topOuts.join(","), ');'); + topBlock.splice(0, topBlock.length); + topOuts.splice(0, topOuts.length); + }, + + addLocals: function(blocks) + { + var varNames = []; + this.getVarNames(varNames); + + var map = {}; + for (var i = 0; i < varNames.length; ++i) + { + var name = varNames[i]; + if ( map.hasOwnProperty(name) ) + continue; + + map[name] = 1; + var names = name.split("."); + blocks.push('var ', names[0] + ' = ' + '__in__.' + names[0] + ';'); + } + }, + + compileDOM: function() + { + var path = []; + var blocks = []; + this.domArgs = []; + path.embedIndex = 0; + path.loopIndex = 0; + path.staticIndex = 0; + path.renderIndex = 0; + var nodeCount = this.generateDOM(path, blocks, this.domArgs); + + var fnBlock = ['r=(function (root, context, o']; + + for (var i = 0; i < path.staticIndex; ++i) + fnBlock.push(', ', 's'+i); + + for (var i = 0; i < path.renderIndex; ++i) + fnBlock.push(', ', 'd'+i); + + fnBlock.push(') {'); + for (var i = 0; i < path.loopIndex; ++i) + fnBlock.push('var l', i, ' = 0;'); + for (var i = 0; i < path.embedIndex; ++i) + fnBlock.push('var e', i, ' = 0;'); + + if (this.subject) + fnBlock.push('with (this) {'); + if (this.context) + fnBlock.push('with (context) {'); + + fnBlock.push(blocks.join("")); + + if (this.subject) + fnBlock.push('}'); + if (this.context) + fnBlock.push('}'); + + fnBlock.push('return ', nodeCount, ';'); + fnBlock.push('})'); + + function __bind__(object, fn) + { + return function(event) { return fn.apply(object, [event]); }; + } + + function __link__(node, tag, args) + { + if (!tag || !tag.tag) + return; + + tag.tag.compile(); + + var domArgs = [node, tag.tag.context, 0]; + domArgs.push.apply(domArgs, tag.tag.domArgs); + domArgs.push.apply(domArgs, args); + //if (FBTrace.DBG_DOM) FBTrace.dumpProperties("domplate__link__ domArgs:", domArgs); + return tag.tag.renderDOM.apply(tag.tag.subject, domArgs); + } + + var self = this; + function __loop__(iter, fn) + { + var nodeCount = 0; + for (var i = 0; i < iter.length; ++i) + { + iter[i][0] = i; + iter[i][1] = nodeCount; + nodeCount += fn.apply(this, iter[i]); + //if (FBTrace.DBG_DOM) FBTrace.sysout("nodeCount", nodeCount); + } + return nodeCount; + } + + function __path__(parent, offset) + { + //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate __path__ offset: "+ offset+"\n"); + var root = parent; + + for (var i = 2; i < arguments.length; ++i) + { + var index = arguments[i]; + if (i == 3) + index += offset; + + if (index == -1) + parent = parent.parentNode; + else + parent = parent.childNodes[index]; + } + + //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate: "+arguments[2]+", root: "+ root+", parent: "+ parent+"\n"); + return parent; + } + + var js = fnBlock.join(""); + //if (FBTrace.DBG_DOM) FBTrace.sysout(js.replace(/(\;|\{)/g, "$1\n")); + var r = null; + eval(js); + this.renderDOM = r; + }, + + generateDOM: function(path, blocks, args) + { + if (this.listeners || this.props) + this.generateNodePath(path, blocks); + + if (this.listeners) + { + for (var i = 0; i < this.listeners.length; i += 2) + { + var val = this.listeners[i+1]; + var arg = generateArg(val, path, args); + //blocks.push('node.addEventListener("', this.listeners[i], '", __bind__(this, ', arg, '), false);'); + blocks.push('addEvent(node, "', this.listeners[i], '", __bind__(this, ', arg, '), false);'); + } + } + + if (this.props) + { + for (var name in this.props) + { + var val = this.props[name]; + var arg = generateArg(val, path, args); + blocks.push('node.', name, ' = ', arg, ';'); + } + } + + this.generateChildDOM(path, blocks, args); + return 1; + }, + + generateNodePath: function(path, blocks) + { + blocks.push("var node = __path__(root, o"); + for (var i = 0; i < path.length; ++i) + blocks.push(",", path[i]); + blocks.push(");"); + }, + + generateChildDOM: function(path, blocks, args) + { + path.push(0); + for (var i = 0; i < this.children.length; ++i) + { + var child = this.children[i]; + if (isTag(child)) + path[path.length-1] += '+' + child.tag.generateDOM(path, blocks, args); + else + path[path.length-1] += '+1'; + } + path.pop(); + } +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +DomplateEmbed.prototype = copyObject(DomplateTag.prototype, +{ + merge: function(args, oldTag) + { + this.value = oldTag ? oldTag.value : parseValue(args[0]); + this.attrs = oldTag ? oldTag.attrs : {}; + this.vars = oldTag ? copyArray(oldTag.vars) : []; + + var attrs = args[1]; + for (var name in attrs) + { + var val = parseValue(attrs[name]); + this.attrs[name] = val; + readPartNames(val, this.vars); + } + + return creator(this, DomplateEmbed); + }, + + getVarNames: function(names) + { + if (this.value instanceof Parts) + names.push(this.value.parts[0].name); + + if (this.vars) + names.push.apply(names, this.vars); + }, + + generateMarkup: function(topBlock, topOuts, blocks, info) + { + this.addCode(topBlock, topOuts, blocks); + + blocks.push('__link__('); + addParts(this.value, '', blocks, info); + blocks.push(', __code__, __out__, {'); + + var lastName = null; + for (var name in this.attrs) + { + if (lastName) + blocks.push(','); + lastName = name; + + var val = this.attrs[name]; + blocks.push('"', name, '":'); + addParts(val, '', blocks, info); + } + + blocks.push('});'); + //this.generateChildMarkup(topBlock, topOuts, blocks, info); + }, + + generateDOM: function(path, blocks, args) + { + var embedName = 'e'+path.embedIndex++; + + this.generateNodePath(path, blocks); + + var valueName = 'd' + path.renderIndex++; + var argsName = 'd' + path.renderIndex++; + blocks.push(embedName + ' = __link__(node, ', valueName, ', ', argsName, ');'); + + return embedName; + } +}); + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +DomplateLoop.prototype = copyObject(DomplateTag.prototype, +{ + merge: function(args, oldTag) + { + this.varName = oldTag ? oldTag.varName : args[0]; + this.iter = oldTag ? oldTag.iter : parseValue(args[1]); + this.vars = []; + + this.children = oldTag ? copyArray(oldTag.children) : []; + + var offset = Math.min(args.length, 2); + parseChildren(args, offset, this.vars, this.children); + + return creator(this, DomplateLoop); + }, + + getVarNames: function(names) + { + if (this.iter instanceof Parts) + names.push(this.iter.parts[0].name); + + DomplateTag.prototype.getVarNames.apply(this, [names]); + }, + + generateMarkup: function(topBlock, topOuts, blocks, info) + { + this.addCode(topBlock, topOuts, blocks); + + var iterName; + if (this.iter instanceof Parts) + { + var part = this.iter.parts[0]; + iterName = part.name; + + if (part.format) + { + for (var i = 0; i < part.format.length; ++i) + iterName = part.format[i] + "(" + iterName + ")"; + } + } + else + iterName = this.iter; + + blocks.push('__loop__.apply(this, [', iterName, ', __out__, function(', this.varName, ', __out__) {'); + this.generateChildMarkup(topBlock, topOuts, blocks, info); + this.addCode(topBlock, topOuts, blocks); + blocks.push('}]);'); + }, + + generateDOM: function(path, blocks, args) + { + var iterName = 'd'+path.renderIndex++; + var counterName = 'i'+path.loopIndex; + var loopName = 'l'+path.loopIndex++; + + if (!path.length) + path.push(-1, 0); + + var preIndex = path.renderIndex; + path.renderIndex = 0; + + var nodeCount = 0; + + var subBlocks = []; + var basePath = path[path.length-1]; + for (var i = 0; i < this.children.length; ++i) + { + path[path.length-1] = basePath+'+'+loopName+'+'+nodeCount; + + var child = this.children[i]; + if (isTag(child)) + nodeCount += '+' + child.tag.generateDOM(path, subBlocks, args); + else + nodeCount += '+1'; + } + + path[path.length-1] = basePath+'+'+loopName; + + blocks.push(loopName,' = __loop__.apply(this, [', iterName, ', function(', counterName,',',loopName); + for (var i = 0; i < path.renderIndex; ++i) + blocks.push(',d'+i); + blocks.push(') {'); + blocks.push(subBlocks.join("")); + blocks.push('return ', nodeCount, ';'); + blocks.push('}]);'); + + path.renderIndex = preIndex; + + return loopName; + } +}); + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +function Variable(name, format) +{ + this.name = name; + this.format = format; +} + +function Parts(parts) +{ + this.parts = parts; +} + +// ************************************************************************************************ + +function parseParts(str) +{ + var re = /\$([_A-Za-z][_A-Za-z0-9.|]*)/g; + var index = 0; + var parts = []; + + var m; + while (m = re.exec(str)) + { + var pre = str.substr(index, (re.lastIndex-m[0].length)-index); + if (pre) + parts.push(pre); + + var expr = m[1].split("|"); + parts.push(new Variable(expr[0], expr.slice(1))); + index = re.lastIndex; + } + + if (!index) + return str; + + var post = str.substr(index); + if (post) + parts.push(post); + + return new Parts(parts); +} + +function parseValue(val) +{ + return typeof(val) == 'string' ? parseParts(val) : val; +} + +function parseChildren(args, offset, vars, children) +{ + for (var i = offset; i < args.length; ++i) + { + var val = parseValue(args[i]); + children.push(val); + readPartNames(val, vars); + } +} + +function readPartNames(val, vars) +{ + if (val instanceof Parts) + { + for (var i = 0; i < val.parts.length; ++i) + { + var part = val.parts[i]; + if (part instanceof Variable) + vars.push(part.name); + } + } +} + +function generateArg(val, path, args) +{ + if (val instanceof Parts) + { + var vals = []; + for (var i = 0; i < val.parts.length; ++i) + { + var part = val.parts[i]; + if (part instanceof Variable) + { + var varName = 'd'+path.renderIndex++; + if (part.format) + { + for (var j = 0; j < part.format.length; ++j) + varName = part.format[j] + '(' + varName + ')'; + } + + vals.push(varName); + } + else + vals.push('"'+part.replace(/"/g, '\\"')+'"'); + } + + return vals.join('+'); + } + else + { + args.push(val); + return 's' + path.staticIndex++; + } +} + +function addParts(val, delim, block, info, escapeIt) +{ + var vals = []; + if (val instanceof Parts) + { + for (var i = 0; i < val.parts.length; ++i) + { + var part = val.parts[i]; + if (part instanceof Variable) + { + var partName = part.name; + if (part.format) + { + for (var j = 0; j < part.format.length; ++j) + partName = part.format[j] + "(" + partName + ")"; + } + + if (escapeIt) + vals.push("__escape__(" + partName + ")"); + else + vals.push(partName); + } + else + vals.push('"'+ part + '"'); + } + } + else if (isTag(val)) + { + info.args.push(val); + vals.push('s'+info.argIndex++); + } + else + vals.push('"'+ val + '"'); + + var parts = vals.join(delim); + if (parts) + block.push(delim, parts); +} + +function isTag(obj) +{ + return (typeof(obj) == "function" || obj instanceof Function) && !!obj.tag; +} + +function creator(tag, cons) +{ + var fn = new Function( + "var tag = arguments.callee.tag;" + + "var cons = arguments.callee.cons;" + + "var newTag = new cons();" + + "return newTag.merge(arguments, tag);"); + + fn.tag = tag; + fn.cons = cons; + extend(fn, Renderer); + + return fn; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +function copyArray(oldArray) +{ + var ary = []; + if (oldArray) + for (var i = 0; i < oldArray.length; ++i) + ary.push(oldArray[i]); + return ary; +} + +function copyObject(l, r) +{ + var m = {}; + extend(m, l); + extend(m, r); + return m; +} + +function extend(l, r) +{ + for (var n in r) + l[n] = r[n]; +} + +function addEvent(object, name, handler) +{ + if (document.all) + object.attachEvent("on"+name, handler); + else + object.addEventListener(name, handler, false); +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +function ArrayIterator(array) +{ + var index = -1; + + this.next = function() + { + if (++index >= array.length) + throw StopIteration; + + return array[index]; + }; +} + +function StopIteration() {} + +FBL.$break = function() +{ + throw StopIteration; +}; + +// ************************************************************************************************ + +var Renderer = +{ + renderHTML: function(args, outputs, self) + { + var code = []; + var markupArgs = [code, this.tag.context, args, outputs]; + markupArgs.push.apply(markupArgs, this.tag.markupArgs); + this.tag.renderMarkup.apply(self ? self : this.tag.subject, markupArgs); + return code.join(""); + }, + + insertRows: function(args, before, self) + { + this.tag.compile(); + + var outputs = []; + var html = this.renderHTML(args, outputs, self); + + var doc = before.ownerDocument; + var div = doc.createElement("div"); + div.innerHTML = ""+html+"
      "; + + var tbody = div.firstChild.firstChild; + var parent = before.tagName == "TR" ? before.parentNode : before; + var after = before.tagName == "TR" ? before.nextSibling : null; + + var firstRow = tbody.firstChild, lastRow; + while (tbody.firstChild) + { + lastRow = tbody.firstChild; + if (after) + parent.insertBefore(lastRow, after); + else + parent.appendChild(lastRow); + } + + var offset = 0; + if (before.tagName == "TR") + { + var node = firstRow.parentNode.firstChild; + for (; node && node != firstRow; node = node.nextSibling) + ++offset; + } + + var domArgs = [firstRow, this.tag.context, offset]; + domArgs.push.apply(domArgs, this.tag.domArgs); + domArgs.push.apply(domArgs, outputs); + + this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs); + return [firstRow, lastRow]; + }, + + insertBefore: function(args, before, self) + { + return this.insertNode(args, before.ownerDocument, before, false, self); + }, + + insertAfter: function(args, after, self) + { + return this.insertNode(args, after.ownerDocument, after, true, self); + }, + + insertNode: function(args, doc, element, isAfter, self) + { + if (!args) + args = {}; + + this.tag.compile(); + + var outputs = []; + var html = this.renderHTML(args, outputs, self); + + //if (FBTrace.DBG_DOM) + // FBTrace.sysout("domplate.insertNode html: "+html+"\n"); + + var doc = element.ownerDocument; + if (!womb || womb.ownerDocument != doc) + womb = doc.createElement("div"); + + womb.innerHTML = html; + + var root = womb.firstChild; + if (isAfter) + { + while (womb.firstChild) + if (element.nextSibling) + element.parentNode.insertBefore(womb.firstChild, element.nextSibling); + else + element.parentNode.appendChild(womb.firstChild); + } + else + { + while (womb.lastChild) + element.parentNode.insertBefore(womb.lastChild, element); + } + + var domArgs = [root, this.tag.context, 0]; + domArgs.push.apply(domArgs, this.tag.domArgs); + domArgs.push.apply(domArgs, outputs); + + //if (FBTrace.DBG_DOM) + // FBTrace.sysout("domplate.insertNode domArgs:", domArgs); + this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs); + + return root; + }, + /**/ + + /* + insertAfter: function(args, before, self) + { + this.tag.compile(); + + var outputs = []; + var html = this.renderHTML(args, outputs, self); + + var doc = before.ownerDocument; + if (!womb || womb.ownerDocument != doc) + womb = doc.createElement("div"); + + womb.innerHTML = html; + + var root = womb.firstChild; + while (womb.firstChild) + if (before.nextSibling) + before.parentNode.insertBefore(womb.firstChild, before.nextSibling); + else + before.parentNode.appendChild(womb.firstChild); + + var domArgs = [root, this.tag.context, 0]; + domArgs.push.apply(domArgs, this.tag.domArgs); + domArgs.push.apply(domArgs, outputs); + + this.tag.renderDOM.apply(self ? self : (this.tag.subject ? this.tag.subject : null), + domArgs); + + return root; + }, + /**/ + + replace: function(args, parent, self) + { + this.tag.compile(); + + var outputs = []; + var html = this.renderHTML(args, outputs, self); + + var root; + if (parent.nodeType == 1) + { + parent.innerHTML = html; + root = parent.firstChild; + } + else + { + if (!parent || parent.nodeType != 9) + parent = document; + + if (!womb || womb.ownerDocument != parent) + womb = parent.createElement("div"); + womb.innerHTML = html; + + root = womb.firstChild; + //womb.removeChild(root); + } + + var domArgs = [root, this.tag.context, 0]; + domArgs.push.apply(domArgs, this.tag.domArgs); + domArgs.push.apply(domArgs, outputs); + this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs); + + return root; + }, + + append: function(args, parent, self) + { + this.tag.compile(); + + var outputs = []; + var html = this.renderHTML(args, outputs, self); + //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate.append html: "+html+"\n"); + + if (!womb || womb.ownerDocument != parent.ownerDocument) + womb = parent.ownerDocument.createElement("div"); + womb.innerHTML = html; + + // TODO: xxxpedro domplate port to Firebug + var root = womb.firstChild; + while (womb.firstChild) + parent.appendChild(womb.firstChild); + + // clearing element reference to avoid reference error in IE8 when switching contexts + womb = null; + + var domArgs = [root, this.tag.context, 0]; + domArgs.push.apply(domArgs, this.tag.domArgs); + domArgs.push.apply(domArgs, outputs); + + //if (FBTrace.DBG_DOM) FBTrace.dumpProperties("domplate append domArgs:", domArgs); + this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs); + + return root; + } +}; + +// ************************************************************************************************ + +function defineTags() +{ + for (var i = 0; i < arguments.length; ++i) + { + var tagName = arguments[i]; + var fn = new Function("var newTag = new arguments.callee.DomplateTag('"+tagName+"'); return newTag.merge(arguments);"); + fn.DomplateTag = DomplateTag; + + var fnName = tagName.toUpperCase(); + FBL[fnName] = fn; + } +} + +defineTags( + "a", "button", "br", "canvas", "code", "col", "colgroup", "div", "fieldset", "form", "h1", "h2", "h3", "hr", + "img", "input", "label", "legend", "li", "ol", "optgroup", "option", "p", "pre", "select", + "span", "strong", "table", "tbody", "td", "textarea", "tfoot", "th", "thead", "tr", "tt", "ul", "iframe" +); + +})(); + + +/* See license.txt for terms of usage */ + +var FirebugReps = FBL.ns(function() { with (FBL) { + + +// ************************************************************************************************ +// Common Tags + +var OBJECTBOX = this.OBJECTBOX = + SPAN({"class": "objectBox objectBox-$className"}); + +var OBJECTBLOCK = this.OBJECTBLOCK = + DIV({"class": "objectBox objectBox-$className"}); + +var OBJECTLINK = this.OBJECTLINK = isIE6 ? // IE6 object link representation + A({ + "class": "objectLink objectLink-$className a11yFocus", + href: "javascript:void(0)", + _repObject: "$object" + }) + : // Other browsers + A({ + "class": "objectLink objectLink-$className a11yFocus", + _repObject: "$object" + }); + + +// ************************************************************************************************ + +this.Undefined = domplate(Firebug.Rep, +{ + tag: OBJECTBOX("undefined"), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "undefined", + + supportsObject: function(object, type) + { + return type == "undefined"; + } +}); + +// ************************************************************************************************ + +this.Null = domplate(Firebug.Rep, +{ + tag: OBJECTBOX("null"), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "null", + + supportsObject: function(object, type) + { + return object == null; + } +}); + +// ************************************************************************************************ + +this.Nada = domplate(Firebug.Rep, +{ + tag: SPAN(""), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "nada" +}); + +// ************************************************************************************************ + +this.Number = domplate(Firebug.Rep, +{ + tag: OBJECTBOX("$object"), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "number", + + supportsObject: function(object, type) + { + return type == "boolean" || type == "number"; + } +}); + +// ************************************************************************************************ + +this.String = domplate(Firebug.Rep, +{ + tag: OBJECTBOX(""$object""), + + shortTag: OBJECTBOX(""$object|cropString""), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "string", + + supportsObject: function(object, type) + { + return type == "string"; + } +}); + +// ************************************************************************************************ + +this.Text = domplate(Firebug.Rep, +{ + tag: OBJECTBOX("$object"), + + shortTag: OBJECTBOX("$object|cropString"), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "text" +}); + +// ************************************************************************************************ + +this.Caption = domplate(Firebug.Rep, +{ + tag: SPAN({"class": "caption"}, "$object") +}); + +// ************************************************************************************************ + +this.Warning = domplate(Firebug.Rep, +{ + tag: DIV({"class": "warning focusRow", role : 'listitem'}, "$object|STR") +}); + +// ************************************************************************************************ + +this.Func = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK("$object|summarizeFunction"), + + summarizeFunction: function(fn) + { + var fnRegex = /function ([^(]+\([^)]*\)) \{/; + var fnText = safeToString(fn); + + var m = fnRegex.exec(fnText); + return m ? m[1] : "function()"; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + copySource: function(fn) + { + copyToClipboard(safeToString(fn)); + }, + + monitor: function(fn, script, monitored) + { + if (monitored) + Firebug.Debugger.unmonitorScript(fn, script, "monitor"); + else + Firebug.Debugger.monitorScript(fn, script, "monitor"); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "function", + + supportsObject: function(object, type) + { + return isFunction(object); + }, + + inspectObject: function(fn, context) + { + var sourceLink = findSourceForFunction(fn, context); + if (sourceLink) + Firebug.chrome.select(sourceLink); + if (FBTrace.DBG_FUNCTION_NAME) + FBTrace.sysout("reps.function.inspectObject selected sourceLink is ", sourceLink); + }, + + getTooltip: function(fn, context) + { + var script = findScriptForFunctionInContext(context, fn); + if (script) + return $STRF("Line", [normalizeURL(script.fileName), script.baseLineNumber]); + else + if (fn.toString) + return fn.toString(); + }, + + getTitle: function(fn, context) + { + var name = fn.name ? fn.name : "function"; + return name + "()"; + }, + + getContextMenuItems: function(fn, target, context, script) + { + if (!script) + script = findScriptForFunctionInContext(context, fn); + if (!script) + return; + + var scriptInfo = getSourceFileAndLineByScript(context, script); + var monitored = scriptInfo ? fbs.isMonitored(scriptInfo.sourceFile.href, scriptInfo.lineNo) : false; + + var name = script ? getFunctionName(script, context) : fn.name; + return [ + {label: "CopySource", command: bindFixed(this.copySource, this, fn) }, + "-", + {label: $STRF("ShowCallsInConsole", [name]), nol10n: true, + type: "checkbox", checked: monitored, + command: bindFixed(this.monitor, this, fn, script, monitored) } + ]; + } +}); + +// ************************************************************************************************ +/* +this.jsdScript = domplate(Firebug.Rep, +{ + copySource: function(script) + { + var fn = script.functionObject.getWrappedValue(); + return FirebugReps.Func.copySource(fn); + }, + + monitor: function(fn, script, monitored) + { + fn = script.functionObject.getWrappedValue(); + return FirebugReps.Func.monitor(fn, script, monitored); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "jsdScript", + inspectable: false, + + supportsObject: function(object, type) + { + return object instanceof jsdIScript; + }, + + inspectObject: function(script, context) + { + var sourceLink = getSourceLinkForScript(script, context); + if (sourceLink) + Firebug.chrome.select(sourceLink); + }, + + getRealObject: function(script, context) + { + return script; + }, + + getTooltip: function(script) + { + return $STRF("jsdIScript", [script.tag]); + }, + + getTitle: function(script, context) + { + var fn = script.functionObject.getWrappedValue(); + return FirebugReps.Func.getTitle(fn, context); + }, + + getContextMenuItems: function(script, target, context) + { + var fn = script.functionObject.getWrappedValue(); + + var scriptInfo = getSourceFileAndLineByScript(context, script); + var monitored = scriptInfo ? fbs.isMonitored(scriptInfo.sourceFile.href, scriptInfo.lineNo) : false; + + var name = getFunctionName(script, context); + + return [ + {label: "CopySource", command: bindFixed(this.copySource, this, script) }, + "-", + {label: $STRF("ShowCallsInConsole", [name]), nol10n: true, + type: "checkbox", checked: monitored, + command: bindFixed(this.monitor, this, fn, script, monitored) } + ]; + } +}); +/**/ +//************************************************************************************************ + +this.Obj = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK( + SPAN({"class": "objectTitle"}, "$object|getTitle "), + + SPAN({"class": "objectProps"}, + SPAN({"class": "objectLeftBrace", role: "presentation"}, "{"), + FOR("prop", "$object|propIterator", + SPAN({"class": "objectPropName", role: "presentation"}, "$prop.name"), + SPAN({"class": "objectEqual", role: "presentation"}, "$prop.equal"), + TAG("$prop.tag", {object: "$prop.object"}), + SPAN({"class": "objectComma", role: "presentation"}, "$prop.delim") + ), + SPAN({"class": "objectRightBrace"}, "}") + ) + ), + + propNumberTag: + SPAN({"class": "objectProp-number"}, "$object"), + + propStringTag: + SPAN({"class": "objectProp-string"}, ""$object""), + + propObjectTag: + SPAN({"class": "objectProp-object"}, "$object"), + + propIterator: function (object) + { + ///Firebug.ObjectShortIteratorMax; + var maxLength = 55; // default max length for long representation + + if (!object) + return []; + + var props = []; + var length = 0; + + var numProperties = 0; + var numPropertiesShown = 0; + var maxLengthReached = false; + + var lib = this; + + var propRepsMap = + { + "boolean": this.propNumberTag, + "number": this.propNumberTag, + "string": this.propStringTag, + "object": this.propObjectTag + }; + + try + { + var title = Firebug.Rep.getTitle(object); + length += title.length; + + for (var name in object) + { + var value; + try + { + value = object[name]; + } + catch (exc) + { + continue; + } + + var type = typeof(value); + if (type == "boolean" || + type == "number" || + (type == "string" && value) || + (type == "object" && value && value.toString)) + { + var tag = propRepsMap[type]; + + var value = (type == "object") ? + Firebug.getRep(value).getTitle(value) : + value + ""; + + length += name.length + value.length + 4; + + if (length <= maxLength) + { + props.push({ + tag: tag, + name: name, + object: value, + equal: "=", + delim: ", " + }); + + numPropertiesShown++; + } + else + maxLengthReached = true; + + } + + numProperties++; + + if (maxLengthReached && numProperties > numPropertiesShown) + break; + } + + if (numProperties > numPropertiesShown) + { + props.push({ + object: "...", //xxxHonza localization + tag: FirebugReps.Caption.tag, + name: "", + equal:"", + delim:"" + }); + } + else if (props.length > 0) + { + props[props.length-1].delim = ''; + } + } + catch (exc) + { + // Sometimes we get exceptions when trying to read from certain objects, like + // StorageList, but don't let that gum up the works + // XXXjjb also History.previous fails because object is a web-page object which does not have + // permission to read the history + } + return props; + }, + + fb_1_6_propIterator: function (object, max) + { + max = max || 3; + if (!object) + return []; + + var props = []; + var len = 0, count = 0; + + try + { + for (var name in object) + { + var value; + try + { + value = object[name]; + } + catch (exc) + { + continue; + } + + var t = typeof(value); + if (t == "boolean" || t == "number" || (t == "string" && value) + || (t == "object" && value && value.toString)) + { + var rep = Firebug.getRep(value); + var tag = rep.shortTag || rep.tag; + if (t == "object") + { + value = rep.getTitle(value); + tag = rep.titleTag; + } + count++; + if (count <= max) + props.push({tag: tag, name: name, object: value, equal: "=", delim: ", "}); + else + break; + } + } + if (count > max) + { + props[Math.max(1,max-1)] = { + object: "more...", //xxxHonza localization + tag: FirebugReps.Caption.tag, + name: "", + equal:"", + delim:"" + }; + } + else if (props.length > 0) + { + props[props.length-1].delim = ''; + } + } + catch (exc) + { + // Sometimes we get exceptions when trying to read from certain objects, like + // StorageList, but don't let that gum up the works + // XXXjjb also History.previous fails because object is a web-page object which does not have + // permission to read the history + } + return props; + }, + + /* + propIterator: function (object) + { + if (!object) + return []; + + var props = []; + var len = 0; + + try + { + for (var name in object) + { + var val; + try + { + val = object[name]; + } + catch (exc) + { + continue; + } + + var t = typeof val; + if (t == "boolean" || t == "number" || (t == "string" && val) + || (t == "object" && !isFunction(val) && val && val.toString)) + { + var title = (t == "object") + ? Firebug.getRep(val).getTitle(val) + : val+""; + + len += name.length + title.length + 1; + if (len < 50) + props.push({name: name, value: title}); + else + break; + } + } + } + catch (exc) + { + // Sometimes we get exceptions when trying to read from certain objects, like + // StorageList, but don't let that gum up the works + // XXXjjb also History.previous fails because object is a web-page object which does not have + // permission to read the history + } + + return props; + }, + /**/ + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "object", + + supportsObject: function(object, type) + { + return true; + } +}); + + +// ************************************************************************************************ + +this.Arr = domplate(Firebug.Rep, +{ + tag: + OBJECTBOX({_repObject: "$object"}, + SPAN({"class": "arrayLeftBracket", role : "presentation"}, "["), + FOR("item", "$object|arrayIterator", + TAG("$item.tag", {object: "$item.object"}), + SPAN({"class": "arrayComma", role : "presentation"}, "$item.delim") + ), + SPAN({"class": "arrayRightBracket", role : "presentation"}, "]") + ), + + shortTag: + OBJECTBOX({_repObject: "$object"}, + SPAN({"class": "arrayLeftBracket", role : "presentation"}, "["), + FOR("item", "$object|shortArrayIterator", + TAG("$item.tag", {object: "$item.object"}), + SPAN({"class": "arrayComma", role : "presentation"}, "$item.delim") + ), + // TODO: xxxpedro - confirm this on Firebug + //FOR("prop", "$object|shortPropIterator", + // " $prop.name=", + // SPAN({"class": "objectPropValue"}, "$prop.value|cropString") + //), + SPAN({"class": "arrayRightBracket"}, "]") + ), + + arrayIterator: function(array) + { + var items = []; + for (var i = 0; i < array.length; ++i) + { + var value = array[i]; + var rep = Firebug.getRep(value); + var tag = rep.shortTag ? rep.shortTag : rep.tag; + var delim = (i == array.length-1 ? "" : ", "); + + items.push({object: value, tag: tag, delim: delim}); + } + + return items; + }, + + shortArrayIterator: function(array) + { + var items = []; + for (var i = 0; i < array.length && i < 3; ++i) + { + var value = array[i]; + var rep = Firebug.getRep(value); + var tag = rep.shortTag ? rep.shortTag : rep.tag; + var delim = (i == array.length-1 ? "" : ", "); + + items.push({object: value, tag: tag, delim: delim}); + } + + if (array.length > 3) + items.push({object: (array.length-3) + " more...", tag: FirebugReps.Caption.tag, delim: ""}); + + return items; + }, + + shortPropIterator: this.Obj.propIterator, + + getItemIndex: function(child) + { + var arrayIndex = 0; + for (child = child.previousSibling; child; child = child.previousSibling) + { + if (child.repObject) + ++arrayIndex; + } + return arrayIndex; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "array", + + supportsObject: function(object) + { + return this.isArray(object); + }, + + // http://code.google.com/p/fbug/issues/detail?id=874 + // BEGIN Yahoo BSD Source (modified here) YAHOO.lang.isArray, YUI 2.2.2 June 2007 + isArray: function(obj) { + try { + if (!obj) + return false; + else if (isIE && !isFunction(obj) && typeof obj == "object" && isFinite(obj.length) && obj.nodeType != 8) + return true; + else if (isFinite(obj.length) && isFunction(obj.splice)) + return true; + else if (isFinite(obj.length) && isFunction(obj.callee)) // arguments + return true; + else if (instanceOf(obj, "HTMLCollection")) + return true; + else if (instanceOf(obj, "NodeList")) + return true; + else + return false; + } + catch(exc) + { + if (FBTrace.DBG_ERRORS) + { + FBTrace.sysout("isArray FAILS:", exc); /* Something weird: without the try/catch, OOM, with no exception?? */ + FBTrace.sysout("isArray Fails on obj", obj); + } + } + + return false; + }, + // END Yahoo BSD SOURCE See license below. + + getTitle: function(object, context) + { + return "[" + object.length + "]"; + } +}); + +// ************************************************************************************************ + +this.Property = domplate(Firebug.Rep, +{ + supportsObject: function(object) + { + return object instanceof Property; + }, + + getRealObject: function(prop, context) + { + return prop.object[prop.name]; + }, + + getTitle: function(prop, context) + { + return prop.name; + } +}); + +// ************************************************************************************************ + +this.NetFile = domplate(this.Obj, +{ + supportsObject: function(object) + { + return object instanceof Firebug.NetFile; + }, + + browseObject: function(file, context) + { + openNewTab(file.href); + return true; + }, + + getRealObject: function(file, context) + { + return null; + } +}); + +// ************************************************************************************************ + +this.Except = domplate(Firebug.Rep, +{ + tag: + OBJECTBOX({_repObject: "$object"}, "$object.message"), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "exception", + + supportsObject: function(object) + { + return object instanceof ErrorCopy; + } +}); + + +// ************************************************************************************************ + +this.Element = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK( + "<", + SPAN({"class": "nodeTag"}, "$object.nodeName|toLowerCase"), + FOR("attr", "$object|attrIterator", + " $attr.nodeName="", SPAN({"class": "nodeValue"}, "$attr.nodeValue"), """ + ), + ">" + ), + + shortTag: + OBJECTLINK( + SPAN({"class": "$object|getVisible"}, + SPAN({"class": "selectorTag"}, "$object|getSelectorTag"), + SPAN({"class": "selectorId"}, "$object|getSelectorId"), + SPAN({"class": "selectorClass"}, "$object|getSelectorClass"), + SPAN({"class": "selectorValue"}, "$object|getValue") + ) + ), + + getVisible: function(elt) + { + return isVisible(elt) ? "" : "selectorHidden"; + }, + + getSelectorTag: function(elt) + { + return elt.nodeName.toLowerCase(); + }, + + getSelectorId: function(elt) + { + return elt.id ? "#" + elt.id : ""; + }, + + getSelectorClass: function(elt) + { + return elt.className ? "." + elt.className.split(" ")[0] : ""; + }, + + getValue: function(elt) + { + // TODO: xxxpedro + return ""; + var value; + if (elt instanceof HTMLImageElement) + value = getFileName(elt.src); + else if (elt instanceof HTMLAnchorElement) + value = getFileName(elt.href); + else if (elt instanceof HTMLInputElement) + value = elt.value; + else if (elt instanceof HTMLFormElement) + value = getFileName(elt.action); + else if (elt instanceof HTMLScriptElement) + value = getFileName(elt.src); + + return value ? " " + cropString(value, 20) : ""; + }, + + attrIterator: function(elt) + { + var attrs = []; + var idAttr, classAttr; + if (elt.attributes) + { + for (var i = 0; i < elt.attributes.length; ++i) + { + var attr = elt.attributes[i]; + if (attr.nodeName && attr.nodeName.indexOf("firebug-") != -1) + continue; + else if (attr.nodeName == "id") + idAttr = attr; + else if (attr.nodeName == "class") + classAttr = attr; + else + attrs.push(attr); + } + } + if (classAttr) + attrs.splice(0, 0, classAttr); + if (idAttr) + attrs.splice(0, 0, idAttr); + + return attrs; + }, + + shortAttrIterator: function(elt) + { + var attrs = []; + if (elt.attributes) + { + for (var i = 0; i < elt.attributes.length; ++i) + { + var attr = elt.attributes[i]; + if (attr.nodeName == "id" || attr.nodeName == "class") + attrs.push(attr); + } + } + + return attrs; + }, + + getHidden: function(elt) + { + return isVisible(elt) ? "" : "nodeHidden"; + }, + + getXPath: function(elt) + { + return getElementTreeXPath(elt); + }, + + // TODO: xxxpedro remove this? + getNodeText: function(element) + { + var text = element.textContent; + if (Firebug.showFullTextNodes) + return text; + else + return cropString(text, 50); + }, + /**/ + + getNodeTextGroups: function(element) + { + var text = element.textContent; + if (!Firebug.showFullTextNodes) + { + text=cropString(text,50); + } + + var escapeGroups=[]; + + if (Firebug.showTextNodesWithWhitespace) + escapeGroups.push({ + 'group': 'whitespace', + 'class': 'nodeWhiteSpace', + 'extra': { + '\t': '_Tab', + '\n': '_Para', + ' ' : '_Space' + } + }); + if (Firebug.showTextNodesWithEntities) + escapeGroups.push({ + 'group':'text', + 'class':'nodeTextEntity', + 'extra':{} + }); + + if (escapeGroups.length) + return escapeGroupsForEntities(text, escapeGroups); + else + return [{str:text,'class':'',extra:''}]; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + copyHTML: function(elt) + { + var html = getElementXML(elt); + copyToClipboard(html); + }, + + copyInnerHTML: function(elt) + { + copyToClipboard(elt.innerHTML); + }, + + copyXPath: function(elt) + { + var xpath = getElementXPath(elt); + copyToClipboard(xpath); + }, + + persistor: function(context, xpath) + { + var elts = xpath + ? getElementsByXPath(context.window.document, xpath) + : null; + + return elts && elts.length ? elts[0] : null; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "element", + + supportsObject: function(object) + { + //return object instanceof Element || object.nodeType == 1 && typeof object.nodeName == "string"; + return instanceOf(object, "Element"); + }, + + browseObject: function(elt, context) + { + var tag = elt.nodeName.toLowerCase(); + if (tag == "script") + openNewTab(elt.src); + else if (tag == "link") + openNewTab(elt.href); + else if (tag == "a") + openNewTab(elt.href); + else if (tag == "img") + openNewTab(elt.src); + + return true; + }, + + persistObject: function(elt, context) + { + var xpath = getElementXPath(elt); + + return bind(this.persistor, top, xpath); + }, + + getTitle: function(element, context) + { + return getElementCSSSelector(element); + }, + + getTooltip: function(elt) + { + return this.getXPath(elt); + }, + + getContextMenuItems: function(elt, target, context) + { + var monitored = areEventsMonitored(elt, null, context); + + return [ + {label: "CopyHTML", command: bindFixed(this.copyHTML, this, elt) }, + {label: "CopyInnerHTML", command: bindFixed(this.copyInnerHTML, this, elt) }, + {label: "CopyXPath", command: bindFixed(this.copyXPath, this, elt) }, + "-", + {label: "ShowEventsInConsole", type: "checkbox", checked: monitored, + command: bindFixed(toggleMonitorEvents, FBL, elt, null, monitored, context) }, + "-", + {label: "ScrollIntoView", command: bindFixed(elt.scrollIntoView, elt) } + ]; + } +}); + +// ************************************************************************************************ + +this.TextNode = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK( + "<", + SPAN({"class": "nodeTag"}, "TextNode"), + " textContent="", SPAN({"class": "nodeValue"}, "$object.textContent|cropString"), """, + ">" + ), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "textNode", + + supportsObject: function(object) + { + return object instanceof Text; + } +}); + +// ************************************************************************************************ + +this.Document = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK("Document ", SPAN({"class": "objectPropValue"}, "$object|getLocation")), + + getLocation: function(doc) + { + return doc.location ? getFileName(doc.location.href) : ""; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "object", + + supportsObject: function(object) + { + //return object instanceof Document || object instanceof XMLDocument; + return instanceOf(object, "Document"); + }, + + browseObject: function(doc, context) + { + openNewTab(doc.location.href); + return true; + }, + + persistObject: function(doc, context) + { + return this.persistor; + }, + + persistor: function(context) + { + return context.window.document; + }, + + getTitle: function(win, context) + { + return "document"; + }, + + getTooltip: function(doc) + { + return doc.location.href; + } +}); + +// ************************************************************************************************ + +this.StyleSheet = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK("StyleSheet ", SPAN({"class": "objectPropValue"}, "$object|getLocation")), + + getLocation: function(styleSheet) + { + return getFileName(styleSheet.href); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + copyURL: function(styleSheet) + { + copyToClipboard(styleSheet.href); + }, + + openInTab: function(styleSheet) + { + openNewTab(styleSheet.href); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "object", + + supportsObject: function(object) + { + //return object instanceof CSSStyleSheet; + return instanceOf(object, "CSSStyleSheet"); + }, + + browseObject: function(styleSheet, context) + { + openNewTab(styleSheet.href); + return true; + }, + + persistObject: function(styleSheet, context) + { + return bind(this.persistor, top, styleSheet.href); + }, + + getTooltip: function(styleSheet) + { + return styleSheet.href; + }, + + getContextMenuItems: function(styleSheet, target, context) + { + return [ + {label: "CopyLocation", command: bindFixed(this.copyURL, this, styleSheet) }, + "-", + {label: "OpenInTab", command: bindFixed(this.openInTab, this, styleSheet) } + ]; + }, + + persistor: function(context, href) + { + return getStyleSheetByHref(href, context); + } +}); + +// ************************************************************************************************ + +this.Window = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK("Window ", SPAN({"class": "objectPropValue"}, "$object|getLocation")), + + getLocation: function(win) + { + try + { + return (win && win.location && !win.closed) ? getFileName(win.location.href) : ""; + } + catch (exc) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("reps.Window window closed?"); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "object", + + supportsObject: function(object) + { + return instanceOf(object, "Window"); + }, + + browseObject: function(win, context) + { + openNewTab(win.location.href); + return true; + }, + + persistObject: function(win, context) + { + return this.persistor; + }, + + persistor: function(context) + { + return context.window; + }, + + getTitle: function(win, context) + { + return "window"; + }, + + getTooltip: function(win) + { + if (win && !win.closed) + return win.location.href; + } +}); + +// ************************************************************************************************ + +this.Event = domplate(Firebug.Rep, +{ + tag: TAG("$copyEventTag", {object: "$object|copyEvent"}), + + copyEventTag: + OBJECTLINK("$object|summarizeEvent"), + + summarizeEvent: function(event) + { + var info = [event.type, ' ']; + + var eventFamily = getEventFamily(event.type); + if (eventFamily == "mouse") + info.push("clientX=", event.clientX, ", clientY=", event.clientY); + else if (eventFamily == "key") + info.push("charCode=", event.charCode, ", keyCode=", event.keyCode); + + return info.join(""); + }, + + copyEvent: function(event) + { + return new EventCopy(event); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "object", + + supportsObject: function(object) + { + //return object instanceof Event || object instanceof EventCopy; + return instanceOf(object, "Event") || instanceOf(object, "EventCopy"); + }, + + getTitle: function(event, context) + { + return "Event " + event.type; + } +}); + +// ************************************************************************************************ + +this.SourceLink = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK({$collapsed: "$object|hideSourceLink"}, "$object|getSourceLinkTitle"), + + hideSourceLink: function(sourceLink) + { + return sourceLink ? sourceLink.href.indexOf("XPCSafeJSObjectWrapper") != -1 : true; + }, + + getSourceLinkTitle: function(sourceLink) + { + if (!sourceLink) + return ""; + + try + { + var fileName = getFileName(sourceLink.href); + fileName = decodeURIComponent(fileName); + fileName = cropString(fileName, 17); + } + catch(exc) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("reps.getSourceLinkTitle decodeURIComponent fails for \'"+fileName+"\': "+exc, exc); + } + + return typeof sourceLink.line == "number" ? + fileName + " (line " + sourceLink.line + ")" : + fileName; + + // TODO: xxxpedro + //return $STRF("Line", [fileName, sourceLink.line]); + }, + + copyLink: function(sourceLink) + { + copyToClipboard(sourceLink.href); + }, + + openInTab: function(sourceLink) + { + openNewTab(sourceLink.href); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "sourceLink", + + supportsObject: function(object) + { + return object instanceof SourceLink; + }, + + getTooltip: function(sourceLink) + { + return decodeURI(sourceLink.href); + }, + + inspectObject: function(sourceLink, context) + { + if (sourceLink.type == "js") + { + var scriptFile = getSourceFileByHref(sourceLink.href, context); + if (scriptFile) + return Firebug.chrome.select(sourceLink); + } + else if (sourceLink.type == "css") + { + // If an object is defined, treat it as the highest priority for + // inspect actions + if (sourceLink.object) { + Firebug.chrome.select(sourceLink.object); + return; + } + + var stylesheet = getStyleSheetByHref(sourceLink.href, context); + if (stylesheet) + { + var ownerNode = stylesheet.ownerNode; + if (ownerNode) + { + Firebug.chrome.select(sourceLink, "html"); + return; + } + + var panel = context.getPanel("stylesheet"); + if (panel && panel.getRuleByLine(stylesheet, sourceLink.line)) + return Firebug.chrome.select(sourceLink); + } + } + + // Fallback is to just open the view-source window on the file + viewSource(sourceLink.href, sourceLink.line); + }, + + browseObject: function(sourceLink, context) + { + openNewTab(sourceLink.href); + return true; + }, + + getContextMenuItems: function(sourceLink, target, context) + { + return [ + {label: "CopyLocation", command: bindFixed(this.copyLink, this, sourceLink) }, + "-", + {label: "OpenInTab", command: bindFixed(this.openInTab, this, sourceLink) } + ]; + } +}); + +// ************************************************************************************************ + +this.SourceFile = domplate(this.SourceLink, +{ + tag: + OBJECTLINK({$collapsed: "$object|hideSourceLink"}, "$object|getSourceLinkTitle"), + + persistor: function(context, href) + { + return getSourceFileByHref(href, context); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "sourceFile", + + supportsObject: function(object) + { + return object instanceof SourceFile; + }, + + persistObject: function(sourceFile) + { + return bind(this.persistor, top, sourceFile.href); + }, + + browseObject: function(sourceLink, context) + { + }, + + getTooltip: function(sourceFile) + { + return sourceFile.href; + } +}); + +// ************************************************************************************************ + +this.StackFrame = domplate(Firebug.Rep, // XXXjjb Since the repObject is fn the stack does not have correct line numbers +{ + tag: + OBJECTBLOCK( + A({"class": "objectLink objectLink-function focusRow a11yFocus", _repObject: "$object.fn"}, "$object|getCallName"), + " ( ", + FOR("arg", "$object|argIterator", + TAG("$arg.tag", {object: "$arg.value"}), + SPAN({"class": "arrayComma"}, "$arg.delim") + ), + " )", + SPAN({"class": "objectLink-sourceLink objectLink"}, "$object|getSourceLinkTitle") + ), + + getCallName: function(frame) + { + //TODO: xxxpedro reps StackFrame + return frame.name || "anonymous"; + + //return getFunctionName(frame.script, frame.context); + }, + + getSourceLinkTitle: function(frame) + { + //TODO: xxxpedro reps StackFrame + var fileName = cropString(getFileName(frame.href), 20); + return fileName + (frame.lineNo ? " (line " + frame.lineNo + ")" : ""); + + var fileName = cropString(getFileName(frame.href), 17); + return $STRF("Line", [fileName, frame.lineNo]); + }, + + argIterator: function(frame) + { + if (!frame.args) + return []; + + var items = []; + + for (var i = 0; i < frame.args.length; ++i) + { + var arg = frame.args[i]; + + if (!arg) + break; + + var rep = Firebug.getRep(arg.value); + var tag = rep.shortTag ? rep.shortTag : rep.tag; + + var delim = (i == frame.args.length-1 ? "" : ", "); + + items.push({name: arg.name, value: arg.value, tag: tag, delim: delim}); + } + + return items; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "stackFrame", + + supportsObject: function(object) + { + return object instanceof StackFrame; + }, + + inspectObject: function(stackFrame, context) + { + var sourceLink = new SourceLink(stackFrame.href, stackFrame.lineNo, "js"); + Firebug.chrome.select(sourceLink); + }, + + getTooltip: function(stackFrame, context) + { + return $STRF("Line", [stackFrame.href, stackFrame.lineNo]); + } + +}); + +// ************************************************************************************************ + +this.StackTrace = domplate(Firebug.Rep, +{ + tag: + FOR("frame", "$object.frames focusRow", + TAG(this.StackFrame.tag, {object: "$frame"}) + ), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "stackTrace", + + supportsObject: function(object) + { + return object instanceof StackTrace; + } +}); + +// ************************************************************************************************ + +this.jsdStackFrame = domplate(Firebug.Rep, +{ + inspectable: false, + + supportsObject: function(object) + { + return (object instanceof jsdIStackFrame) && (object.isValid); + }, + + getTitle: function(frame, context) + { + if (!frame.isValid) return "(invalid frame)"; // XXXjjb avoid frame.script == null + return getFunctionName(frame.script, context); + }, + + getTooltip: function(frame, context) + { + if (!frame.isValid) return "(invalid frame)"; // XXXjjb avoid frame.script == null + var sourceInfo = FBL.getSourceFileAndLineByScript(context, frame.script, frame); + if (sourceInfo) + return $STRF("Line", [sourceInfo.sourceFile.href, sourceInfo.lineNo]); + else + return $STRF("Line", [frame.script.fileName, frame.line]); + }, + + getContextMenuItems: function(frame, target, context) + { + var fn = frame.script.functionObject.getWrappedValue(); + return FirebugReps.Func.getContextMenuItems(fn, target, context, frame.script); + } +}); + +// ************************************************************************************************ + +this.ErrorMessage = domplate(Firebug.Rep, +{ + tag: + OBJECTBOX({ + $hasTwisty: "$object|hasStackTrace", + $hasBreakSwitch: "$object|hasBreakSwitch", + $breakForError: "$object|hasErrorBreak", + _repObject: "$object", + _stackTrace: "$object|getLastErrorStackTrace", + onclick: "$onToggleError"}, + + DIV({"class": "errorTitle a11yFocus", role : 'checkbox', 'aria-checked' : 'false'}, + "$object.message|getMessage" + ), + DIV({"class": "errorTrace"}), + DIV({"class": "errorSourceBox errorSource-$object|getSourceType"}, + IMG({"class": "errorBreak a11yFocus", src:"blank.gif", role : 'checkbox', 'aria-checked':'false', title: "Break on this error"}), + A({"class": "errorSource a11yFocus"}, "$object|getLine") + ), + TAG(this.SourceLink.tag, {object: "$object|getSourceLink"}) + ), + + getLastErrorStackTrace: function(error) + { + return error.trace; + }, + + hasStackTrace: function(error) + { + var url = error.href.toString(); + var fromCommandLine = (url.indexOf("XPCSafeJSObjectWrapper") != -1); + return !fromCommandLine && error.trace; + }, + + hasBreakSwitch: function(error) + { + return error.href && error.lineNo > 0; + }, + + hasErrorBreak: function(error) + { + return fbs.hasErrorBreakpoint(error.href, error.lineNo); + }, + + getMessage: function(message) + { + var re = /\[Exception... "(.*?)" nsresult:/; + var m = re.exec(message); + return m ? m[1] : message; + }, + + getLine: function(error) + { + if (error.category == "js") + { + if (error.source) + return cropString(error.source, 80); + else if (error.href && error.href.indexOf("XPCSafeJSObjectWrapper") == -1) + return cropString(error.getSourceLine(), 80); + } + }, + + getSourceLink: function(error) + { + var ext = error.category == "css" ? "css" : "js"; + return error.lineNo ? new SourceLink(error.href, error.lineNo, ext) : null; + }, + + getSourceType: function(error) + { + // Errors occurring inside of HTML event handlers look like "foo.html (line 1)" + // so let's try to skip those + if (error.source) + return "syntax"; + else if (error.lineNo == 1 && getFileExtension(error.href) != "js") + return "none"; + else if (error.category == "css") + return "none"; + else if (!error.href || !error.lineNo) + return "none"; + else + return "exec"; + }, + + onToggleError: function(event) + { + var target = event.currentTarget; + if (hasClass(event.target, "errorBreak")) + { + this.breakOnThisError(target.repObject); + } + else if (hasClass(event.target, "errorSource")) + { + var panel = Firebug.getElementPanel(event.target); + this.inspectObject(target.repObject, panel.context); + } + else if (hasClass(event.target, "errorTitle")) + { + var traceBox = target.childNodes[1]; + toggleClass(target, "opened"); + event.target.setAttribute('aria-checked', hasClass(target, "opened")); + if (hasClass(target, "opened")) + { + if (target.stackTrace) + var node = FirebugReps.StackTrace.tag.append({object: target.stackTrace}, traceBox); + if (Firebug.A11yModel.enabled) + { + var panel = Firebug.getElementPanel(event.target); + dispatch([Firebug.A11yModel], "onLogRowContentCreated", [panel , traceBox]); + } + } + else + clearNode(traceBox); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + copyError: function(error) + { + var message = [ + this.getMessage(error.message), + error.href, + "Line " + error.lineNo + ]; + copyToClipboard(message.join("\n")); + }, + + breakOnThisError: function(error) + { + if (this.hasErrorBreak(error)) + Firebug.Debugger.clearErrorBreakpoint(error.href, error.lineNo); + else + Firebug.Debugger.setErrorBreakpoint(error.href, error.lineNo); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "errorMessage", + inspectable: false, + + supportsObject: function(object) + { + return object instanceof ErrorMessage; + }, + + inspectObject: function(error, context) + { + var sourceLink = this.getSourceLink(error); + FirebugReps.SourceLink.inspectObject(sourceLink, context); + }, + + getContextMenuItems: function(error, target, context) + { + var breakOnThisError = this.hasErrorBreak(error); + + var items = [ + {label: "CopyError", command: bindFixed(this.copyError, this, error) } + ]; + + if (error.category == "css") + { + items.push( + "-", + {label: "BreakOnThisError", type: "checkbox", checked: breakOnThisError, + command: bindFixed(this.breakOnThisError, this, error) }, + + optionMenu("BreakOnAllErrors", "breakOnErrors") + ); + } + + return items; + } +}); + +// ************************************************************************************************ + +this.Assert = domplate(Firebug.Rep, +{ + tag: + DIV( + DIV({"class": "errorTitle"}), + DIV({"class": "assertDescription"}) + ), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "assert", + + inspectObject: function(error, context) + { + var sourceLink = this.getSourceLink(error); + Firebug.chrome.select(sourceLink); + }, + + getContextMenuItems: function(error, target, context) + { + var breakOnThisError = this.hasErrorBreak(error); + + return [ + {label: "CopyError", command: bindFixed(this.copyError, this, error) }, + "-", + {label: "BreakOnThisError", type: "checkbox", checked: breakOnThisError, + command: bindFixed(this.breakOnThisError, this, error) }, + {label: "BreakOnAllErrors", type: "checkbox", checked: Firebug.breakOnErrors, + command: bindFixed(this.breakOnAllErrors, this, error) } + ]; + } +}); + +// ************************************************************************************************ + +this.SourceText = domplate(Firebug.Rep, +{ + tag: + DIV( + FOR("line", "$object|lineIterator", + DIV({"class": "sourceRow", role : "presentation"}, + SPAN({"class": "sourceLine", role : "presentation"}, "$line.lineNo"), + SPAN({"class": "sourceRowText", role : "presentation"}, "$line.text") + ) + ) + ), + + lineIterator: function(sourceText) + { + var maxLineNoChars = (sourceText.lines.length + "").length; + var list = []; + + for (var i = 0; i < sourceText.lines.length; ++i) + { + // Make sure all line numbers are the same width (with a fixed-width font) + var lineNo = (i+1) + ""; + while (lineNo.length < maxLineNoChars) + lineNo = " " + lineNo; + + list.push({lineNo: lineNo, text: sourceText.lines[i]}); + } + + return list; + }, + + getHTML: function(sourceText) + { + return getSourceLineRange(sourceText, 1, sourceText.lines.length); + } +}); + +//************************************************************************************************ +this.nsIDOMHistory = domplate(Firebug.Rep, +{ + tag:OBJECTBOX({onclick: "$showHistory"}, + OBJECTLINK("$object|summarizeHistory") + ), + + className: "nsIDOMHistory", + + summarizeHistory: function(history) + { + try + { + var items = history.length; + return items + " history entries"; + } + catch(exc) + { + return "object does not support history (nsIDOMHistory)"; + } + }, + + showHistory: function(history) + { + try + { + var items = history.length; // if this throws, then unsupported + Firebug.chrome.select(history); + } + catch (exc) + { + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + supportsObject: function(object, type) + { + return (object instanceof Ci.nsIDOMHistory); + } +}); + +// ************************************************************************************************ +this.ApplicationCache = domplate(Firebug.Rep, +{ + tag:OBJECTBOX({onclick: "$showApplicationCache"}, + OBJECTLINK("$object|summarizeCache") + ), + + summarizeCache: function(applicationCache) + { + try + { + return applicationCache.length + " items in offline cache"; + } + catch(exc) + { + return "https://bugzilla.mozilla.org/show_bug.cgi?id=422264"; + } + }, + + showApplicationCache: function(event) + { + openNewTab("https://bugzilla.mozilla.org/show_bug.cgi?id=422264"); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "applicationCache", + + supportsObject: function(object, type) + { + if (Ci.nsIDOMOfflineResourceList) + return (object instanceof Ci.nsIDOMOfflineResourceList); + } + +}); + +this.Storage = domplate(Firebug.Rep, +{ + tag: OBJECTBOX({onclick: "$show"}, OBJECTLINK("$object|summarize")), + + summarize: function(storage) + { + return storage.length +" items in Storage"; + }, + show: function(storage) + { + openNewTab("http://dev.w3.org/html5/webstorage/#storage-0"); + }, + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "Storage", + + supportsObject: function(object, type) + { + return (object instanceof Storage); + } + +}); + +// ************************************************************************************************ +Firebug.registerRep( + //this.nsIDOMHistory, // make this early to avoid exceptions + this.Undefined, + this.Null, + this.Number, + this.String, + this.Window, + //this.ApplicationCache, // must come before Arr (array) else exceptions. + //this.ErrorMessage, + this.Element, + //this.TextNode, + this.Document, + this.StyleSheet, + this.Event, + //this.SourceLink, + //this.SourceFile, + //this.StackTrace, + //this.StackFrame, + //this.jsdStackFrame, + //this.jsdScript, + //this.NetFile, + this.Property, + this.Except, + this.Arr +); + +Firebug.setDefaultReps(this.Func, this.Obj); + +}}); + +// ************************************************************************************************ +/* + * The following is http://developer.yahoo.com/yui/license.txt and applies to only code labeled "Yahoo BSD Source" + * in only this file reps.js. John J. Barton June 2007. + * +Software License Agreement (BSD License) + +Copyright (c) 2006, Yahoo! Inc. +All rights reserved. + +Redistribution and use of this software in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of Yahoo! Inc. nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of Yahoo! Inc. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * / + */ + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// Constants + +var saveTimeout = 400; +var pageAmount = 10; + +// ************************************************************************************************ +// Globals + +var currentTarget = null; +var currentGroup = null; +var currentPanel = null; +var currentEditor = null; + +var defaultEditor = null; + +var originalClassName = null; + +var originalValue = null; +var defaultValue = null; +var previousValue = null; + +var invalidEditor = false; +var ignoreNextInput = false; + +// ************************************************************************************************ + +Firebug.Editor = extend(Firebug.Module, +{ + supportsStopEvent: true, + + dispatchName: "editor", + tabCharacter: " ", + + startEditing: function(target, value, editor) + { + this.stopEditing(); + + if (hasClass(target, "insertBefore") || hasClass(target, "insertAfter")) + return; + + var panel = Firebug.getElementPanel(target); + if (!panel.editable) + return; + + if (FBTrace.DBG_EDITOR) + FBTrace.sysout("editor.startEditing " + value, target); + + defaultValue = target.getAttribute("defaultValue"); + if (value == undefined) + { + var textContent = isIE ? "innerText" : "textContent"; + value = target[textContent]; + if (value == defaultValue) + value = ""; + } + + originalValue = previousValue = value; + + invalidEditor = false; + currentTarget = target; + currentPanel = panel; + currentGroup = getAncestorByClass(target, "editGroup"); + + currentPanel.editing = true; + + var panelEditor = currentPanel.getEditor(target, value); + currentEditor = editor ? editor : panelEditor; + if (!currentEditor) + currentEditor = getDefaultEditor(currentPanel); + + var inlineParent = getInlineParent(target); + var targetSize = getOffsetSize(inlineParent); + + setClass(panel.panelNode, "editing"); + setClass(target, "editing"); + if (currentGroup) + setClass(currentGroup, "editing"); + + currentEditor.show(target, currentPanel, value, targetSize); + //dispatch(this.fbListeners, "onBeginEditing", [currentPanel, currentEditor, target, value]); + currentEditor.beginEditing(target, value); + if (FBTrace.DBG_EDITOR) + FBTrace.sysout("Editor start panel "+currentPanel.name); + this.attachListeners(currentEditor, panel.context); + }, + + stopEditing: function(cancel) + { + if (!currentTarget) + return; + + if (FBTrace.DBG_EDITOR) + FBTrace.sysout("editor.stopEditing cancel:" + cancel+" saveTimeout: "+this.saveTimeout); + + clearTimeout(this.saveTimeout); + delete this.saveTimeout; + + this.detachListeners(currentEditor, currentPanel.context); + + removeClass(currentPanel.panelNode, "editing"); + removeClass(currentTarget, "editing"); + if (currentGroup) + removeClass(currentGroup, "editing"); + + var value = currentEditor.getValue(); + if (value == defaultValue) + value = ""; + + var removeGroup = currentEditor.endEditing(currentTarget, value, cancel); + + try + { + if (cancel) + { + //dispatch([Firebug.A11yModel], 'onInlineEditorClose', [currentPanel, currentTarget, removeGroup && !originalValue]); + if (value != originalValue) + this.saveEditAndNotifyListeners(currentTarget, originalValue, previousValue); + + if (removeGroup && !originalValue && currentGroup) + currentGroup.parentNode.removeChild(currentGroup); + } + else if (!value) + { + this.saveEditAndNotifyListeners(currentTarget, null, previousValue); + + if (removeGroup && currentGroup) + currentGroup.parentNode.removeChild(currentGroup); + } + else + this.save(value); + } + catch (exc) + { + //throw exc.message; + //ERROR(exc); + } + + currentEditor.hide(); + currentPanel.editing = false; + + //dispatch(this.fbListeners, "onStopEdit", [currentPanel, currentEditor, currentTarget]); + //if (FBTrace.DBG_EDITOR) + // FBTrace.sysout("Editor stop panel "+currentPanel.name); + + currentTarget = null; + currentGroup = null; + currentPanel = null; + currentEditor = null; + originalValue = null; + invalidEditor = false; + + return value; + }, + + cancelEditing: function() + { + return this.stopEditing(true); + }, + + update: function(saveNow) + { + if (this.saveTimeout) + clearTimeout(this.saveTimeout); + + invalidEditor = true; + + currentEditor.layout(); + + if (saveNow) + this.save(); + else + { + var context = currentPanel.context; + this.saveTimeout = context.setTimeout(bindFixed(this.save, this), saveTimeout); + if (FBTrace.DBG_EDITOR) + FBTrace.sysout("editor.update saveTimeout: "+this.saveTimeout); + } + }, + + save: function(value) + { + if (!invalidEditor) + return; + + if (value == undefined) + value = currentEditor.getValue(); + if (FBTrace.DBG_EDITOR) + FBTrace.sysout("editor.save saveTimeout: "+this.saveTimeout+" currentPanel: "+(currentPanel?currentPanel.name:"null")); + try + { + this.saveEditAndNotifyListeners(currentTarget, value, previousValue); + + previousValue = value; + invalidEditor = false; + } + catch (exc) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("editor.save FAILS "+exc, exc); + } + }, + + saveEditAndNotifyListeners: function(currentTarget, value, previousValue) + { + currentEditor.saveEdit(currentTarget, value, previousValue); + //dispatch(this.fbListeners, "onSaveEdit", [currentPanel, currentEditor, currentTarget, value, previousValue]); + }, + + setEditTarget: function(element) + { + if (!element) + { + dispatch([Firebug.A11yModel], 'onInlineEditorClose', [currentPanel, currentTarget, true]); + this.stopEditing(); + } + else if (hasClass(element, "insertBefore")) + this.insertRow(element, "before"); + else if (hasClass(element, "insertAfter")) + this.insertRow(element, "after"); + else + this.startEditing(element); + }, + + tabNextEditor: function() + { + if (!currentTarget) + return; + + var value = currentEditor.getValue(); + var nextEditable = currentTarget; + do + { + nextEditable = !value && currentGroup + ? getNextOutsider(nextEditable, currentGroup) + : getNextByClass(nextEditable, "editable"); + } + while (nextEditable && !nextEditable.offsetHeight); + + this.setEditTarget(nextEditable); + }, + + tabPreviousEditor: function() + { + if (!currentTarget) + return; + + var value = currentEditor.getValue(); + var prevEditable = currentTarget; + do + { + prevEditable = !value && currentGroup + ? getPreviousOutsider(prevEditable, currentGroup) + : getPreviousByClass(prevEditable, "editable"); + } + while (prevEditable && !prevEditable.offsetHeight); + + this.setEditTarget(prevEditable); + }, + + insertRow: function(relative, insertWhere) + { + var group = + relative || getAncestorByClass(currentTarget, "editGroup") || currentTarget; + var value = this.stopEditing(); + + currentPanel = Firebug.getElementPanel(group); + + currentEditor = currentPanel.getEditor(group, value); + if (!currentEditor) + currentEditor = getDefaultEditor(currentPanel); + + currentGroup = currentEditor.insertNewRow(group, insertWhere); + if (!currentGroup) + return; + + var editable = hasClass(currentGroup, "editable") + ? currentGroup + : getNextByClass(currentGroup, "editable"); + + if (editable) + this.setEditTarget(editable); + }, + + insertRowForObject: function(relative) + { + var container = getAncestorByClass(relative, "insertInto"); + if (container) + { + relative = getChildByClass(container, "insertBefore"); + if (relative) + this.insertRow(relative, "before"); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + attachListeners: function(editor, context) + { + var win = isIE ? + currentTarget.ownerDocument.parentWindow : + currentTarget.ownerDocument.defaultView; + + addEvent(win, "resize", this.onResize); + addEvent(win, "blur", this.onBlur); + + var chrome = Firebug.chrome; + + this.listeners = [ + chrome.keyCodeListen("ESCAPE", null, bind(this.cancelEditing, this)) + ]; + + if (editor.arrowCompletion) + { + this.listeners.push( + chrome.keyCodeListen("UP", null, bindFixed(editor.completeValue, editor, -1)), + chrome.keyCodeListen("DOWN", null, bindFixed(editor.completeValue, editor, 1)), + chrome.keyCodeListen("PAGE_UP", null, bindFixed(editor.completeValue, editor, -pageAmount)), + chrome.keyCodeListen("PAGE_DOWN", null, bindFixed(editor.completeValue, editor, pageAmount)) + ); + } + + if (currentEditor.tabNavigation) + { + this.listeners.push( + chrome.keyCodeListen("RETURN", null, bind(this.tabNextEditor, this)), + chrome.keyCodeListen("RETURN", isControl, bind(this.insertRow, this, null, "after")), + chrome.keyCodeListen("TAB", null, bind(this.tabNextEditor, this)), + chrome.keyCodeListen("TAB", isShift, bind(this.tabPreviousEditor, this)) + ); + } + else if (currentEditor.multiLine) + { + this.listeners.push( + chrome.keyCodeListen("TAB", null, insertTab) + ); + } + else + { + this.listeners.push( + chrome.keyCodeListen("RETURN", null, bindFixed(this.stopEditing, this)) + ); + + if (currentEditor.tabCompletion) + { + this.listeners.push( + chrome.keyCodeListen("TAB", null, bind(editor.completeValue, editor, 1)), + chrome.keyCodeListen("TAB", isShift, bind(editor.completeValue, editor, -1)) + ); + } + } + }, + + detachListeners: function(editor, context) + { + if (!this.listeners) + return; + + var win = isIE ? + currentTarget.ownerDocument.parentWindow : + currentTarget.ownerDocument.defaultView; + + removeEvent(win, "resize", this.onResize); + removeEvent(win, "blur", this.onBlur); + + var chrome = Firebug.chrome; + if (chrome) + { + for (var i = 0; i < this.listeners.length; ++i) + chrome.keyIgnore(this.listeners[i]); + } + + delete this.listeners; + }, + + onResize: function(event) + { + currentEditor.layout(true); + }, + + onBlur: function(event) + { + if (currentEditor.enterOnBlur && isAncestor(event.target, currentEditor.box)) + this.stopEditing(); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Module + + initialize: function() + { + Firebug.Module.initialize.apply(this, arguments); + + this.onResize = bindFixed(this.onResize, this); + this.onBlur = bind(this.onBlur, this); + }, + + disable: function() + { + this.stopEditing(); + }, + + showContext: function(browser, context) + { + this.stopEditing(); + }, + + showPanel: function(browser, panel) + { + this.stopEditing(); + } +}); + +// ************************************************************************************************ +// BaseEditor + +Firebug.BaseEditor = extend(Firebug.MeasureBox, +{ + getValue: function() + { + }, + + setValue: function(value) + { + }, + + show: function(target, panel, value, textSize, targetSize) + { + }, + + hide: function() + { + }, + + layout: function(forceAll) + { + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Support for context menus within inline editors. + + getContextMenuItems: function(target) + { + var items = []; + items.push({label: "Cut", commandID: "cmd_cut"}); + items.push({label: "Copy", commandID: "cmd_copy"}); + items.push({label: "Paste", commandID: "cmd_paste"}); + return items; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Editor Module listeners will get "onBeginEditing" just before this call + + beginEditing: function(target, value) + { + }, + + // Editor Module listeners will get "onSaveEdit" just after this call + saveEdit: function(target, value, previousValue) + { + }, + + endEditing: function(target, value, cancel) + { + // Remove empty groups by default + return true; + }, + + insertNewRow: function(target, insertWhere) + { + } +}); + +// ************************************************************************************************ +// InlineEditor + +// basic inline editor attributes +var inlineEditorAttributes = { + "class": "textEditorInner", + + type: "text", + spellcheck: "false", + + onkeypress: "$onKeyPress", + + onoverflow: "$onOverflow", + oncontextmenu: "$onContextMenu" +}; + +// IE does not support the oninput event, so we're using the onkeydown to signalize +// the relevant keyboard events, and the onpropertychange to actually handle the +// input event, which should happen after the onkeydown event is fired and after the +// value of the input is updated, but before the onkeyup and before the input (with the +// new value) is rendered +if (isIE) +{ + inlineEditorAttributes.onpropertychange = "$onInput"; + inlineEditorAttributes.onkeydown = "$onKeyDown"; +} +// for other browsers we use the oninput event +else +{ + inlineEditorAttributes.oninput = "$onInput"; +} + +Firebug.InlineEditor = function(doc) +{ + this.initializeInline(doc); +}; + +Firebug.InlineEditor.prototype = domplate(Firebug.BaseEditor, +{ + enterOnBlur: true, + outerMargin: 8, + shadowExpand: 7, + + tag: + DIV({"class": "inlineEditor"}, + DIV({"class": "textEditorTop1"}, + DIV({"class": "textEditorTop2"}) + ), + DIV({"class": "textEditorInner1"}, + DIV({"class": "textEditorInner2"}, + INPUT( + inlineEditorAttributes + ) + ) + ), + DIV({"class": "textEditorBottom1"}, + DIV({"class": "textEditorBottom2"}) + ) + ), + + inputTag : + INPUT({"class": "textEditorInner", type: "text", + /*oninput: "$onInput",*/ onkeypress: "$onKeyPress", onoverflow: "$onOverflow"} + ), + + expanderTag: + IMG({"class": "inlineExpander", src: "blank.gif"}), + + initialize: function() + { + this.fixedWidth = false; + this.completeAsYouType = true; + this.tabNavigation = true; + this.multiLine = false; + this.tabCompletion = false; + this.arrowCompletion = true; + this.noWrap = true; + this.numeric = false; + }, + + destroy: function() + { + this.destroyInput(); + }, + + initializeInline: function(doc) + { + if (FBTrace.DBG_EDITOR) + FBTrace.sysout("Firebug.InlineEditor initializeInline()"); + + //this.box = this.tag.replace({}, doc, this); + this.box = this.tag.append({}, doc.body, this); + + //this.input = this.box.childNodes[1].firstChild.firstChild; // XXXjjb childNode[1] required + this.input = this.box.getElementsByTagName("input")[0]; + + if (isIElt8) + { + this.input.style.top = "-8px"; + } + + this.expander = this.expanderTag.replace({}, doc, this); + this.initialize(); + }, + + destroyInput: function() + { + // XXXjoe Need to remove input/keypress handlers to avoid leaks + }, + + getValue: function() + { + return this.input.value; + }, + + setValue: function(value) + { + // It's only a one-line editor, so new lines shouldn't be allowed + return this.input.value = stripNewLines(value); + }, + + show: function(target, panel, value, targetSize) + { + //dispatch([Firebug.A11yModel], "onInlineEditorShow", [panel, this]); + this.target = target; + this.panel = panel; + + this.targetSize = targetSize; + + // TODO: xxxpedro editor + //this.targetOffset = getClientOffset(target); + + // Some browsers (IE, Google Chrome and Safari) will have problem trying to get the + // offset values of invisible elements, or empty elements. So, in order to get the + // correct values, we temporary inject a character in the innerHTML of the empty element, + // then we get the offset values, and next, we restore the original innerHTML value. + var innerHTML = target.innerHTML; + var isEmptyElement = !innerHTML; + if (isEmptyElement) + target.innerHTML = "."; + + // Get the position of the target element (that is about to be edited) + this.targetOffset = + { + x: target.offsetLeft, + y: target.offsetTop + }; + + // Restore the original innerHTML value of the empty element + if (isEmptyElement) + target.innerHTML = innerHTML; + + this.originalClassName = this.box.className; + + var classNames = target.className.split(" "); + for (var i = 0; i < classNames.length; ++i) + setClass(this.box, "editor-" + classNames[i]); + + // Make the editor match the target's font style + copyTextStyles(target, this.box); + + this.setValue(value); + + if (this.fixedWidth) + this.updateLayout(true); + else + { + this.startMeasuring(target); + this.textSize = this.measureInputText(value); + + // Correct the height of the box to make the funky CSS drop-shadow line up + var parent = this.input.parentNode; + if (hasClass(parent, "textEditorInner2")) + { + var yDiff = this.textSize.height - this.shadowExpand; + + // IE6 height offset + if (isIE6) + yDiff -= 2; + + parent.style.height = yDiff + "px"; + parent.parentNode.style.height = yDiff + "px"; + } + + this.updateLayout(true); + } + + this.getAutoCompleter().reset(); + + if (isIElt8) + panel.panelNode.appendChild(this.box); + else + target.offsetParent.appendChild(this.box); + + //console.log(target); + //this.input.select(); // it's called bellow, with setTimeout + + if (isIE) + { + // reset input style + this.input.style.fontFamily = "Monospace"; + this.input.style.fontSize = "11px"; + } + + // Insert the "expander" to cover the target element with white space + if (!this.fixedWidth) + { + copyBoxStyles(target, this.expander); + + target.parentNode.replaceChild(this.expander, target); + collapse(target, true); + this.expander.parentNode.insertBefore(target, this.expander); + } + + //TODO: xxxpedro + //scrollIntoCenterView(this.box, null, true); + + // Display the editor after change its size and position to avoid flickering + this.box.style.display = "block"; + + // we need to call input.focus() and input.select() with a timeout, + // otherwise it won't work on all browsers due to timing issues + var self = this; + setTimeout(function(){ + self.input.focus(); + self.input.select(); + },0); + }, + + hide: function() + { + this.box.className = this.originalClassName; + + if (!this.fixedWidth) + { + this.stopMeasuring(); + + collapse(this.target, false); + + if (this.expander.parentNode) + this.expander.parentNode.removeChild(this.expander); + } + + if (this.box.parentNode) + { + ///setSelectionRange(this.input, 0, 0); + this.input.blur(); + + this.box.parentNode.removeChild(this.box); + } + + delete this.target; + delete this.panel; + }, + + layout: function(forceAll) + { + if (!this.fixedWidth) + this.textSize = this.measureInputText(this.input.value); + + if (forceAll) + this.targetOffset = getClientOffset(this.expander); + + this.updateLayout(false, forceAll); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + beginEditing: function(target, value) + { + }, + + saveEdit: function(target, value, previousValue) + { + }, + + endEditing: function(target, value, cancel) + { + // Remove empty groups by default + return true; + }, + + insertNewRow: function(target, insertWhere) + { + }, + + advanceToNext: function(target, charCode) + { + return false; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getAutoCompleteRange: function(value, offset) + { + }, + + getAutoCompleteList: function(preExpr, expr, postExpr) + { + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getAutoCompleter: function() + { + if (!this.autoCompleter) + { + this.autoCompleter = new Firebug.AutoCompleter(null, + bind(this.getAutoCompleteRange, this), bind(this.getAutoCompleteList, this), + true, false); + } + + return this.autoCompleter; + }, + + completeValue: function(amt) + { + //console.log("completeValue"); + + var selectRangeCallback = this.getAutoCompleter().complete(currentPanel.context, this.input, true, amt < 0); + + if (selectRangeCallback) + { + Firebug.Editor.update(true); + + // We need to select the editor text after calling update in Safari/Chrome, + // otherwise the text won't be selected + if (isSafari) + setTimeout(selectRangeCallback,0); + else + selectRangeCallback(); + } + else + this.incrementValue(amt); + }, + + incrementValue: function(amt) + { + var value = this.input.value; + + // TODO: xxxpedro editor + if (isIE) + var start = getInputSelectionStart(this.input), end = start; + else + var start = this.input.selectionStart, end = this.input.selectionEnd; + + //debugger; + var range = this.getAutoCompleteRange(value, start); + if (!range || range.type != "int") + range = {start: 0, end: value.length-1}; + + var expr = value.substr(range.start, range.end-range.start+1); + preExpr = value.substr(0, range.start); + postExpr = value.substr(range.end+1); + + // See if the value is an integer, and if so increment it + var intValue = parseInt(expr); + if (!!intValue || intValue == 0) + { + var m = /\d+/.exec(expr); + var digitPost = expr.substr(m.index+m[0].length); + + var completion = intValue-amt; + this.input.value = preExpr + completion + digitPost + postExpr; + + setSelectionRange(this.input, start, end); + + Firebug.Editor.update(true); + + return true; + } + else + return false; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + onKeyPress: function(event) + { + //console.log("onKeyPress", event); + if (event.keyCode == 27 && !this.completeAsYouType) + { + var reverted = this.getAutoCompleter().revert(this.input); + if (reverted) + cancelEvent(event); + } + else if (event.charCode && this.advanceToNext(this.target, event.charCode)) + { + Firebug.Editor.tabNextEditor(); + cancelEvent(event); + } + else + { + if (this.numeric && event.charCode && (event.charCode < 48 || event.charCode > 57) + && event.charCode != 45 && event.charCode != 46) + FBL.cancelEvent(event); + else + { + // If the user backspaces, don't autocomplete after the upcoming input event + this.ignoreNextInput = event.keyCode == 8; + } + } + }, + + onOverflow: function() + { + this.updateLayout(false, false, 3); + }, + + onKeyDown: function(event) + { + //console.log("onKeyDown", event.keyCode); + if (event.keyCode > 46 || event.keyCode == 32 || event.keyCode == 8) + { + this.keyDownPressed = true; + } + }, + + onInput: function(event) + { + //debugger; + + // skip not relevant onpropertychange calls on IE + if (isIE) + { + if (event.propertyName != "value" || !isVisible(this.input) || !this.keyDownPressed) + return; + + this.keyDownPressed = false; + } + + //console.log("onInput", event); + //console.trace(); + + var selectRangeCallback; + + if (this.ignoreNextInput) + { + this.ignoreNextInput = false; + this.getAutoCompleter().reset(); + } + else if (this.completeAsYouType) + selectRangeCallback = this.getAutoCompleter().complete(currentPanel.context, this.input, false); + else + this.getAutoCompleter().reset(); + + Firebug.Editor.update(); + + if (selectRangeCallback) + { + // We need to select the editor text after calling update in Safari/Chrome, + // otherwise the text won't be selected + if (isSafari) + setTimeout(selectRangeCallback,0); + else + selectRangeCallback(); + } + }, + + onContextMenu: function(event) + { + cancelEvent(event); + + var popup = $("fbInlineEditorPopup"); + FBL.eraseNode(popup); + + var target = event.target || event.srcElement; + var menu = this.getContextMenuItems(target); + if (menu) + { + for (var i = 0; i < menu.length; ++i) + FBL.createMenuItem(popup, menu[i]); + } + + if (!popup.firstChild) + return false; + + popup.openPopupAtScreen(event.screenX, event.screenY, true); + return true; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + updateLayout: function(initial, forceAll, extraWidth) + { + if (this.fixedWidth) + { + this.box.style.left = (this.targetOffset.x) + "px"; + this.box.style.top = (this.targetOffset.y) + "px"; + + var w = this.target.offsetWidth; + var h = this.target.offsetHeight; + this.input.style.width = w + "px"; + this.input.style.height = (h-3) + "px"; + } + else + { + if (initial || forceAll) + { + this.box.style.left = this.targetOffset.x + "px"; + this.box.style.top = this.targetOffset.y + "px"; + } + + var approxTextWidth = this.textSize.width; + var maxWidth = (currentPanel.panelNode.scrollWidth - this.targetOffset.x) + - this.outerMargin; + + var wrapped = initial + ? this.noWrap && this.targetSize.height > this.textSize.height+3 + : this.noWrap && approxTextWidth > maxWidth; + + if (wrapped) + { + var style = isIE ? + this.target.currentStyle : + this.target.ownerDocument.defaultView.getComputedStyle(this.target, ""); + + targetMargin = parseInt(style.marginLeft) + parseInt(style.marginRight); + + // Make the width fit the remaining x-space from the offset to the far right + approxTextWidth = maxWidth - targetMargin; + + this.input.style.width = "100%"; + this.box.style.width = approxTextWidth + "px"; + } + else + { + // Make the input one character wider than the text value so that + // typing does not ever cause the textbox to scroll + var charWidth = this.measureInputText('m').width; + + // Sometimes we need to make the editor a little wider, specifically when + // an overflow happens, otherwise it will scroll off some text on the left + if (extraWidth) + charWidth *= extraWidth; + + var inputWidth = approxTextWidth + charWidth; + + if (initial) + { + if (isIE) + { + // TODO: xxxpedro + var xDiff = 13; + this.box.style.width = (inputWidth + xDiff) + "px"; + } + else + this.box.style.width = "auto"; + } + else + { + // TODO: xxxpedro + var xDiff = isIE ? 13: this.box.scrollWidth - this.input.offsetWidth; + this.box.style.width = (inputWidth + xDiff) + "px"; + } + + this.input.style.width = inputWidth + "px"; + } + + this.expander.style.width = approxTextWidth + "px"; + this.expander.style.height = Math.max(this.textSize.height-3,0) + "px"; + } + + if (forceAll) + scrollIntoCenterView(this.box, null, true); + } +}); + +// ************************************************************************************************ +// Autocompletion + +Firebug.AutoCompleter = function(getExprOffset, getRange, evaluator, selectMode, caseSensitive) +{ + var candidates = null; + var originalValue = null; + var originalOffset = -1; + var lastExpr = null; + var lastOffset = -1; + var exprOffset = 0; + var lastIndex = 0; + var preParsed = null; + var preExpr = null; + var postExpr = null; + + this.revert = function(textBox) + { + if (originalOffset != -1) + { + textBox.value = originalValue; + + setSelectionRange(textBox, originalOffset, originalOffset); + + this.reset(); + return true; + } + else + { + this.reset(); + return false; + } + }; + + this.reset = function() + { + candidates = null; + originalValue = null; + originalOffset = -1; + lastExpr = null; + lastOffset = 0; + exprOffset = 0; + }; + + this.complete = function(context, textBox, cycle, reverse) + { + //console.log("complete", context, textBox, cycle, reverse); + // TODO: xxxpedro important port to firebug (variable leak) + //var value = lastValue = textBox.value; + var value = textBox.value; + + //var offset = textBox.selectionStart; + var offset = getInputSelectionStart(textBox); + + // The result of selectionStart() in Safari/Chrome is 1 unit less than the result + // in Firefox. Therefore, we need to manually adjust the value here. + if (isSafari && !cycle && offset >= 0) offset++; + + if (!selectMode && originalOffset != -1) + offset = originalOffset; + + if (!candidates || !cycle || offset != lastOffset) + { + originalOffset = offset; + originalValue = value; + + // Find the part of the string that will be parsed + var parseStart = getExprOffset ? getExprOffset(value, offset, context) : 0; + preParsed = value.substr(0, parseStart); + var parsed = value.substr(parseStart); + + // Find the part of the string that is being completed + var range = getRange ? getRange(parsed, offset-parseStart, context) : null; + if (!range) + range = {start: 0, end: parsed.length-1 }; + + var expr = parsed.substr(range.start, range.end-range.start+1); + preExpr = parsed.substr(0, range.start); + postExpr = parsed.substr(range.end+1); + exprOffset = parseStart + range.start; + + if (!cycle) + { + if (!expr) + return; + else if (lastExpr && lastExpr.indexOf(expr) != 0) + { + candidates = null; + } + else if (lastExpr && lastExpr.length >= expr.length) + { + candidates = null; + lastExpr = expr; + return; + } + } + + lastExpr = expr; + lastOffset = offset; + + var searchExpr; + + // Check if the cursor is at the very right edge of the expression, or + // somewhere in the middle of it + if (expr && offset != parseStart+range.end+1) + { + if (cycle) + { + // We are in the middle of the expression, but we can + // complete by cycling to the next item in the values + // list after the expression + offset = range.start; + searchExpr = expr; + expr = ""; + } + else + { + // We can't complete unless we are at the ridge edge + return; + } + } + + var values = evaluator(preExpr, expr, postExpr, context); + if (!values) + return; + + if (expr) + { + // Filter the list of values to those which begin with expr. We + // will then go on to complete the first value in the resulting list + candidates = []; + + if (caseSensitive) + { + for (var i = 0; i < values.length; ++i) + { + var name = values[i]; + if (name.indexOf && name.indexOf(expr) == 0) + candidates.push(name); + } + } + else + { + var lowerExpr = caseSensitive ? expr : expr.toLowerCase(); + for (var i = 0; i < values.length; ++i) + { + var name = values[i]; + if (name.indexOf && name.toLowerCase().indexOf(lowerExpr) == 0) + candidates.push(name); + } + } + + lastIndex = reverse ? candidates.length-1 : 0; + } + else if (searchExpr) + { + var searchIndex = -1; + + // Find the first instance of searchExpr in the values list. We + // will then complete the string that is found + if (caseSensitive) + { + searchIndex = values.indexOf(expr); + } + else + { + var lowerExpr = searchExpr.toLowerCase(); + for (var i = 0; i < values.length; ++i) + { + var name = values[i]; + if (name && name.toLowerCase().indexOf(lowerExpr) == 0) + { + searchIndex = i; + break; + } + } + } + + // Nothing found, so there's nothing to complete to + if (searchIndex == -1) + return this.reset(); + + expr = searchExpr; + candidates = cloneArray(values); + lastIndex = searchIndex; + } + else + { + expr = ""; + candidates = []; + for (var i = 0; i < values.length; ++i) + { + if (values[i].substr) + candidates.push(values[i]); + } + lastIndex = -1; + } + } + + if (cycle) + { + expr = lastExpr; + lastIndex += reverse ? -1 : 1; + } + + if (!candidates.length) + return; + + if (lastIndex >= candidates.length) + lastIndex = 0; + else if (lastIndex < 0) + lastIndex = candidates.length-1; + + var completion = candidates[lastIndex]; + var preCompletion = expr.substr(0, offset-exprOffset); + var postCompletion = completion.substr(offset-exprOffset); + + textBox.value = preParsed + preExpr + preCompletion + postCompletion + postExpr; + var offsetEnd = preParsed.length + preExpr.length + completion.length; + + // TODO: xxxpedro remove the following commented code, if the lib.setSelectionRange() + // is working well. + /* + if (textBox.setSelectionRange) + { + // we must select the range with a timeout, otherwise the text won't + // be properly selected (because after this function executes, the editor's + // input will be resized to fit the whole text) + setTimeout(function(){ + if (selectMode) + textBox.setSelectionRange(offset, offsetEnd); + else + textBox.setSelectionRange(offsetEnd, offsetEnd); + },0); + } + /**/ + + // we must select the range with a timeout, otherwise the text won't + // be properly selected (because after this function executes, the editor's + // input will be resized to fit the whole text) + /* + setTimeout(function(){ + if (selectMode) + setSelectionRange(textBox, offset, offsetEnd); + else + setSelectionRange(textBox, offsetEnd, offsetEnd); + },0); + + return true; + /**/ + + // The editor text should be selected only after calling the editor.update() + // in Safari/Chrome, otherwise the text won't be selected. So, we're returning + // a function to be called later (in the proper time for all browsers). + // + // TODO: xxxpedro see if we can move the editor.update() calls to here, and avoid + // returning a closure. the complete() function seems to be called only twice in + // editor.js. See if this function is called anywhere else (like css.js for example). + return function(){ + //console.log("autocomplete ", textBox, offset, offsetEnd); + + if (selectMode) + setSelectionRange(textBox, offset, offsetEnd); + else + setSelectionRange(textBox, offsetEnd, offsetEnd); + }; + /**/ + }; +}; + +// ************************************************************************************************ +// Local Helpers + +var getDefaultEditor = function getDefaultEditor(panel) +{ + if (!defaultEditor) + { + var doc = panel.document; + defaultEditor = new Firebug.InlineEditor(doc); + } + + return defaultEditor; +} + +/** + * An outsider is the first element matching the stepper element that + * is not an child of group. Elements tagged with insertBefore or insertAfter + * classes are also excluded from these results unless they are the sibling + * of group, relative to group's parent editGroup. This allows for the proper insertion + * rows when groups are nested. + */ +var getOutsider = function getOutsider(element, group, stepper) +{ + var parentGroup = getAncestorByClass(group.parentNode, "editGroup"); + var next; + do + { + next = stepper(next || element); + } + while (isAncestor(next, group) || isGroupInsert(next, parentGroup)); + + return next; +} + +var isGroupInsert = function isGroupInsert(next, group) +{ + return (!group || isAncestor(next, group)) + && (hasClass(next, "insertBefore") || hasClass(next, "insertAfter")); +} + +var getNextOutsider = function getNextOutsider(element, group) +{ + return getOutsider(element, group, bind(getNextByClass, FBL, "editable")); +} + +var getPreviousOutsider = function getPreviousOutsider(element, group) +{ + return getOutsider(element, group, bind(getPreviousByClass, FBL, "editable")); +} + +var getInlineParent = function getInlineParent(element) +{ + var lastInline = element; + for (; element; element = element.parentNode) + { + //var s = element.ownerDocument.defaultView.getComputedStyle(element, ""); + var s = isIE ? + element.currentStyle : + element.ownerDocument.defaultView.getComputedStyle(element, ""); + + if (s.display != "inline") + return lastInline; + else + lastInline = element; + } + return null; +} + +var insertTab = function insertTab() +{ + insertTextIntoElement(currentEditor.input, Firebug.Editor.tabCharacter); +} + +// ************************************************************************************************ + +Firebug.registerModule(Firebug.Editor); + +// ************************************************************************************************ + +}}); + + +/* 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(); + + 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" ? FirebugChrome.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 + + + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +// next-generation Console Panel (will override consoje.js) +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +// Constants + +/* +const Cc = Components.classes; +const Ci = Components.interfaces; +const nsIPrefBranch2 = Ci.nsIPrefBranch2; +const PrefService = Cc["@mozilla.org/preferences-service;1"]; +const prefs = PrefService.getService(nsIPrefBranch2); +/**/ +/* + +// new offline message handler +o = {x:1,y:2}; + +r = Firebug.getRep(o); + +r.tag.tag.compile(); + +outputs = []; +html = r.tag.renderHTML({object:o}, outputs); + + +// finish rendering the template (the DOM part) +target = $("build"); +target.innerHTML = html; +root = target.firstChild; + +domArgs = [root, r.tag.context, 0]; +domArgs.push.apply(domArgs, r.tag.domArgs); +domArgs.push.apply(domArgs, outputs); +r.tag.tag.renderDOM.apply(self ? self : r.tag.subject, domArgs); + + + */ +var consoleQueue = []; +var lastHighlightedObject; +var FirebugContext = Env.browser; + +// ************************************************************************************************ + +var maxQueueRequests = 500; + +// ************************************************************************************************ + +Firebug.ConsoleBase = +{ + log: function(object, context, className, rep, noThrottle, sourceLink) + { + //dispatch(this.fbListeners,"log",[context, object, className, sourceLink]); + return this.logRow(appendObject, object, context, className, rep, sourceLink, noThrottle); + }, + + logFormatted: function(objects, context, className, noThrottle, sourceLink) + { + //dispatch(this.fbListeners,"logFormatted",[context, objects, className, sourceLink]); + return this.logRow(appendFormatted, objects, context, className, null, sourceLink, noThrottle); + }, + + openGroup: function(objects, context, className, rep, noThrottle, sourceLink, noPush) + { + return this.logRow(appendOpenGroup, objects, context, className, rep, sourceLink, noThrottle); + }, + + closeGroup: function(context, noThrottle) + { + return this.logRow(appendCloseGroup, null, context, null, null, null, noThrottle, true); + }, + + logRow: function(appender, objects, context, className, rep, sourceLink, noThrottle, noRow) + { + // TODO: xxxpedro console console2 + noThrottle = true; // xxxpedro forced because there is no TabContext yet + + if (!context) + context = FirebugContext; + + if (FBTrace.DBG_ERRORS && !context) + FBTrace.sysout("Console.logRow has no context, skipping objects", objects); + + if (!context) + return; + + if (noThrottle || !context) + { + var panel = this.getPanel(context); + if (panel) + { + var row = panel.append(appender, objects, className, rep, sourceLink, noRow); + var container = panel.panelNode; + + // TODO: xxxpedro what is this? console console2 + /* + var template = Firebug.NetMonitor.NetLimit; + + while (container.childNodes.length > maxQueueRequests + 1) + { + clearDomplate(container.firstChild.nextSibling); + container.removeChild(container.firstChild.nextSibling); + panel.limit.limitInfo.totalCount++; + template.updateCounter(panel.limit); + } + dispatch([Firebug.A11yModel], "onLogRowCreated", [panel , row]); + /**/ + return row; + } + else + { + consoleQueue.push([appender, objects, context, className, rep, sourceLink, noThrottle, noRow]); + } + } + else + { + if (!context.throttle) + { + //FBTrace.sysout("console.logRow has not context.throttle! "); + return; + } + var args = [appender, objects, context, className, rep, sourceLink, true, noRow]; + context.throttle(this.logRow, this, args); + } + }, + + appendFormatted: function(args, row, context) + { + if (!context) + context = FirebugContext; + + var panel = this.getPanel(context); + panel.appendFormatted(args, row); + }, + + clear: function(context) + { + if (!context) + //context = FirebugContext; + context = Firebug.context; + + /* + if (context) + Firebug.Errors.clear(context); + /**/ + + var panel = this.getPanel(context, true); + if (panel) + { + panel.clear(); + } + }, + + // Override to direct output to your panel + getPanel: function(context, noCreate) + { + //return context.getPanel("console", noCreate); + // TODO: xxxpedro console console2 + return Firebug.chrome ? Firebug.chrome.getPanel("Console") : null; + } + +}; + +// ************************************************************************************************ + +//TODO: xxxpedro +//var ActivableConsole = extend(Firebug.ActivableModule, Firebug.ConsoleBase); +var ActivableConsole = extend(Firebug.ConsoleBase, +{ + isAlwaysEnabled: function() + { + return true; + } +}); + +Firebug.Console = Firebug.Console = extend(ActivableConsole, +//Firebug.Console = extend(ActivableConsole, +{ + dispatchName: "console", + + error: function() + { + Firebug.Console.logFormatted(arguments, Firebug.browser, "error"); + }, + + flush: function() + { + dispatch(this.fbListeners,"flush",[]); + + for (var i=0, length=consoleQueue.length; i objects.length) // then too few parameters for format, assume unformatted. + { + format = ""; + objIndex = -1; + parts.length = 0; + break; + } + } + + } + for (var i = 0; i < parts.length; ++i) + { + var part = parts[i]; + if (part && typeof(part) == "object") + { + var object = objects[++objIndex]; + if (typeof(object) != "undefined") + this.appendObject(object, row, part.rep); + else + this.appendObject(part.type, row, FirebugReps.Text); + } + else + FirebugReps.Text.tag.append({object: part}, row); + } + + for (var i = objIndex+1; i < objects.length; ++i) + { + logText(" ", row); + var object = objects[i]; + if (typeof(object) == "string") + FirebugReps.Text.tag.append({object: object}, row); + else + this.appendObject(object, row); + } + }, + + appendOpenGroup: function(objects, row, rep) + { + if (!this.groups) + this.groups = []; + + setClass(row, "logGroup"); + setClass(row, "opened"); + + var innerRow = this.createRow("logRow"); + setClass(innerRow, "logGroupLabel"); + if (rep) + rep.tag.replace({"objects": objects}, innerRow); + else + this.appendFormatted(objects, innerRow, rep); + row.appendChild(innerRow); + //dispatch([Firebug.A11yModel], 'onLogRowCreated', [this, innerRow]); + var groupBody = this.createRow("logGroupBody"); + row.appendChild(groupBody); + groupBody.setAttribute('role', 'group'); + this.groups.push(groupBody); + + addEvent(innerRow, "mousedown", function(event) + { + if (isLeftClick(event)) + { + //console.log(event.currentTarget == event.target); + + var target = event.target || event.srcElement; + + target = getAncestorByClass(target, "logGroupLabel"); + + var groupRow = target.parentNode; + + if (hasClass(groupRow, "opened")) + { + removeClass(groupRow, "opened"); + target.setAttribute('aria-expanded', 'false'); + } + else + { + setClass(groupRow, "opened"); + target.setAttribute('aria-expanded', 'true'); + } + } + }); + }, + + appendCloseGroup: function(object, row, rep) + { + if (this.groups) + this.groups.pop(); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // TODO: xxxpedro console2 + onMouseMove: function(event) + { + var target = event.srcElement || event.target; + + var object = getAncestorByClass(target, "objectLink-element"); + object = object ? object.repObject : null; + + if(object && instanceOf(object, "Element") && object.nodeType == 1) + { + if(object != lastHighlightedObject) + { + Firebug.Inspector.drawBoxModel(object); + object = lastHighlightedObject; + } + } + else + Firebug.Inspector.hideBoxModel(); + + }, + + onMouseDown: function(event) + { + var target = event.srcElement || event.target; + + var object = getAncestorByClass(target, "objectLink"); + var repObject = object ? object.repObject : null; + + if (!repObject) + { + return; + } + + if (hasClass(object, "objectLink-object")) + { + Firebug.chrome.selectPanel("DOM"); + Firebug.chrome.getPanel("DOM").select(repObject, true); + } + else if (hasClass(object, "objectLink-element")) + { + Firebug.chrome.selectPanel("HTML"); + Firebug.chrome.getPanel("HTML").select(repObject, true); + } + + /* + if(object && instanceOf(object, "Element") && object.nodeType == 1) + { + if(object != lastHighlightedObject) + { + Firebug.Inspector.drawBoxModel(object); + object = lastHighlightedObject; + } + } + else + Firebug.Inspector.hideBoxModel(); + /**/ + + }, + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "Console", + title: "Console", + //searchable: true, + //breakable: true, + //editable: false, + + options: + { + hasCommandLine: true, + hasToolButtons: true, + isPreRendered: true + }, + + create: function() + { + Firebug.Panel.create.apply(this, arguments); + + this.context = Firebug.browser.window; + this.document = Firebug.chrome.document; + this.onMouseMove = bind(this.onMouseMove, this); + this.onMouseDown = bind(this.onMouseDown, this); + + this.clearButton = new Button({ + element: $("fbConsole_btClear"), + owner: Firebug.Console, + onClick: Firebug.Console.clear + }); + }, + + initialize: function() + { + Firebug.Panel.initialize.apply(this, arguments); // loads persisted content + //Firebug.ActivablePanel.initialize.apply(this, arguments); // loads persisted content + + if (!this.persistedContent && Firebug.Console.isAlwaysEnabled()) + { + this.insertLogLimit(this.context); + + // Initialize log limit and listen for changes. + this.updateMaxLimit(); + + if (this.context.consoleReloadWarning) // we have not yet injected the console + this.insertReloadWarning(); + } + + //Firebug.Console.injector.install(Firebug.browser.window); + + addEvent(this.panelNode, "mouseover", this.onMouseMove); + addEvent(this.panelNode, "mousedown", this.onMouseDown); + + this.clearButton.initialize(); + + //consolex.trace(); + //TODO: xxxpedro remove this + /* + Firebug.Console.openGroup(["asd"], null, "group", null, false); + Firebug.Console.log("asd"); + Firebug.Console.log("asd"); + Firebug.Console.log("asd"); + /**/ + + //TODO: xxxpedro preferences prefs + //prefs.addObserver(Firebug.prefDomain, this, false); + }, + + initializeNode : function() + { + //dispatch([Firebug.A11yModel], 'onInitializeNode', [this]); + if (FBTrace.DBG_CONSOLE) + { + this.onScroller = bind(this.onScroll, this); + addEvent(this.panelNode, "scroll", this.onScroller); + } + + this.onResizer = bind(this.onResize, this); + this.resizeEventTarget = Firebug.chrome.$('fbContentBox'); + addEvent(this.resizeEventTarget, "resize", this.onResizer); + }, + + destroyNode : function() + { + //dispatch([Firebug.A11yModel], 'onDestroyNode', [this]); + if (this.onScroller) + removeEvent(this.panelNode, "scroll", this.onScroller); + + //removeEvent(this.resizeEventTarget, "resize", this.onResizer); + }, + + shutdown: function() + { + //TODO: xxxpedro console console2 + this.clearButton.shutdown(); + + removeEvent(this.panelNode, "mousemove", this.onMouseMove); + removeEvent(this.panelNode, "mousedown", this.onMouseDown); + + this.destroyNode(); + + Firebug.Panel.shutdown.apply(this, arguments); + + //TODO: xxxpedro preferences prefs + //prefs.removeObserver(Firebug.prefDomain, this, false); + }, + + ishow: function(state) + { + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("Console.panel show; " + this.context.getName(), state); + + var enabled = Firebug.Console.isAlwaysEnabled(); + if (enabled) + { + Firebug.Console.disabledPanelPage.hide(this); + this.showCommandLine(true); + this.showToolbarButtons("fbConsoleButtons", true); + Firebug.chrome.setGlobalAttribute("cmd_togglePersistConsole", "checked", this.persistContent); + + if (state && state.wasScrolledToBottom) + { + this.wasScrolledToBottom = state.wasScrolledToBottom; + delete state.wasScrolledToBottom; + } + + if (this.wasScrolledToBottom) + scrollToBottom(this.panelNode); + + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.show ------------------ wasScrolledToBottom: " + + this.wasScrolledToBottom + ", " + this.context.getName()); + } + else + { + this.hide(state); + Firebug.Console.disabledPanelPage.show(this); + } + }, + + ihide: function(state) + { + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("Console.panel hide; " + this.context.getName(), state); + + this.showToolbarButtons("fbConsoleButtons", false); + this.showCommandLine(false); + + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.hide ------------------ wasScrolledToBottom: " + + this.wasScrolledToBottom + ", " + this.context.getName()); + }, + + destroy: function(state) + { + if (this.panelNode.offsetHeight) + this.wasScrolledToBottom = isScrolledToBottom(this.panelNode); + + if (state) + state.wasScrolledToBottom = this.wasScrolledToBottom; + + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.destroy ------------------ wasScrolledToBottom: " + + this.wasScrolledToBottom + ", " + this.context.getName()); + }, + + shouldBreakOnNext: function() + { + // xxxHonza: shouldn't the breakOnErrors be context related? + // xxxJJB, yes, but we can't support it because we can't yet tell + // which window the error is on. + return Firebug.getPref(Firebug.servicePrefDomain, "breakOnErrors"); + }, + + getBreakOnNextTooltip: function(enabled) + { + return (enabled ? $STR("console.Disable Break On All Errors") : + $STR("console.Break On All Errors")); + }, + + enablePanel: function(module) + { + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.ConsolePanel.enablePanel; " + this.context.getName()); + + Firebug.ActivablePanel.enablePanel.apply(this, arguments); + + this.showCommandLine(true); + + if (this.wasScrolledToBottom) + scrollToBottom(this.panelNode); + }, + + disablePanel: function(module) + { + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.ConsolePanel.disablePanel; " + this.context.getName()); + + Firebug.ActivablePanel.disablePanel.apply(this, arguments); + + this.showCommandLine(false); + }, + + getOptionsMenuItems: function() + { + return [ + optionMenu("ShowJavaScriptErrors", "showJSErrors"), + optionMenu("ShowJavaScriptWarnings", "showJSWarnings"), + optionMenu("ShowCSSErrors", "showCSSErrors"), + optionMenu("ShowXMLErrors", "showXMLErrors"), + optionMenu("ShowXMLHttpRequests", "showXMLHttpRequests"), + optionMenu("ShowChromeErrors", "showChromeErrors"), + optionMenu("ShowChromeMessages", "showChromeMessages"), + optionMenu("ShowExternalErrors", "showExternalErrors"), + optionMenu("ShowNetworkErrors", "showNetworkErrors"), + this.getShowStackTraceMenuItem(), + this.getStrictOptionMenuItem(), + "-", + optionMenu("LargeCommandLine", "largeCommandLine") + ]; + }, + + getShowStackTraceMenuItem: function() + { + var menuItem = serviceOptionMenu("ShowStackTrace", "showStackTrace"); + if (FirebugContext && !Firebug.Debugger.isAlwaysEnabled()) + menuItem.disabled = true; + return menuItem; + }, + + getStrictOptionMenuItem: function() + { + var strictDomain = "javascript.options"; + var strictName = "strict"; + var strictValue = prefs.getBoolPref(strictDomain+"."+strictName); + return {label: "JavascriptOptionsStrict", type: "checkbox", checked: strictValue, + command: bindFixed(Firebug.setPref, Firebug, strictDomain, strictName, !strictValue) }; + }, + + getBreakOnMenuItems: function() + { + //xxxHonza: no BON options for now. + /*return [ + optionMenu("console.option.Persist Break On Error", "persistBreakOnError") + ];*/ + return []; + }, + + search: function(text) + { + if (!text) + return; + + // Make previously visible nodes invisible again + if (this.matchSet) + { + for (var i in this.matchSet) + removeClass(this.matchSet[i], "matched"); + } + + this.matchSet = []; + + function findRow(node) { return getAncestorByClass(node, "logRow"); } + var search = new TextSearch(this.panelNode, findRow); + + var logRow = search.find(text); + if (!logRow) + { + dispatch([Firebug.A11yModel], 'onConsoleSearchMatchFound', [this, text, []]); + return false; + } + for (; logRow; logRow = search.findNext()) + { + setClass(logRow, "matched"); + this.matchSet.push(logRow); + } + dispatch([Firebug.A11yModel], 'onConsoleSearchMatchFound', [this, text, this.matchSet]); + return true; + }, + + breakOnNext: function(breaking) + { + Firebug.setPref(Firebug.servicePrefDomain, "breakOnErrors", breaking); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // private + + createRow: function(rowName, className) + { + var elt = this.document.createElement("div"); + elt.className = rowName + (className ? " " + rowName + "-" + className : ""); + return elt; + }, + + getTopContainer: function() + { + if (this.groups && this.groups.length) + return this.groups[this.groups.length-1]; + else + return this.panelNode; + }, + + filterLogRow: function(logRow, scrolledToBottom) + { + if (this.searchText) + { + setClass(logRow, "matching"); + setClass(logRow, "matched"); + + // Search after a delay because we must wait for a frame to be created for + // the new logRow so that the finder will be able to locate it + setTimeout(bindFixed(function() + { + if (this.searchFilter(this.searchText, logRow)) + this.matchSet.push(logRow); + else + removeClass(logRow, "matched"); + + removeClass(logRow, "matching"); + + if (scrolledToBottom) + scrollToBottom(this.panelNode); + }, this), 100); + } + }, + + searchFilter: function(text, logRow) + { + var count = this.panelNode.childNodes.length; + var searchRange = this.document.createRange(); + searchRange.setStart(this.panelNode, 0); + searchRange.setEnd(this.panelNode, count); + + var startPt = this.document.createRange(); + startPt.setStartBefore(logRow); + + var endPt = this.document.createRange(); + endPt.setStartAfter(logRow); + + return finder.Find(text, searchRange, startPt, endPt) != null; + }, + + // nsIPrefObserver + observe: function(subject, topic, data) + { + // We're observing preferences only. + if (topic != "nsPref:changed") + return; + + // xxxHonza check this out. + var prefDomain = "Firebug.extension."; + var prefName = data.substr(prefDomain.length); + if (prefName == "console.logLimit") + this.updateMaxLimit(); + }, + + updateMaxLimit: function() + { + var value = 1000; + //TODO: xxxpedro preferences log limit? + //var value = Firebug.getPref(Firebug.prefDomain, "console.logLimit"); + maxQueueRequests = value ? value : maxQueueRequests; + }, + + showCommandLine: function(shouldShow) + { + //TODO: xxxpedro show command line important + return; + + if (shouldShow) + { + collapse(Firebug.chrome.$("fbCommandBox"), false); + Firebug.CommandLine.setMultiLine(Firebug.largeCommandLine, Firebug.chrome); + } + else + { + // Make sure that entire content of the Console panel is hidden when + // the panel is disabled. + Firebug.CommandLine.setMultiLine(false, Firebug.chrome, Firebug.largeCommandLine); + collapse(Firebug.chrome.$("fbCommandBox"), true); + } + }, + + onScroll: function(event) + { + // Update the scroll position flag if the position changes. + this.wasScrolledToBottom = FBL.isScrolledToBottom(this.panelNode); + + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.onScroll ------------------ wasScrolledToBottom: " + + this.wasScrolledToBottom + ", wasScrolledToBottom: " + + this.context.getName(), event); + }, + + onResize: function(event) + { + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.onResize ------------------ wasScrolledToBottom: " + + this.wasScrolledToBottom + ", offsetHeight: " + this.panelNode.offsetHeight + + ", scrollTop: " + this.panelNode.scrollTop + ", scrollHeight: " + + this.panelNode.scrollHeight + ", " + this.context.getName(), event); + + if (this.wasScrolledToBottom) + scrollToBottom(this.panelNode); + } +}); + +// ************************************************************************************************ + +function parseFormat(format) +{ + var parts = []; + if (format.length <= 0) + return parts; + + var reg = /((^%|.%)(\d+)?(\.)([a-zA-Z]))|((^%|.%)([a-zA-Z]))/; + for (var m = reg.exec(format); m; m = reg.exec(format)) + { + if (m[0].substr(0, 2) == "%%") + { + parts.push(format.substr(0, m.index)); + parts.push(m[0].substr(1)); + } + else + { + var type = m[8] ? m[8] : m[5]; + var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0); + + var rep = null; + switch (type) + { + case "s": + rep = FirebugReps.Text; + break; + case "f": + case "i": + case "d": + rep = FirebugReps.Number; + break; + case "o": + rep = null; + break; + } + + parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1)); + parts.push({rep: rep, precision: precision, type: ("%" + type)}); + } + + format = format.substr(m.index+m[0].length); + } + + parts.push(format); + return parts; +} + +// ************************************************************************************************ + +var appendObject = Firebug.ConsolePanel.prototype.appendObject; +var appendFormatted = Firebug.ConsolePanel.prototype.appendFormatted; +var appendOpenGroup = Firebug.ConsolePanel.prototype.appendOpenGroup; +var appendCloseGroup = Firebug.ConsolePanel.prototype.appendCloseGroup; + +// ************************************************************************************************ + +//Firebug.registerActivableModule(Firebug.Console); +Firebug.registerModule(Firebug.Console); +Firebug.registerPanel(Firebug.ConsolePanel); + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// Constants + +//const Cc = Components.classes; +//const Ci = Components.interfaces; + +var frameCounters = {}; +var traceRecursion = 0; + +Firebug.Console.injector = +{ + install: function(context) + { + var win = context.window; + + var consoleHandler = new FirebugConsoleHandler(context, win); + + var properties = + [ + "log", + "debug", + "info", + "warn", + "error", + "assert", + "dir", + "dirxml", + "group", + "groupCollapsed", + "groupEnd", + "time", + "timeEnd", + "count", + "trace", + "profile", + "profileEnd", + "clear", + "open", + "close" + ]; + + var Handler = function(name) + { + var c = consoleHandler; + var f = consoleHandler[name]; + return function(){return f.apply(c,arguments)}; + }; + + var installer = function(c) + { + for (var i=0, l=properties.length; i 1) + { + traceRecursion--; + return; + } + + var frames = []; + + for (var fn = arguments.callee.caller.caller; fn; fn = fn.caller) + { + if (wasVisited(fn)) break; + + var args = []; + + for (var i = 0, l = fn.arguments.length; i < l; ++i) + { + args.push({value: fn.arguments[i]}); + } + + frames.push({fn: fn, name: getFuncName(fn), args: args}); + } + + + // **************************************************************************************** + + try + { + (0)(); + } + catch(e) + { + var result = e; + + var stack = + result.stack || // Firefox / Google Chrome + result.stacktrace || // Opera + ""; + + stack = stack.replace(/\n\r|\r\n/g, "\n"); // normalize line breaks + var items = stack.split(/[\n\r]/); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Google Chrome + if (FBL.isSafari) + { + //var reChromeStackItem = /^\s+at\s+([^\(]+)\s\((.*)\)$/; + //var reChromeStackItem = /^\s+at\s+(.*)((?:http|https|ftp|file):\/\/.*)$/; + var reChromeStackItem = /^\s+at\s+(.*)((?:http|https|ftp|file):\/\/.*)$/; + + var reChromeStackItemName = /\s*\($/; + var reChromeStackItemValue = /^(.+)\:(\d+\:\d+)\)?$/; + + var framePos = 0; + for (var i=4, length=items.length; i 1) + { + objects = [errorObject]; + for (var i = 1; i < args.length; i++) + objects.push(args[i]); + } + + var row = Firebug.Console.log(objects, context, "errorMessage", null, true); // noThrottle + row.scrollIntoView(); + } + + function getComponentsStackDump() + { + // Starting with our stack, walk back to the user-level code + var frame = Components.stack; + var userURL = win.location.href.toString(); + + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("consoleInjector.getComponentsStackDump initial stack for userURL "+userURL, frame); + + // Drop frames until we get into user code. + while (frame && FBL.isSystemURL(frame.filename) ) + frame = frame.caller; + + // Drop two more frames, the injected console function and firebugAppendConsole() + if (frame) + frame = frame.caller; + if (frame) + frame = frame.caller; + + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("consoleInjector.getComponentsStackDump final stack for userURL "+userURL, frame); + + return frame; + } + + function getStackLink() + { + // TODO: xxxpedro console2 + return; + //return FBL.getFrameSourceLink(getComponentsStackDump()); + } + + function getJSDUserStack() + { + var trace = FBL.getCurrentStackTrace(context); + + var frames = trace ? trace.frames : null; + if (frames && (frames.length > 0) ) + { + var oldest = frames.length - 1; // 6 - 1 = 5 + for (var i = 0; i < frames.length; i++) + { + if (frames[oldest - i].href.indexOf("chrome:") == 0) break; + var fn = frames[oldest - i].fn + ""; + if (fn && (fn.indexOf("_firebugEvalEvent") != -1) ) break; // command line + } + FBTrace.sysout("consoleInjector getJSDUserStack: "+frames.length+" oldest: "+oldest+" i: "+i+" i - oldest + 2: "+(i - oldest + 2), trace); + trace.frames = trace.frames.slice(2 - i); // take the oldest frames, leave 2 behind they are injection code + + return trace; + } + else + return "Firebug failed to get stack trace with any frames"; + } +} + +// ************************************************************************************************ +// Register console namespace + +FBL.registerConsole = function() +{ + //TODO: xxxpedro console options override + //if (Env.Options.overrideConsole) + var win = Env.browser.window; + Firebug.Console.injector.install(win); +}; + +registerConsole(); + +}}); + + +/* 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) +{ + commandHistory.push(command); + commandPointer = 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(); + + 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 (commandPointer > 0 && commandHistory.length > 0) + this.element.value = commandHistory[--commandPointer]; + }, + + nextCommand: function() + { + var element = this.element; + + var limit = commandHistory.length -1; + var i = commandPointer; + + if (i < limit) + element.value = commandHistory[++commandPointer]; + + else if (i == limit) + { + ++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; + + // TODO: xxxpedro html3 + ///Firebug.Console.log(o, Firebug.context, "dirxml", Firebug.HTMLPanel.SoloElement); + var div = Firebug.Console.log(o, Firebug.context, "dirxml"); + var html = []; + Firebug.Reps.appendNode(o, html); + div.innerHTML = html.join(""); + + } +}; + +// ************************************************************************************************ + +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]; + } +}; + +// ************************************************************************************************ +}}); + +/* 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(); + }; +} + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var reIgnore = /about:|javascript:|resource:|chrome:|jar:/; +var layoutInterval = 300; +var indentWidth = 18; + +var cacheSession = null; +var contexts = new Array(); +var panelName = "net"; +var maxQueueRequests = 500; +//var panelBar1 = $("fbPanelBar1"); // chrome not available at startup +var activeRequests = []; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var mimeExtensionMap = +{ + "txt": "text/plain", + "html": "text/html", + "htm": "text/html", + "xhtml": "text/html", + "xml": "text/xml", + "css": "text/css", + "js": "application/x-javascript", + "jss": "application/x-javascript", + "jpg": "image/jpg", + "jpeg": "image/jpeg", + "gif": "image/gif", + "png": "image/png", + "bmp": "image/bmp", + "swf": "application/x-shockwave-flash", + "flv": "video/x-flv" +}; + +var fileCategories = +{ + "undefined": 1, + "html": 1, + "css": 1, + "js": 1, + "xhr": 1, + "image": 1, + "flash": 1, + "txt": 1, + "bin": 1 +}; + +var textFileCategories = +{ + "txt": 1, + "html": 1, + "xhr": 1, + "css": 1, + "js": 1 +}; + +var binaryFileCategories = +{ + "bin": 1, + "flash": 1 +}; + +var mimeCategoryMap = +{ + "text/plain": "txt", + "application/octet-stream": "bin", + "text/html": "html", + "text/xml": "html", + "text/css": "css", + "application/x-javascript": "js", + "text/javascript": "js", + "application/javascript" : "js", + "image/jpeg": "image", + "image/jpg": "image", + "image/gif": "image", + "image/png": "image", + "image/bmp": "image", + "application/x-shockwave-flash": "flash", + "video/x-flv": "flash" +}; + +var binaryCategoryMap = +{ + "image": 1, + "flash" : 1 +}; + +// ************************************************************************************************ + +/** + * @module Represents a module object for the Net panel. This object is derived + * from Firebug.ActivableModule in order to support activation (enable/disable). + * This allows to avoid (performance) expensive features if the functionality is not necessary + * for the user. + */ +Firebug.NetMonitor = extend(Firebug.ActivableModule, +{ + dispatchName: "netMonitor", + + clear: function(context) + { + // The user pressed a Clear button so, remove content of the panel... + var panel = context.getPanel(panelName, true); + if (panel) + panel.clear(); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Module + + initialize: function() + { + return; + + this.panelName = panelName; + + Firebug.ActivableModule.initialize.apply(this, arguments); + + if (Firebug.TraceModule) + Firebug.TraceModule.addListener(this.TraceListener); + + // HTTP observer must be registered now (and not in monitorContext, since if a + // page is opened in a new tab the top document request would be missed otherwise. + NetHttpObserver.registerObserver(); + NetHttpActivityObserver.registerObserver(); + + Firebug.Debugger.addListener(this.DebuggerListener); + }, + + shutdown: function() + { + return; + + prefs.removeObserver(Firebug.prefDomain, this, false); + if (Firebug.TraceModule) + Firebug.TraceModule.removeListener(this.TraceListener); + + NetHttpObserver.unregisterObserver(); + NetHttpActivityObserver.unregisterObserver(); + + Firebug.Debugger.removeListener(this.DebuggerListener); + } +}); + + +/** + * @domplate Represents a template that is used to reneder detailed info about a request. + * This template is rendered when a request is expanded. + */ +Firebug.NetMonitor.NetInfoBody = domplate(Firebug.Rep, new Firebug.Listener(), +{ + tag: + DIV({"class": "netInfoBody", _repObject: "$file"}, + TAG("$infoTabs", {file: "$file"}), + TAG("$infoBodies", {file: "$file"}) + ), + + infoTabs: + DIV({"class": "netInfoTabs focusRow subFocusRow", "role": "tablist"}, + A({"class": "netInfoParamsTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Params", + $collapsed: "$file|hideParams"}, + $STR("URLParameters") + ), + A({"class": "netInfoHeadersTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Headers"}, + $STR("Headers") + ), + A({"class": "netInfoPostTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Post", + $collapsed: "$file|hidePost"}, + $STR("Post") + ), + A({"class": "netInfoPutTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Put", + $collapsed: "$file|hidePut"}, + $STR("Put") + ), + A({"class": "netInfoResponseTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Response", + $collapsed: "$file|hideResponse"}, + $STR("Response") + ), + A({"class": "netInfoCacheTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Cache", + $collapsed: "$file|hideCache"}, + $STR("Cache") + ), + A({"class": "netInfoHtmlTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Html", + $collapsed: "$file|hideHtml"}, + $STR("HTML") + ) + ), + + infoBodies: + DIV({"class": "netInfoBodies outerFocusRow"}, + TABLE({"class": "netInfoParamsText netInfoText netInfoParamsTable", "role": "tabpanel", + cellpadding: 0, cellspacing: 0}, TBODY()), + DIV({"class": "netInfoHeadersText netInfoText", "role": "tabpanel"}), + DIV({"class": "netInfoPostText netInfoText", "role": "tabpanel"}), + DIV({"class": "netInfoPutText netInfoText", "role": "tabpanel"}), + PRE({"class": "netInfoResponseText netInfoText", "role": "tabpanel"}), + DIV({"class": "netInfoCacheText netInfoText", "role": "tabpanel"}, + TABLE({"class": "netInfoCacheTable", cellpadding: 0, cellspacing: 0, "role": "presentation"}, + TBODY({"role": "list", "aria-label": $STR("Cache")}) + ) + ), + DIV({"class": "netInfoHtmlText netInfoText", "role": "tabpanel"}, + IFRAME({"class": "netInfoHtmlPreview", "role": "document"}) + ) + ), + + headerDataTag: + FOR("param", "$headers", + TR({"role": "listitem"}, + TD({"class": "netInfoParamName", "role": "presentation"}, + TAG("$param|getNameTag", {param: "$param"}) + ), + TD({"class": "netInfoParamValue", "role": "list", "aria-label": "$param.name"}, + FOR("line", "$param|getParamValueIterator", + CODE({"class": "focusRow subFocusRow", "role": "listitem"}, "$line") + ) + ) + ) + ), + + customTab: + A({"class": "netInfo$tabId\\Tab netInfoTab", onclick: "$onClickTab", view: "$tabId", "role": "tab"}, + "$tabTitle" + ), + + customBody: + DIV({"class": "netInfo$tabId\\Text netInfoText", "role": "tabpanel"}), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + nameTag: + SPAN("$param|getParamName"), + + nameWithTooltipTag: + SPAN({title: "$param.name"}, "$param|getParamName"), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getNameTag: function(param) + { + return (this.getParamName(param) == param.name) ? this.nameTag : this.nameWithTooltipTag; + }, + + getParamName: function(param) + { + var limit = 25; + var name = param.name; + if (name.length > limit) + name = name.substr(0, limit) + "..."; + return name; + }, + + getParamTitle: function(param) + { + var limit = 25; + var name = param.name; + if (name.length > limit) + return name; + return ""; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + hideParams: function(file) + { + return !file.urlParams || !file.urlParams.length; + }, + + hidePost: function(file) + { + return file.method.toUpperCase() != "POST"; + }, + + hidePut: function(file) + { + return file.method.toUpperCase() != "PUT"; + }, + + hideResponse: function(file) + { + return false; + //return file.category in binaryFileCategories; + }, + + hideCache: function(file) + { + return true; + //xxxHonza: I don't see any reason why not to display the cache also info for images. + return !file.cacheEntry; // || file.category=="image"; + }, + + hideHtml: function(file) + { + return (file.mimeType != "text/html") && (file.mimeType != "application/xhtml+xml"); + }, + + onClickTab: function(event) + { + this.selectTab(event.currentTarget || event.srcElement); + }, + + getParamValueIterator: function(param) + { + // TODO: xxxpedro console2 + return param.value; + + // This value is inserted into CODE element and so, make sure the HTML isn't escaped (1210). + // This is why the second parameter is true. + // The CODE (with style white-space:pre) element preserves whitespaces so they are + // displayed the same, as they come from the server (1194). + // In case of a long header values of post parameters the value must be wrapped (2105). + return wrapText(param.value, true); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + appendTab: function(netInfoBox, tabId, tabTitle) + { + // Create new tab and body. + var args = {tabId: tabId, tabTitle: tabTitle}; + ///this.customTab.append(args, netInfoBox.getElementsByClassName("netInfoTabs").item(0)); + ///this.customBody.append(args, netInfoBox.getElementsByClassName("netInfoBodies").item(0)); + this.customTab.append(args, $$(".netInfoTabs", netInfoBox)[0]); + this.customBody.append(args, $$(".netInfoBodies", netInfoBox)[0]); + }, + + selectTabByName: function(netInfoBox, tabName) + { + var tab = getChildByClass(netInfoBox, "netInfoTabs", "netInfo"+tabName+"Tab"); + if (tab) + this.selectTab(tab); + }, + + selectTab: function(tab) + { + var view = tab.getAttribute("view"); + + var netInfoBox = getAncestorByClass(tab, "netInfoBody"); + + var selectedTab = netInfoBox.selectedTab; + + if (selectedTab) + { + //netInfoBox.selectedText.removeAttribute("selected"); + removeClass(netInfoBox.selectedText, "netInfoTextSelected"); + + removeClass(selectedTab, "netInfoTabSelected"); + //selectedTab.removeAttribute("selected"); + selectedTab.setAttribute("aria-selected", "false"); + } + + var textBodyName = "netInfo" + view + "Text"; + + selectedTab = netInfoBox.selectedTab = tab; + + netInfoBox.selectedText = $$("."+textBodyName, netInfoBox)[0]; + //netInfoBox.selectedText = netInfoBox.getElementsByClassName(textBodyName).item(0); + + //netInfoBox.selectedText.setAttribute("selected", "true"); + setClass(netInfoBox.selectedText, "netInfoTextSelected"); + + setClass(selectedTab, "netInfoTabSelected"); + selectedTab.setAttribute("selected", "true"); + selectedTab.setAttribute("aria-selected", "true"); + + var file = Firebug.getRepObject(netInfoBox); + + //var context = Firebug.getElementPanel(netInfoBox).context; + var context = Firebug.chrome; + + this.updateInfo(netInfoBox, file, context); + }, + + updateInfo: function(netInfoBox, file, context) + { + if (FBTrace.DBG_NET) + FBTrace.sysout("net.updateInfo; file", file); + + if (!netInfoBox) + { + if (FBTrace.DBG_NET || FBTrace.DBG_ERRORS) + FBTrace.sysout("net.updateInfo; ERROR netInfo == null " + file.href, file); + return; + } + + var tab = netInfoBox.selectedTab; + + if (hasClass(tab, "netInfoParamsTab")) + { + if (file.urlParams && !netInfoBox.urlParamsPresented) + { + netInfoBox.urlParamsPresented = true; + this.insertHeaderRows(netInfoBox, file.urlParams, "Params"); + } + } + + else if (hasClass(tab, "netInfoHeadersTab")) + { + var headersText = $$(".netInfoHeadersText", netInfoBox)[0]; + //var headersText = netInfoBox.getElementsByClassName("netInfoHeadersText").item(0); + + if (file.responseHeaders && !netInfoBox.responseHeadersPresented) + { + netInfoBox.responseHeadersPresented = true; + NetInfoHeaders.renderHeaders(headersText, file.responseHeaders, "ResponseHeaders"); + } + + if (file.requestHeaders && !netInfoBox.requestHeadersPresented) + { + netInfoBox.requestHeadersPresented = true; + NetInfoHeaders.renderHeaders(headersText, file.requestHeaders, "RequestHeaders"); + } + } + + else if (hasClass(tab, "netInfoPostTab")) + { + if (!netInfoBox.postPresented) + { + netInfoBox.postPresented = true; + //var postText = netInfoBox.getElementsByClassName("netInfoPostText").item(0); + var postText = $$(".netInfoPostText", netInfoBox)[0]; + NetInfoPostData.render(context, postText, file); + } + } + + else if (hasClass(tab, "netInfoPutTab")) + { + if (!netInfoBox.putPresented) + { + netInfoBox.putPresented = true; + //var putText = netInfoBox.getElementsByClassName("netInfoPutText").item(0); + var putText = $$(".netInfoPutText", netInfoBox)[0]; + NetInfoPostData.render(context, putText, file); + } + } + + else if (hasClass(tab, "netInfoResponseTab") && file.loaded && !netInfoBox.responsePresented) + { + ///var responseTextBox = netInfoBox.getElementsByClassName("netInfoResponseText").item(0); + var responseTextBox = $$(".netInfoResponseText", netInfoBox)[0]; + if (file.category == "image") + { + netInfoBox.responsePresented = true; + + var responseImage = netInfoBox.ownerDocument.createElement("img"); + responseImage.src = file.href; + + clearNode(responseTextBox); + responseTextBox.appendChild(responseImage, responseTextBox); + } + else ///if (!(binaryCategoryMap.hasOwnProperty(file.category))) + { + this.setResponseText(file, netInfoBox, responseTextBox, context); + } + } + + else if (hasClass(tab, "netInfoCacheTab") && file.loaded && !netInfoBox.cachePresented) + { + var responseTextBox = netInfoBox.getElementsByClassName("netInfoCacheText").item(0); + if (file.cacheEntry) { + netInfoBox.cachePresented = true; + this.insertHeaderRows(netInfoBox, file.cacheEntry, "Cache"); + } + } + + else if (hasClass(tab, "netInfoHtmlTab") && file.loaded && !netInfoBox.htmlPresented) + { + netInfoBox.htmlPresented = true; + + var text = Utils.getResponseText(file, context); + + ///var iframe = netInfoBox.getElementsByClassName("netInfoHtmlPreview").item(0); + var iframe = $$(".netInfoHtmlPreview", netInfoBox)[0]; + + ///iframe.contentWindow.document.body.innerHTML = text; + + // TODO: xxxpedro net - remove scripts + var reScript = //gi; + + text = text.replace(reScript, ""); + + iframe.contentWindow.document.write(text); + iframe.contentWindow.document.close(); + } + + // Notify listeners about update so, content of custom tabs can be updated. + dispatch(NetInfoBody.fbListeners, "updateTabBody", [netInfoBox, file, context]); + }, + + setResponseText: function(file, netInfoBox, responseTextBox, context) + { + //********************************************** + //********************************************** + //********************************************** + netInfoBox.responsePresented = true; + // line breaks somehow are different in IE + // make this only once in the initialization? we don't have net panels and modules yet. + if (isIE) + responseTextBox.style.whiteSpace = "nowrap"; + + responseTextBox[ + typeof responseTextBox.textContent != "undefined" ? + "textContent" : + "innerText" + ] = file.responseText; + + return; + //********************************************** + //********************************************** + //********************************************** + + // Get response text and make sure it doesn't exceed the max limit. + var text = Utils.getResponseText(file, context); + var limit = Firebug.netDisplayedResponseLimit + 15; + var limitReached = text ? (text.length > limit) : false; + if (limitReached) + text = text.substr(0, limit) + "..."; + + // Insert the response into the UI. + if (text) + insertWrappedText(text, responseTextBox); + else + insertWrappedText("", responseTextBox); + + // Append a message informing the user that the response isn't fully displayed. + if (limitReached) + { + var object = { + text: $STR("net.responseSizeLimitMessage"), + onClickLink: function() { + var panel = context.getPanel("net", true); + panel.openResponseInTab(file); + } + }; + Firebug.NetMonitor.ResponseSizeLimit.append(object, responseTextBox); + } + + netInfoBox.responsePresented = true; + + if (FBTrace.DBG_NET) + FBTrace.sysout("net.setResponseText; response text updated"); + }, + + insertHeaderRows: function(netInfoBox, headers, tableName, rowName) + { + if (!headers.length) + return; + + var headersTable = $$(".netInfo"+tableName+"Table", netInfoBox)[0]; + //var headersTable = netInfoBox.getElementsByClassName("netInfo"+tableName+"Table").item(0); + var tbody = getChildByClass(headersTable, "netInfo" + rowName + "Body"); + if (!tbody) + tbody = headersTable.firstChild; + var titleRow = getChildByClass(tbody, "netInfo" + rowName + "Title"); + + this.headerDataTag.insertRows({headers: headers}, titleRow ? titleRow : tbody); + removeClass(titleRow, "collapsed"); + } +}); + +var NetInfoBody = Firebug.NetMonitor.NetInfoBody; + +// ************************************************************************************************ + +/** + * @domplate Used within the Net panel to display raw source of request and response headers + * as well as pretty-formatted summary of these headers. + */ +Firebug.NetMonitor.NetInfoHeaders = domplate(Firebug.Rep, //new Firebug.Listener(), +{ + tag: + DIV({"class": "netInfoHeadersTable", "role": "tabpanel"}, + DIV({"class": "netInfoHeadersGroup netInfoResponseHeadersTitle"}, + SPAN($STR("ResponseHeaders")), + SPAN({"class": "netHeadersViewSource response collapsed", onclick: "$onViewSource", + _sourceDisplayed: false, _rowName: "ResponseHeaders"}, + $STR("net.headers.view source") + ) + ), + TABLE({cellpadding: 0, cellspacing: 0}, + TBODY({"class": "netInfoResponseHeadersBody", "role": "list", + "aria-label": $STR("ResponseHeaders")}) + ), + DIV({"class": "netInfoHeadersGroup netInfoRequestHeadersTitle"}, + SPAN($STR("RequestHeaders")), + SPAN({"class": "netHeadersViewSource request collapsed", onclick: "$onViewSource", + _sourceDisplayed: false, _rowName: "RequestHeaders"}, + $STR("net.headers.view source") + ) + ), + TABLE({cellpadding: 0, cellspacing: 0}, + TBODY({"class": "netInfoRequestHeadersBody", "role": "list", + "aria-label": $STR("RequestHeaders")}) + ) + ), + + sourceTag: + TR({"role": "presentation"}, + TD({colspan: 2, "role": "presentation"}, + PRE({"class": "source"}) + ) + ), + + onViewSource: function(event) + { + var target = event.target; + var requestHeaders = (target.rowName == "RequestHeaders"); + + var netInfoBox = getAncestorByClass(target, "netInfoBody"); + var file = netInfoBox.repObject; + + if (target.sourceDisplayed) + { + var headers = requestHeaders ? file.requestHeaders : file.responseHeaders; + this.insertHeaderRows(netInfoBox, headers, target.rowName); + target.innerHTML = $STR("net.headers.view source"); + } + else + { + var source = requestHeaders ? file.requestHeadersText : file.responseHeadersText; + this.insertSource(netInfoBox, source, target.rowName); + target.innerHTML = $STR("net.headers.pretty print"); + } + + target.sourceDisplayed = !target.sourceDisplayed; + + cancelEvent(event); + }, + + insertSource: function(netInfoBox, source, rowName) + { + // This breaks copy to clipboard. + //if (source) + // source = source.replace(/\r\n/gm, "\\r\\n\r\n"); + + ///var tbody = netInfoBox.getElementsByClassName("netInfo" + rowName + "Body").item(0); + var tbody = $$(".netInfo" + rowName + "Body", netInfoBox)[0]; + var node = this.sourceTag.replace({}, tbody); + ///var sourceNode = node.getElementsByClassName("source").item(0); + var sourceNode = $$(".source", node)[0]; + sourceNode.innerHTML = source; + }, + + insertHeaderRows: function(netInfoBox, headers, rowName) + { + var headersTable = $$(".netInfoHeadersTable", netInfoBox)[0]; + var tbody = $$(".netInfo" + rowName + "Body", headersTable)[0]; + + //var headersTable = netInfoBox.getElementsByClassName("netInfoHeadersTable").item(0); + //var tbody = headersTable.getElementsByClassName("netInfo" + rowName + "Body").item(0); + + clearNode(tbody); + + if (!headers.length) + return; + + NetInfoBody.headerDataTag.insertRows({headers: headers}, tbody); + + var titleRow = getChildByClass(headersTable, "netInfo" + rowName + "Title"); + removeClass(titleRow, "collapsed"); + }, + + init: function(parent) + { + var rootNode = this.tag.append({}, parent); + + var netInfoBox = getAncestorByClass(parent, "netInfoBody"); + var file = netInfoBox.repObject; + + var viewSource; + + viewSource = $$(".request", rootNode)[0]; + //viewSource = rootNode.getElementsByClassName("netHeadersViewSource request").item(0); + if (file.requestHeadersText) + removeClass(viewSource, "collapsed"); + + viewSource = $$(".response", rootNode)[0]; + //viewSource = rootNode.getElementsByClassName("netHeadersViewSource response").item(0); + if (file.responseHeadersText) + removeClass(viewSource, "collapsed"); + }, + + renderHeaders: function(parent, headers, rowName) + { + if (!parent.firstChild) + this.init(parent); + + this.insertHeaderRows(parent, headers, rowName); + } +}); + +var NetInfoHeaders = Firebug.NetMonitor.NetInfoHeaders; + +// ************************************************************************************************ + +/** + * @domplate Represents posted data within request info (the info, which is visible when + * a request entry is expanded. This template renders content of the Post tab. + */ +Firebug.NetMonitor.NetInfoPostData = domplate(Firebug.Rep, /*new Firebug.Listener(),*/ +{ + // application/x-www-form-urlencoded + paramsTable: + TABLE({"class": "netInfoPostParamsTable", cellpadding: 0, cellspacing: 0, "role": "presentation"}, + TBODY({"role": "list", "aria-label": $STR("net.label.Parameters")}, + TR({"class": "netInfoPostParamsTitle", "role": "presentation"}, + TD({colspan: 3, "role": "presentation"}, + DIV({"class": "netInfoPostParams"}, + $STR("net.label.Parameters"), + SPAN({"class": "netInfoPostContentType"}, + "application/x-www-form-urlencoded" + ) + ) + ) + ) + ) + ), + + // multipart/form-data + partsTable: + TABLE({"class": "netInfoPostPartsTable", cellpadding: 0, cellspacing: 0, "role": "presentation"}, + TBODY({"role": "list", "aria-label": $STR("net.label.Parts")}, + TR({"class": "netInfoPostPartsTitle", "role": "presentation"}, + TD({colspan: 2, "role":"presentation" }, + DIV({"class": "netInfoPostParams"}, + $STR("net.label.Parts"), + SPAN({"class": "netInfoPostContentType"}, + "multipart/form-data" + ) + ) + ) + ) + ) + ), + + // application/json + jsonTable: + TABLE({"class": "netInfoPostJSONTable", cellpadding: 0, cellspacing: 0, "role": "presentation"}, + ///TBODY({"role": "list", "aria-label": $STR("jsonviewer.tab.JSON")}, + TBODY({"role": "list", "aria-label": $STR("JSON")}, + TR({"class": "netInfoPostJSONTitle", "role": "presentation"}, + TD({"role": "presentation" }, + DIV({"class": "netInfoPostParams"}, + ///$STR("jsonviewer.tab.JSON") + $STR("JSON") + ) + ) + ), + TR( + TD({"class": "netInfoPostJSONBody"}) + ) + ) + ), + + // application/xml + xmlTable: + TABLE({"class": "netInfoPostXMLTable", cellpadding: 0, cellspacing: 0, "role": "presentation"}, + TBODY({"role": "list", "aria-label": $STR("xmlviewer.tab.XML")}, + TR({"class": "netInfoPostXMLTitle", "role": "presentation"}, + TD({"role": "presentation" }, + DIV({"class": "netInfoPostParams"}, + $STR("xmlviewer.tab.XML") + ) + ) + ), + TR( + TD({"class": "netInfoPostXMLBody"}) + ) + ) + ), + + sourceTable: + TABLE({"class": "netInfoPostSourceTable", cellpadding: 0, cellspacing: 0, "role": "presentation"}, + TBODY({"role": "list", "aria-label": $STR("net.label.Source")}, + TR({"class": "netInfoPostSourceTitle", "role": "presentation"}, + TD({colspan: 2, "role": "presentation"}, + DIV({"class": "netInfoPostSource"}, + $STR("net.label.Source") + ) + ) + ) + ) + ), + + sourceBodyTag: + TR({"role": "presentation"}, + TD({colspan: 2, "role": "presentation"}, + FOR("line", "$param|getParamValueIterator", + CODE({"class":"focusRow subFocusRow" , "role": "listitem"},"$line") + ) + ) + ), + + getParamValueIterator: function(param) + { + return NetInfoBody.getParamValueIterator(param); + }, + + render: function(context, parentNode, file) + { + //debugger; + var spy = getAncestorByClass(parentNode, "spyHead"); + var spyObject = spy.repObject; + var data = spyObject.data; + + ///var contentType = Utils.findHeader(file.requestHeaders, "content-type"); + var contentType = file.mimeType; + + ///var text = Utils.getPostText(file, context, true); + ///if (text == undefined) + /// return; + + ///if (Utils.isURLEncodedRequest(file, context)) + // fake Utils.isURLEncodedRequest identification + if (contentType && contentType == "application/x-www-form-urlencoded" || + data && data.indexOf("=") != -1) + { + ///var lines = text.split("\n"); + ///var params = parseURLEncodedText(lines[lines.length-1]); + var params = parseURLEncodedTextArray(data); + if (params) + this.insertParameters(parentNode, params); + } + + ///if (Utils.isMultiPartRequest(file, context)) + ///{ + /// var data = this.parseMultiPartText(file, context); + /// if (data) + /// this.insertParts(parentNode, data); + ///} + + // moved to the top + ///var contentType = Utils.findHeader(file.requestHeaders, "content-type"); + + ///if (Firebug.JSONViewerModel.isJSON(contentType)) + var jsonData = { + responseText: data + }; + + if (Firebug.JSONViewerModel.isJSON(contentType, data)) + ///this.insertJSON(parentNode, file, context); + this.insertJSON(parentNode, jsonData, context); + + ///if (Firebug.XMLViewerModel.isXML(contentType)) + /// this.insertXML(parentNode, file, context); + + ///var postText = Utils.getPostText(file, context); + ///postText = Utils.formatPostText(postText); + var postText = data; + if (postText) + this.insertSource(parentNode, postText); + }, + + insertParameters: function(parentNode, params) + { + if (!params || !params.length) + return; + + var paramTable = this.paramsTable.append({object:{}}, parentNode); + var row = $$(".netInfoPostParamsTitle", paramTable)[0]; + //var paramTable = this.paramsTable.append(null, parentNode); + //var row = paramTable.getElementsByClassName("netInfoPostParamsTitle").item(0); + + var tbody = paramTable.getElementsByTagName("tbody")[0]; + + NetInfoBody.headerDataTag.insertRows({headers: params}, row); + }, + + insertParts: function(parentNode, data) + { + if (!data.params || !data.params.length) + return; + + var partsTable = this.partsTable.append({object:{}}, parentNode); + var row = $$(".netInfoPostPartsTitle", paramTable)[0]; + //var partsTable = this.partsTable.append(null, parentNode); + //var row = partsTable.getElementsByClassName("netInfoPostPartsTitle").item(0); + + NetInfoBody.headerDataTag.insertRows({headers: data.params}, row); + }, + + insertJSON: function(parentNode, file, context) + { + ///var text = Utils.getPostText(file, context); + var text = file.responseText; + ///var data = parseJSONString(text, "http://" + file.request.originalURI.host); + var data = parseJSONString(text); + if (!data) + return; + + ///var jsonTable = this.jsonTable.append(null, parentNode); + var jsonTable = this.jsonTable.append({}, parentNode); + ///var jsonBody = jsonTable.getElementsByClassName("netInfoPostJSONBody").item(0); + var jsonBody = $$(".netInfoPostJSONBody", jsonTable)[0]; + + if (!this.toggles) + this.toggles = {}; + + Firebug.DOMPanel.DirTable.tag.replace( + {object: data, toggles: this.toggles}, jsonBody); + }, + + insertXML: function(parentNode, file, context) + { + var text = Utils.getPostText(file, context); + + var jsonTable = this.xmlTable.append(null, parentNode); + ///var jsonBody = jsonTable.getElementsByClassName("netInfoPostXMLBody").item(0); + var jsonBody = $$(".netInfoPostXMLBody", jsonTable)[0]; + + Firebug.XMLViewerModel.insertXML(jsonBody, text); + }, + + insertSource: function(parentNode, text) + { + var sourceTable = this.sourceTable.append({object:{}}, parentNode); + var row = $$(".netInfoPostSourceTitle", sourceTable)[0]; + //var sourceTable = this.sourceTable.append(null, parentNode); + //var row = sourceTable.getElementsByClassName("netInfoPostSourceTitle").item(0); + + var param = {value: [text]}; + this.sourceBodyTag.insertRows({param: param}, row); + }, + + parseMultiPartText: function(file, context) + { + var text = Utils.getPostText(file, context); + if (text == undefined) + return null; + + FBTrace.sysout("net.parseMultiPartText; boundary: ", text); + + var boundary = text.match(/\s*boundary=\s*(.*)/)[1]; + + var divider = "\r\n\r\n"; + var bodyStart = text.indexOf(divider); + var body = text.substr(bodyStart + divider.length); + + var postData = {}; + postData.mimeType = "multipart/form-data"; + postData.params = []; + + var parts = body.split("--" + boundary); + for (var i=0; i 1) ? m[1] : "", + value: trim(part[1]) + }); + } + + return postData; + } +}); + +var NetInfoPostData = Firebug.NetMonitor.NetInfoPostData; + +// ************************************************************************************************ + + +// TODO: xxxpedro net i18n +var $STRP = function(a){return a;}; + +Firebug.NetMonitor.NetLimit = domplate(Firebug.Rep, +{ + collapsed: true, + + tableTag: + DIV( + TABLE({width: "100%", cellpadding: 0, cellspacing: 0}, + TBODY() + ) + ), + + limitTag: + TR({"class": "netRow netLimitRow", $collapsed: "$isCollapsed"}, + TD({"class": "netCol netLimitCol", colspan: 6}, + TABLE({cellpadding: 0, cellspacing: 0}, + TBODY( + TR( + TD( + SPAN({"class": "netLimitLabel"}, + $STRP("plural.Limit_Exceeded", [0]) + ) + ), + TD({style: "width:100%"}), + TD( + BUTTON({"class": "netLimitButton", title: "$limitPrefsTitle", + onclick: "$onPreferences"}, + $STR("LimitPrefs") + ) + ), + TD(" ") + ) + ) + ) + ) + ), + + isCollapsed: function() + { + return this.collapsed; + }, + + onPreferences: function(event) + { + openNewTab("about:config"); + }, + + updateCounter: function(row) + { + removeClass(row, "collapsed"); + + // Update info within the limit row. + var limitLabel = row.getElementsByClassName("netLimitLabel").item(0); + limitLabel.firstChild.nodeValue = $STRP("plural.Limit_Exceeded", [row.limitInfo.totalCount]); + }, + + createTable: function(parent, limitInfo) + { + var table = this.tableTag.replace({}, parent); + var row = this.createRow(table.firstChild.firstChild, limitInfo); + return [table, row]; + }, + + createRow: function(parent, limitInfo) + { + var row = this.limitTag.insertRows(limitInfo, parent, this)[0]; + row.limitInfo = limitInfo; + return row; + }, + + // nsIPrefObserver + observe: function(subject, topic, data) + { + // We're observing preferences only. + if (topic != "nsPref:changed") + return; + + if (data.indexOf("net.logLimit") != -1) + this.updateMaxLimit(); + }, + + updateMaxLimit: function() + { + var value = Firebug.getPref(Firebug.prefDomain, "net.logLimit"); + maxQueueRequests = value ? value : maxQueueRequests; + } +}); + +var NetLimit = Firebug.NetMonitor.NetLimit; + +// ************************************************************************************************ + +Firebug.NetMonitor.ResponseSizeLimit = domplate(Firebug.Rep, +{ + tag: + DIV({"class": "netInfoResponseSizeLimit"}, + SPAN("$object.beforeLink"), + A({"class": "objectLink", onclick: "$onClickLink"}, + "$object.linkText" + ), + SPAN("$object.afterLink") + ), + + reLink: /^(.*)(.*)<\/a>(.*$)/, + append: function(obj, parent) + { + var m = obj.text.match(this.reLink); + return this.tag.append({onClickLink: obj.onClickLink, + object: { + beforeLink: m[1], + linkText: m[2], + afterLink: m[3] + }}, parent, this); + } +}); + +// ************************************************************************************************ +// ************************************************************************************************ + +Firebug.NetMonitor.Utils = +{ + findHeader: function(headers, name) + { + if (!headers) + return null; + + name = name.toLowerCase(); + for (var i = 0; i < headers.length; ++i) + { + var headerName = headers[i].name.toLowerCase(); + if (headerName == name) + return headers[i].value; + } + }, + + formatPostText: function(text) + { + if (text instanceof XMLDocument) + return getElementXML(text.documentElement); + else + return text; + }, + + getPostText: function(file, context, noLimit) + { + if (!file.postText) + { + file.postText = readPostTextFromRequest(file.request, context); + + if (!file.postText && context) + file.postText = readPostTextFromPage(file.href, context); + } + + if (!file.postText) + return file.postText; + + var limit = Firebug.netDisplayedPostBodyLimit; + if (file.postText.length > limit && !noLimit) + { + return cropString(file.postText, limit, + "\n\n... " + $STR("net.postDataSizeLimitMessage") + " ...\n\n"); + } + + return file.postText; + }, + + getResponseText: function(file, context) + { + // The response can be also empty string so, check agains "undefined". + return (typeof(file.responseText) != "undefined")? file.responseText : + context.sourceCache.loadText(file.href, file.method, file); + }, + + isURLEncodedRequest: function(file, context) + { + var text = Utils.getPostText(file, context); + if (text && text.toLowerCase().indexOf("content-type: application/x-www-form-urlencoded") == 0) + return true; + + // The header value doesn't have to be always exactly "application/x-www-form-urlencoded", + // there can be even charset specified. So, use indexOf rather than just "==". + var headerValue = Utils.findHeader(file.requestHeaders, "content-type"); + if (headerValue && headerValue.indexOf("application/x-www-form-urlencoded") == 0) + return true; + + return false; + }, + + isMultiPartRequest: function(file, context) + { + var text = Utils.getPostText(file, context); + if (text && text.toLowerCase().indexOf("content-type: multipart/form-data") == 0) + return true; + return false; + }, + + getMimeType: function(mimeType, uri) + { + if (!mimeType || !(mimeCategoryMap.hasOwnProperty(mimeType))) + { + var ext = getFileExtension(uri); + if (!ext) + return mimeType; + else + { + var extMimeType = mimeExtensionMap[ext.toLowerCase()]; + return extMimeType ? extMimeType : mimeType; + } + } + else + return mimeType; + }, + + getDateFromSeconds: function(s) + { + var d = new Date(); + d.setTime(s*1000); + return d; + }, + + getHttpHeaders: function(request, file) + { + try + { + var http = QI(request, Ci.nsIHttpChannel); + file.status = request.responseStatus; + + // xxxHonza: is there any problem to do this in requestedFile method? + file.method = http.requestMethod; + file.urlParams = parseURLParams(file.href); + file.mimeType = Utils.getMimeType(request.contentType, request.name); + + if (!file.responseHeaders && Firebug.collectHttpHeaders) + { + var requestHeaders = [], responseHeaders = []; + + http.visitRequestHeaders({ + visitHeader: function(name, value) + { + requestHeaders.push({name: name, value: value}); + } + }); + http.visitResponseHeaders({ + visitHeader: function(name, value) + { + responseHeaders.push({name: name, value: value}); + } + }); + + file.requestHeaders = requestHeaders; + file.responseHeaders = responseHeaders; + } + } + catch (exc) + { + // An exception can be throwed e.g. when the request is aborted and + // request.responseStatus is accessed. + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("net.getHttpHeaders FAILS " + file.href, exc); + } + }, + + isXHR: function(request) + { + try + { + var callbacks = request.notificationCallbacks; + var xhrRequest = callbacks ? callbacks.getInterface(Ci.nsIXMLHttpRequest) : null; + if (FBTrace.DBG_NET) + FBTrace.sysout("net.isXHR; " + (xhrRequest != null) + ", " + safeGetName(request)); + + return (xhrRequest != null); + } + catch (exc) + { + } + + return false; + }, + + getFileCategory: function(file) + { + if (file.category) + { + if (FBTrace.DBG_NET) + FBTrace.sysout("net.getFileCategory; current: " + file.category + " for: " + file.href, file); + return file.category; + } + + if (file.isXHR) + { + if (FBTrace.DBG_NET) + FBTrace.sysout("net.getFileCategory; XHR for: " + file.href, file); + return file.category = "xhr"; + } + + if (!file.mimeType) + { + var ext = getFileExtension(file.href); + if (ext) + file.mimeType = mimeExtensionMap[ext.toLowerCase()]; + } + + /*if (FBTrace.DBG_NET) + FBTrace.sysout("net.getFileCategory; " + mimeCategoryMap[file.mimeType] + + ", mimeType: " + file.mimeType + " for: " + file.href, file);*/ + + if (!file.mimeType) + return ""; + + // Solve cases when charset is also specified, eg "text/html; charset=UTF-8". + var mimeType = file.mimeType; + if (mimeType) + mimeType = mimeType.split(";")[0]; + + return (file.category = mimeCategoryMap[mimeType]); + } +}; + +var Utils = Firebug.NetMonitor.Utils; + +// ************************************************************************************************ + +//Firebug.registerRep(Firebug.NetMonitor.NetRequestTable); +//Firebug.registerActivableModule(Firebug.NetMonitor); +//Firebug.registerPanel(NetPanel); + +Firebug.registerModule(Firebug.NetMonitor); +//Firebug.registerRep(Firebug.NetMonitor.BreakpointRep); + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// Constants + +//const Cc = Components.classes; +//const Ci = Components.interfaces; + +// List of contexts with XHR spy attached. +var contexts = []; + +// ************************************************************************************************ +// Spy Module + +/** + * @module Represents a XHR Spy module. The main purpose of the XHR Spy feature is to monitor + * XHR activity of the current page and create appropriate log into the Console panel. + * This feature can be controlled by an option Show XMLHttpRequests (from within the + * console panel). + * + * The module is responsible for attaching/detaching a HTTP Observers when Firebug is + * activated/deactivated for a site. + */ +Firebug.Spy = extend(Firebug.Module, +/** @lends Firebug.Spy */ +{ + dispatchName: "spy", + + initialize: function() + { + if (Firebug.TraceModule) + Firebug.TraceModule.addListener(this.TraceListener); + + Firebug.Module.initialize.apply(this, arguments); + }, + + shutdown: function() + { + Firebug.Module.shutdown.apply(this, arguments); + + if (Firebug.TraceModule) + Firebug.TraceModule.removeListener(this.TraceListener); + }, + + initContext: function(context) + { + context.spies = []; + + if (Firebug.showXMLHttpRequests && Firebug.Console.isAlwaysEnabled()) + this.attachObserver(context, context.window); + + if (FBTrace.DBG_SPY) + FBTrace.sysout("spy.initContext " + contexts.length + " ", context.getName()); + }, + + destroyContext: function(context) + { + // For any spies that are in progress, remove our listeners so that they don't leak + this.detachObserver(context, null); + + if (FBTrace.DBG_SPY && context.spies.length) + FBTrace.sysout("spy.destroyContext; ERROR There are leaking Spies (" + + context.spies.length + ") " + context.getName()); + + delete context.spies; + + if (FBTrace.DBG_SPY) + FBTrace.sysout("spy.destroyContext " + contexts.length + " ", context.getName()); + }, + + watchWindow: function(context, win) + { + if (Firebug.showXMLHttpRequests && Firebug.Console.isAlwaysEnabled()) + this.attachObserver(context, win); + }, + + unwatchWindow: function(context, win) + { + try + { + // This make sure that the existing context is properly removed from "contexts" array. + this.detachObserver(context, win); + } + catch (ex) + { + // Get exceptions here sometimes, so let's just ignore them + // since the window is going away anyhow + ERROR(ex); + } + }, + + updateOption: function(name, value) + { + // XXXjjb Honza, if Console.isEnabled(context) false, then this can't be called, + // but somehow seems not correct + if (name == "showXMLHttpRequests") + { + var tach = value ? this.attachObserver : this.detachObserver; + for (var i = 0; i < TabWatcher.contexts.length; ++i) + { + var context = TabWatcher.contexts[i]; + iterateWindows(context.window, function(win) + { + tach.apply(this, [context, win]); + }); + } + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Attaching Spy to XHR requests. + + /** + * Returns false if Spy should not be attached to XHRs executed by the specified window. + */ + skipSpy: function(win) + { + if (!win) + return true; + + // Don't attach spy to chrome. + var uri = safeGetWindowLocation(win); + if (uri && (uri.indexOf("about:") == 0 || uri.indexOf("chrome:") == 0)) + return true; + }, + + attachObserver: function(context, win) + { + if (Firebug.Spy.skipSpy(win)) + return; + + for (var i=0; insIHttpChannel
      . + * Returns null if the request doesn't represent XHR. + */ + getXHR: function(request) + { + // Does also query-interface for nsIHttpChannel. + if (!(request instanceof Ci.nsIHttpChannel)) + return null; + + try + { + var callbacks = request.notificationCallbacks; + return (callbacks ? callbacks.getInterface(Ci.nsIXMLHttpRequest) : null); + } + catch (exc) + { + if (exc.name == "NS_NOINTERFACE") + { + if (FBTrace.DBG_SPY) + FBTrace.sysout("spy.getXHR; Request is not nsIXMLHttpRequest: " + + safeGetRequestName(request)); + } + } + + return null; + } +}); + + + + + +// ************************************************************************************************ + +/* +function getSpyForXHR(request, xhrRequest, context, noCreate) +{ + var spy = null; + + // Iterate all existing spy objects in this context and look for one that is + // already created for this request. + var length = context.spies.length; + for (var i=0; i= 3) + { + var netInfoBox = getChildByClass(spy.logRow, "spyHead", "netInfoBody"); + if (netInfoBox) + { + netInfoBox.htmlPresented = false; + netInfoBox.responsePresented = false; + } + } + + // If the request is loading update the end time. + if (spy.xhrRequest.readyState == 3) + { + spy.responseTime = spy.endTime - spy.sendTime; + updateTime(spy); + } + + // Request loaded. Get all the info from the request now, just in case the + // XHR would be aborted in the original onReadyStateChange handler. + if (spy.xhrRequest.readyState == 4) + { + // Cumulate response so, multipart response content is properly displayed. + if (SpyHttpActivityObserver.getActivityDistributor()) + spy.responseText += spy.xhrRequest.responseText; + else + { + // xxxHonza: remove from FB 1.6 + if (!spy.responseText) + spy.responseText = spy.xhrRequest.responseText; + } + + // The XHR is loaded now (used also by the activity observer). + spy.loaded = true; + + // Update UI. + updateHttpSpyInfo(spy); + + // Notify Net pane about a request beeing loaded. + // xxxHonza: I don't think this is necessary. + var netProgress = spy.context.netProgress; + if (netProgress) + netProgress.post(netProgress.stopFile, [spy.request, spy.endTime, spy.postText, spy.responseText]); + + // Notify registered listeners about finish of the XHR. + dispatch(Firebug.Spy.fbListeners, "onLoad", [spy.context, spy]); + } + + // Pass the event to the original page handler. + callPageHandler(spy, event, originalHandler); +} + +function onHTTPSpyLoad(spy) +{ + if (FBTrace.DBG_SPY) + FBTrace.sysout("spy.onHTTPSpyLoad: " + spy.href, spy); + + // Detach must be done in onLoad (not in onreadystatechange) otherwise + // onAbort would not be handled. + spy.detach(); + + // xxxHonza: Still needed for Fx 3.5 (#502959) + if (!SpyHttpActivityObserver.getActivityDistributor()) + onHTTPSpyReadyStateChange(spy, null); +} + +function onHTTPSpyError(spy) +{ + if (FBTrace.DBG_SPY) + FBTrace.sysout("spy.onHTTPSpyError; " + spy.href, spy); + + spy.detach(); + spy.loaded = true; + + if (spy.logRow) + { + removeClass(spy.logRow, "loading"); + setClass(spy.logRow, "error"); + } +} + +function onHTTPSpyAbort(spy) +{ + if (FBTrace.DBG_SPY) + FBTrace.sysout("spy.onHTTPSpyAbort: " + spy.href, spy); + + spy.detach(); + spy.loaded = true; + + if (spy.logRow) + { + removeClass(spy.logRow, "loading"); + setClass(spy.logRow, "error"); + } + + spy.statusText = "Aborted"; + updateLogRow(spy); + + // Notify Net pane about a request beeing aborted. + // xxxHonza: the net panel shoud find out this itself. + var netProgress = spy.context.netProgress; + if (netProgress) + netProgress.post(netProgress.abortFile, [spy.request, spy.endTime, spy.postText, spy.responseText]); +} +/**/ + +// ************************************************************************************************ + +/** + * @domplate Represents a template for XHRs logged in the Console panel. The body of the + * log (displayed when expanded) is rendered using {@link Firebug.NetMonitor.NetInfoBody}. + */ + +Firebug.Spy.XHR = domplate(Firebug.Rep, +/** @lends Firebug.Spy.XHR */ + +{ + tag: + DIV({"class": "spyHead", _repObject: "$object"}, + TABLE({"class": "spyHeadTable focusRow outerFocusRow", cellpadding: 0, cellspacing: 0, + "role": "listitem", "aria-expanded": "false"}, + TBODY({"role": "presentation"}, + TR({"class": "spyRow"}, + TD({"class": "spyTitleCol spyCol", onclick: "$onToggleBody"}, + DIV({"class": "spyTitle"}, + "$object|getCaption" + ), + DIV({"class": "spyFullTitle spyTitle"}, + "$object|getFullUri" + ) + ), + TD({"class": "spyCol"}, + DIV({"class": "spyStatus"}, "$object|getStatus") + ), + TD({"class": "spyCol"}, + SPAN({"class": "spyIcon"}) + ), + TD({"class": "spyCol"}, + SPAN({"class": "spyTime"}) + ), + TD({"class": "spyCol"}, + TAG(FirebugReps.SourceLink.tag, {object: "$object.sourceLink"}) + ) + ) + ) + ) + ), + + getCaption: function(spy) + { + return spy.method.toUpperCase() + " " + cropString(spy.getURL(), 100); + }, + + getFullUri: function(spy) + { + return spy.method.toUpperCase() + " " + spy.getURL(); + }, + + getStatus: function(spy) + { + var text = ""; + if (spy.statusCode) + text += spy.statusCode + " "; + + if (spy.statusText) + return text += spy.statusText; + + return text; + }, + + onToggleBody: function(event) + { + var target = event.currentTarget || event.srcElement; + var logRow = getAncestorByClass(target, "logRow-spy"); + + if (isLeftClick(event)) + { + toggleClass(logRow, "opened"); + + var spy = getChildByClass(logRow, "spyHead").repObject; + var spyHeadTable = getAncestorByClass(target, "spyHeadTable"); + + if (hasClass(logRow, "opened")) + { + updateHttpSpyInfo(spy, logRow); + if (spyHeadTable) + spyHeadTable.setAttribute('aria-expanded', 'true'); + } + else + { + //var netInfoBox = getChildByClass(spy.logRow, "spyHead", "netInfoBody"); + //dispatch(Firebug.NetMonitor.NetInfoBody.fbListeners, "destroyTabBody", [netInfoBox, spy]); + //if (spyHeadTable) + // spyHeadTable.setAttribute('aria-expanded', 'false'); + } + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + copyURL: function(spy) + { + copyToClipboard(spy.getURL()); + }, + + copyParams: function(spy) + { + var text = spy.postText; + if (!text) + return; + + var url = reEncodeURL(spy, text, true); + copyToClipboard(url); + }, + + copyResponse: function(spy) + { + copyToClipboard(spy.responseText); + }, + + openInTab: function(spy) + { + openNewTab(spy.getURL(), spy.postText); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + supportsObject: function(object) + { + // TODO: xxxpedro spy xhr + return false; + + return object instanceof Firebug.Spy.XMLHttpRequestSpy; + }, + + browseObject: function(spy, context) + { + var url = spy.getURL(); + openNewTab(url); + return true; + }, + + getRealObject: function(spy, context) + { + return spy.xhrRequest; + }, + + getContextMenuItems: function(spy) + { + var items = [ + {label: "CopyLocation", command: bindFixed(this.copyURL, this, spy) } + ]; + + if (spy.postText) + { + items.push( + {label: "CopyLocationParameters", command: bindFixed(this.copyParams, this, spy) } + ); + } + + items.push( + {label: "CopyResponse", command: bindFixed(this.copyResponse, this, spy) }, + "-", + {label: "OpenInTab", command: bindFixed(this.openInTab, this, spy) } + ); + + return items; + } +}); + +// ************************************************************************************************ + +function updateTime(spy) +{ + var timeBox = spy.logRow.getElementsByClassName("spyTime").item(0); + if (spy.responseTime) + timeBox.textContent = " " + formatTime(spy.responseTime); +} + +function updateLogRow(spy) +{ + updateTime(spy); + + var statusBox = spy.logRow.getElementsByClassName("spyStatus").item(0); + statusBox.textContent = Firebug.Spy.XHR.getStatus(spy); + + removeClass(spy.logRow, "loading"); + setClass(spy.logRow, "loaded"); + + try + { + var errorRange = Math.floor(spy.xhrRequest.status/100); + if (errorRange == 4 || errorRange == 5) + setClass(spy.logRow, "error"); + } + catch (exc) + { + } +} + +var updateHttpSpyInfo = function updateHttpSpyInfo(spy, logRow) +{ + if (!spy.logRow && logRow) + spy.logRow = logRow; + + if (!spy.logRow || !hasClass(spy.logRow, "opened")) + return; + + if (!spy.params) + //spy.params = parseURLParams(spy.href+""); + spy.params = parseURLParams(spy.href+""); + + if (!spy.requestHeaders) + spy.requestHeaders = getRequestHeaders(spy); + + if (!spy.responseHeaders && spy.loaded) + spy.responseHeaders = getResponseHeaders(spy); + + var template = Firebug.NetMonitor.NetInfoBody; + var netInfoBox = getChildByClass(spy.logRow, "spyHead", "netInfoBody"); + if (!netInfoBox) + { + var head = getChildByClass(spy.logRow, "spyHead"); + netInfoBox = template.tag.append({"file": spy}, head); + dispatch(template.fbListeners, "initTabBody", [netInfoBox, spy]); + template.selectTabByName(netInfoBox, "Response"); + } + else + { + template.updateInfo(netInfoBox, spy, spy.context); + } +}; + + + +// ************************************************************************************************ + +function getRequestHeaders(spy) +{ + var headers = []; + + var channel = spy.xhrRequest.channel; + if (channel instanceof Ci.nsIHttpChannel) + { + channel.visitRequestHeaders({ + visitHeader: function(name, value) + { + headers.push({name: name, value: value}); + } + }); + } + + return headers; +} + +function getResponseHeaders(spy) +{ + var headers = []; + + try + { + var channel = spy.xhrRequest.channel; + if (channel instanceof Ci.nsIHttpChannel) + { + channel.visitResponseHeaders({ + visitHeader: function(name, value) + { + headers.push({name: name, value: value}); + } + }); + } + } + catch (exc) + { + if (FBTrace.DBG_SPY || FBTrace.DBG_ERRORS) + FBTrace.sysout("spy.getResponseHeaders; EXCEPTION " + + safeGetRequestName(spy.request), exc); + } + + return headers; +} + +// ************************************************************************************************ +// Registration + +Firebug.registerModule(Firebug.Spy); +//Firebug.registerRep(Firebug.Spy.XHR); + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ + +// List of JSON content types. +var contentTypes = +{ + "text/plain": 1, + "text/javascript": 1, + "text/x-javascript": 1, + "text/json": 1, + "text/x-json": 1, + "application/json": 1, + "application/x-json": 1, + "application/javascript": 1, + "application/x-javascript": 1, + "application/json-rpc": 1 +}; + +// ************************************************************************************************ +// Model implementation + +Firebug.JSONViewerModel = extend(Firebug.Module, +{ + dispatchName: "jsonViewer", + initialize: function() + { + Firebug.NetMonitor.NetInfoBody.addListener(this); + + // Used by Firebug.DOMPanel.DirTable domplate. + this.toggles = {}; + }, + + shutdown: function() + { + Firebug.NetMonitor.NetInfoBody.removeListener(this); + }, + + initTabBody: function(infoBox, file) + { + if (FBTrace.DBG_JSONVIEWER) + FBTrace.sysout("jsonviewer.initTabBody", infoBox); + + // Let listeners to parse the JSON. + dispatch(this.fbListeners, "onParseJSON", [file]); + + // The JSON is still no there, try to parse most common cases. + if (!file.jsonObject) + { + ///if (this.isJSON(safeGetContentType(file.request), file.responseText)) + if (this.isJSON(file.mimeType, file.responseText)) + file.jsonObject = this.parseJSON(file); + } + + // The jsonObject is created so, the JSON tab can be displayed. + if (file.jsonObject && hasProperties(file.jsonObject)) + { + Firebug.NetMonitor.NetInfoBody.appendTab(infoBox, "JSON", + ///$STR("jsonviewer.tab.JSON")); + $STR("JSON")); + + if (FBTrace.DBG_JSONVIEWER) + FBTrace.sysout("jsonviewer.initTabBody; JSON object available " + + (typeof(file.jsonObject) != "undefined"), file.jsonObject); + } + }, + + isJSON: function(contentType, data) + { + // Workaround for JSON responses without proper content type + // Let's consider all responses starting with "{" as JSON. In the worst + // case there will be an exception when parsing. This means that no-JSON + // responses (and post data) (with "{") can be parsed unnecessarily, + // which represents a little overhead, but this happens only if the request + // is actually expanded by the user in the UI (Net & Console panels). + + ///var responseText = data ? trimLeft(data) : null; + ///if (responseText && responseText.indexOf("{") == 0) + /// return true; + var responseText = data ? trim(data) : null; + if (responseText && responseText.indexOf("{") == 0) + return true; + + if (!contentType) + return false; + + contentType = contentType.split(";")[0]; + contentType = trim(contentType); + return contentTypes[contentType]; + }, + + // Update listener for TabView + updateTabBody: function(infoBox, file, context) + { + var tab = infoBox.selectedTab; + ///var tabBody = infoBox.getElementsByClassName("netInfoJSONText").item(0); + var tabBody = $$(".netInfoJSONText", infoBox)[0]; + if (!hasClass(tab, "netInfoJSONTab") || tabBody.updated) + return; + + tabBody.updated = true; + + if (file.jsonObject) { + Firebug.DOMPanel.DirTable.tag.replace( + {object: file.jsonObject, toggles: this.toggles}, tabBody); + } + }, + + parseJSON: function(file) + { + var jsonString = new String(file.responseText); + ///return parseJSONString(jsonString, "http://" + file.request.originalURI.host); + return parseJSONString(jsonString); + } +}); + +// ************************************************************************************************ +// Registration + +Firebug.registerModule(Firebug.JSONViewerModel); + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// Constants + +// List of XML related content types. +var xmlContentTypes = +[ + "text/xml", + "application/xml", + "application/xhtml+xml", + "application/rss+xml", + "application/atom+xml",, + "application/vnd.mozilla.maybe.feed", + "application/rdf+xml", + "application/vnd.mozilla.xul+xml" +]; + +// ************************************************************************************************ +// Model implementation + +/** + * @module Implements viewer for XML based network responses. In order to create a new + * tab wihin network request detail, a listener is registered into + * Firebug.NetMonitor.NetInfoBody object. + */ +Firebug.XMLViewerModel = extend(Firebug.Module, +{ + dispatchName: "xmlViewer", + + initialize: function() + { + ///Firebug.ActivableModule.initialize.apply(this, arguments); + Firebug.Module.initialize.apply(this, arguments); + Firebug.NetMonitor.NetInfoBody.addListener(this); + }, + + shutdown: function() + { + ///Firebug.ActivableModule.shutdown.apply(this, arguments); + Firebug.Module.shutdown.apply(this, arguments); + Firebug.NetMonitor.NetInfoBody.removeListener(this); + }, + + /** + * Check response's content-type and if it's a XML, create a new tab with XML preview. + */ + initTabBody: function(infoBox, file) + { + if (FBTrace.DBG_XMLVIEWER) + FBTrace.sysout("xmlviewer.initTabBody", infoBox); + + // If the response is XML let's display a pretty preview. + ///if (this.isXML(safeGetContentType(file.request))) + if (this.isXML(file.mimeType, file.responseText)) + { + Firebug.NetMonitor.NetInfoBody.appendTab(infoBox, "XML", + ///$STR("xmlviewer.tab.XML")); + $STR("XML")); + + if (FBTrace.DBG_XMLVIEWER) + FBTrace.sysout("xmlviewer.initTabBody; XML response available"); + } + }, + + isXML: function(contentType) + { + if (!contentType) + return false; + + // Look if the response is XML based. + for (var i=0; i\s*/, ""); + + var div = parentNode.ownerDocument.createElement("div"); + div.innerHTML = xmlText; + + var root = div.getElementsByTagName("*")[0]; + + /*** + var parser = CCIN("@mozilla.org/xmlextras/domparser;1", "nsIDOMParser"); + var doc = parser.parseFromString(text, "text/xml"); + var root = doc.documentElement; + + // Error handling + var nsURI = "http://www.mozilla.org/newlayout/xml/parsererror.xml"; + if (root.namespaceURI == nsURI && root.nodeName == "parsererror") + { + this.ParseError.tag.replace({error: { + message: root.firstChild.nodeValue, + source: root.lastChild.textContent + }}, parentNode); + return; + } + /**/ + + if (FBTrace.DBG_XMLVIEWER) + FBTrace.sysout("xmlviewer.updateTabBody; XML response parsed", doc); + + // Override getHidden in these templates. The parsed XML documen is + // hidden, but we want to display it using 'visible' styling. + /* + var templates = [ + Firebug.HTMLPanel.CompleteElement, + Firebug.HTMLPanel.Element, + Firebug.HTMLPanel.TextElement, + Firebug.HTMLPanel.EmptyElement, + Firebug.HTMLPanel.XEmptyElement, + ]; + + var originals = []; + for (var i=0; iFirebug.XMLViewerModel. + */ +Firebug.XMLViewerModel.ParseError = domplate(Firebug.Rep, +{ + tag: + DIV({"class": "xmlInfoError"}, + DIV({"class": "xmlInfoErrorMsg"}, "$error.message"), + PRE({"class": "xmlInfoErrorSource"}, "$error|getSource") + ), + + getSource: function(error) + { + var parts = error.source.split("\n"); + if (parts.length != 2) + return error.source; + + var limit = 50; + var column = parts[1].length; + if (column >= limit) { + parts[0] = "..." + parts[0].substr(column - limit); + parts[1] = "..." + parts[1].substr(column - limit); + } + + if (parts[0].length > 80) + parts[0] = parts[0].substr(0, 80) + "..."; + + return parts.join("\n"); + } +}); + +// ************************************************************************************************ +// Registration + +Firebug.registerModule(Firebug.XMLViewerModel); + +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +// Globals + +var ElementCache = Firebug.Lite.Cache.Element; +var cacheID = Firebug.Lite.Cache.ID; + +var ignoreHTMLProps = +{ + // ignores the attributes injected by Sizzle, otherwise it will + // be visible on IE (when enumerating element.attributes) + sizcache: 1, + sizset: 1 +}; + +// ignores also the cache property injected by firebug +ignoreHTMLProps[cacheID] = 1; + + +// ************************************************************************************************ +// HTML Module + +Firebug.HTML = extend(Firebug.Module, +{ + appendTreeNode: function(nodeArray, html) + { + var reTrim = /^\s+|\s+$/g; + + if (!nodeArray.length) nodeArray = [nodeArray]; + + for (var n=0, node; node=nodeArray[n]; n++) + { + if (node.nodeType == 1) + { + if (Firebug.ignoreFirebugElements && node.firebugIgnore) continue; + + var uid = ElementCache(node); + var child = node.childNodes; + var childLength = child.length; + + var nodeName = node.nodeName.toLowerCase(); + + var nodeVisible = isVisible(node); + + var hasSingleTextChild = childLength == 1 && node.firstChild.nodeType == 3 && + nodeName != "script" && nodeName != "style"; + + var nodeControl = !hasSingleTextChild && childLength > 0 ? + ('
      ') : ''; + + 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 || 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; + + 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; + + 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: true, + 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.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.HTML.selectTreeNode(ElementCache(Firebug.browser.document.body)); + } + + // 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(FirebugChrome.selectedHTMLElementId) + Firebug.HTML.selectTreeNode(FirebugChrome.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"; + + selectedElement = e; + + FirebugChrome.selectedHTMLElementId = e.id; + + var target = ElementCache.get(e.id); + var selectedSidePanel = Firebug.chrome.getPanel("HTML").sidePanelBar.selectedPanel; + + var stack = FirebugChrome.htmlSelectionStack; + + stack.unshift(target); + + if (stack.length > 2) + stack.pop(); + + var lazySelect = function() + { + selectedSidePanelTS = new Date().getTime(); + + 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') + { + 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(' ]'); + } + +}; + + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +/* + +Hack: +Firebug.chrome.currentPanel = Firebug.chrome.selectedPanel; +Firebug.showInfoTips = true; +Firebug.InfoTip.initializeBrowser(Firebug.chrome); + +/**/ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// Constants + +var maxWidth = 100, maxHeight = 80; +var infoTipMargin = 10; +var infoTipWindowPadding = 25; + +// ************************************************************************************************ + +Firebug.InfoTip = extend(Firebug.Module, +{ + dispatchName: "infoTip", + tags: domplate( + { + infoTipTag: DIV({"class": "infoTip"}), + + colorTag: + DIV({style: "background: $rgbValue; width: 100px; height: 40px"}, " "), + + imgTag: + DIV({"class": "infoTipImageBox infoTipLoading"}, + IMG({"class": "infoTipImage", src: "$urlValue", repeat: "$repeat", + onload: "$onLoadImage"}), + IMG({"class": "infoTipBgImage", collapsed: true, src: "blank.gif"}), + DIV({"class": "infoTipCaption"}) + ), + + onLoadImage: function(event) + { + var img = event.currentTarget || event.srcElement; + ///var bgImg = img.nextSibling; + ///if (!bgImg) + /// return; // Sometimes gets called after element is dead + + ///var caption = bgImg.nextSibling; + var innerBox = img.parentNode; + + /// TODO: xxxpedro infoTip hack + var caption = getElementByClass(innerBox, "infoTipCaption"); + var bgImg = getElementByClass(innerBox, "infoTipBgImage"); + if (!bgImg) + return; // Sometimes gets called after element is dead + + // TODO: xxxpedro infoTip IE and timing issue + // TODO: use offline document to avoid flickering + if (isIE) + removeClass(innerBox, "infoTipLoading"); + + var updateInfoTip = function(){ + + var w = img.naturalWidth || img.width || 10, + h = img.naturalHeight || img.height || 10; + + var repeat = img.getAttribute("repeat"); + + if (repeat == "repeat-x" || (w == 1 && h > 1)) + { + collapse(img, true); + collapse(bgImg, false); + bgImg.style.background = "url(" + img.src + ") repeat-x"; + bgImg.style.width = maxWidth + "px"; + if (h > maxHeight) + bgImg.style.height = maxHeight + "px"; + else + bgImg.style.height = h + "px"; + } + else if (repeat == "repeat-y" || (h == 1 && w > 1)) + { + collapse(img, true); + collapse(bgImg, false); + bgImg.style.background = "url(" + img.src + ") repeat-y"; + bgImg.style.height = maxHeight + "px"; + if (w > maxWidth) + bgImg.style.width = maxWidth + "px"; + else + bgImg.style.width = w + "px"; + } + else if (repeat == "repeat" || (w == 1 && h == 1)) + { + collapse(img, true); + collapse(bgImg, false); + bgImg.style.background = "url(" + img.src + ") repeat"; + bgImg.style.width = maxWidth + "px"; + bgImg.style.height = maxHeight + "px"; + } + else + { + if (w > maxWidth || h > maxHeight) + { + if (w > h) + { + img.style.width = maxWidth + "px"; + img.style.height = Math.round((h / w) * maxWidth) + "px"; + } + else + { + img.style.width = Math.round((w / h) * maxHeight) + "px"; + img.style.height = maxHeight + "px"; + } + } + } + + //caption.innerHTML = $STRF("Dimensions", [w, h]); + caption.innerHTML = $STRF(w + " x " + h); + + + }; + + if (isIE) + setTimeout(updateInfoTip, 0); + else + { + updateInfoTip(); + removeClass(innerBox, "infoTipLoading"); + } + + /// + } + + /* + /// onLoadImage original + onLoadImage: function(event) + { + var img = event.currentTarget; + var bgImg = img.nextSibling; + if (!bgImg) + return; // Sometimes gets called after element is dead + + var caption = bgImg.nextSibling; + var innerBox = img.parentNode; + + var w = img.naturalWidth, h = img.naturalHeight; + var repeat = img.getAttribute("repeat"); + + if (repeat == "repeat-x" || (w == 1 && h > 1)) + { + collapse(img, true); + collapse(bgImg, false); + bgImg.style.background = "url(" + img.src + ") repeat-x"; + bgImg.style.width = maxWidth + "px"; + if (h > maxHeight) + bgImg.style.height = maxHeight + "px"; + else + bgImg.style.height = h + "px"; + } + else if (repeat == "repeat-y" || (h == 1 && w > 1)) + { + collapse(img, true); + collapse(bgImg, false); + bgImg.style.background = "url(" + img.src + ") repeat-y"; + bgImg.style.height = maxHeight + "px"; + if (w > maxWidth) + bgImg.style.width = maxWidth + "px"; + else + bgImg.style.width = w + "px"; + } + else if (repeat == "repeat" || (w == 1 && h == 1)) + { + collapse(img, true); + collapse(bgImg, false); + bgImg.style.background = "url(" + img.src + ") repeat"; + bgImg.style.width = maxWidth + "px"; + bgImg.style.height = maxHeight + "px"; + } + else + { + if (w > maxWidth || h > maxHeight) + { + if (w > h) + { + img.style.width = maxWidth + "px"; + img.style.height = Math.round((h / w) * maxWidth) + "px"; + } + else + { + img.style.width = Math.round((w / h) * maxHeight) + "px"; + img.style.height = maxHeight + "px"; + } + } + } + + caption.innerHTML = $STRF("Dimensions", [w, h]); + + removeClass(innerBox, "infoTipLoading"); + } + /**/ + + }), + + initializeBrowser: function(browser) + { + browser.onInfoTipMouseOut = bind(this.onMouseOut, this, browser); + browser.onInfoTipMouseMove = bind(this.onMouseMove, this, browser); + + ///var doc = browser.contentDocument; + var doc = browser.document; + if (!doc) + return; + + ///doc.addEventListener("mouseover", browser.onInfoTipMouseMove, true); + ///doc.addEventListener("mouseout", browser.onInfoTipMouseOut, true); + ///doc.addEventListener("mousemove", browser.onInfoTipMouseMove, true); + addEvent(doc, "mouseover", browser.onInfoTipMouseMove); + addEvent(doc, "mouseout", browser.onInfoTipMouseOut); + addEvent(doc, "mousemove", browser.onInfoTipMouseMove); + + return browser.infoTip = this.tags.infoTipTag.append({}, getBody(doc)); + }, + + uninitializeBrowser: function(browser) + { + if (browser.infoTip) + { + ///var doc = browser.contentDocument; + var doc = browser.document; + ///doc.removeEventListener("mouseover", browser.onInfoTipMouseMove, true); + ///doc.removeEventListener("mouseout", browser.onInfoTipMouseOut, true); + ///doc.removeEventListener("mousemove", browser.onInfoTipMouseMove, true); + removeEvent(doc, "mouseover", browser.onInfoTipMouseMove); + removeEvent(doc, "mouseout", browser.onInfoTipMouseOut); + removeEvent(doc, "mousemove", browser.onInfoTipMouseMove); + + browser.infoTip.parentNode.removeChild(browser.infoTip); + delete browser.infoTip; + delete browser.onInfoTipMouseMove; + } + }, + + showInfoTip: function(infoTip, panel, target, x, y, rangeParent, rangeOffset) + { + if (!Firebug.showInfoTips) + return; + + var scrollParent = getOverflowParent(target); + var scrollX = x + (scrollParent ? scrollParent.scrollLeft : 0); + + if (panel.showInfoTip(infoTip, target, scrollX, y, rangeParent, rangeOffset)) + { + var htmlElt = infoTip.ownerDocument.documentElement; + var panelWidth = htmlElt.clientWidth; + var panelHeight = htmlElt.clientHeight; + + if (x+infoTip.offsetWidth+infoTipMargin > panelWidth) + { + infoTip.style.left = Math.max(0, panelWidth-(infoTip.offsetWidth+infoTipMargin)) + "px"; + infoTip.style.right = "auto"; + } + else + { + infoTip.style.left = (x+infoTipMargin) + "px"; + infoTip.style.right = "auto"; + } + + if (y+infoTip.offsetHeight+infoTipMargin > panelHeight) + { + infoTip.style.top = Math.max(0, panelHeight-(infoTip.offsetHeight+infoTipMargin)) + "px"; + infoTip.style.bottom = "auto"; + } + else + { + infoTip.style.top = (y+infoTipMargin) + "px"; + infoTip.style.bottom = "auto"; + } + + if (FBTrace.DBG_INFOTIP) + FBTrace.sysout("infotip.showInfoTip; top: " + infoTip.style.top + + ", left: " + infoTip.style.left + ", bottom: " + infoTip.style.bottom + + ", right:" + infoTip.style.right + ", offsetHeight: " + infoTip.offsetHeight + + ", offsetWidth: " + infoTip.offsetWidth + + ", x: " + x + ", panelWidth: " + panelWidth + + ", y: " + y + ", panelHeight: " + panelHeight); + + infoTip.setAttribute("active", "true"); + } + else + this.hideInfoTip(infoTip); + }, + + hideInfoTip: function(infoTip) + { + if (infoTip) + infoTip.removeAttribute("active"); + }, + + onMouseOut: function(event, browser) + { + if (!event.relatedTarget) + this.hideInfoTip(browser.infoTip); + }, + + onMouseMove: function(event, browser) + { + // Ignore if the mouse is moving over the existing info tip. + if (getAncestorByClass(event.target, "infoTip")) + return; + + if (browser.currentPanel) + { + var x = event.clientX, y = event.clientY, target = event.target || event.srcElement; + this.showInfoTip(browser.infoTip, browser.currentPanel, target, x, y, event.rangeParent, event.rangeOffset); + } + else + this.hideInfoTip(browser.infoTip); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + populateColorInfoTip: function(infoTip, color) + { + this.tags.colorTag.replace({rgbValue: color}, infoTip); + return true; + }, + + populateImageInfoTip: function(infoTip, url, repeat) + { + if (!repeat) + repeat = "no-repeat"; + + this.tags.imgTag.replace({urlValue: url, repeat: repeat}, infoTip); + + return true; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Module + + disable: function() + { + // XXXjoe For each browser, call uninitializeBrowser + }, + + showPanel: function(browser, panel) + { + if (panel) + { + var infoTip = panel.panelBrowser.infoTip; + if (!infoTip) + infoTip = this.initializeBrowser(panel.panelBrowser); + this.hideInfoTip(infoTip); + } + + }, + + showSidePanel: function(browser, panel) + { + this.showPanel(browser, panel); + } +}); + +// ************************************************************************************************ + +Firebug.registerModule(Firebug.InfoTip); + +// ************************************************************************************************ + +}}); + + +/* See license.txt for terms of usage */ + +// move to FBL +(function() { + +// ************************************************************************************************ +// XPath + +/** + * Gets an XPath for an element which describes its hierarchical location. + */ +this.getElementXPath = function(element) +{ + if (element && element.id) + return '//*[@id="' + element.id + '"]'; + else + return this.getElementTreeXPath(element); +}; + +this.getElementTreeXPath = function(element) +{ + var paths = []; + + for (; element && element.nodeType == 1; element = element.parentNode) + { + var index = 0; + for (var sibling = element.previousSibling; sibling; sibling = sibling.previousSibling) + { + if (sibling.nodeName == element.nodeName) + ++index; + } + + var tagName = element.nodeName.toLowerCase(); + var pathIndex = (index ? "[" + (index+1) + "]" : ""); + paths.splice(0, 0, tagName + pathIndex); + } + + return paths.length ? "/" + paths.join("/") : null; +}; + +this.getElementsByXPath = function(doc, xpath) +{ + var nodes = []; + + try { + var result = doc.evaluate(xpath, doc, null, XPathResult.ANY_TYPE, null); + for (var item = result.iterateNext(); item; item = result.iterateNext()) + nodes.push(item); + } + catch (exc) + { + // Invalid xpath expressions make their way here sometimes. If that happens, + // we still want to return an empty set without an exception. + } + + return nodes; +}; + +this.getRuleMatchingElements = function(rule, doc) +{ + var css = rule.selectorText; + var xpath = this.cssToXPath(css); + return this.getElementsByXPath(doc, xpath); +}; + + +}).call(FBL); + + + + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ + +var toCamelCase = function toCamelCase(s) +{ + return s.replace(reSelectorCase, toCamelCaseReplaceFn); +}; + +var toSelectorCase = function toSelectorCase(s) +{ + return s.replace(reCamelCase, "-$1").toLowerCase(); + +}; + +var reCamelCase = /([A-Z])/g; +var reSelectorCase = /\-(.)/g; +var toCamelCaseReplaceFn = function toCamelCaseReplaceFn(m,g) +{ + return g.toUpperCase(); +}; + + + + + +// ************************************************************************************************ + +var ElementCache = Firebug.Lite.Cache.Element; +var StyleSheetCache = Firebug.Lite.Cache.StyleSheet; + +var globalCSSRuleIndex; + +var externalStyleSheetURLs = []; +var 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") + ) +}); + + +var processAllStyleSheetsTimeout = null; +var loadExternalStylesheet = function(doc, styleSheetIterator, styleSheet) +{ + var url = styleSheet.href; + styleSheet.firebugIgnore = true; + + var source = Firebug.Lite.Proxy.load(url); + + // TODO: check for null and error responses + + + // remove comments + //var reMultiComment = /(\/\*([^\*]|\*(?!\/))*\*\/)/g; + //source = source.replace(reMultiComment, ""); + + // convert relative addresses to absolute ones + source = source.replace(/url\(([^\)]+)\)/g, function(a,name){ + + var hasDomain = /\w+:\/\/./.test(name); + + if (!hasDomain) + { + name = name.replace(/^(["'])(.+)\1$/, "$2"); + var first = name.charAt(0); + + // relative path, based on root + if (first == "/") + { + // TODO: xxxpedro move to lib or Firebug.Lite.something + // getURLRoot + var m = /^([^:]+:\/{1,3}[^\/]+)/.exec(url); + + return m ? + "url(" + m[1] + name + ")" : + "url(" + name + ")"; + } + // relative path, based on current location + else + { + // TODO: xxxpedro move to lib or Firebug.Lite.something + // getURLPath + var path = url.replace(/[^\/]+\.[\w\d]+(\?.+|#.+)?$/g, ""); + + path = path + name; + + var reBack = /[^\/]+\/\.\.\//; + while(reBack.test(path)) + { + path = path.replace(reBack, ""); + } + + //console.log("url(" + path + ")"); + + return "url(" + path + ")"; + } + } + + // if it is an absolute path, there is nothing to do + return a; + }); + + var oldStyle = styleSheet.ownerNode; + + if (!oldStyle) return; + + if (!oldStyle.parentNode) return; + + var style = createGlobalElement("style"); + style.setAttribute("charset","utf-8"); + style.setAttribute("type", "text/css"); + style.innerHTML = source; + + //debugger; + oldStyle.parentNode.insertBefore(style, oldStyle.nextSibling); + oldStyle.parentNode.removeChild(oldStyle); + + + //doc.getElementsByTagName("head")[0].appendChild(style); + + doc.styleSheets[doc.styleSheets.length-1].externalURL = url; + + console.log(url, "call " + externalStyleSheetURLs.length, source); + + externalStyleSheetURLs.pop(); + + if (processAllStyleSheetsTimeout) + { + clearTimeout(processAllStyleSheetsTimeout); + } + + processAllStyleSheetsTimeout = setTimeout(function(){ + console.log("processing"); + FBL.processAllStyleSheets(doc, styleSheetIterator); + processAllStyleSheetsTimeout = null; + },200); + +}; + + +FBL.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 maxSpecificity) + { + maxSpecificity = spec; + mostSpecificSelector = sel; + } + } + } + + rule.specificity = maxSpecificity; + } + } + + rules.sort(sortElementRules); + //rules.sort(solveRulesTied); + + return rules; +}; + +var sortElementRules = function(a, b) +{ + var ruleA = CSSRuleMap[a]; + var ruleB = CSSRuleMap[b]; + + var specificityA = ruleA.specificity; + var specificityB = ruleB.specificity; + + if (specificityA > specificityB) + return 1; + + else if (specificityA < specificityB) + return -1; + + else + return ruleA.order > ruleB.order ? 1 : -1; +}; + +var solveRulesTied = function(a, b) +{ + var ruleA = CSSRuleMap[a]; + var ruleB = CSSRuleMap[b]; + + if (ruleA.specificity == ruleB.specificity) + return ruleA.order > ruleB.order ? 1 : -1; + + return null; +}; + +var reSelectorTag = /(^|\s)(?:\w+)/g; +var reSelectorClass = /\.[\w\d_-]+/g; +var reSelectorId = /#[\w\d_-]+/g; + +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; +}; + +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ + + +// ************************************************************************************************ +// Constants + +//const Cc = Components.classes; +//const Ci = Components.interfaces; +//const nsIDOMCSSStyleRule = Ci.nsIDOMCSSStyleRule; +//const nsIInterfaceRequestor = Ci.nsIInterfaceRequestor; +//const nsISelectionDisplay = Ci.nsISelectionDisplay; +//const nsISelectionController = Ci.nsISelectionController; + +// See: http://mxr.mozilla.org/mozilla1.9.2/source/content/events/public/nsIEventStateManager.h#153 +//const STATE_ACTIVE = 0x01; +//const STATE_FOCUS = 0x02; +//const STATE_HOVER = 0x04; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +Firebug.SourceBoxPanel = Firebug.Panel; + +var domUtils = null; + +var textContent = isIE ? "innerText" : "textContent"; +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var CSSDomplateBase = { + isEditable: function(rule) + { + return !rule.isSystemSheet; + }, + isSelectorEditable: function(rule) + { + return rule.isSelectorEditable && this.isEditable(rule); + } +}; + +var CSSPropTag = domplate(CSSDomplateBase, { + tag: DIV({"class": "cssProp focusRow", $disabledStyle: "$prop.disabled", + $editGroup: "$rule|isEditable", + $cssOverridden: "$prop.overridden", role : "option"}, + A({"class": "cssPropDisable"}, "  "), + SPAN({"class": "cssPropName", $editable: "$rule|isEditable"}, "$prop.name"), + SPAN({"class": "cssColon"}, ":"), + SPAN({"class": "cssPropValue", $editable: "$rule|isEditable"}, "$prop.value$prop.important"), + SPAN({"class": "cssSemi"}, ";") + ) +}); + +var CSSRuleTag = + TAG("$rule.tag", {rule: "$rule"}); + +var CSSImportRuleTag = domplate({ + tag: DIV({"class": "cssRule insertInto focusRow importRule", _repObject: "$rule.rule"}, + "@import "", + A({"class": "objectLink", _repObject: "$rule.rule.styleSheet"}, "$rule.rule.href"), + "";" + ) +}); + +var CSSStyleRuleTag = domplate(CSSDomplateBase, { + tag: DIV({"class": "cssRule insertInto", + $cssEditableRule: "$rule|isEditable", + $editGroup: "$rule|isSelectorEditable", + _repObject: "$rule.rule", + "ruleId": "$rule.id", role : 'presentation'}, + DIV({"class": "cssHead focusRow", role : 'listitem'}, + SPAN({"class": "cssSelector", $editable: "$rule|isSelectorEditable"}, "$rule.selector"), " {" + ), + DIV({role : 'group'}, + DIV({"class": "cssPropertyListBox", role : 'listbox'}, + FOR("prop", "$rule.props", + TAG(CSSPropTag.tag, {rule: "$rule", prop: "$prop"}) + ) + ) + ), + DIV({"class": "editable insertBefore", role:"presentation"}, "}") + ) +}); + +var reSplitCSS = /(url\("?[^"\)]+?"?\))|(rgb\(.*?\))|(#[\dA-Fa-f]+)|(-?\d+(\.\d+)?(%|[a-z]{1,2})?)|([^,\s]+)|"(.*?)"/; + +var reURL = /url\("?([^"\)]+)?"?\)/; + +var reRepeat = /no-repeat|repeat-x|repeat-y|repeat/; + +//const sothinkInstalled = !!$("swfcatcherKey_sidebar"); +var sothinkInstalled = false; +var styleGroups = +{ + text: [ + "font-family", + "font-size", + "font-weight", + "font-style", + "color", + "text-transform", + "text-decoration", + "letter-spacing", + "word-spacing", + "line-height", + "text-align", + "vertical-align", + "direction", + "column-count", + "column-gap", + "column-width" + ], + + background: [ + "background-color", + "background-image", + "background-repeat", + "background-position", + "background-attachment", + "opacity" + ], + + box: [ + "width", + "height", + "top", + "right", + "bottom", + "left", + "margin-top", + "margin-right", + "margin-bottom", + "margin-left", + "padding-top", + "padding-right", + "padding-bottom", + "padding-left", + "border-top-width", + "border-right-width", + "border-bottom-width", + "border-left-width", + "border-top-color", + "border-right-color", + "border-bottom-color", + "border-left-color", + "border-top-style", + "border-right-style", + "border-bottom-style", + "border-left-style", + "-moz-border-top-radius", + "-moz-border-right-radius", + "-moz-border-bottom-radius", + "-moz-border-left-radius", + "outline-top-width", + "outline-right-width", + "outline-bottom-width", + "outline-left-width", + "outline-top-color", + "outline-right-color", + "outline-bottom-color", + "outline-left-color", + "outline-top-style", + "outline-right-style", + "outline-bottom-style", + "outline-left-style" + ], + + layout: [ + "position", + "display", + "visibility", + "z-index", + "overflow-x", // http://www.w3.org/TR/2002/WD-css3-box-20021024/#overflow + "overflow-y", + "overflow-clip", + "white-space", + "clip", + "float", + "clear", + "-moz-box-sizing" + ], + + other: [ + "cursor", + "list-style-image", + "list-style-position", + "list-style-type", + "marker-offset", + "user-focus", + "user-select", + "user-modify", + "user-input" + ] +}; + +var styleGroupTitles = +{ + text: "Text", + background: "Background", + box: "Box Model", + layout: "Layout", + other: "Other" +}; + +Firebug.CSSModule = extend(Firebug.Module, +{ + freeEdit: function(styleSheet, value) + { + if (!styleSheet.editStyleSheet) + { + var ownerNode = getStyleSheetOwnerNode(styleSheet); + styleSheet.disabled = true; + + var url = CCSV("@mozilla.org/network/standard-url;1", Components.interfaces.nsIURL); + url.spec = styleSheet.href; + + var editStyleSheet = ownerNode.ownerDocument.createElementNS( + "http://www.w3.org/1999/xhtml", + "style"); + unwrapObject(editStyleSheet).firebugIgnore = true; + editStyleSheet.setAttribute("type", "text/css"); + editStyleSheet.setAttributeNS( + "http://www.w3.org/XML/1998/namespace", + "base", + url.directory); + if (ownerNode.hasAttribute("media")) + { + editStyleSheet.setAttribute("media", ownerNode.getAttribute("media")); + } + + // Insert the edited stylesheet directly after the old one to ensure the styles + // cascade properly. + ownerNode.parentNode.insertBefore(editStyleSheet, ownerNode.nextSibling); + + styleSheet.editStyleSheet = editStyleSheet; + } + + styleSheet.editStyleSheet.innerHTML = value; + if (FBTrace.DBG_CSS) + FBTrace.sysout("css.saveEdit styleSheet.href:"+styleSheet.href+" got innerHTML:"+value+"\n"); + + dispatch(this.fbListeners, "onCSSFreeEdit", [styleSheet, value]); + }, + + insertRule: function(styleSheet, cssText, ruleIndex) + { + if (FBTrace.DBG_CSS) FBTrace.sysout("Insert: " + ruleIndex + " " + cssText); + var insertIndex = styleSheet.insertRule(cssText, ruleIndex); + + dispatch(this.fbListeners, "onCSSInsertRule", [styleSheet, cssText, ruleIndex]); + + return insertIndex; + }, + + deleteRule: function(styleSheet, ruleIndex) + { + if (FBTrace.DBG_CSS) FBTrace.sysout("deleteRule: " + ruleIndex + " " + styleSheet.cssRules.length, styleSheet.cssRules); + dispatch(this.fbListeners, "onCSSDeleteRule", [styleSheet, ruleIndex]); + + styleSheet.deleteRule(ruleIndex); + }, + + setProperty: function(rule, propName, propValue, propPriority) + { + var style = rule.style || rule; + + // Record the original CSS text for the inline case so we can reconstruct at a later + // point for diffing purposes + var baseText = style.cssText; + + // good browsers + if (style.getPropertyValue) + { + var prevValue = style.getPropertyValue(propName); + var prevPriority = style.getPropertyPriority(propName); + + // XXXjoe Gecko bug workaround: Just changing priority doesn't have any effect + // unless we remove the property first + style.removeProperty(propName); + + style.setProperty(propName, propValue, propPriority); + } + // sad browsers + else + { + // TODO: xxxpedro parse CSS rule to find property priority in IE? + //console.log(propName, propValue); + style[toCamelCase(propName)] = propValue; + } + + if (propName) { + dispatch(this.fbListeners, "onCSSSetProperty", [style, propName, propValue, propPriority, prevValue, prevPriority, rule, baseText]); + } + }, + + removeProperty: function(rule, propName, parent) + { + var style = rule.style || rule; + + // Record the original CSS text for the inline case so we can reconstruct at a later + // point for diffing purposes + var baseText = style.cssText; + + if (style.getPropertyValue) + { + + var prevValue = style.getPropertyValue(propName); + var prevPriority = style.getPropertyPriority(propName); + + style.removeProperty(propName); + } + else + { + style[toCamelCase(propName)] = ""; + } + + if (propName) { + dispatch(this.fbListeners, "onCSSRemoveProperty", [style, propName, prevValue, prevPriority, rule, baseText]); + } + }/*, + + cleanupSheets: function(doc, context) + { + // Due to the manner in which the layout engine handles multiple + // references to the same sheet we need to kick it a little bit. + // The injecting a simple stylesheet then removing it will force + // Firefox to regenerate it's CSS hierarchy. + // + // WARN: This behavior was determined anecdotally. + // See http://code.google.com/p/fbug/issues/detail?id=2440 + var style = doc.createElementNS("http://www.w3.org/1999/xhtml", "style"); + style.setAttribute("charset","utf-8"); + unwrapObject(style).firebugIgnore = true; + style.setAttribute("type", "text/css"); + style.innerHTML = "#fbIgnoreStyleDO_NOT_USE {}"; + addStyleSheet(doc, style); + style.parentNode.removeChild(style); + + // https://bugzilla.mozilla.org/show_bug.cgi?id=500365 + // This voodoo touches each style sheet to force some Firefox internal change to allow edits. + var styleSheets = getAllStyleSheets(context); + for(var i = 0; i < styleSheets.length; i++) + { + try + { + var rules = styleSheets[i].cssRules; + if (rules.length > 0) + var touch = rules[0]; + if (FBTrace.DBG_CSS && touch) + FBTrace.sysout("css.show() touch "+typeof(touch)+" in "+(styleSheets[i].href?styleSheets[i].href:context.getName())); + } + catch(e) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("css.show: sheet.cssRules FAILS for "+(styleSheets[i]?styleSheets[i].href:"null sheet")+e, e); + } + } + }, + cleanupSheetHandler: function(event, context) + { + var target = event.target || event.srcElement, + tagName = (target.tagName || "").toLowerCase(); + if (tagName == "link") + { + this.cleanupSheets(target.ownerDocument, context); + } + }, + watchWindow: function(context, win) + { + var cleanupSheets = bind(this.cleanupSheets, this), + cleanupSheetHandler = bind(this.cleanupSheetHandler, this, context), + doc = win.document; + + //doc.addEventListener("DOMAttrModified", cleanupSheetHandler, false); + //doc.addEventListener("DOMNodeInserted", cleanupSheetHandler, false); + }, + loadedContext: function(context) + { + var self = this; + iterateWindows(context.browser.contentWindow, function(subwin) + { + self.cleanupSheets(subwin.document, context); + }); + } + /**/ +}); + +// ************************************************************************************************ + +Firebug.CSSStyleSheetPanel = function() {}; + +Firebug.CSSStyleSheetPanel.prototype = extend(Firebug.SourceBoxPanel, +{ + template: domplate( + { + tag: + DIV({"class": "cssSheet insertInto a11yCSSView"}, + FOR("rule", "$rules", + CSSRuleTag + ), + DIV({"class": "cssSheet editable insertBefore"}, "") + ) + }), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + refresh: function() + { + if (this.location) + this.updateLocation(this.location); + else if (this.selection) + this.updateSelection(this.selection); + }, + + toggleEditing: function() + { + if (!this.stylesheetEditor) + this.stylesheetEditor = new StyleSheetEditor(this.document); + + if (this.editing) + Firebug.Editor.stopEditing(); + else + { + if (!this.location) + return; + + var styleSheet = this.location.editStyleSheet + ? this.location.editStyleSheet.sheet + : this.location; + + var css = getStyleSheetCSS(styleSheet, this.context); + //var topmost = getTopmostRuleLine(this.panelNode); + + this.stylesheetEditor.styleSheet = this.location; + Firebug.Editor.startEditing(this.panelNode, css, this.stylesheetEditor); + //this.stylesheetEditor.scrollToLine(topmost.line, topmost.offset); + } + }, + + getStylesheetURL: function(rule) + { + if (this.location.href) + return this.location.href; + else + return this.context.window.location.href; + }, + + getRuleByLine: function(styleSheet, line) + { + if (!domUtils) + return null; + + var cssRules = styleSheet.cssRules; + for (var i = 0; i < cssRules.length; ++i) + { + var rule = cssRules[i]; + if (rule instanceof CSSStyleRule) + { + var ruleLine = domUtils.getRuleLine(rule); + if (ruleLine >= line) + return rule; + } + } + }, + + highlightRule: function(rule) + { + var ruleElement = Firebug.getElementByRepObject(this.panelNode.firstChild, rule); + if (ruleElement) + { + scrollIntoCenterView(ruleElement, this.panelNode); + setClassTimed(ruleElement, "jumpHighlight", this.context); + } + }, + + getStyleSheetRules: function(context, styleSheet) + { + var isSystemSheet = isSystemStyleSheet(styleSheet); + + function appendRules(cssRules) + { + for (var i = 0; i < cssRules.length; ++i) + { + var rule = cssRules[i]; + + // TODO: xxxpedro opera instanceof stylesheet remove the following comments when + // the issue with opera and style sheet Classes has been solved. + + //if (rule instanceof CSSStyleRule) + if (instanceOf(rule, "CSSStyleRule")) + { + var props = this.getRuleProperties(context, rule); + //var line = domUtils.getRuleLine(rule); + var line = null; + + var selector = rule.selectorText; + + if (isIE) + { + selector = selector.replace(reSelectorTag, + function(s){return s.toLowerCase();}); + } + + var ruleId = rule.selectorText+"/"+line; + rules.push({tag: CSSStyleRuleTag.tag, rule: rule, id: ruleId, + selector: selector, props: props, + isSystemSheet: isSystemSheet, + isSelectorEditable: true}); + } + //else if (rule instanceof CSSImportRule) + else if (instanceOf(rule, "CSSImportRule")) + rules.push({tag: CSSImportRuleTag.tag, rule: rule}); + //else if (rule instanceof CSSMediaRule) + else if (instanceOf(rule, "CSSMediaRule")) + appendRules.apply(this, [rule.cssRules]); + else + { + if (FBTrace.DBG_ERRORS || FBTrace.DBG_CSS) + FBTrace.sysout("css getStyleSheetRules failed to classify a rule ", rule); + } + } + } + + var rules = []; + appendRules.apply(this, [styleSheet.cssRules || styleSheet.rules]); + return rules; + }, + + parseCSSProps: function(style, inheritMode) + { + var props = []; + + if (Firebug.expandShorthandProps) + { + var count = style.length-1, + index = style.length; + while (index--) + { + var propName = style.item(count - index); + this.addProperty(propName, style.getPropertyValue(propName), !!style.getPropertyPriority(propName), false, inheritMode, props); + } + } + else + { + var lines = style.cssText.match(/(?:[^;\(]*(?:\([^\)]*?\))?[^;\(]*)*;?/g); + var propRE = /\s*([^:\s]*)\s*:\s*(.*?)\s*(! important)?;?$/; + var line,i=0; + // TODO: xxxpedro port to firebug: variable leaked into global namespace + var m; + + while(line=lines[i++]){ + m = propRE.exec(line); + if(!m) + continue; + //var name = m[1], value = m[2], important = !!m[3]; + if (m[2]) + this.addProperty(m[1], m[2], !!m[3], false, inheritMode, props); + }; + } + + return props; + }, + + getRuleProperties: function(context, rule, inheritMode) + { + var props = this.parseCSSProps(rule.style, inheritMode); + + // TODO: xxxpedro port to firebug: variable leaked into global namespace + //var line = domUtils.getRuleLine(rule); + var line; + var ruleId = rule.selectorText+"/"+line; + this.addOldProperties(context, ruleId, inheritMode, props); + sortProperties(props); + + return props; + }, + + addOldProperties: function(context, ruleId, inheritMode, props) + { + if (context.selectorMap && context.selectorMap.hasOwnProperty(ruleId) ) + { + var moreProps = context.selectorMap[ruleId]; + for (var i = 0; i < moreProps.length; ++i) + { + var prop = moreProps[i]; + this.addProperty(prop.name, prop.value, prop.important, true, inheritMode, props); + } + } + }, + + addProperty: function(name, value, important, disabled, inheritMode, props) + { + name = name.toLowerCase(); + + if (inheritMode && !inheritedStyleNames[name]) + return; + + name = this.translateName(name, value); + if (name) + { + value = stripUnits(rgbToHex(value)); + important = important ? " !important" : ""; + + var prop = {name: name, value: value, important: important, disabled: disabled}; + props.push(prop); + } + }, + + translateName: function(name, value) + { + // Don't show these proprietary Mozilla properties + if ((value == "-moz-initial" + && (name == "-moz-background-clip" || name == "-moz-background-origin" + || name == "-moz-background-inline-policy")) + || (value == "physical" + && (name == "margin-left-ltr-source" || name == "margin-left-rtl-source" + || name == "margin-right-ltr-source" || name == "margin-right-rtl-source")) + || (value == "physical" + && (name == "padding-left-ltr-source" || name == "padding-left-rtl-source" + || name == "padding-right-ltr-source" || name == "padding-right-rtl-source"))) + return null; + + // Translate these back to the form the user probably expects + if (name == "margin-left-value") + return "margin-left"; + else if (name == "margin-right-value") + return "margin-right"; + else if (name == "margin-top-value") + return "margin-top"; + else if (name == "margin-bottom-value") + return "margin-bottom"; + else if (name == "padding-left-value") + return "padding-left"; + else if (name == "padding-right-value") + return "padding-right"; + else if (name == "padding-top-value") + return "padding-top"; + else if (name == "padding-bottom-value") + return "padding-bottom"; + // XXXjoe What about border! + else + return name; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + editElementStyle: function() + { + ///var rulesBox = this.panelNode.getElementsByClassName("cssElementRuleContainer")[0]; + var rulesBox = $$(".cssElementRuleContainer", this.panelNode)[0]; + var styleRuleBox = rulesBox && Firebug.getElementByRepObject(rulesBox, this.selection); + if (!styleRuleBox) + { + var rule = {rule: this.selection, inherited: false, selector: "element.style", props: []}; + if (!rulesBox) + { + // The element did not have any displayed styles. We need to create the whole tree and remove + // the no styles message + styleRuleBox = this.template.cascadedTag.replace({ + rules: [rule], inherited: [], inheritLabel: "Inherited from" // $STR("InheritedFrom") + }, this.panelNode); + + ///styleRuleBox = styleRuleBox.getElementsByClassName("cssElementRuleContainer")[0]; + styleRuleBox = $$(".cssElementRuleContainer", styleRuleBox)[0]; + } + else + styleRuleBox = this.template.ruleTag.insertBefore({rule: rule}, rulesBox); + + ///styleRuleBox = styleRuleBox.getElementsByClassName("insertInto")[0]; + styleRuleBox = $$(".insertInto", styleRuleBox)[0]; + } + + Firebug.Editor.insertRowForObject(styleRuleBox); + }, + + insertPropertyRow: function(row) + { + Firebug.Editor.insertRowForObject(row); + }, + + insertRule: function(row) + { + var location = getAncestorByClass(row, "cssRule"); + if (!location) + { + location = getChildByClass(this.panelNode, "cssSheet"); + Firebug.Editor.insertRowForObject(location); + } + else + { + Firebug.Editor.insertRow(location, "before"); + } + }, + + editPropertyRow: function(row) + { + var propValueBox = getChildByClass(row, "cssPropValue"); + Firebug.Editor.startEditing(propValueBox); + }, + + deletePropertyRow: function(row) + { + var rule = Firebug.getRepObject(row); + var propName = getChildByClass(row, "cssPropName")[textContent]; + Firebug.CSSModule.removeProperty(rule, propName); + + // Remove the property from the selector map, if it was disabled + var ruleId = Firebug.getRepNode(row).getAttribute("ruleId"); + if ( this.context.selectorMap && this.context.selectorMap.hasOwnProperty(ruleId) ) + { + var map = this.context.selectorMap[ruleId]; + for (var i = 0; i < map.length; ++i) + { + if (map[i].name == propName) + { + map.splice(i, 1); + break; + } + } + } + if (this.name == "stylesheet") + dispatch([Firebug.A11yModel], 'onInlineEditorClose', [this, row.firstChild, true]); + row.parentNode.removeChild(row); + + this.markChange(this.name == "stylesheet"); + }, + + disablePropertyRow: function(row) + { + toggleClass(row, "disabledStyle"); + + var rule = Firebug.getRepObject(row); + var propName = getChildByClass(row, "cssPropName")[textContent]; + + if (!this.context.selectorMap) + this.context.selectorMap = {}; + + // XXXjoe Generate unique key for elements too + var ruleId = Firebug.getRepNode(row).getAttribute("ruleId"); + if (!(this.context.selectorMap.hasOwnProperty(ruleId))) + this.context.selectorMap[ruleId] = []; + + var map = this.context.selectorMap[ruleId]; + var propValue = getChildByClass(row, "cssPropValue")[textContent]; + var parsedValue = parsePriority(propValue); + if (hasClass(row, "disabledStyle")) + { + Firebug.CSSModule.removeProperty(rule, propName); + + map.push({"name": propName, "value": parsedValue.value, + "important": parsedValue.priority}); + } + else + { + Firebug.CSSModule.setProperty(rule, propName, parsedValue.value, parsedValue.priority); + + var index = findPropByName(map, propName); + map.splice(index, 1); + } + + this.markChange(this.name == "stylesheet"); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + onMouseDown: function(event) + { + //console.log("onMouseDown", event.target || event.srcElement, event); + + // xxxpedro adjusting coordinates because the panel isn't a window yet + var offset = event.clientX - this.panelNode.parentNode.offsetLeft; + + // XXjoe Hack to only allow clicking on the checkbox + if (!isLeftClick(event) || offset > 20) + return; + + var target = event.target || event.srcElement; + if (hasClass(target, "textEditor")) + return; + + var row = getAncestorByClass(target, "cssProp"); + if (row && hasClass(row, "editGroup")) + { + this.disablePropertyRow(row); + cancelEvent(event); + } + }, + + onDoubleClick: function(event) + { + //console.log("onDoubleClick", event.target || event.srcElement, event); + + // xxxpedro adjusting coordinates because the panel isn't a window yet + var offset = event.clientX - this.panelNode.parentNode.offsetLeft; + + if (!isLeftClick(event) || offset <= 20) + return; + + var target = event.target || event.srcElement; + + //console.log("ok", target, hasClass(target, "textEditorInner"), !isLeftClick(event), offset <= 20); + + // if the inline editor was clicked, don't insert a new rule + if (hasClass(target, "textEditorInner")) + return; + + var row = getAncestorByClass(target, "cssRule"); + if (row && !getAncestorByClass(target, "cssPropName") + && !getAncestorByClass(target, "cssPropValue")) + { + this.insertPropertyRow(row); + cancelEvent(event); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "stylesheet", + title: "CSS", + parentPanel: null, + searchable: true, + dependents: ["css", "stylesheet", "dom", "domSide", "layout"], + + options: + { + hasToolButtons: true + }, + + create: function() + { + Firebug.Panel.create.apply(this, arguments); + + this.onMouseDown = bind(this.onMouseDown, this); + this.onDoubleClick = bind(this.onDoubleClick, this); + + if (this.name == "stylesheet") + { + this.onChangeSelect = bind(this.onChangeSelect, this); + + var doc = Firebug.browser.document; + var selectNode = this.selectNode = createElement("select"); + + processAllStyleSheets(doc, function(doc, styleSheet) + { + var key = StyleSheetCache.key(styleSheet); + var fileName = getFileName(styleSheet.href) || getFileName(doc.location.href); + var option = createElement("option", {value: key}); + + option.appendChild(Firebug.chrome.document.createTextNode(fileName)); + selectNode.appendChild(option); + }); + + this.toolButtonsNode.appendChild(selectNode); + } + /**/ + }, + + onChangeSelect: function(event) + { + event = event || window.event; + var target = event.srcElement || event.currentTarget; + var key = target.value; + var styleSheet = StyleSheetCache.get(key); + + this.updateLocation(styleSheet); + }, + + initialize: function() + { + Firebug.Panel.initialize.apply(this, arguments); + + //if (!domUtils) + //{ + // try { + // domUtils = CCSV("@mozilla.org/inspector/dom-utils;1", "inIDOMUtils"); + // } catch (exc) { + // if (FBTrace.DBG_ERRORS) + // FBTrace.sysout("@mozilla.org/inspector/dom-utils;1 FAILED to load: "+exc, exc); + // } + //} + + //TODO: xxxpedro + this.context = Firebug.chrome; // TODO: xxxpedro css2 + this.document = Firebug.chrome.document; // TODO: xxxpedro css2 + + this.initializeNode(); + + if (this.name == "stylesheet") + { + var styleSheets = Firebug.browser.document.styleSheets; + + if (styleSheets.length > 0) + { + addEvent(this.selectNode, "change", this.onChangeSelect); + + this.updateLocation(styleSheets[0]); + } + } + + //Firebug.SourceBoxPanel.initialize.apply(this, arguments); + }, + + shutdown: function() + { + // must destroy the editor when we leave the panel to avoid problems (Issue 2981) + Firebug.Editor.stopEditing(); + + if (this.name == "stylesheet") + { + removeEvent(this.selectNode, "change", this.onChangeSelect); + } + + this.destroyNode(); + + Firebug.Panel.shutdown.apply(this, arguments); + }, + + destroy: function(state) + { + //state.scrollTop = this.panelNode.scrollTop ? this.panelNode.scrollTop : this.lastScrollTop; + + //persistObjects(this, state); + + // xxxpedro we are stopping the editor in the shutdown method already + //Firebug.Editor.stopEditing(); + Firebug.Panel.destroy.apply(this, arguments); + }, + + initializeNode: function(oldPanelNode) + { + addEvent(this.panelNode, "mousedown", this.onMouseDown); + addEvent(this.panelNode, "dblclick", this.onDoubleClick); + //Firebug.SourceBoxPanel.initializeNode.apply(this, arguments); + //dispatch([Firebug.A11yModel], 'onInitializeNode', [this, 'css']); + }, + + destroyNode: function() + { + removeEvent(this.panelNode, "mousedown", this.onMouseDown); + removeEvent(this.panelNode, "dblclick", this.onDoubleClick); + //Firebug.SourceBoxPanel.destroyNode.apply(this, arguments); + //dispatch([Firebug.A11yModel], 'onDestroyNode', [this, 'css']); + }, + + ishow: function(state) + { + Firebug.Inspector.stopInspecting(true); + + this.showToolbarButtons("fbCSSButtons", true); + + if (this.context.loaded && !this.location) // wait for loadedContext to restore the panel + { + restoreObjects(this, state); + + if (!this.location) + this.location = this.getDefaultLocation(); + + if (state && state.scrollTop) + this.panelNode.scrollTop = state.scrollTop; + } + }, + + ihide: function() + { + this.showToolbarButtons("fbCSSButtons", false); + + this.lastScrollTop = this.panelNode.scrollTop; + }, + + supportsObject: function(object) + { + if (object instanceof CSSStyleSheet) + return 1; + else if (object instanceof CSSStyleRule) + return 2; + else if (object instanceof CSSStyleDeclaration) + return 2; + else if (object instanceof SourceLink && object.type == "css" && reCSS.test(object.href)) + return 2; + else + return 0; + }, + + updateLocation: function(styleSheet) + { + if (!styleSheet) + return; + if (styleSheet.editStyleSheet) + styleSheet = styleSheet.editStyleSheet.sheet; + + // if it is a restricted stylesheet, show the warning message and abort the update process + if (styleSheet.restricted) + { + FirebugReps.Warning.tag.replace({object: "AccessRestricted"}, this.panelNode); + + // TODO: xxxpedro remove when there the external resource problem is fixed + externalStyleSheetWarning.tag.append({ + object: "The stylesheet could not be loaded due to access restrictions. ", + link: "more...", + href: "http://getfirebug.com/wiki/index.php/Firebug_Lite_FAQ#I_keep_seeing_.22Access_to_restricted_URI_denied.22" + }, this.panelNode); + + return; + } + + var rules = this.getStyleSheetRules(this.context, styleSheet); + + var result; + if (rules.length) + result = this.template.tag.replace({rules: rules}, this.panelNode); + else + result = FirebugReps.Warning.tag.replace({object: "EmptyStyleSheet"}, this.panelNode); + + // TODO: xxxpedro need to fix showToolbarButtons function + //this.showToolbarButtons("fbCSSButtons", !isSystemStyleSheet(this.location)); + + //dispatch([Firebug.A11yModel], 'onCSSRulesAdded', [this, this.panelNode]); + }, + + updateSelection: function(object) + { + this.selection = null; + + if (object instanceof CSSStyleDeclaration) { + object = object.parentRule; + } + + if (object instanceof CSSStyleRule) + { + this.navigate(object.parentStyleSheet); + this.highlightRule(object); + } + else if (object instanceof CSSStyleSheet) + { + this.navigate(object); + } + else if (object instanceof SourceLink) + { + try + { + var sourceLink = object; + + var sourceFile = getSourceFileByHref(sourceLink.href, this.context); + if (sourceFile) + { + clearNode(this.panelNode); // replace rendered stylesheets + this.showSourceFile(sourceFile); + + var lineNo = object.line; + if (lineNo) + this.scrollToLine(lineNo, this.jumpHighlightFactory(lineNo, this.context)); + } + else // XXXjjb we should not be taking this path + { + var stylesheet = getStyleSheetByHref(sourceLink.href, this.context); + if (stylesheet) + this.navigate(stylesheet); + else + { + if (FBTrace.DBG_CSS) + FBTrace.sysout("css.updateSelection no sourceFile for "+sourceLink.href, sourceLink); + } + } + } + catch(exc) { + if (FBTrace.DBG_CSS) + FBTrace.sysout("css.upDateSelection FAILS "+exc, exc); + } + } + }, + + updateOption: function(name, value) + { + if (name == "expandShorthandProps") + this.refresh(); + }, + + getLocationList: function() + { + var styleSheets = getAllStyleSheets(this.context); + return styleSheets; + }, + + getOptionsMenuItems: function() + { + return [ + {label: "Expand Shorthand Properties", type: "checkbox", checked: Firebug.expandShorthandProps, + command: bindFixed(Firebug.togglePref, Firebug, "expandShorthandProps") }, + "-", + {label: "Refresh", command: bind(this.refresh, this) } + ]; + }, + + getContextMenuItems: function(style, target) + { + var items = []; + + if (this.infoTipType == "color") + { + items.push( + {label: "CopyColor", + command: bindFixed(copyToClipboard, FBL, this.infoTipObject) } + ); + } + else if (this.infoTipType == "image") + { + items.push( + {label: "CopyImageLocation", + command: bindFixed(copyToClipboard, FBL, this.infoTipObject) }, + {label: "OpenImageInNewTab", + command: bindFixed(openNewTab, FBL, this.infoTipObject) } + ); + } + + ///if (this.selection instanceof Element) + if (isElement(this.selection)) + { + items.push( + //"-", + {label: "EditStyle", + command: bindFixed(this.editElementStyle, this) } + ); + } + else if (!isSystemStyleSheet(this.selection)) + { + items.push( + //"-", + {label: "NewRule", + command: bindFixed(this.insertRule, this, target) } + ); + } + + var cssRule = getAncestorByClass(target, "cssRule"); + if (cssRule && hasClass(cssRule, "cssEditableRule")) + { + items.push( + "-", + {label: "NewProp", + command: bindFixed(this.insertPropertyRow, this, target) } + ); + + var propRow = getAncestorByClass(target, "cssProp"); + if (propRow) + { + var propName = getChildByClass(propRow, "cssPropName")[textContent]; + var isDisabled = hasClass(propRow, "disabledStyle"); + + items.push( + {label: $STRF("EditProp", [propName]), nol10n: true, + command: bindFixed(this.editPropertyRow, this, propRow) }, + {label: $STRF("DeleteProp", [propName]), nol10n: true, + command: bindFixed(this.deletePropertyRow, this, propRow) }, + {label: $STRF("DisableProp", [propName]), nol10n: true, + type: "checkbox", checked: isDisabled, + command: bindFixed(this.disablePropertyRow, this, propRow) } + ); + } + } + + items.push( + "-", + {label: "Refresh", command: bind(this.refresh, this) } + ); + + return items; + }, + + browseObject: function(object) + { + if (this.infoTipType == "image") + { + openNewTab(this.infoTipObject); + return true; + } + }, + + showInfoTip: function(infoTip, target, x, y) + { + var propValue = getAncestorByClass(target, "cssPropValue"); + if (propValue) + { + var offset = getClientOffset(propValue); + var offsetX = x-offset.x; + + var text = propValue[textContent]; + var charWidth = propValue.offsetWidth/text.length; + var charOffset = Math.floor(offsetX/charWidth); + + var cssValue = parseCSSValue(text, charOffset); + if (cssValue) + { + if (cssValue.value == this.infoTipValue) + return true; + + this.infoTipValue = cssValue.value; + + if (cssValue.type == "rgb" || (!cssValue.type && isColorKeyword(cssValue.value))) + { + this.infoTipType = "color"; + this.infoTipObject = cssValue.value; + + return Firebug.InfoTip.populateColorInfoTip(infoTip, cssValue.value); + } + else if (cssValue.type == "url") + { + ///var propNameNode = target.parentNode.getElementsByClassName("cssPropName").item(0); + var propNameNode = getElementByClass(target.parentNode, "cssPropName"); + if (propNameNode && isImageRule(propNameNode[textContent])) + { + var rule = Firebug.getRepObject(target); + var baseURL = this.getStylesheetURL(rule); + var relURL = parseURLValue(cssValue.value); + var absURL = isDataURL(relURL) ? relURL:absoluteURL(relURL, baseURL); + var repeat = parseRepeatValue(text); + + this.infoTipType = "image"; + this.infoTipObject = absURL; + + return Firebug.InfoTip.populateImageInfoTip(infoTip, absURL, repeat); + } + } + } + } + + delete this.infoTipType; + delete this.infoTipValue; + delete this.infoTipObject; + }, + + getEditor: function(target, value) + { + if (target == this.panelNode + || hasClass(target, "cssSelector") || hasClass(target, "cssRule") + || hasClass(target, "cssSheet")) + { + if (!this.ruleEditor) + this.ruleEditor = new CSSRuleEditor(this.document); + + return this.ruleEditor; + } + else + { + if (!this.editor) + this.editor = new CSSEditor(this.document); + + return this.editor; + } + }, + + getDefaultLocation: function() + { + try + { + var styleSheets = this.context.window.document.styleSheets; + if (styleSheets.length) + { + var sheet = styleSheets[0]; + return (Firebug.filterSystemURLs && isSystemURL(getURLForStyleSheet(sheet))) ? null : sheet; + } + } + catch (exc) + { + if (FBTrace.DBG_LOCATIONS) + FBTrace.sysout("css.getDefaultLocation FAILS "+exc, exc); + } + }, + + getObjectDescription: function(styleSheet) + { + var url = getURLForStyleSheet(styleSheet); + var instance = getInstanceForStyleSheet(styleSheet); + + var baseDescription = splitURLBase(url); + if (instance) { + baseDescription.name = baseDescription.name + " #" + (instance + 1); + } + return baseDescription; + }, + + search: function(text, reverse) + { + var curDoc = this.searchCurrentDoc(!Firebug.searchGlobal, text, reverse); + if (!curDoc && Firebug.searchGlobal) + { + return this.searchOtherDocs(text, reverse); + } + return curDoc; + }, + + searchOtherDocs: function(text, reverse) + { + var scanRE = Firebug.Search.getTestingRegex(text); + function scanDoc(styleSheet) { + // we don't care about reverse here as we are just looking for existence, + // if we do have a result we will handle the reverse logic on display + for (var i = 0; i < styleSheet.cssRules.length; i++) + { + if (scanRE.test(styleSheet.cssRules[i].cssText)) + { + return true; + } + } + } + + if (this.navigateToNextDocument(scanDoc, reverse)) + { + return this.searchCurrentDoc(true, text, reverse); + } + }, + + searchCurrentDoc: function(wrapSearch, text, reverse) + { + if (!text) + { + delete this.currentSearch; + return false; + } + + var row; + if (this.currentSearch && text == this.currentSearch.text) + { + row = this.currentSearch.findNext(wrapSearch, false, reverse, Firebug.Search.isCaseSensitive(text)); + } + else + { + if (this.editing) + { + this.currentSearch = new TextSearch(this.stylesheetEditor.box); + row = this.currentSearch.find(text, reverse, Firebug.Search.isCaseSensitive(text)); + + if (row) + { + var sel = this.document.defaultView.getSelection(); + sel.removeAllRanges(); + sel.addRange(this.currentSearch.range); + scrollSelectionIntoView(this); + return true; + } + else + return false; + } + else + { + function findRow(node) { return node.nodeType == 1 ? node : node.parentNode; } + this.currentSearch = new TextSearch(this.panelNode, findRow); + row = this.currentSearch.find(text, reverse, Firebug.Search.isCaseSensitive(text)); + } + } + + if (row) + { + this.document.defaultView.getSelection().selectAllChildren(row); + scrollIntoCenterView(row, this.panelNode); + dispatch([Firebug.A11yModel], 'onCSSSearchMatchFound', [this, text, row]); + return true; + } + else + { + dispatch([Firebug.A11yModel], 'onCSSSearchMatchFound', [this, text, null]); + return false; + } + }, + + getSearchOptionsMenuItems: function() + { + return [ + Firebug.Search.searchOptionMenu("search.Case_Sensitive", "searchCaseSensitive"), + Firebug.Search.searchOptionMenu("search.Multiple_Files", "searchGlobal") + ]; + } +}); +/**/ +// ************************************************************************************************ + +function CSSElementPanel() {} + +CSSElementPanel.prototype = extend(Firebug.CSSStyleSheetPanel.prototype, +{ + template: domplate( + { + cascadedTag: + DIV({"class": "a11yCSSView", role : 'presentation'}, + DIV({role : 'list', 'aria-label' : $STR('aria.labels.style rules') }, + FOR("rule", "$rules", + TAG("$ruleTag", {rule: "$rule"}) + ) + ), + DIV({role : "list", 'aria-label' :$STR('aria.labels.inherited style rules')}, + FOR("section", "$inherited", + H1({"class": "cssInheritHeader groupHeader focusRow", role : 'listitem' }, + SPAN({"class": "cssInheritLabel"}, "$inheritLabel"), + TAG(FirebugReps.Element.shortTag, {object: "$section.element"}) + ), + DIV({role : 'group'}, + FOR("rule", "$section.rules", + TAG("$ruleTag", {rule: "$rule"}) + ) + ) + ) + ) + ), + + ruleTag: + isIE ? + // IE needs the sourceLink first, otherwise it will be rendered outside the panel + DIV({"class": "cssElementRuleContainer"}, + TAG(FirebugReps.SourceLink.tag, {object: "$rule.sourceLink"}), + TAG(CSSStyleRuleTag.tag, {rule: "$rule"}) + ) + : + // other browsers need the sourceLink last, otherwise it will cause an extra space + // before the rule representation + DIV({"class": "cssElementRuleContainer"}, + TAG(CSSStyleRuleTag.tag, {rule: "$rule"}), + TAG(FirebugReps.SourceLink.tag, {object: "$rule.sourceLink"}) + ) + }), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + updateCascadeView: function(element) + { + //dispatch([Firebug.A11yModel], 'onBeforeCSSRulesAdded', [this]); + var rules = [], sections = [], usedProps = {}; + this.getInheritedRules(element, sections, usedProps); + this.getElementRules(element, rules, usedProps); + + if (rules.length || sections.length) + { + var inheritLabel = "Inherited from"; // $STR("InheritedFrom"); + var result = this.template.cascadedTag.replace({rules: rules, inherited: sections, + inheritLabel: inheritLabel}, this.panelNode); + //dispatch([Firebug.A11yModel], 'onCSSRulesAdded', [this, result]); + } + else + { + var result = FirebugReps.Warning.tag.replace({object: "EmptyElementCSS"}, this.panelNode); + //dispatch([Firebug.A11yModel], 'onCSSRulesAdded', [this, result]); + } + + // TODO: xxxpedro remove when there the external resource problem is fixed + if (externalStyleSheetURLs.length > 0) + externalStyleSheetWarning.tag.append({ + object: "The results here may be inaccurate because some " + + "stylesheets could not be loaded due to access restrictions. ", + link: "more...", + href: "http://getfirebug.com/wiki/index.php/Firebug_Lite_FAQ#I_keep_seeing_.22This_element_has_no_style_rules.22" + }, this.panelNode); + }, + + getStylesheetURL: function(rule) + { + // if the parentStyleSheet.href is null, CSS std says its inline style. + // TODO: xxxpedro IE doesn't have rule.parentStyleSheet so we must fall back to the doc.location + if (rule && rule.parentStyleSheet && rule.parentStyleSheet.href) + return rule.parentStyleSheet.href; + else + return this.selection.ownerDocument.location.href; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getInheritedRules: function(element, sections, usedProps) + { + var parent = element.parentNode; + if (parent && parent.nodeType == 1) + { + this.getInheritedRules(parent, sections, usedProps); + + var rules = []; + this.getElementRules(parent, rules, usedProps, true); + + if (rules.length) + sections.splice(0, 0, {element: parent, rules: rules}); + } + }, + + getElementRules: function(element, rules, usedProps, inheritMode) + { + var inspectedRules, displayedRules = {}; + + // TODO: xxxpedro remove document specificity issue + //var eid = ElementCache(element); + //inspectedRules = ElementCSSRulesMap[eid]; + + inspectedRules = getElementCSSRules(element); + + if (inspectedRules) + { + for (var i = 0, length=inspectedRules.length; i < length; ++i) + { + var ruleId = inspectedRules[i]; + var ruleData = CSSRuleMap[ruleId]; + var rule = ruleData.rule; + + var ssid = ruleData.styleSheetId; + var parentStyleSheet = StyleSheetCache.get(ssid); + + var href = parentStyleSheet.externalURL ? parentStyleSheet.externalURL : parentStyleSheet.href; // Null means inline + + var instance = null; + //var instance = getInstanceForStyleSheet(rule.parentStyleSheet, element.ownerDocument); + + var isSystemSheet = false; + //var isSystemSheet = isSystemStyleSheet(rule.parentStyleSheet); + + if (!Firebug.showUserAgentCSS && isSystemSheet) // This removes user agent rules + continue; + + if (!href) + href = element.ownerDocument.location.href; // http://code.google.com/p/fbug/issues/detail?id=452 + + var props = this.getRuleProperties(this.context, rule, inheritMode); + if (inheritMode && !props.length) + continue; + + // + //var line = domUtils.getRuleLine(rule); + var line; + + var ruleId = rule.selectorText+"/"+line; + var sourceLink = new SourceLink(href, line, "css", rule, instance); + + this.markOverridenProps(props, usedProps, inheritMode); + + rules.splice(0, 0, {rule: rule, id: ruleId, + selector: ruleData.selector, sourceLink: sourceLink, + props: props, inherited: inheritMode, + isSystemSheet: isSystemSheet}); + } + } + + if (element.style) + this.getStyleProperties(element, rules, usedProps, inheritMode); + + if (FBTrace.DBG_CSS) + FBTrace.sysout("getElementRules "+rules.length+" rules for "+getElementXPath(element), rules); + }, + /* + getElementRules: function(element, rules, usedProps, inheritMode) + { + var inspectedRules, displayedRules = {}; + try + { + inspectedRules = domUtils ? domUtils.getCSSStyleRules(element) : null; + } catch (exc) {} + + if (inspectedRules) + { + for (var i = 0; i < inspectedRules.Count(); ++i) + { + var rule = QI(inspectedRules.GetElementAt(i), nsIDOMCSSStyleRule); + + var href = rule.parentStyleSheet.href; // Null means inline + + var instance = getInstanceForStyleSheet(rule.parentStyleSheet, element.ownerDocument); + + var isSystemSheet = isSystemStyleSheet(rule.parentStyleSheet); + if (!Firebug.showUserAgentCSS && isSystemSheet) // This removes user agent rules + continue; + if (!href) + href = element.ownerDocument.location.href; // http://code.google.com/p/fbug/issues/detail?id=452 + + var props = this.getRuleProperties(this.context, rule, inheritMode); + if (inheritMode && !props.length) + continue; + + var line = domUtils.getRuleLine(rule); + var ruleId = rule.selectorText+"/"+line; + var sourceLink = new SourceLink(href, line, "css", rule, instance); + + this.markOverridenProps(props, usedProps, inheritMode); + + rules.splice(0, 0, {rule: rule, id: ruleId, + selector: rule.selectorText, sourceLink: sourceLink, + props: props, inherited: inheritMode, + isSystemSheet: isSystemSheet}); + } + } + + if (element.style) + this.getStyleProperties(element, rules, usedProps, inheritMode); + + if (FBTrace.DBG_CSS) + FBTrace.sysout("getElementRules "+rules.length+" rules for "+getElementXPath(element), rules); + }, + /**/ + markOverridenProps: function(props, usedProps, inheritMode) + { + for (var i = 0; i < props.length; ++i) + { + var prop = props[i]; + if ( usedProps.hasOwnProperty(prop.name) ) + { + var deadProps = usedProps[prop.name]; // all previous occurrences of this property + for (var j = 0; j < deadProps.length; ++j) + { + var deadProp = deadProps[j]; + if (!deadProp.disabled && !deadProp.wasInherited && deadProp.important && !prop.important) + prop.overridden = true; // new occurrence overridden + else if (!prop.disabled) + deadProp.overridden = true; // previous occurrences overridden + } + } + else + usedProps[prop.name] = []; + + prop.wasInherited = inheritMode ? true : false; + usedProps[prop.name].push(prop); // all occurrences of a property seen so far, by name + } + }, + + getStyleProperties: function(element, rules, usedProps, inheritMode) + { + var props = this.parseCSSProps(element.style, inheritMode); + this.addOldProperties(this.context, getElementXPath(element), inheritMode, props); + + sortProperties(props); + this.markOverridenProps(props, usedProps, inheritMode); + + if (props.length) + rules.splice(0, 0, + {rule: element, id: getElementXPath(element), + selector: "element.style", props: props, inherited: inheritMode}); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "css", + title: "Style", + parentPanel: "HTML", + order: 0, + + initialize: function() + { + this.context = Firebug.chrome; // TODO: xxxpedro css2 + this.document = Firebug.chrome.document; // TODO: xxxpedro css2 + + Firebug.CSSStyleSheetPanel.prototype.initialize.apply(this, arguments); + + // TODO: xxxpedro css2 + var selection = ElementCache.get(FirebugChrome.selectedHTMLElementId); + if (selection) + this.select(selection, true); + + //this.updateCascadeView(document.getElementsByTagName("h1")[0]); + //this.updateCascadeView(document.getElementById("build")); + + /* + this.onStateChange = bindFixed(this.contentStateCheck, this); + this.onHoverChange = bindFixed(this.contentStateCheck, this, STATE_HOVER); + this.onActiveChange = bindFixed(this.contentStateCheck, this, STATE_ACTIVE); + /**/ + }, + + ishow: function(state) + { + }, + + watchWindow: function(win) + { + if (domUtils) + { + // Normally these would not be required, but in order to update after the state is set + // using the options menu we need to monitor these global events as well + var doc = win.document; + ///addEvent(doc, "mouseover", this.onHoverChange); + ///addEvent(doc, "mousedown", this.onActiveChange); + } + }, + unwatchWindow: function(win) + { + var doc = win.document; + ///removeEvent(doc, "mouseover", this.onHoverChange); + ///removeEvent(doc, "mousedown", this.onActiveChange); + + if (isAncestor(this.stateChangeEl, doc)) + { + this.removeStateChangeHandlers(); + } + }, + + supportsObject: function(object) + { + return object instanceof Element ? 1 : 0; + }, + + updateView: function(element) + { + this.updateCascadeView(element); + if (domUtils) + { + this.contentState = safeGetContentState(element); + this.addStateChangeHandlers(element); + } + }, + + updateSelection: function(element) + { + if ( !instanceOf(element , "Element") ) // html supports SourceLink + return; + + if (sothinkInstalled) + { + FirebugReps.Warning.tag.replace({object: "SothinkWarning"}, this.panelNode); + return; + } + + /* + if (!domUtils) + { + FirebugReps.Warning.tag.replace({object: "DOMInspectorWarning"}, this.panelNode); + return; + } + /**/ + + if (!element) + return; + + this.updateView(element); + }, + + updateOption: function(name, value) + { + if (name == "showUserAgentCSS" || name == "expandShorthandProps") + this.refresh(); + }, + + getOptionsMenuItems: function() + { + var ret = [ + {label: "Show User Agent CSS", type: "checkbox", checked: Firebug.showUserAgentCSS, + command: bindFixed(Firebug.togglePref, Firebug, "showUserAgentCSS") }, + {label: "Expand Shorthand Properties", type: "checkbox", checked: Firebug.expandShorthandProps, + command: bindFixed(Firebug.togglePref, Firebug, "expandShorthandProps") } + ]; + if (domUtils && this.selection) + { + var state = safeGetContentState(this.selection); + + ret.push("-"); + ret.push({label: ":active", type: "checkbox", checked: state & STATE_ACTIVE, + command: bindFixed(this.updateContentState, this, STATE_ACTIVE, state & STATE_ACTIVE)}); + ret.push({label: ":hover", type: "checkbox", checked: state & STATE_HOVER, + command: bindFixed(this.updateContentState, this, STATE_HOVER, state & STATE_HOVER)}); + } + return ret; + }, + + updateContentState: function(state, remove) + { + domUtils.setContentState(remove ? this.selection.ownerDocument.documentElement : this.selection, state); + this.refresh(); + }, + + addStateChangeHandlers: function(el) + { + this.removeStateChangeHandlers(); + + /* + addEvent(el, "focus", this.onStateChange); + addEvent(el, "blur", this.onStateChange); + addEvent(el, "mouseup", this.onStateChange); + addEvent(el, "mousedown", this.onStateChange); + addEvent(el, "mouseover", this.onStateChange); + addEvent(el, "mouseout", this.onStateChange); + /**/ + + this.stateChangeEl = el; + }, + + removeStateChangeHandlers: function() + { + var sel = this.stateChangeEl; + if (sel) + { + /* + removeEvent(sel, "focus", this.onStateChange); + removeEvent(sel, "blur", this.onStateChange); + removeEvent(sel, "mouseup", this.onStateChange); + removeEvent(sel, "mousedown", this.onStateChange); + removeEvent(sel, "mouseover", this.onStateChange); + removeEvent(sel, "mouseout", this.onStateChange); + /**/ + } + }, + + contentStateCheck: function(state) + { + if (!state || this.contentState & state) + { + var timeoutRunner = bindFixed(function() + { + var newState = safeGetContentState(this.selection); + if (newState != this.contentState) + { + this.context.invalidatePanels(this.name); + } + }, this); + + // Delay exec until after the event has processed and the state has been updated + setTimeout(timeoutRunner, 0); + } + } +}); + +function safeGetContentState(selection) +{ + try + { + return domUtils.getContentState(selection); + } + catch (e) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("css.safeGetContentState; EXCEPTION", e); + } +} + +// ************************************************************************************************ + +function CSSComputedElementPanel() {} + +CSSComputedElementPanel.prototype = extend(CSSElementPanel.prototype, +{ + template: domplate( + { + computedTag: + DIV({"class": "a11yCSSView", role : "list", "aria-label" : $STR('aria.labels.computed styles')}, + FOR("group", "$groups", + H1({"class": "cssInheritHeader groupHeader focusRow", role : "listitem"}, + SPAN({"class": "cssInheritLabel"}, "$group.title") + ), + TABLE({width: "100%", role : 'group'}, + TBODY({role : 'presentation'}, + FOR("prop", "$group.props", + TR({"class": 'focusRow computedStyleRow', role : 'listitem'}, + TD({"class": "stylePropName", role : 'presentation'}, "$prop.name"), + TD({"class": "stylePropValue", role : 'presentation'}, "$prop.value") + ) + ) + ) + ) + ) + ) + }), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + updateComputedView: function(element) + { + var win = isIE ? + element.ownerDocument.parentWindow : + element.ownerDocument.defaultView; + + var style = isIE ? + element.currentStyle : + win.getComputedStyle(element, ""); + + var groups = []; + + for (var groupName in styleGroups) + { + // TODO: xxxpedro i18n $STR + //var title = $STR("StyleGroup-" + groupName); + var title = styleGroupTitles[groupName]; + var group = {title: title, props: []}; + groups.push(group); + + var props = styleGroups[groupName]; + for (var i = 0; i < props.length; ++i) + { + var propName = props[i]; + var propValue = style.getPropertyValue ? + style.getPropertyValue(propName) : + ""+style[toCamelCase(propName)]; + + if (propValue === undefined || propValue === null) + continue; + + propValue = stripUnits(rgbToHex(propValue)); + if (propValue) + group.props.push({name: propName, value: propValue}); + } + } + + var result = this.template.computedTag.replace({groups: groups}, this.panelNode); + //dispatch([Firebug.A11yModel], 'onCSSRulesAdded', [this, result]); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "computed", + title: "Computed", + parentPanel: "HTML", + order: 1, + + updateView: function(element) + { + this.updateComputedView(element); + }, + + getOptionsMenuItems: function() + { + return [ + {label: "Refresh", command: bind(this.refresh, this) } + ]; + } +}); + +// ************************************************************************************************ +// CSSEditor + +function CSSEditor(doc) +{ + this.initializeInline(doc); +} + +CSSEditor.prototype = domplate(Firebug.InlineEditor.prototype, +{ + insertNewRow: function(target, insertWhere) + { + var rule = Firebug.getRepObject(target); + var emptyProp = + { + // TODO: xxxpedro - uses charCode(255) to force the element being rendered, + // allowing webkit to get the correct position of the property name "span", + // when inserting a new CSS rule? + name: "", + value: "", + important: "" + }; + + if (insertWhere == "before") + return CSSPropTag.tag.insertBefore({prop: emptyProp, rule: rule}, target); + else + return CSSPropTag.tag.insertAfter({prop: emptyProp, rule: rule}, target); + }, + + saveEdit: function(target, value, previousValue) + { + // We need to check the value first in order to avoid a problem in IE8 + // See Issue 3038: Empty (null) styles when adding CSS styles in Firebug Lite + if (!value) return; + + target.innerHTML = escapeForCss(value); + + var row = getAncestorByClass(target, "cssProp"); + if (hasClass(row, "disabledStyle")) + toggleClass(row, "disabledStyle"); + + var rule = Firebug.getRepObject(target); + + if (hasClass(target, "cssPropName")) + { + if (value && previousValue != value) // name of property has changed. + { + var propValue = getChildByClass(row, "cssPropValue")[textContent]; + var parsedValue = parsePriority(propValue); + + if (propValue && propValue != "undefined") { + if (FBTrace.DBG_CSS) + FBTrace.sysout("CSSEditor.saveEdit : "+previousValue+"->"+value+" = "+propValue+"\n"); + if (previousValue) + Firebug.CSSModule.removeProperty(rule, previousValue); + Firebug.CSSModule.setProperty(rule, value, parsedValue.value, parsedValue.priority); + } + } + else if (!value) // name of the property has been deleted, so remove the property. + Firebug.CSSModule.removeProperty(rule, previousValue); + } + else if (getAncestorByClass(target, "cssPropValue")) + { + var propName = getChildByClass(row, "cssPropName")[textContent]; + var propValue = getChildByClass(row, "cssPropValue")[textContent]; + + if (FBTrace.DBG_CSS) + { + FBTrace.sysout("CSSEditor.saveEdit propName=propValue: "+propName +" = "+propValue+"\n"); + // FBTrace.sysout("CSSEditor.saveEdit BEFORE style:",style); + } + + if (value && value != "null") + { + var parsedValue = parsePriority(value); + Firebug.CSSModule.setProperty(rule, propName, parsedValue.value, parsedValue.priority); + } + else if (previousValue && previousValue != "null") + Firebug.CSSModule.removeProperty(rule, propName); + } + + this.panel.markChange(this.panel.name == "stylesheet"); + }, + + advanceToNext: function(target, charCode) + { + if (charCode == 58 /*":"*/ && hasClass(target, "cssPropName")) + return true; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getAutoCompleteRange: function(value, offset) + { + if (hasClass(this.target, "cssPropName")) + return {start: 0, end: value.length-1}; + else + return parseCSSValue(value, offset); + }, + + getAutoCompleteList: function(preExpr, expr, postExpr) + { + if (hasClass(this.target, "cssPropName")) + { + return getCSSPropertyNames(); + } + else + { + var row = getAncestorByClass(this.target, "cssProp"); + var propName = getChildByClass(row, "cssPropName")[textContent]; + return getCSSKeywordsByProperty(propName); + } + } +}); + +//************************************************************************************************ +//CSSRuleEditor + +function CSSRuleEditor(doc) +{ + this.initializeInline(doc); + this.completeAsYouType = false; +} +CSSRuleEditor.uniquifier = 0; +CSSRuleEditor.prototype = domplate(Firebug.InlineEditor.prototype, +{ + insertNewRow: function(target, insertWhere) + { + var emptyRule = { + selector: "", + id: "", + props: [], + isSelectorEditable: true + }; + + if (insertWhere == "before") + return CSSStyleRuleTag.tag.insertBefore({rule: emptyRule}, target); + else + return CSSStyleRuleTag.tag.insertAfter({rule: emptyRule}, target); + }, + + saveEdit: function(target, value, previousValue) + { + if (FBTrace.DBG_CSS) + FBTrace.sysout("CSSRuleEditor.saveEdit: '" + value + "' '" + previousValue + "'", target); + + target.innerHTML = escapeForCss(value); + + if (value === previousValue) return; + + var row = getAncestorByClass(target, "cssRule"); + var styleSheet = this.panel.location; + styleSheet = styleSheet.editStyleSheet ? styleSheet.editStyleSheet.sheet : styleSheet; + + var cssRules = styleSheet.cssRules; + var rule = Firebug.getRepObject(target), oldRule = rule; + var ruleIndex = cssRules.length; + if (rule || Firebug.getRepObject(row.nextSibling)) + { + var searchRule = rule || Firebug.getRepObject(row.nextSibling); + for (ruleIndex=0; ruleIndex b.name ? 1 : -1; + }); +} + +function getTopmostRuleLine(panelNode) +{ + for (var child = panelNode.firstChild; child; child = child.nextSibling) + { + if (child.offsetTop+child.offsetHeight > panelNode.scrollTop) + { + var rule = child.repObject; + if (rule) + return { + line: domUtils.getRuleLine(rule), + offset: panelNode.scrollTop-child.offsetTop + }; + } + } + return 0; +} + +function getStyleSheetCSS(sheet, context) +{ + if (sheet.ownerNode instanceof HTMLStyleElement) + return sheet.ownerNode.innerHTML; + else + return context.sourceCache.load(sheet.href).join(""); +} + +function getStyleSheetOwnerNode(sheet) { + for (; sheet && !sheet.ownerNode; sheet = sheet.parentStyleSheet); + + return sheet.ownerNode; +} + +function scrollSelectionIntoView(panel) +{ + var selCon = getSelectionController(panel); + selCon.scrollSelectionIntoView( + nsISelectionController.SELECTION_NORMAL, + nsISelectionController.SELECTION_FOCUS_REGION, true); +} + +function getSelectionController(panel) +{ + var browser = Firebug.chrome.getPanelBrowser(panel); + return browser.docShell.QueryInterface(nsIInterfaceRequestor) + .getInterface(nsISelectionDisplay) + .QueryInterface(nsISelectionController); +} + +// ************************************************************************************************ + +Firebug.registerModule(Firebug.CSSModule); +Firebug.registerPanel(Firebug.CSSStyleSheetPanel); +Firebug.registerPanel(CSSElementPanel); +Firebug.registerPanel(CSSComputedElementPanel); + +// ************************************************************************************************ + +}}); + + +/* 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 (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; +}; + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var ElementCache = Firebug.Lite.Cache.Element; + +var insertSliceSize = 18; +var insertInterval = 40; + +var ignoreVars = +{ + "__firebug__": 1, + "eval": 1, + + // We are forced to ignore Java-related variables, because + // trying to access them causes browser freeze + "java": 1, + "sun": 1, + "Packages": 1, + "JavaArray": 1, + "JavaMember": 1, + "JavaObject": 1, + "JavaClass": 1, + "JavaPackage": 1, + "_firebug": 1, + "_FirebugConsole": 1, + "_FirebugCommandLine": 1 +}; + +if (Firebug.ignoreFirebugElements) + ignoreVars[Firebug.Lite.Cache.ID] = 1; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var memberPanelRep = + isIE6 ? + {"class": "memberLabel $member.type\\Label", href: "javacript:void(0)"} + : + {"class": "memberLabel $member.type\\Label"}; + +var RowTag = + TR({"class": "memberRow $member.open $member.type\\Row", $hasChildren: "$member.hasChildren", role : 'presentation', + level: "$member.level"}, + TD({"class": "memberLabelCell", style: "padding-left: $member.indent\\px", role : 'presentation'}, + A(memberPanelRep, + SPAN({}, "$member.name") + ) + ), + TD({"class": "memberValueCell", role : 'presentation'}, + TAG("$member.tag", {object: "$member.value"}) + ) + ); + +var WatchRowTag = + TR({"class": "watchNewRow", level: 0}, + TD({"class": "watchEditCell", colspan: 2}, + DIV({"class": "watchEditBox a11yFocusNoTab", role: "button", 'tabindex' : '0', + 'aria-label' : $STR('press enter to add new watch expression')}, + $STR("NewWatch") + ) + ) + ); + +var SizerRow = + TR({role : 'presentation'}, + TD({width: "30%"}), + TD({width: "70%"}) + ); + +var domTableClass = isIElt8 ? "domTable domTableIE" : "domTable"; +var DirTablePlate = domplate(Firebug.Rep, +{ + tag: + TABLE({"class": domTableClass, cellpadding: 0, cellspacing: 0, onclick: "$onClick", role :"tree"}, + TBODY({role: 'presentation'}, + SizerRow, + FOR("member", "$object|memberIterator", RowTag) + ) + ), + + watchTag: + TABLE({"class": domTableClass, cellpadding: 0, cellspacing: 0, + _toggles: "$toggles", _domPanel: "$domPanel", onclick: "$onClick", role : 'tree'}, + TBODY({role : 'presentation'}, + SizerRow, + WatchRowTag + ) + ), + + tableTag: + TABLE({"class": domTableClass, cellpadding: 0, cellspacing: 0, + _toggles: "$toggles", _domPanel: "$domPanel", onclick: "$onClick", role : 'tree'}, + TBODY({role : 'presentation'}, + SizerRow + ) + ), + + rowTag: + FOR("member", "$members", RowTag), + + memberIterator: function(object, level) + { + return getMembers(object, level); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + onClick: function(event) + { + if (!isLeftClick(event)) + return; + + var target = event.target || event.srcElement; + + var row = getAncestorByClass(target, "memberRow"); + var label = getAncestorByClass(target, "memberLabel"); + if (label && hasClass(row, "hasChildren")) + { + var row = label.parentNode.parentNode; + this.toggleRow(row); + } + else + { + var object = Firebug.getRepObject(target); + if (typeof(object) == "function") + { + Firebug.chrome.select(object, "script"); + cancelEvent(event); + } + else if (event.detail == 2 && !object) + { + var panel = row.parentNode.parentNode.domPanel; + if (panel) + { + var rowValue = panel.getRowPropertyValue(row); + if (typeof(rowValue) == "boolean") + panel.setPropertyValue(row, !rowValue); + else + panel.editProperty(row); + + cancelEvent(event); + } + } + } + + return false; + }, + + toggleRow: function(row) + { + var level = parseInt(row.getAttribute("level")); + var toggles = row.parentNode.parentNode.toggles; + + if (hasClass(row, "opened")) + { + removeClass(row, "opened"); + + if (toggles) + { + var path = getPath(row); + + // Remove the path from the toggle tree + for (var i = 0; i < path.length; ++i) + { + if (i == path.length-1) + delete toggles[path[i]]; + else + toggles = toggles[path[i]]; + } + } + + var rowTag = this.rowTag; + var tbody = row.parentNode; + + setTimeout(function() + { + for (var firstRow = row.nextSibling; firstRow; firstRow = row.nextSibling) + { + if (parseInt(firstRow.getAttribute("level")) <= level) + break; + + tbody.removeChild(firstRow); + } + }, row.insertTimeout ? row.insertTimeout : 0); + } + else + { + setClass(row, "opened"); + + if (toggles) + { + var path = getPath(row); + + // Mark the path in the toggle tree + for (var i = 0; i < path.length; ++i) + { + var name = path[i]; + if (toggles.hasOwnProperty(name)) + toggles = toggles[name]; + else + toggles = toggles[name] = {}; + } + } + + var value = row.lastChild.firstChild.repObject; + var members = getMembers(value, level+1); + + var rowTag = this.rowTag; + var lastRow = row; + + var delay = 0; + //var setSize = members.length; + //var rowCount = 1; + while (members.length) + { + with({slice: members.splice(0, insertSliceSize), isLast: !members.length}) + { + setTimeout(function() + { + if (lastRow.parentNode) + { + var result = rowTag.insertRows({members: slice}, lastRow); + lastRow = result[1]; + //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [null, result, rowCount, setSize]); + //rowCount += insertSliceSize; + } + if (isLast) + row.removeAttribute("insertTimeout"); + }, delay); + } + + delay += insertInterval; + } + + row.insertTimeout = delay; + } + } +}); + + + +// ************************************************************************************************ + +Firebug.DOMBasePanel = function() {} + +Firebug.DOMBasePanel.prototype = extend(Firebug.Panel, +{ + tag: DirTablePlate.tableTag, + + getRealObject: function(object) + { + // TODO: Move this to some global location + // TODO: Unwrapping should be centralized rather than sprinkling it around ad hoc. + // TODO: We might be able to make this check more authoritative with QueryInterface. + if (!object) return object; + if (object.wrappedJSObject) return object.wrappedJSObject; + return object; + }, + + rebuild: function(update, scrollTop) + { + //dispatch([Firebug.A11yModel], 'onBeforeDomUpdateSelection', [this]); + var members = getMembers(this.selection); + expandMembers(members, this.toggles, 0, 0); + + this.showMembers(members, update, scrollTop); + + //TODO: xxxpedro statusbar + if (!this.parentPanel) + updateStatusBar(this); + }, + + showMembers: function(members, update, scrollTop) + { + // If we are still in the midst of inserting rows, cancel all pending + // insertions here - this is a big speedup when stepping in the debugger + if (this.timeouts) + { + for (var i = 0; i < this.timeouts.length; ++i) + this.context.clearTimeout(this.timeouts[i]); + delete this.timeouts; + } + + if (!members.length) + return this.showEmptyMembers(); + + var panelNode = this.panelNode; + var priorScrollTop = scrollTop == undefined ? panelNode.scrollTop : scrollTop; + + // If we are asked to "update" the current view, then build the new table + // offscreen and swap it in when it's done + var offscreen = update && panelNode.firstChild; + var dest = offscreen ? panelNode.ownerDocument : panelNode; + + var table = this.tag.replace({domPanel: this, toggles: this.toggles}, dest); + var tbody = table.lastChild; + var rowTag = DirTablePlate.rowTag; + + // Insert the first slice immediately + //var slice = members.splice(0, insertSliceSize); + //var result = rowTag.insertRows({members: slice}, tbody.lastChild); + + //var setSize = members.length; + //var rowCount = 1; + + var panel = this; + var result; + + //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [panel, result, rowCount, setSize]); + var timeouts = []; + + var delay = 0; + + // enable to measure rendering performance + var renderStart = new Date().getTime(); + while (members.length) + { + with({slice: members.splice(0, insertSliceSize), isLast: !members.length}) + { + timeouts.push(this.context.setTimeout(function() + { + // TODO: xxxpedro can this be a timing error related to the + // "iteration number" approach insted of "duration time"? + // avoid error in IE8 + if (!tbody.lastChild) return; + + result = rowTag.insertRows({members: slice}, tbody.lastChild); + + //rowCount += insertSliceSize; + //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [panel, result, rowCount, setSize]); + + if ((panelNode.scrollHeight+panelNode.offsetHeight) >= priorScrollTop) + panelNode.scrollTop = priorScrollTop; + + + // enable to measure rendering performance + //if (isLast) alert(new Date().getTime() - renderStart + "ms"); + + + }, delay)); + + delay += insertInterval; + } + } + + if (offscreen) + { + timeouts.push(this.context.setTimeout(function() + { + if (panelNode.firstChild) + panelNode.replaceChild(table, panelNode.firstChild); + else + panelNode.appendChild(table); + + // Scroll back to where we were before + panelNode.scrollTop = priorScrollTop; + }, delay)); + } + else + { + timeouts.push(this.context.setTimeout(function() + { + panelNode.scrollTop = scrollTop == undefined ? 0 : scrollTop; + }, delay)); + } + this.timeouts = timeouts; + }, + + /* + // new + showMembers: function(members, update, scrollTop) + { + // If we are still in the midst of inserting rows, cancel all pending + // insertions here - this is a big speedup when stepping in the debugger + if (this.timeouts) + { + for (var i = 0; i < this.timeouts.length; ++i) + this.context.clearTimeout(this.timeouts[i]); + delete this.timeouts; + } + + if (!members.length) + return this.showEmptyMembers(); + + var panelNode = this.panelNode; + var priorScrollTop = scrollTop == undefined ? panelNode.scrollTop : scrollTop; + + // If we are asked to "update" the current view, then build the new table + // offscreen and swap it in when it's done + var offscreen = update && panelNode.firstChild; + var dest = offscreen ? panelNode.ownerDocument : panelNode; + + var table = this.tag.replace({domPanel: this, toggles: this.toggles}, dest); + var tbody = table.lastChild; + var rowTag = DirTablePlate.rowTag; + + // Insert the first slice immediately + //var slice = members.splice(0, insertSliceSize); + //var result = rowTag.insertRows({members: slice}, tbody.lastChild); + + //var setSize = members.length; + //var rowCount = 1; + + var panel = this; + var result; + + //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [panel, result, rowCount, setSize]); + var timeouts = []; + + var delay = 0; + var _insertSliceSize = insertSliceSize; + var _insertInterval = insertInterval; + + // enable to measure rendering performance + var renderStart = new Date().getTime(); + var lastSkip = renderStart, now; + + while (members.length) + { + with({slice: members.splice(0, _insertSliceSize), isLast: !members.length}) + { + var _tbody = tbody; + var _rowTag = rowTag; + var _panelNode = panelNode; + var _priorScrollTop = priorScrollTop; + + timeouts.push(this.context.setTimeout(function() + { + // TODO: xxxpedro can this be a timing error related to the + // "iteration number" approach insted of "duration time"? + // avoid error in IE8 + if (!_tbody.lastChild) return; + + result = _rowTag.insertRows({members: slice}, _tbody.lastChild); + + //rowCount += _insertSliceSize; + //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [panel, result, rowCount, setSize]); + + if ((_panelNode.scrollHeight + _panelNode.offsetHeight) >= _priorScrollTop) + _panelNode.scrollTop = _priorScrollTop; + + + // enable to measure rendering performance + //alert("gap: " + (new Date().getTime() - lastSkip)); + //lastSkip = new Date().getTime(); + + //if (isLast) alert("new: " + (new Date().getTime() - renderStart) + "ms"); + + }, delay)); + + delay += _insertInterval; + } + } + + if (offscreen) + { + timeouts.push(this.context.setTimeout(function() + { + if (panelNode.firstChild) + panelNode.replaceChild(table, panelNode.firstChild); + else + panelNode.appendChild(table); + + // Scroll back to where we were before + panelNode.scrollTop = priorScrollTop; + }, delay)); + } + else + { + timeouts.push(this.context.setTimeout(function() + { + panelNode.scrollTop = scrollTop == undefined ? 0 : scrollTop; + }, delay)); + } + this.timeouts = timeouts; + }, + /**/ + + showEmptyMembers: function() + { + FirebugReps.Warning.tag.replace({object: "NoMembersWarning"}, this.panelNode); + }, + + findPathObject: function(object) + { + var pathIndex = -1; + for (var i = 0; i < this.objectPath.length; ++i) + { + // IE needs === instead of == or otherwise some objects will + // be considered equal to different objects, returning the + // wrong index of the objectPath array + if (this.getPathObject(i) === object) + return i; + } + + return -1; + }, + + getPathObject: function(index) + { + var object = this.objectPath[index]; + + if (object instanceof Property) + return object.getObject(); + else + return object; + }, + + getRowObject: function(row) + { + var object = getRowOwnerObject(row); + return object ? object : this.selection; + }, + + getRowPropertyValue: function(row) + { + var object = this.getRowObject(row); + object = this.getRealObject(object); + if (object) + { + var propName = getRowName(row); + + if (object instanceof jsdIStackFrame) + return Firebug.Debugger.evaluate(propName, this.context); + else + return object[propName]; + } + }, + /* + copyProperty: function(row) + { + var value = this.getRowPropertyValue(row); + copyToClipboard(value); + }, + + editProperty: function(row, editValue) + { + if (hasClass(row, "watchNewRow")) + { + if (this.context.stopped) + Firebug.Editor.startEditing(row, ""); + else if (Firebug.Console.isAlwaysEnabled()) // not stopped in debugger, need command line + { + if (Firebug.CommandLine.onCommandLineFocus()) + Firebug.Editor.startEditing(row, ""); + else + row.innerHTML = $STR("warning.Command line blocked?"); + } + else + row.innerHTML = $STR("warning.Console must be enabled"); + } + else if (hasClass(row, "watchRow")) + Firebug.Editor.startEditing(row, getRowName(row)); + else + { + var object = this.getRowObject(row); + this.context.thisValue = object; + + if (!editValue) + { + var propValue = this.getRowPropertyValue(row); + + var type = typeof(propValue); + if (type == "undefined" || type == "number" || type == "boolean") + editValue = propValue; + else if (type == "string") + editValue = "\"" + escapeJS(propValue) + "\""; + else if (propValue == null) + editValue = "null"; + else if (object instanceof Window || object instanceof jsdIStackFrame) + editValue = getRowName(row); + else + editValue = "this." + getRowName(row); + } + + + Firebug.Editor.startEditing(row, editValue); + } + }, + + deleteProperty: function(row) + { + if (hasClass(row, "watchRow")) + this.deleteWatch(row); + else + { + var object = getRowOwnerObject(row); + if (!object) + object = this.selection; + object = this.getRealObject(object); + + if (object) + { + var name = getRowName(row); + try + { + delete object[name]; + } + catch (exc) + { + return; + } + + this.rebuild(true); + this.markChange(); + } + } + }, + + setPropertyValue: function(row, value) // value must be string + { + if(FBTrace.DBG_DOM) + { + FBTrace.sysout("row: "+row); + FBTrace.sysout("value: "+value+" type "+typeof(value), value); + } + + var name = getRowName(row); + if (name == "this") + return; + + var object = this.getRowObject(row); + object = this.getRealObject(object); + if (object && !(object instanceof jsdIStackFrame)) + { + // unwrappedJSObject.property = unwrappedJSObject + Firebug.CommandLine.evaluate(value, this.context, object, this.context.getGlobalScope(), + function success(result, context) + { + if (FBTrace.DBG_DOM) + FBTrace.sysout("setPropertyValue evaluate success object["+name+"]="+result+" type "+typeof(result), result); + object[name] = result; + }, + function failed(exc, context) + { + try + { + if (FBTrace.DBG_DOM) + FBTrace.sysout("setPropertyValue evaluate failed with exc:"+exc+" object["+name+"]="+value+" type "+typeof(value), exc); + // If the value doesn't parse, then just store it as a string. Some users will + // not realize they're supposed to enter a JavaScript expression and just type + // literal text + object[name] = String(value); // unwrappedJSobject.property = string + } + catch (exc) + { + return; + } + } + ); + } + else if (this.context.stopped) + { + try + { + Firebug.CommandLine.evaluate(name+"="+value, this.context); + } + catch (exc) + { + try + { + // See catch block above... + object[name] = String(value); // unwrappedJSobject.property = string + } + catch (exc) + { + return; + } + } + } + + this.rebuild(true); + this.markChange(); + }, + + highlightRow: function(row) + { + if (this.highlightedRow) + cancelClassTimed(this.highlightedRow, "jumpHighlight", this.context); + + this.highlightedRow = row; + + if (row) + setClassTimed(row, "jumpHighlight", this.context); + },/**/ + + onMouseMove: function(event) + { + var target = event.srcElement || event.target; + + var object = getAncestorByClass(target, "objectLink-element"); + object = object ? object.repObject : null; + + if(object && instanceOf(object, "Element") && object.nodeType == 1) + { + if(object != lastHighlightedObject) + { + Firebug.Inspector.drawBoxModel(object); + object = lastHighlightedObject; + } + } + else + Firebug.Inspector.hideBoxModel(); + + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + create: function() + { + // TODO: xxxpedro + this.context = Firebug.browser; + + this.objectPath = []; + this.propertyPath = []; + this.viewPath = []; + this.pathIndex = -1; + this.toggles = {}; + + Firebug.Panel.create.apply(this, arguments); + + this.panelNode.style.padding = "0 1px"; + }, + + initialize: function(){ + Firebug.Panel.initialize.apply(this, arguments); + + addEvent(this.panelNode, "mousemove", this.onMouseMove); + }, + + shutdown: function() + { + removeEvent(this.panelNode, "mousemove", this.onMouseMove); + + Firebug.Panel.shutdown.apply(this, arguments); + }, + + /* + destroy: function(state) + { + var view = this.viewPath[this.pathIndex]; + if (view && this.panelNode.scrollTop) + view.scrollTop = this.panelNode.scrollTop; + + if (this.pathIndex) + state.pathIndex = this.pathIndex; + if (this.viewPath) + state.viewPath = this.viewPath; + if (this.propertyPath) + state.propertyPath = this.propertyPath; + + if (this.propertyPath.length > 0 && !this.propertyPath[1]) + state.firstSelection = persistObject(this.getPathObject(1), this.context); + + Firebug.Panel.destroy.apply(this, arguments); + }, + /**/ + + ishow: function(state) + { + if (this.context.loaded && !this.selection) + { + if (!state) + { + this.select(null); + return; + } + if (state.viewPath) + this.viewPath = state.viewPath; + if (state.propertyPath) + this.propertyPath = state.propertyPath; + + var defaultObject = this.getDefaultSelection(this.context); + var selectObject = defaultObject; + + if (state.firstSelection) + { + var restored = state.firstSelection(this.context); + if (restored) + { + selectObject = restored; + this.objectPath = [defaultObject, restored]; + } + else + this.objectPath = [defaultObject]; + } + else + this.objectPath = [defaultObject]; + + if (this.propertyPath.length > 1) + { + for (var i = 1; i < this.propertyPath.length; ++i) + { + var name = this.propertyPath[i]; + if (!name) + continue; + + var object = selectObject; + try + { + selectObject = object[name]; + } + catch (exc) + { + selectObject = null; + } + + if (selectObject) + { + this.objectPath.push(new Property(object, name)); + } + else + { + // If we can't access a property, just stop + this.viewPath.splice(i); + this.propertyPath.splice(i); + this.objectPath.splice(i); + selectObject = this.getPathObject(this.objectPath.length-1); + break; + } + } + } + + var selection = state.pathIndex <= this.objectPath.length-1 + ? this.getPathObject(state.pathIndex) + : this.getPathObject(this.objectPath.length-1); + + this.select(selection); + } + }, + /* + hide: function() + { + var view = this.viewPath[this.pathIndex]; + if (view && this.panelNode.scrollTop) + view.scrollTop = this.panelNode.scrollTop; + }, + /**/ + + supportsObject: function(object) + { + if (object == null) + return 1000; + + if (typeof(object) == "undefined") + return 1000; + else if (object instanceof SourceLink) + return 0; + else + return 1; // just agree to support everything but not agressively. + }, + + refresh: function() + { + this.rebuild(true); + }, + + updateSelection: function(object) + { + var previousIndex = this.pathIndex; + var previousView = previousIndex == -1 ? null : this.viewPath[previousIndex]; + + var newPath = this.pathToAppend; + delete this.pathToAppend; + + var pathIndex = this.findPathObject(object); + if (newPath || pathIndex == -1) + { + this.toggles = {}; + + if (newPath) + { + // Remove everything after the point where we are inserting, so we + // essentially replace it with the new path + if (previousView) + { + if (this.panelNode.scrollTop) + previousView.scrollTop = this.panelNode.scrollTop; + + var start = previousIndex + 1, + // Opera needs the length argument in splice(), otherwise + // it will consider that only one element should be removed + length = this.objectPath.length - start; + + this.objectPath.splice(start, length); + this.propertyPath.splice(start, length); + this.viewPath.splice(start, length); + } + + var value = this.getPathObject(previousIndex); + if (!value) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("dom.updateSelection no pathObject for "+previousIndex+"\n"); + return; + } + + for (var i = 0, length = newPath.length; i < length; ++i) + { + var name = newPath[i]; + var object = value; + try + { + value = value[name]; + } + catch(exc) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("dom.updateSelection FAILS at path_i="+i+" for name:"+name+"\n"); + return; + } + + ++this.pathIndex; + this.objectPath.push(new Property(object, name)); + this.propertyPath.push(name); + this.viewPath.push({toggles: this.toggles, scrollTop: 0}); + } + } + else + { + this.toggles = {}; + + var win = Firebug.browser.window; + //var win = this.context.getGlobalScope(); + if (object === win) + { + this.pathIndex = 0; + this.objectPath = [win]; + this.propertyPath = [null]; + this.viewPath = [{toggles: this.toggles, scrollTop: 0}]; + } + else + { + this.pathIndex = 1; + this.objectPath = [win, object]; + this.propertyPath = [null, null]; + this.viewPath = [ + {toggles: {}, scrollTop: 0}, + {toggles: this.toggles, scrollTop: 0} + ]; + } + } + + this.panelNode.scrollTop = 0; + this.rebuild(); + } + else + { + this.pathIndex = pathIndex; + + var view = this.viewPath[pathIndex]; + this.toggles = view.toggles; + + // Persist the current scroll location + if (previousView && this.panelNode.scrollTop) + previousView.scrollTop = this.panelNode.scrollTop; + + this.rebuild(false, view.scrollTop); + } + }, + + getObjectPath: function(object) + { + return this.objectPath; + }, + + getDefaultSelection: function() + { + return Firebug.browser.window; + //return this.context.getGlobalScope(); + }/*, + + updateOption: function(name, value) + { + const optionMap = {showUserProps: 1, showUserFuncs: 1, showDOMProps: 1, + showDOMFuncs: 1, showDOMConstants: 1}; + if ( optionMap.hasOwnProperty(name) ) + this.rebuild(true); + }, + + getOptionsMenuItems: function() + { + return [ + optionMenu("ShowUserProps", "showUserProps"), + optionMenu("ShowUserFuncs", "showUserFuncs"), + optionMenu("ShowDOMProps", "showDOMProps"), + optionMenu("ShowDOMFuncs", "showDOMFuncs"), + optionMenu("ShowDOMConstants", "showDOMConstants"), + "-", + {label: "Refresh", command: bindFixed(this.rebuild, this, true) } + ]; + }, + + getContextMenuItems: function(object, target) + { + var row = getAncestorByClass(target, "memberRow"); + + var items = []; + + if (row) + { + var rowName = getRowName(row); + var rowObject = this.getRowObject(row); + var rowValue = this.getRowPropertyValue(row); + + var isWatch = hasClass(row, "watchRow"); + var isStackFrame = rowObject instanceof jsdIStackFrame; + + if (typeof(rowValue) == "string" || typeof(rowValue) == "number") + { + // Functions already have a copy item in their context menu + items.push( + "-", + {label: "CopyValue", + command: bindFixed(this.copyProperty, this, row) } + ); + } + + items.push( + "-", + {label: isWatch ? "EditWatch" : (isStackFrame ? "EditVariable" : "EditProperty"), + command: bindFixed(this.editProperty, this, row) } + ); + + if (isWatch || (!isStackFrame && !isDOMMember(rowObject, rowName))) + { + items.push( + {label: isWatch ? "DeleteWatch" : "DeleteProperty", + command: bindFixed(this.deleteProperty, this, row) } + ); + } + } + + items.push( + "-", + {label: "Refresh", command: bindFixed(this.rebuild, this, true) } + ); + + return items; + }, + + getEditor: function(target, value) + { + if (!this.editor) + this.editor = new DOMEditor(this.document); + + return this.editor; + }/**/ +}); + +// ************************************************************************************************ + +// TODO: xxxpedro statusbar +var updateStatusBar = function(panel) +{ + var path = panel.propertyPath; + var index = panel.pathIndex; + + var r = []; + + for (var i=0, l=path.length; i'); + r.push(i==0 ? "window" : path[i] || "Object"); + r.push('
      '); + + if(i < l-1) + r.push('>'); + } + panel.statusBarNode.innerHTML = r.join(""); +}; + + +var DOMMainPanel = Firebug.DOMPanel = function () {}; + +Firebug.DOMPanel.DirTable = DirTablePlate; + +DOMMainPanel.prototype = extend(Firebug.DOMBasePanel.prototype, +{ + onClickStatusBar: function(event) + { + var target = event.srcElement || event.target; + var element = getAncestorByClass(target, "fbHover"); + + if(element) + { + var pathIndex = element.getAttribute("pathIndex"); + + if(pathIndex) + { + this.select(this.getPathObject(pathIndex)); + } + } + }, + + selectRow: function(row, target) + { + if (!target) + target = row.lastChild.firstChild; + + if (!target || !target.repObject) + return; + + this.pathToAppend = getPath(row); + + // If the object is inside an array, look up its index + var valueBox = row.lastChild.firstChild; + if (hasClass(valueBox, "objectBox-array")) + { + var arrayIndex = FirebugReps.Arr.getItemIndex(target); + this.pathToAppend.push(arrayIndex); + } + + // Make sure we get a fresh status path for the object, since otherwise + // it might find the object in the existing path and not refresh it + //Firebug.chrome.clearStatusPath(); + + this.select(target.repObject, true); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + onClick: function(event) + { + var target = event.srcElement || event.target; + var repNode = Firebug.getRepNode(target); + if (repNode) + { + var row = getAncestorByClass(target, "memberRow"); + if (row) + { + this.selectRow(row, repNode); + cancelEvent(event); + } + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "DOM", + title: "DOM", + searchable: true, + statusSeparator: ">", + + options: { + hasToolButtons: true, + hasStatusBar: true + }, + + create: function() + { + Firebug.DOMBasePanel.prototype.create.apply(this, arguments); + + this.onClick = bind(this.onClick, this); + + //TODO: xxxpedro + this.onClickStatusBar = bind(this.onClickStatusBar, this); + + this.panelNode.style.padding = "0 1px"; + }, + + initialize: function(oldPanelNode) + { + //this.panelNode.addEventListener("click", this.onClick, false); + //dispatch([Firebug.A11yModel], 'onInitializeNode', [this, 'console']); + + Firebug.DOMBasePanel.prototype.initialize.apply(this, arguments); + + addEvent(this.panelNode, "click", this.onClick); + + // TODO: xxxpedro dom + this.ishow(); + + //TODO: xxxpedro + addEvent(this.statusBarNode, "click", this.onClickStatusBar); + }, + + shutdown: function() + { + //this.panelNode.removeEventListener("click", this.onClick, false); + //dispatch([Firebug.A11yModel], 'onDestroyNode', [this, 'console']); + + removeEvent(this.panelNode, "click", this.onClick); + + Firebug.DOMBasePanel.prototype.shutdown.apply(this, arguments); + }/*, + + search: function(text, reverse) + { + if (!text) + { + delete this.currentSearch; + this.highlightRow(null); + return false; + } + + var row; + if (this.currentSearch && text == this.currentSearch.text) + row = this.currentSearch.findNext(true, undefined, reverse, Firebug.searchCaseSensitive); + else + { + function findRow(node) { return getAncestorByClass(node, "memberRow"); } + this.currentSearch = new TextSearch(this.panelNode, findRow); + row = this.currentSearch.find(text, reverse, Firebug.searchCaseSensitive); + } + + if (row) + { + var sel = this.document.defaultView.getSelection(); + sel.removeAllRanges(); + sel.addRange(this.currentSearch.range); + + scrollIntoCenterView(row, this.panelNode); + + this.highlightRow(row); + dispatch([Firebug.A11yModel], 'onDomSearchMatchFound', [this, text, row]); + return true; + } + else + { + dispatch([Firebug.A11yModel], 'onDomSearchMatchFound', [this, text, null]); + return false; + } + }/**/ +}); + +Firebug.registerPanel(DOMMainPanel); + + +// ************************************************************************************************ + + + +// ************************************************************************************************ +// Local Helpers + +var getMembers = function getMembers(object, level) // we expect object to be user-level object wrapped in security blanket +{ + if (!level) + level = 0; + + var ordinals = [], userProps = [], userClasses = [], userFuncs = [], + domProps = [], domFuncs = [], domConstants = []; + + try + { + var domMembers = getDOMMembers(object); + //var domMembers = {}; // TODO: xxxpedro + //var domConstantMap = {}; // TODO: xxxpedro + + if (object.wrappedJSObject) + var insecureObject = object.wrappedJSObject; + else + var insecureObject = object; + + // IE function prototype is not listed in (for..in) + if (isIE && isFunction(object)) + addMember("user", userProps, "prototype", object.prototype, level); + + for (var name in insecureObject) // enumeration is safe + { + if (ignoreVars[name] == 1) // javascript.options.strict says ignoreVars is undefined. + continue; + + var val; + try + { + val = insecureObject[name]; // getter is safe + } + catch (exc) + { + // Sometimes we get exceptions trying to access certain members + if (FBTrace.DBG_ERRORS && FBTrace.DBG_DOM) + FBTrace.sysout("dom.getMembers cannot access "+name, exc); + } + + var ordinal = parseInt(name); + if (ordinal || ordinal == 0) + { + addMember("ordinal", ordinals, name, val, level); + } + else if (isFunction(val)) + { + if (isClassFunction(val) && !(name in domMembers)) + addMember("userClass", userClasses, name, val, level); + else if (name in domMembers) + addMember("domFunction", domFuncs, name, val, level, domMembers[name]); + else + addMember("userFunction", userFuncs, name, val, level); + } + else + { + //TODO: xxxpedro + /* + var getterFunction = insecureObject.__lookupGetter__(name), + setterFunction = insecureObject.__lookupSetter__(name), + prefix = ""; + + if(getterFunction && !setterFunction) + prefix = "get "; + /**/ + + var prefix = ""; + + if (name in domMembers && !(name in domConstantMap)) + addMember("dom", domProps, (prefix+name), val, level, domMembers[name]); + else if (name in domConstantMap) + addMember("dom", domConstants, (prefix+name), val, level); + else + addMember("user", userProps, (prefix+name), val, level); + } + } + } + catch (exc) + { + // Sometimes we get exceptions just from trying to iterate the members + // of certain objects, like StorageList, but don't let that gum up the works + throw exc; + if (FBTrace.DBG_ERRORS && FBTrace.DBG_DOM) + FBTrace.sysout("dom.getMembers FAILS: ", exc); + //throw exc; + } + + function sortName(a, b) { return a.name > b.name ? 1 : -1; } + function sortOrder(a, b) { return a.order > b.order ? 1 : -1; } + + var members = []; + + members.push.apply(members, ordinals); + + Firebug.showUserProps = true; // TODO: xxxpedro + Firebug.showUserFuncs = true; // TODO: xxxpedro + Firebug.showDOMProps = true; + Firebug.showDOMFuncs = true; + Firebug.showDOMConstants = true; + + if (Firebug.showUserProps) + { + userProps.sort(sortName); + members.push.apply(members, userProps); + } + + if (Firebug.showUserFuncs) + { + userClasses.sort(sortName); + members.push.apply(members, userClasses); + + userFuncs.sort(sortName); + members.push.apply(members, userFuncs); + } + + if (Firebug.showDOMProps) + { + domProps.sort(sortName); + members.push.apply(members, domProps); + } + + if (Firebug.showDOMFuncs) + { + domFuncs.sort(sortName); + members.push.apply(members, domFuncs); + } + + if (Firebug.showDOMConstants) + members.push.apply(members, domConstants); + + return members; +} + +function expandMembers(members, toggles, offset, level) // recursion starts with offset=0, level=0 +{ + var expanded = 0; + for (var i = offset; i < members.length; ++i) + { + var member = members[i]; + if (member.level > level) + break; + + if ( toggles.hasOwnProperty(member.name) ) + { + member.open = "opened"; // member.level <= level && member.name in toggles. + + var newMembers = getMembers(member.value, level+1); // sets newMembers.level to level+1 + + var args = [i+1, 0]; + args.push.apply(args, newMembers); + members.splice.apply(members, args); + + /* + if (FBTrace.DBG_DOM) + { + FBTrace.sysout("expandMembers member.name", member.name); + FBTrace.sysout("expandMembers toggles", toggles); + FBTrace.sysout("expandMembers toggles[member.name]", toggles[member.name]); + FBTrace.sysout("dom.expandedMembers level: "+level+" member", member); + } + /**/ + + expanded += newMembers.length; + i += newMembers.length + expandMembers(members, toggles[member.name], i+1, level+1); + } + } + + return expanded; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + +function isClassFunction(fn) +{ + try + { + for (var name in fn.prototype) + return true; + } catch (exc) {} + return false; +} + +var hasProperties = function hasProperties(ob) +{ + try + { + for (var name in ob) + return true; + } catch (exc) {} + + // IE function prototype is not listed in (for..in) + if (isFunction(ob)) return true; + + return false; +} + +FBL.ErrorCopy = function(message) +{ + this.message = message; +}; + +var addMember = function addMember(type, props, name, value, level, order) +{ + var rep = Firebug.getRep(value); // do this first in case a call to instanceof reveals contents + var tag = rep.shortTag ? rep.shortTag : rep.tag; + + var ErrorCopy = function(){}; //TODO: xxxpedro + + var valueType = typeof(value); + var hasChildren = hasProperties(value) && !(value instanceof ErrorCopy) && + (isFunction(value) || (valueType == "object" && value != null) + || (valueType == "string" && value.length > Firebug.stringCropLength)); + + props.push({ + name: name, + value: value, + type: type, + rowClass: "memberRow-"+type, + open: "", + order: order, + level: level, + indent: level*16, + hasChildren: hasChildren, + tag: tag + }); +} + +var getWatchRowIndex = function getWatchRowIndex(row) +{ + var index = -1; + for (; row && hasClass(row, "watchRow"); row = row.previousSibling) + ++index; + return index; +} + +var getRowName = function getRowName(row) +{ + var node = row.firstChild; + return node.textContent ? node.textContent : node.innerText; +} + +var getRowValue = function getRowValue(row) +{ + return row.lastChild.firstChild.repObject; +} + +var getRowOwnerObject = function getRowOwnerObject(row) +{ + var parentRow = getParentRow(row); + if (parentRow) + return getRowValue(parentRow); +} + +var getParentRow = function getParentRow(row) +{ + var level = parseInt(row.getAttribute("level"))-1; + for (row = row.previousSibling; row; row = row.previousSibling) + { + if (parseInt(row.getAttribute("level")) == level) + return row; + } +} + +var getPath = function getPath(row) +{ + var name = getRowName(row); + var path = [name]; + + var level = parseInt(row.getAttribute("level"))-1; + for (row = row.previousSibling; row; row = row.previousSibling) + { + if (parseInt(row.getAttribute("level")) == level) + { + var name = getRowName(row); + path.splice(0, 0, name); + + --level; + } + } + + return path; +} + +// ************************************************************************************************ + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + +// ************************************************************************************************ +// DOM Module + +Firebug.DOM = extend(Firebug.Module, +{ + getPanel: function() + { + return Firebug.chrome ? Firebug.chrome.getPanel("DOM") : null; + } +}); + +Firebug.registerModule(Firebug.DOM); + + +// ************************************************************************************************ +// DOM Panel + +var lastHighlightedObject; + +function DOMSidePanel(){}; + +DOMSidePanel.prototype = extend(Firebug.DOMBasePanel.prototype, +{ + selectRow: function(row, target) + { + if (!target) + target = row.lastChild.firstChild; + + if (!target || !target.repObject) + return; + + this.pathToAppend = getPath(row); + + // If the object is inside an array, look up its index + var valueBox = row.lastChild.firstChild; + if (hasClass(valueBox, "objectBox-array")) + { + var arrayIndex = FirebugReps.Arr.getItemIndex(target); + this.pathToAppend.push(arrayIndex); + } + + // Make sure we get a fresh status path for the object, since otherwise + // it might find the object in the existing path and not refresh it + //Firebug.chrome.clearStatusPath(); + + var object = target.repObject; + + if (instanceOf(object, "Element")) + { + Firebug.HTML.selectTreeNode(ElementCache(object)); + } + else + { + Firebug.chrome.selectPanel("DOM"); + Firebug.chrome.getPanel("DOM").select(object, true); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + onClick: function(event) + { + /* + var target = event.srcElement || event.target; + + var object = getAncestorByClass(target, "objectLink"); + object = object ? object.repObject : null; + + if(!object) return; + + if (instanceOf(object, "Element")) + { + Firebug.HTML.selectTreeNode(ElementCache(object)); + } + else + { + Firebug.chrome.selectPanel("DOM"); + Firebug.chrome.getPanel("DOM").select(object, true); + } + /**/ + + + var target = event.srcElement || event.target; + var repNode = Firebug.getRepNode(target); + if (repNode) + { + var row = getAncestorByClass(target, "memberRow"); + if (row) + { + this.selectRow(row, repNode); + cancelEvent(event); + } + } + /**/ + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "DOMSidePanel", + parentPanel: "HTML", + title: "DOM", + + options: { + hasToolButtons: true + }, + + isInitialized: false, + + create: function() + { + Firebug.DOMBasePanel.prototype.create.apply(this, arguments); + + this.onClick = bind(this.onClick, this); + }, + + initialize: function(){ + Firebug.DOMBasePanel.prototype.initialize.apply(this, arguments); + + addEvent(this.panelNode, "click", this.onClick); + + // TODO: xxxpedro css2 + var selection = ElementCache.get(FirebugChrome.selectedHTMLElementId); + if (selection) + this.select(selection, true); + }, + + shutdown: function() + { + removeEvent(this.panelNode, "click", this.onClick); + + Firebug.DOMBasePanel.prototype.shutdown.apply(this, arguments); + }, + + reattach: function(oldChrome) + { + //this.isInitialized = oldChrome.getPanel("DOM").isInitialized; + this.toggles = oldChrome.getPanel("DOMSidePanel").toggles; + } + +}); + +Firebug.registerPanel(DOMSidePanel); + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +FBL.FBTrace = {}; + +(function() { +// ************************************************************************************************ + +var traceOptions = { + DBG_TIMESTAMP: 1, + DBG_INITIALIZE: 1, + DBG_CHROME: 1, + DBG_ERRORS: 1, + DBG_DISPATCH: 1, + DBG_CSS: 1 +}; + +this.module = null; + +this.initialize = function() +{ + if (!this.messageQueue) + this.messageQueue = []; + + for (var name in traceOptions) + this[name] = traceOptions[name]; +}; + +// ************************************************************************************************ +// FBTrace API + +this.sysout = function() +{ + return this.logFormatted(arguments, ""); +}; + +this.dumpProperties = function(title, object) +{ + return this.logFormatted("dumpProperties() not supported.", "warning"); +}; + +this.dumpStack = function() +{ + return this.logFormatted("dumpStack() not supported.", "warning"); +}; + +this.flush = function(module) +{ + this.module = module; + + var queue = this.messageQueue; + this.messageQueue = []; + + for (var i = 0; i < queue.length; ++i) + this.writeMessage(queue[i][0], queue[i][1], queue[i][2]); +}; + +this.getPanel = function() +{ + return this.module ? this.module.getPanel() : null; +}; + +//************************************************************************************************* + +this.logFormatted = function(objects, className) +{ + var html = this.DBG_TIMESTAMP ? [getTimestamp(), " | "] : []; + var length = objects.length; + + for (var i = 0; i < length; ++i) + { + appendText(" ", html); + + var object = objects[i]; + + if (i == 0) + { + html.push(""); + 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); + +/* 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(); + } + +}); + +Firebug.registerPanel(TracePanel); + +// ************************************************************************************************ +}}); + +/* 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); + } + +}); + + + + +// ************************************************************************************************ +}}); + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +FirebugChrome.Skin = +{ + CSS: '.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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/textEditorBorders.png) repeat-y;_background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/textEditorBorders.gif) repeat-y;_overflow:hidden;}.textEditorInner2{position:relative;padding-right:2px;background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/textEditorBorders.png) repeat-y 100% 0;_background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/textEditorBorders.gif) repeat-y 100% 0;_position:fixed;}.textEditorTop1{background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/textEditorCorners.png) no-repeat 100% 0;margin-left:11px;height:10px;_background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/textEditorCorners.gif) no-repeat 100% 0;_overflow:hidden;}.textEditorTop2{position:relative;left:-11px;width:11px;height:10px;background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/textEditorCorners.png) no-repeat;_background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/textEditorCorners.gif) no-repeat;}.textEditorBottom1{position:relative;background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/textEditorCorners.png) no-repeat 100% 100%;margin-left:11px;height:12px;_background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/textEditorCorners.gif) no-repeat 100% 100%;}.textEditorBottom2{position:relative;left:-11px;width:11px;height:12px;background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/textEditorCorners.png) no-repeat 0 100%;_background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/disable.png) no-repeat 2px 1px;_background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/disable.gif) no-repeat 2px 1px;}.cssProp.editGroup.editing{background:none;}.cssProp.disabledStyle{background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/disableHover.png) no-repeat 2px 1px;_background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/chrome://firebug/skin/tableHeaderActive.gif) repeat-x;}.netHeaderSorted{background:#7D93B2 url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/chrome://firebug/skin/tableHeaderSorted.gif) repeat-x;}.netHeaderSorted > .netHeaderCellBox{border-right-color:#6B7C93;background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/chrome://firebug/skin/arrowDown.png) no-repeat right;}.netHeaderSorted.sortedAscending > .netHeaderCellBox{background-image:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/chrome://firebug/skin/arrowUp.png);}.netHeaderSorted:hover:active{background:#536B90 url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/chrome://firebug/skin/breakpoint.png);}.netRow[breakpoint="true"][disabledBreakpoint="true"] .netRowHeader{background-image:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/chrome://firebug/skin/netBarResolving.gif) repeat-x;z-index:60;}.netConnectingBar{position:absolute;left:0;top:0;bottom:0;background:#FFFFFF url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/chrome://firebug/skin/netBarConnecting.gif) repeat-x;z-index:50;}.netBlockingBar{position:absolute;left:0;top:0;bottom:0;background:#FFFFFF url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/chrome://firebug/skin/netBarWaiting.gif) repeat-x;z-index:40;}.netSendingBar{position:absolute;left:0;top:0;bottom:0;background:#FFFFFF url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/chrome://firebug/skin/netBarSending.gif) repeat-x;z-index:30;}.netWaitingBar{position:absolute;left:0;top:0;bottom:0;background:#FFFFFF url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/chrome://firebug/skin/netBarLoaded.gif) repeat-x;border-color:#B6B6B6;}.fromCache .netReceivingBar,.fromCache.netReceivingBar{background:#D6D6D6 url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/tabMenuTarget.png);}.fbTabMenuTarget:hover{background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/tabMenuTargetHover.png);}.fbShadow{float:left;background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/shadowAlpha.png) no-repeat bottom right !important;background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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;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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/tabMenuPin.png) no-repeat right 0;}.fbMenuGroup:hover{background:#316AC5 url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/tabMenuPin.png) no-repeat right -17px;}.fbMenuGroupSelected{color:#fff;background:#316AC5 url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/tabMenuPin.png) no-repeat right -17px;}.fbMenuChecked{background:transparent url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/tabMenuCheckbox.png) no-repeat 4px 0;}.fbMenuChecked:hover{background:#316AC5 url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/tabMenuCheckbox.png) no-repeat 4px -17px;}.fbMenuRadioSelected{background:transparent url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/tabMenuRadio.png) no-repeat 4px 0;}.fbMenuRadioSelected:hover{background:#316AC5 url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/search.png) no-repeat 4px 2px !important;background:#fff url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/errorIcon.png) no-repeat !important;background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/sprite.png) #f1f2ee 0 0;height:27px;font-size:11px;}#fbPanelBarBox{background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/sprite.png) #f1f2ee 0 0;}#fbPanelBar1{width:1024px; z-index:8;left:0;white-space:nowrap;background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/sprite.png) #dbd9c9 0 -27px;position:absolute;left:4px;}#fbPanelBar2Box{background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/down.png) no-repeat;position:absolute;right:2px;bottom:3px;z-index:99;}#fbSmallCommandLineIcon:hover{background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/up.png) no-repeat;position:absolute;right:1px;bottom:1px;z-index:10;}#fbLargeCommandLineIcon:hover{background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/min.png);}#fbWindow_btClose:hover{background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/minHover.png);}#fbWindow_btDetach{background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/detach.png);}#fbWindow_btDetach:hover{background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/detachHover.png);}#fbWindow_btDeactivate{background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/off.png);}#fbWindow_btDeactivate:hover{background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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;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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/sprite.png) 0 -73px;}a.fbTab:hover .fbTabL{background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/sprite.png) -16px -96px;}a.fbTab:hover .fbTabR{background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/sprite.png) -24px -96px;}.fbSelectedTab{background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/sprite.png) #f1f2ee 0 -50px !important;color:#000;}.fbSelectedTab .fbTabL{background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/sprite.png) 0 -96px !important;}.fbSelectedTab .fbTabR{background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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 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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/tree_open.gif);_float:none;_display:inline;_position:absolute;}div.nodeMaximized{background:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/infoIcon.png) !important;background-image:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/infoIcon.gif);}.logRow-warn{background-color:cyan;background-image:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/warningIcon.png) !important;background-image:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/warningIcon.gif);}.logRow-error{background-color:LightYellow;background-image:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/skin/xp/errorIcon.png) !important;background-image:url(chrome-extension://bmagokdooijbeehmkpknfglimnifench/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;}', + HTML: '
       
       
      >>>
      2 errors' +}; + +// ************************************************************************************************ +}}); + +// ************************************************************************************************ +FBL.initialize(); +// ************************************************************************************************ + +})(); \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/firebug.jpg b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/firebug.jpg new file mode 100755 index 0000000000000000000000000000000000000000..2a18aa0dff623b9f5a346a18c34fae9dac9e384c GIT binary patch literal 34998 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/firebug128.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/firebug128.png new file mode 100755 index 0000000000000000000000000000000000000000..dbca545fe4fab491dd38e1f5e52bf28ad9de5759 GIT binary patch literal 19240 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 P00000NkvXXu0mjfAQ^>n literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/firebug16.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/firebug16.png new file mode 100755 index 0000000000000000000000000000000000000000..d8d0c249060e3e485fca290fbf53e9aaeb115972 GIT binary patch literal 1053 zcmV+&1mgRNP)K^D zBF6baiEKtTjn&8pD`C>DLm)1cE;8iBbz4d4*0HrKx3w+3y)Qo3Y5d@Maz31s=Q%m& zJpUhaXnz|tV;BZ3%V1#G2OUo!$?EE{qt^PywG#8M^-z=797iIwIz}!=j5&KYX#lJYqS{Ll^J?=kuEZ-5La!&;igDxhde=e`Hc9pFwt*0Fi(`UO_ zRb`;Lc36hV2gmZfp2ydY8BAXhYQL%VnGlT);ZuM5NQbT2e{mG!lb0~*{Vg6(DVtcr ziqLZ+Ou7uRjmmq@!I>$U=*nX%zx%|NJ8#%*)-hDsZCIAj+3Uc^FE_zEe*QW!pzXlZ z>tke}?LN$me}`t@=*&vIvUOR((T8rpu>Y}Gx+ZO<=ai( znso-Fv2xGDmXojA3OcyJE#W7FPRARwn4!*!kn8;k)ApLw6b?RV#<8IwJn2##eJmfr zg$uWya~He=Mf@y5MYq7@P7b;j6*ie)_)4Eg?A}@s`zUZzv?p%NVSj@jUCt<6nQ9zq z5K$gAX5)r9JO9*NOiNTuaP!r(e9t85^ta%Y~k1fX9RN5F@yixUjhsO XvjU95kpgPJ00000NkvXXu0mjf$Qk(5 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/firebug24.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/firebug24.png new file mode 100755 index 0000000000000000000000000000000000000000..f50ff926c93d8b400eb513e480ac92002da6e991 GIT binary patch literal 1949 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/firebug48.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/firebug48.png new file mode 100755 index 0000000000000000000000000000000000000000..b44313276a3415fcdf62612e4de7cb66bb0da66d GIT binary patch literal 4096 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 HDWM4fu+KD3 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/buttonBgHover.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/buttonBgHover.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/detach.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/detach.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/disable.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/disable.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/disableHover.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/disableHover.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/disableHover.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/disableHover.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/downActive.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/downActive.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/downHover.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/downHover.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/errorIcon-sm.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/errorIcon-sm.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/firebug-1.3a2.css b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/firebug-1.3a2.css new file mode 100755 index 0000000..b5dd5dd --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/firebug.IE6.css b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/firebug.IE6.css new file mode 100755 index 0000000..14f8aa8 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/firebug.css b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/firebug.css new file mode 100755 index 0000000..decd591 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/firebug.css @@ -0,0 +1,3056 @@ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/* 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: 0 10px 0 0; + font-family: Lucida Grande, Tahoma, sans-serif; + font-weight: bold; + vertical-align: top; + text-align: right; + white-space: nowrap; +} + +.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; +} + +.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: 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; + 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: 49px; +} + +#fbToolbar { + background: url(sprite.png) #f1f2ee 0 0; + height: 27px; + font-size: 11px; +} + +#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; + 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 Monaco, monospace; + position: absolute; + top: 0; + left: 0; + margin: 0; + padding: 0 5px 0 20px; + 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-warning { + 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-warning { + 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/firebug.html b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/firebug.html new file mode 100755 index 0000000..4432a32 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/firebug.html @@ -0,0 +1,213 @@ + + + + +Firebug Lite + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      +   +   +   +
      + + +
      +
      + + + +   + + + + + + + + + Inspect + + + + + Clear + + + + + + + + + + + + + +
      + +
      + + + + + +
       
      + +
      +
      +
      +
      +
      +
      + + +
       
      + + +
      + + +
      +
      +
      + +
      + + + + + +
      + Run + Clear + + +
      + +
      +
      +
      >>>
      + + +
      +
      + + + + 2 errors + + + + + \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/firebug.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/firebug.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/infoIcon.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/infoIcon.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/min.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/min.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/off.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/off.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/search.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/search.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/search.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/search.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/shadow.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/shadow.gif new file mode 100755 index 0000000000000000000000000000000000000000..af7f537e391f08327e417c7be6323c917d5d3788 GIT binary patch literal 4364 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 mNRx4)$-Se2KGVRJG=-nEko^8U73WMVE8{ literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/shadow2.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/shadow2.gif new file mode 100755 index 0000000000000000000000000000000000000000..099cbf35d455e13d49010e736c40bab22c3d1a23 GIT binary patch literal 3093 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/shadowAlpha.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/shadowAlpha.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/sprite.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/sprite.png new file mode 100755 index 0000000000000000000000000000000000000000..3fe97bb6ad8f3310f2a43d2d88dede842074da86 GIT binary patch literal 40027 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabHoverLeft.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabHoverLeft.png new file mode 100755 index 0000000000000000000000000000000000000000..5852d8d78183b96443d4e28b6fcc96f7e88ebbce GIT binary patch literal 433 zcmeAS@N?(olHy`uVBq!ia0vp^96&6_!3HG%UcQ?Eq!^2X+?^QKos)S9lbCYGe8D3oWGWGJ|M`UZqI@`(ej;_-BG4AD4WJ8`!kvm=k|`L7k48csn< z9H~d*l@+tNysEso_BFO#c*<*cGeYC6t7oA>@Np9({Zg92y# zS}`55={=7(iL085+4s2@oqICBM_^`5qf>;-1*MKS5!MfC*_)h9a~n@`T@czUr>m&* zDMisYp%n7dTE|B_LfneV0TnlXYi z4g`gE1haCc%vkza>}%PQDgWN&uuZXDG9{xtbGwEugW3euju!%3J*C^Y`P!W=BfNMH zyH?sgIQjAGThrTj@y8ZLQuo|;N8c~d`}6bZ)c=pftqR<% UWiz?zfq}>1>FVdQ&MBb@0P;?pKmY&$ literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabHoverMid.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabHoverMid.png new file mode 100755 index 0000000000000000000000000000000000000000..e7c9ba75a2bcb2fbc794eab91c00deb3fea491f9 GIT binary patch literal 263 zcmeAS@N?(olHy`uVBq!ia0vp^Oh7Eg!3HE>ee_)kq!^2X+?^QKos)S9lbCYGe8D3oWGWGJ|M`UZqI@`(c#C3(6yhHzYuJ!{R^9KhppF}r$&<{_p< z8|o(rh<0<_yimPlgQsA)yIg(F{cGF~my=l>)|N8N(b~D3wd}Fij8GFEFOOfhf1Py^ zu~}5${_d*bdhxDZm#e&M&Xp(C*$SU7WB9--c8>q@rJCRwK-(BRUHx3vIVCg!0Pi(c AH~;_u literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabHoverRight.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabHoverRight.png new file mode 100755 index 0000000000000000000000000000000000000000..3c62c981f948724a2f909a6e58f0e44f09fb906f GIT binary patch literal 441 zcmeAS@N?(olHy`uVBq!ia0vp^96&6_!3HG%UcQ?Eq!^2X+?^QKos)S9lbCYGe8D3oWGWGJ|M`UZqI@`(ej67h6#4AD4WJ8`2Qv!Q^?{U6^nG@6t& zI8=n1{sH5*W=ZBx4_9;c*m}L8UZsoPl-%f5jn83qec71hp*>3(v zuRblBmsl;LEB0JxI`^XYpA`(Y2_Bj;$GH7IGou1alE}49zDuT@TG$%$>$sXi)@lQe zzQ0R_BsfnoNtH3A3kNx^QhUAB@sQEQZKQf{(_eGJ%B zowD#?x8X&T$>KIHTRoX>x@67Tx!_XBA)$#=R>Y^s3WwB83^Mk7$f+|`#H)3EOoo@% zgd#Tw7hz+Ao093Dua<6kD|zvGo!X1v^X9+r`}=S5*(%pP`}cm@e`{On=6#wgrOD)>88a^OkwbH=LHdI0qPr44$rjF6*2UngG29u{!_& literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabLeft.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabLeft.png new file mode 100755 index 0000000000000000000000000000000000000000..3368de7393b03d32071f0e006a9c5906f9956d39 GIT binary patch literal 458 zcmeAS@N?(olHy`uVBq!ia0vp^96&6_!3HG%UcQ?Eq!^2X+?^QKos)S9l zuISIWVSgi8hCRqDLnuSY;fe1tv!zqsF7?gkn0{-@oacwV3?vRoFzysAW1ZB&8UE(y zRFxKk))TyQKR-J@;qr{Yn2i!|npC8?6&G!rVAW`PULiDSikg7aO5PpH9-Gs*Y~4RO z?M=$2zZb)VmZqrO$l15S)_q=3RtuYNtoiTt4O*)lZ%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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabMenuPin.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabMenuPin.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabMenuRadio.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabMenuRadio.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabMenuTarget.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabMenuTarget.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabMenuTargetHover.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabMenuTargetHover.png new file mode 100755 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)S9lJ`ZS1APH@>g`D8t5Z>G|JJ=O3Fee_*z^RcfzTr{@l|lEKr}&t;uc GLK6TK(_LKv literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabRight.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tabRight.png new file mode 100755 index 0000000000000000000000000000000000000000..8470a95e51eb8e32f29edf62d9ae15be3280cc56 GIT binary patch literal 459 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 L`)q75=;;3dF|oR- literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/textEditorCorners.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/textEditorCorners.png new file mode 100755 index 0000000000000000000000000000000000000000..a0f839dc598edd80d093e1cf954134a916db5af0 GIT binary patch literal 3960 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/titlebarMid.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/titlebarMid.png new file mode 100755 index 0000000000000000000000000000000000000000..e9a74163dc10ef83b2640f2d534b828518bbb61e GIT binary patch literal 215 zcmeAS@N?(olHy`uVBq!ia0vp^tUxTo!3HE(ZY$jeq!^2X+?^QKos)S9lS| zxv6<249-QVi6yBi3gww484B*6z5(HleBwYwMxHK?AsXkCb22i1oNr*0`2YWZzv78c z|Nd69@f`G=tY#>%{O_xylO?ofN^EEdJgBI}!7%rf;L>TEKiU9wGkCiCxvXlpYMr7(8A5T-G@yGywqnA5d%n literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tree_close.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tree_close.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tree_open.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/tree_open.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/twistyClosed.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/twistyClosed.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/twistyOpen.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/twistyOpen.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/up.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/up.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/warningIcon.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/warningIcon.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/warningIcon.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/warningIcon.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/buttonBgHover.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/buttonBgHover.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/close.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/close.png new file mode 100755 index 0000000000000000000000000000000000000000..ada59d8ac1c40449a11a44840b17b7378b98f291 GIT binary patch literal 3490 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 Qk^lez07*qoM6N<$f^Eu$H~;_u literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/closeHover.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/closeHover.png new file mode 100755 index 0000000000000000000000000000000000000000..be0145d2e164da5ab1cfd8c1e071ea6a8dd82e6d GIT binary patch literal 3480 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/disable.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/disable.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/disable.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/disable.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/disableHover.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/disableHover.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/disableHover.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/disableHover.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/downActive.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/downActive.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/downHover.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/downHover.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/errorIcon-sm.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/errorIcon-sm.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/firebug.css b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/firebug.css new file mode 100755 index 0000000..7af18e6 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/firebug-lite/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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/firebug.html b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/firebug.html new file mode 100755 index 0000000..4432a32 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/firebug-lite/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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/firebug.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/firebug.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/group.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/group.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/infoIcon.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/infoIcon.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/min.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/min.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/off.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/off.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/search.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/search.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/search.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/search.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/shadow.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/shadow.gif new file mode 100755 index 0000000000000000000000000000000000000000..af7f537e391f08327e417c7be6323c917d5d3788 GIT binary patch literal 4364 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 mNRx4)$-Se2KGVRJG=-nEko^8U73WMVE8{ literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/shadow2.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/shadow2.gif new file mode 100755 index 0000000000000000000000000000000000000000..099cbf35d455e13d49010e736c40bab22c3d1a23 GIT binary patch literal 3093 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/shadowAlpha.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/shadowAlpha.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/sprite.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/sprite.png new file mode 100755 index 0000000000000000000000000000000000000000..d117e123ff41a807615546f28a7857e39aa0e2cf GIT binary patch literal 7464 zcmV+@9oOQCP)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} z000tGNkl>_!O-3uD)jmX-$R%$zwBp~KD1&DPfT+O=ykGBPO6{q^%FH#au}!+#+mAr!OT zy?b}Y+5O$SciT|eObiSRk_+cEFfgdyzRSSC@J>OIfq~(RrXIt)ckg!ZSXWh5^&b^5 zF)%QkTfaCwEDYVf@7}#Td~pA}ckj@200000|Nmkf?s3l2-``K`IA?tE;>G{}|37{D z#K6Fyrly84ii3mW|NsBY%*^O^+zAe6=Hq|9eif^zsGyz^oXsR`Zm#(5n~bTA;p^9G zvu3bsYS=w}%CD}+@b2Ba=g*)2#{f(#*KRyNwGd|v3JMCMNdN!<0RR8O8MP$GEY&oy zoH>1lG!2SMilk}a;^HDr11~QxX&V0i{Y#n#PEJnJG(3FxkTear@)7l%bmZ_6Ya44u zM#g{t{$0I#Ra{&g!q(8xz^>uP&+m+kj7&^S|Ni~^_wOG!H#ajgGoGMheD&(pjvYH7 z91jnVYuBzp*!K4J*b^TM3ybxOZ`Loq*?s!Q!oniZw^X2SiSXPF@87?FFmc|WPhTEP zocI3y`^%BJ3=9mHBXb$wy?ghwAd-udfsK*zd)u;)GC~4;44jM%->za8XJKGqxDXir z?Vo_R0$ZS;_kpkfAy%_9Ffc5HI+cTgK@cX+#K6Gt=g7)^>lS^H)L*}8E5Tp|2xqa3 zQ^VlP(}Pe0>BWq^f;?#&n3za&6$=Xs3uzi~)pXR;z|PK2nuec0f6~~~BnKFymtd-pCRwQFf<;nZLzB>a5J3)J1d`wQ(SX;^Y2fekBiGIOr7~p zi0A){H{VViX5tiQP?!IG{@RCC3z%4+-F^4<>!+VT&c1xge*N^5cOPDV{kq}*SC(gY zZ``^n7Z-f?>O-@g2I^1NG!?w=g%L~hg#%WKm7dpgQ)!QXHg0hFaNjg6F+|-Tz#=H zFfhFR{g3g*bLNPNB3yhVSBeDv0AR;#LYoMpIR5r4Gofo+FcBgRMZpgmDTI<*(o0WX zJxK8;f+*ra4+@?_4k;eJdJq-$V4*dF0dunIK_N+F0@^lh!Fd#Q>;wM3pzfR#uo?hnfFw!Q0$8<{84w5rECpDe z>_kn|I{XbR|EA$^*jj+w?Y0)Mn~`f9fVF&K24IXk`~<9>CuTq*k?{Nd0ATuR(=Ss> zGntIT;n)$EW!dF&u>nZ4NeF2fcXK02k_aJ`QZr&UmP{~vF48rQ;{-uy0e-v^{^1S&ZJkJ{jm}#m7*t?$D>0dIE1(2B42oP*SE5wOh)+MlYBY6 z>v|CY1VV^X?YnVVkfb-kiN2X+u}kj<5LC6X_RaJBfr!xkk+D;;cMAYM0D+KtwR+^* z#ifsFnHn_tx!7!)>o?cehayit&AgSr*ESzdFQ}>r08%fzpDJO5g% z`vGutYE>!U8Ay$Pna_Z29N-?n1pqM}Q`Fk>)i@T#wPwBBhH_fn4}hXmC0&bm_1HNs zYtUYfOa2c{-Z9VT@<+Sr`775?4*FzS4uwK(a}_^o75XZaDmKPOy>Re^CLz@|bja!a zS8qC(dY?$lR^#E|?OUL$=~81OyBNt5&3$@#ezpx)ZMvY6dFo_r7kWm%j|_2 zn4R63@!?NLT0@gvb}OX(51Yx^GygZ|KmX=Gr{;|Nr1O+ehZA zRXwY<)vA3~1>kv}q`%3MCP(z}@UYwM76joAc_nG)4P!|=y_G(`q5%{jXhhrgLYqeJKN>(mn-KvJ{o6ir>2CUTGB~d+ ziq?I5D4?wQc}c8U`hDp!=6WaP8&*!Ci>2Z zAHNHL=x^Ek)a46bKltL|< z#mWks+wE>`ZOsfo@bbBE!EVj_rNJel|RL|IV-Fgh$>f5jbEL*F}sjw=A6|# zsjV)tv}R=F>i+%vGGKu$%OjtkoxT}$a#0}nuj``w>;QjWu8GCrf zCe11^`6X+P7P8emdw^kL;Sfqn*BYA|%WE1A?47zX5f$UJhHcL{EWejGu?zzs-%^~J zI~vO}&LX4jp`DkO%c;ip21yKud5guGnb=f!a{s_!YfJMTf3JNV{2RVMS>w#cO8$qv zGmnkpy5sow&9Rr)p53+A%bJ9?_@FknVic$Y!T}1E2ud1-q@rq~HfhtQQiYIERgkKv zQUw*tfg%;5szORh=pnUr8;+zogpGoWLrPr0N8)P>KG*i%mv@f$`p0;OwFxC&Zw1~7fFHv8aE;71Xl2v7tl0u%v?0EHb3 z?ccw@uw$X2p`pU|fZ5sb;xq6G=6r<>VD^$w(E}d`VD_qCu?yYy9x!`l+H`=UM~@bE zC^4P4=u(g#FncFgF&6qb0JFCn7KhQ>ei$wI^m@U2px^-teiV{rxv&Au-Z*c1EL2RZ z6z9bM?*N~+cxZ7_UyMd?w@{+sJ<#3VUDyB}9UX-YP*YvAdCO)|6bT3b-27Hx`WL1s zN=JK#-C?h-sWocC5kf#_fYSWVYQP{@JS$&m zK`8}edV#G^1Ymy7W*)#0$mQ#gbO{Ni)Ce~yr69x*l6(X}ZiFTOg=YY|6eTCgA%+tc zUC}g+v3VC6+L-*YYta=$#$@iCI2a6`fBWsm#>NV-R}{sY6Lo|TMNwvFW_o&hHnz3` z7#<$>`~6O*^HzbNrfJD!a&mIAy1KfuveH}tv+Jztwet!%oc<5W%zdhZ-?wjH=4#LM z!9$J;KQC(}5+{+wf=@I_M<*r@9Hg0yt)U)3ti63;{if0tbzD+r*QeNMaKUF{M!DSE z*Ltt2$z>Zi0x;D+35UahU5}MN^eraO0ian$beE}#6mmK|U2I1LG5+`VJB}O%@Q%l` z;)$PV=@bB(&RDB_@@yD9PxQ)#x=7Gwo%!vro2Rb>$hQxGGKkB{nXIVcIG6X3CoZ1< zQ2V04Qt(x1nK^lMk|Si1eE~p>X%$psl#&w19Zx;Viy~80HIWoOE&#(X9AiBL_WGI> zo6jIk0bighsLH#g`s2?FRx8WO@@&Yu+z;U0hrh4A)hTVdCz4Z78ul4jhOw28JuKL4 z05Y-I_@B;L0X-1D***j0GJC_}r^ONnfK+g%|HnVKWHm6bw5r?Z01T*EJ~4}Am`#n1 zAAB}8HKh?k%1SfIWbZe=ZEHJS5*V?*`o?H(J+l)KrmrD1t_}9~ZQe0GG^lbMSLuz1 zB4>%{Y&+(T_d8C#c$H@K_PTwV2xqON?t9;)RDEgB-s5}r@*-dJ-CeSc&_o!?@FM$k zc1-g**PS?`QF{2Ed!K7*mG*#AU`iaLmaGm>q zCXWo=^}=)3=YOF*eZV^&F7)H_#W) zW`_H^+y8LFFNhli5x`&S>L*pj#qqTki;LrR`vL%)$CDboCW4DamF(^VbDUaB1Sb#s zcXq3Qo#z>NfK1T&M0}~&8yW7m0#iWx!5s-;J>UVPyPC3q1ZaQ&yq^QGc|7UCYZACM z0ANExMIr>C0cd~?X@+zdK)(IxaK9T^yKum10-Ex^)$Pyg2ReWMyYp>rexgw@0uX=@ z#xeZ_V=1=gfgRhP`l0d5FC98`{K%12>9nRd26%wWo%8??Jo)7AXPzT3L@ZgN006X9NK3_;=+H#RnK#>=4*S+En?7Pk)RKD-@FnGZNjZS? mr(b+%!y3WYy!4a1{~iDbIfUK%sDK&(0000&(o|OpIW_ z!o|e}mEI!|a%5LkW=b|Q z?{595kaT54NPP>r0DKLDzSR8;Yq$asIR+;H#UKo&pX$l^-ODAMz^l-RwqM90MDrZ( z7lbgqb%+M9i!KTUFmXM}RV@?Fe8H zgo&pez@8h_4~KUlSMbXPY9n~`#Rqo~2nke5Nk?j}t(wTt%r3?l_TV>{Oe{|I 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tabHoverRight.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tabHoverRight.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tabMenuPin.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tabMenuPin.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tabMenuRadio.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tabMenuRadio.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tabMenuTarget.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tabMenuTarget.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tabMenuTargetHover.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tabMenuTargetHover.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tabRight.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tabRight.png new file mode 100755 index 0000000000000000000000000000000000000000..b43c352d7f2d4e8bf3740a79d54a50b49d4c53a2 GIT binary patch literal 433 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 L`)q75=;;3dF|oR- literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/textEditorCorners.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/textEditorCorners.png new file mode 100755 index 0000000000000000000000000000000000000000..a0f839dc598edd80d093e1cf954134a916db5af0 GIT binary patch literal 3960 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/titlebarMid.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/titlebarMid.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/toolbarMid.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/toolbarMid.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tree_close.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tree_close.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tree_open.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/tree_open.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/twistyClosed.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/twistyClosed.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/twistyOpen.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/twistyOpen.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/up.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/up.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/warningIcon.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/warningIcon.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/warningIcon.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/light/warningIcon.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/buttonBgHover.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/buttonBgHover.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/detach.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/detach.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/disable.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/disable.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/disableHover.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/disableHover.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/disableHover.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/disableHover.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/downActive.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/downActive.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/downHover.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/downHover.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/errorIcon-sm.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/errorIcon-sm.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/firebug-1.3a2.css b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/firebug-1.3a2.css new file mode 100755 index 0000000..b5dd5dd --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/firebug-lite/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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/firebug.IE6.css b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/firebug.IE6.css new file mode 100755 index 0000000..14f8aa8 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/firebug-lite/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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/firebug.css b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/firebug.css new file mode 100755 index 0000000..92e6c3b --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/firebug.css @@ -0,0 +1,3140 @@ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/*************************************************************************************************/ +/* 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 { + 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; + 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; +} + +#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; + 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 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/firebug.html b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/firebug.html new file mode 100755 index 0000000..4432a32 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/firebug.html @@ -0,0 +1,213 @@ + + + + +Firebug Lite + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      +   +   +   +
      + + +
      +
      + + + +   + + + + + + + + + Inspect + + + + + Clear + + + + + + + + + + + + + +
      + +
      + + + + + +
       
      + +
      +
      +
      +
      +
      +
      + + +
       
      + + +
      + + +
      +
      +
      + +
      + + + + + +
      + Run + Clear + + +
      + +
      +
      +
      >>>
      + + +
      +
      + + + + 2 errors + + + + + \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/firebug.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/firebug.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/infoIcon.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/infoIcon.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/min.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/min.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/off.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/off.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/search.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/search.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/search.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/search.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/shadow.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/shadow.gif new file mode 100755 index 0000000000000000000000000000000000000000..af7f537e391f08327e417c7be6323c917d5d3788 GIT binary patch literal 4364 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 mNRx4)$-Se2KGVRJG=-nEko^8U73WMVE8{ literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/shadow2.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/shadow2.gif new file mode 100755 index 0000000000000000000000000000000000000000..099cbf35d455e13d49010e736c40bab22c3d1a23 GIT binary patch literal 3093 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/shadowAlpha.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/shadowAlpha.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/sprite.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/sprite.png new file mode 100755 index 0000000000000000000000000000000000000000..33d2c4d4649ec35b7771213977d7c83180907ccd GIT binary patch literal 40027 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabHoverMid.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabHoverMid.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabHoverRight.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabHoverRight.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabMenuCheckbox.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabMenuCheckbox.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabMenuPin.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabMenuPin.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabMenuRadio.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabMenuRadio.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabMenuTarget.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabMenuTarget.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabMenuTargetHover.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabMenuTargetHover.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabRight.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tabRight.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/textEditorBorders.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/textEditorBorders.gif new file mode 100755 index 0000000000000000000000000000000000000000..0ee5497874cec4a5599e562dd7c00b8c57bc5a44 GIT binary patch literal 117 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 L`)q75=;;3dF|oR- literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/textEditorCorners.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/textEditorCorners.png new file mode 100755 index 0000000000000000000000000000000000000000..a0f839dc598edd80d093e1cf954134a916db5af0 GIT binary patch literal 3960 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/titlebarMid.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/titlebarMid.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tree_close.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tree_close.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tree_open.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/tree_open.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/up.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/up.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/warningIcon.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/warningIcon.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/warningIcon.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/xp/warningIcon.png new file mode 100755 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").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),b.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write((f.support.boxModel?"":"")+""),cl.close();d=cl.createElement(a),cl.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ck)}cj[a]=e}return cj[a]}function ct(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function cs(){cq=b}function cr(){setTimeout(cs,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;e=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?+d:j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){if(typeof c!="string"||!c)return null;var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
      a",d=p.getElementsByTagName("*"),e=p.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=p.getElementsByTagName("input")[0],b={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:p.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,pixelMargin:!0},f.boxModel=b.boxModel=c.compatMode==="CSS1Compat",i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete p.test}catch(r){b.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",function(){b.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),i.setAttribute("name","t"),p.appendChild(i),j=c.createDocumentFragment(),j.appendChild(p.lastChild),b.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,j.removeChild(i),j.appendChild(p);if(p.attachEvent)for(n in{submit:1,change:1,focusin:1})m="on"+n,o=m in p,o||(p.setAttribute(m,"return;"),o=typeof p[m]=="function"),b[n+"Bubbles"]=o;j.removeChild(p),j=g=h=p=i=null,f(function(){var d,e,g,h,i,j,l,m,n,q,r,s,t,u=c.getElementsByTagName("body")[0];!u||(m=1,t="padding:0;margin:0;border:",r="position:absolute;top:0;left:0;width:1px;height:1px;",s=t+"0;visibility:hidden;",n="style='"+r+t+"5px solid #000;",q="
      "+""+"
      ",d=c.createElement("div"),d.style.cssText=s+"width:0;height:0;position:static;top:0;margin-top:"+m+"px",u.insertBefore(d,u.firstChild),p=c.createElement("div"),d.appendChild(p),p.innerHTML="
      t
      ",k=p.getElementsByTagName("td"),o=k[0].offsetHeight===0,k[0].style.display="",k[1].style.display="none",b.reliableHiddenOffsets=o&&k[0].offsetHeight===0,a.getComputedStyle&&(p.innerHTML="",l=c.createElement("div"),l.style.width="0",l.style.marginRight="0",p.style.width="2px",p.appendChild(l),b.reliableMarginRight=(parseInt((a.getComputedStyle(l,null)||{marginRight:0}).marginRight,10)||0)===0),typeof p.style.zoom!="undefined"&&(p.innerHTML="",p.style.width=p.style.padding="1px",p.style.border=0,p.style.overflow="hidden",p.style.display="inline",p.style.zoom=1,b.inlineBlockNeedsLayout=p.offsetWidth===3,p.style.display="block",p.style.overflow="visible",p.innerHTML="
      ",b.shrinkWrapBlocks=p.offsetWidth!==3),p.style.cssText=r+s,p.innerHTML=q,e=p.firstChild,g=e.firstChild,i=e.nextSibling.firstChild.firstChild,j={doesNotAddBorder:g.offsetTop!==5,doesAddBorderForTableAndCells:i.offsetTop===5},g.style.position="fixed",g.style.top="20px",j.fixedPosition=g.offsetTop===20||g.offsetTop===15,g.style.position=g.style.top="",e.style.overflow="hidden",e.style.position="relative",j.subtractsBorderForOverflowNotVisible=g.offsetTop===-5,j.doesNotIncludeMarginInBodyOffset=u.offsetTop!==m,a.getComputedStyle&&(p.style.marginTop="1%",b.pixelMargin=(a.getComputedStyle(p,null)||{marginTop:0}).marginTop!=="1%"),typeof d.style.zoom!="undefined"&&(d.style.zoom=1),u.removeChild(d),l=p=d=null,f.extend(b,j))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e1,null,!1)},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){var d=2;typeof a!="string"&&(c=a,a="fx",d--);if(arguments.length1)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,f.prop,a,b,arguments.length>1)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.type]||f.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.type]||f.valHooks[g.nodeName.toLowerCase()];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h,i=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;i=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/(?:^|\s)hover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function( +a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler,g=p.selector),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&j.push({elem:this,matches:d.slice(e)});for(k=0;k0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));o.match.globalPOS=p;var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

      ";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
      ";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/]","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*",""],legend:[1,"
      ","
      "],thead:[1,"","
      "],tr:[2,"","
      "],td:[3,"","
      "],col:[2,"","
      "],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
      ","
      "]),f.fn.extend({text:function(a){return f.access(this,function(a){return a===b?f.text(this):this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f +.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){return f.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(;d1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||f.isXMLDoc(a)||!bc.test("<"+a.nodeName+">")?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g,h,i,j=[];b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);for(var k=0,l;(l=a[k])!=null;k++){typeof l=="number"&&(l+="");if(!l)continue;if(typeof l=="string")if(!_.test(l))l=b.createTextNode(l);else{l=l.replace(Y,"<$1>");var m=(Z.exec(l)||["",""])[1].toLowerCase(),n=bg[m]||bg._default,o=n[0],p=b.createElement("div"),q=bh.childNodes,r;b===c?bh.appendChild(p):U(b).appendChild(p),p.innerHTML=n[1]+l+n[2];while(o--)p=p.lastChild;if(!f.support.tbody){var s=$.test(l),t=m==="table"&&!s?p.firstChild&&p.firstChild.childNodes:n[1]===""&&!s?p.childNodes:[];for(i=t.length-1;i>=0;--i)f.nodeName(t[i],"tbody")&&!t[i].childNodes.length&&t[i].parentNode.removeChild(t[i])}!f.support.leadingWhitespace&&X.test(l)&&p.insertBefore(b.createTextNode(X.exec(l)[0]),p.firstChild),l=p.childNodes,p&&(p.parentNode.removeChild(p),q.length>0&&(r=q[q.length-1],r&&r.parentNode&&r.parentNode.removeChild(r)))}var u;if(!f.support.appendChecked)if(l[0]&&typeof (u=l.length)=="number")for(i=0;i1)},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=by(a,"opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bu.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(by)return by(a,c)},swap:function(a,b,c){var d={},e,f;for(f in b)d[f]=a.style[f],a.style[f]=b[f];e=c.call(a);for(f in b)a.style[f]=d[f];return e}}),f.curCSS=f.css,c.defaultView&&c.defaultView.getComputedStyle&&(bz=function(a,b){var c,d,e,g,h=a.style;b=b.replace(br,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b))),!f.support.pixelMargin&&e&&bv.test(b)&&bt.test(c)&&(g=h.width,h.width=c,c=e.width,h.width=g);return c}),c.documentElement.currentStyle&&(bA=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f==null&&g&&(e=g[b])&&(f=e),bt.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),by=bz||bA,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0?bB(a,b,d):f.swap(a,bw,function(){return bB(a,b,d)})},set:function(a,b){return bs.test(b)?b+"px":b}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bq.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bp,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bp.test(g)?g.replace(bp,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){return f.swap(a,{display:"inline-block"},function(){return b?by(a,"margin-right"):a.style.marginRight})}})}),f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)}),f.each({margin:"",padding:"",border:"Width"},function(a,b){f.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bx[d]+b]=e[d]||e[d-2]||e[0];return f}}});var bC=/%20/g,bD=/\[\]$/,bE=/\r?\n/g,bF=/#.*$/,bG=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bH=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bI=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bJ=/^(?:GET|HEAD)$/,bK=/^\/\//,bL=/\?/,bM=/)<[^<]*)*<\/script>/gi,bN=/^(?:select|textarea)/i,bO=/\s+/,bP=/([?&])_=[^&]*/,bQ=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bR=f.fn.load,bS={},bT={},bU,bV,bW=["*/"]+["*"];try{bU=e.href}catch(bX){bU=c.createElement("a"),bU.href="",bU=bU.href}bV=bQ.exec(bU.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bR)return bR.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
      ").append(c.replace(bM,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bN.test(this.nodeName)||bH.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bE,"\r\n")}}):{name:b.name,value:c.replace(bE,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b$(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b$(a,b);return a},ajaxSettings:{url:bU,isLocal:bI.test(bV[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bW},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bY(bS),ajaxTransport:bY(bT),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?ca(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cb(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bF,"").replace(bK,bV[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bO),d.crossDomain==null&&(r=bQ.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bV[1]&&r[2]==bV[2]&&(r[3]||(r[1]==="http:"?80:443))==(bV[3]||(bV[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bZ(bS,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bJ.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bL.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bP,"$1_="+x);d.url=y+(y===d.url?(bL.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bW+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bZ(bT,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)b_(g,a[g],c,e);return d.join("&").replace(bC,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cc=f.now(),cd=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cc++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=typeof b.data=="string"&&/^application\/x\-www\-form\-urlencoded/.test(b.contentType);if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cd.test(b.url)||e&&cd.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cd,l),b.url===j&&(e&&(k=k.replace(cd,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ce=a.ActiveXObject?function(){for(var a in cg)cg[a](0,1)}:!1,cf=0,cg;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ch()||ci()}:ch,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ce&&delete cg[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n);try{m.text=h.responseText}catch(a){}try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cf,ce&&(cg||(cg={},f(a).unload(ce)),cg[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cj={},ck,cl,cm=/^(?:toggle|show|hide)$/,cn=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,co,cp=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cq;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(ct("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);f.fn[a]=function(e){return f.access(this,function(a,e,g){var h=cy(a);if(g===b)return h?c in h?h[c]:f.support.boxModel&&h.document.documentElement[e]||h.document.body[e]:a[e];h?h.scrollTo(d?f(h).scrollLeft():g,d?g:f(h).scrollTop()):a[e]=g},a,e,arguments.length,null)}}),f.each({Height:"height",Width:"width"},function(a,c){var d="client"+a,e="scroll"+a,g="offset"+a;f.fn["inner"+a]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,c,"padding")):this[c]():null},f.fn["outer"+a]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,c,a?"margin":"border")):this[c]():null},f.fn[c]=function(a){return f.access(this,function(a,c,h){var i,j,k,l;if(f.isWindow(a)){i=a.document,j=i.documentElement[d];return f.support.boxModel&&j||i.body&&i.body[d]||j}if(a.nodeType===9){i=a.documentElement;if(i[d]>=i[e])return i[d];return Math.max(a.body[e],i[e],a.body[g],i[g])}if(h===b){k=f.css(a,c),l=parseFloat(k);return f.isNumeric(l)?l:k}f(a).css(c,h)},c,a,arguments.length,null)}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/lib/qunit/qunit.css b/php/kindeditor_demo/kindeditor/lib/qunit/qunit.css new file mode 100755 index 0000000..b3c6db5 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/qunit/qunit.css @@ -0,0 +1,225 @@ +/** + * QUnit - A JavaScript Unit Testing Framework + * + * http://docs.jquery.com/QUnit + * + * Copyright (c) 2011 John Resig, Jörn Zaefferer + * Dual licensed under the MIT (MIT-LICENSE.txt) + * or GPL (GPL-LICENSE.txt) licenses. + */ + +/** Font Family and Sizes */ + +#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { + font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; +} + +#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } +#qunit-tests { font-size: smaller; } + + +/** Resets */ + +#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult { + margin: 0; + padding: 0; +} + + +/** Header */ + +#qunit-header { + padding: 0.5em 0 0.5em 1em; + + color: #8699a4; + background-color: #0d3349; + + font-size: 1.5em; + line-height: 1em; + font-weight: normal; + + border-radius: 15px 15px 0 0; + -moz-border-radius: 15px 15px 0 0; + -webkit-border-top-right-radius: 15px; + -webkit-border-top-left-radius: 15px; +} + +#qunit-header a { + text-decoration: none; + color: #c2ccd1; +} + +#qunit-header a:hover, +#qunit-header a:focus { + color: #fff; +} + +#qunit-banner { + height: 5px; +} + +#qunit-testrunner-toolbar { + padding: 0.5em 0 0.5em 2em; + color: #5E740B; + background-color: #eee; +} + +#qunit-userAgent { + padding: 0.5em 0 0.5em 2.5em; + background-color: #2b81af; + color: #fff; + text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; +} + + +/** Tests: Pass/Fail */ + +#qunit-tests { + list-style-position: inside; +} + +#qunit-tests li { + padding: 0.4em 0.5em 0.4em 2.5em; + border-bottom: 1px solid #fff; + list-style-position: inside; +} + +#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running { + display: none; +} + +#qunit-tests li strong { + cursor: pointer; +} + +#qunit-tests li a { + padding: 0.5em; + color: #c2ccd1; + text-decoration: none; +} +#qunit-tests li a:hover, +#qunit-tests li a:focus { + color: #000; +} + +#qunit-tests ol { + margin-top: 0.5em; + padding: 0.5em; + + background-color: #fff; + + border-radius: 15px; + -moz-border-radius: 15px; + -webkit-border-radius: 15px; + + box-shadow: inset 0px 2px 13px #999; + -moz-box-shadow: inset 0px 2px 13px #999; + -webkit-box-shadow: inset 0px 2px 13px #999; +} + +#qunit-tests table { + border-collapse: collapse; + margin-top: .2em; +} + +#qunit-tests th { + text-align: right; + vertical-align: top; + padding: 0 .5em 0 0; +} + +#qunit-tests td { + vertical-align: top; +} + +#qunit-tests pre { + margin: 0; + white-space: pre-wrap; + word-wrap: break-word; +} + +#qunit-tests del { + background-color: #e0f2be; + color: #374e0c; + text-decoration: none; +} + +#qunit-tests ins { + background-color: #ffcaca; + color: #500; + text-decoration: none; +} + +/*** Test Counts */ + +#qunit-tests b.counts { color: black; } +#qunit-tests b.passed { color: #5E740B; } +#qunit-tests b.failed { color: #710909; } + +#qunit-tests li li { + margin: 0.5em; + padding: 0.4em 0.5em 0.4em 0.5em; + background-color: #fff; + border-bottom: none; + list-style-position: inside; +} + +/*** Passing Styles */ + +#qunit-tests li li.pass { + color: #5E740B; + background-color: #fff; + border-left: 26px solid #C6E746; +} + +#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } +#qunit-tests .pass .test-name { color: #366097; } + +#qunit-tests .pass .test-actual, +#qunit-tests .pass .test-expected { color: #999999; } + +#qunit-banner.qunit-pass { background-color: #C6E746; } + +/*** Failing Styles */ + +#qunit-tests li li.fail { + color: #710909; + background-color: #fff; + border-left: 26px solid #EE5757; +} + +#qunit-tests > li:last-child { + border-radius: 0 0 15px 15px; + -moz-border-radius: 0 0 15px 15px; + -webkit-border-bottom-right-radius: 15px; + -webkit-border-bottom-left-radius: 15px; +} + +#qunit-tests .fail { color: #000000; background-color: #EE5757; } +#qunit-tests .fail .test-name, +#qunit-tests .fail .module-name { color: #000000; } + +#qunit-tests .fail .test-actual { color: #EE5757; } +#qunit-tests .fail .test-expected { color: green; } + +#qunit-banner.qunit-fail { background-color: #EE5757; } + + +/** Result */ + +#qunit-testresult { + padding: 0.5em 0.5em 0.5em 2.5em; + + color: #2b81af; + background-color: #D2E0E6; + + border-bottom: 1px solid white; +} + +/** Fixture */ + +#qunit-fixture { + position: absolute; + top: -10000px; + left: -10000px; +} diff --git a/php/kindeditor_demo/kindeditor/lib/qunit/qunit.js b/php/kindeditor_demo/kindeditor/lib/qunit/qunit.js new file mode 100755 index 0000000..9ca4b91 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/qunit/qunit.js @@ -0,0 +1,1448 @@ +/** + * QUnit - A JavaScript Unit Testing Framework + * + * http://docs.jquery.com/QUnit + * + * Copyright (c) 2011 John Resig, Jörn Zaefferer + * Dual licensed under the MIT (MIT-LICENSE.txt) + * or GPL (GPL-LICENSE.txt) licenses. + */ + +(function(window) { + +var defined = { + setTimeout: typeof window.setTimeout !== "undefined", + sessionStorage: (function() { + try { + return !!sessionStorage.getItem; + } catch(e){ + return false; + } + })() +}; + +var testId = 0; + +var Test = function(name, testName, expected, testEnvironmentArg, async, callback) { + this.name = name; + this.testName = testName; + this.expected = expected; + this.testEnvironmentArg = testEnvironmentArg; + this.async = async; + this.callback = callback; + this.assertions = []; +}; +Test.prototype = { + init: function() { + var tests = id("qunit-tests"); + if (tests) { + var b = document.createElement("strong"); + b.innerHTML = "Running " + this.name; + var li = document.createElement("li"); + li.appendChild( b ); + li.className = "running"; + li.id = this.id = "test-output" + testId++; + tests.appendChild( li ); + } + }, + setup: function() { + if (this.module != config.previousModule) { + if ( config.previousModule ) { + QUnit.moduleDone( { + name: config.previousModule, + failed: config.moduleStats.bad, + passed: config.moduleStats.all - config.moduleStats.bad, + total: config.moduleStats.all + } ); + } + config.previousModule = this.module; + config.moduleStats = { all: 0, bad: 0 }; + QUnit.moduleStart( { + name: this.module + } ); + } + + config.current = this; + this.testEnvironment = extend({ + setup: function() {}, + teardown: function() {} + }, this.moduleTestEnvironment); + if (this.testEnvironmentArg) { + extend(this.testEnvironment, this.testEnvironmentArg); + } + + QUnit.testStart( { + name: this.testName + } ); + + // allow utility functions to access the current test environment + // TODO why?? + QUnit.current_testEnvironment = this.testEnvironment; + + try { + if ( !config.pollution ) { + saveGlobal(); + } + + this.testEnvironment.setup.call(this.testEnvironment); + } catch(e) { + QUnit.ok( false, "Setup failed on " + this.testName + ": " + e.message ); + } + }, + run: function() { + if ( this.async ) { + QUnit.stop(); + } + + if ( config.notrycatch ) { + this.callback.call(this.testEnvironment); + return; + } + //try { + this.callback.call(this.testEnvironment); + /*} catch(e) { + fail("Test " + this.testName + " died, exception and test follows", e, this.callback); + QUnit.ok( false, "Died on test #" + (this.assertions.length + 1) + ": " + e.message + " - " + QUnit.jsDump.parse(e) ); + // else next test will carry the responsibility + saveGlobal(); + + // Restart the tests if they're blocking + if ( config.blocking ) { + start(); + } + }*/ + }, + teardown: function() { + try { + this.testEnvironment.teardown.call(this.testEnvironment); + checkPollution(); + } catch(e) { + QUnit.ok( false, "Teardown failed on " + this.testName + ": " + e.message ); + } + }, + finish: function() { + if ( this.expected && this.expected != this.assertions.length ) { + QUnit.ok( false, "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run" ); + } + + var good = 0, bad = 0, + tests = id("qunit-tests"); + + config.stats.all += this.assertions.length; + config.moduleStats.all += this.assertions.length; + + if ( tests ) { + var ol = document.createElement("ol"); + + for ( var i = 0; i < this.assertions.length; i++ ) { + var assertion = this.assertions[i]; + + var li = document.createElement("li"); + li.className = assertion.result ? "pass" : "fail"; + li.innerHTML = assertion.message || (assertion.result ? "okay" : "failed"); + ol.appendChild( li ); + + if ( assertion.result ) { + good++; + } else { + bad++; + config.stats.bad++; + config.moduleStats.bad++; + } + } + + // store result when possible + if ( QUnit.config.reorder && defined.sessionStorage ) { + if (bad) { + sessionStorage.setItem("qunit-" + this.module + "-" + this.testName, bad); + } else { + sessionStorage.removeItem("qunit-" + this.module + "-" + this.testName); + } + } + + if (bad == 0) { + ol.style.display = "none"; + } + + var b = document.createElement("strong"); + b.innerHTML = this.name + " (" + bad + ", " + good + ", " + this.assertions.length + ")"; + + var a = document.createElement("a"); + a.innerHTML = "Rerun"; + a.href = QUnit.url({ filter: getText([b]).replace(/\([^)]+\)$/, "").replace(/(^\s*|\s*$)/g, "") }); + + addEvent(b, "click", function() { + var next = b.nextSibling.nextSibling, + display = next.style.display; + next.style.display = display === "none" ? "block" : "none"; + }); + + addEvent(b, "dblclick", function(e) { + var target = e && e.target ? e.target : window.event.srcElement; + if ( target.nodeName.toLowerCase() == "span" || target.nodeName.toLowerCase() == "b" ) { + target = target.parentNode; + } + if ( window.location && target.nodeName.toLowerCase() === "strong" ) { + window.location = QUnit.url({ filter: getText([target]).replace(/\([^)]+\)$/, "").replace(/(^\s*|\s*$)/g, "") }); + } + }); + + var li = id(this.id); + li.className = bad ? "fail" : "pass"; + li.removeChild( li.firstChild ); + li.appendChild( b ); + li.appendChild( a ); + li.appendChild( ol ); + + } else { + for ( var i = 0; i < this.assertions.length; i++ ) { + if ( !this.assertions[i].result ) { + bad++; + config.stats.bad++; + config.moduleStats.bad++; + } + } + } + + try { + QUnit.reset(); + } catch(e) { + fail("reset() failed, following Test " + this.testName + ", exception and reset fn follows", e, QUnit.reset); + } + + QUnit.testDone( { + name: this.testName, + failed: bad, + passed: this.assertions.length - bad, + total: this.assertions.length + } ); + }, + + queue: function() { + var test = this; + synchronize(function() { + test.init(); + }); + function run() { + // each of these can by async + synchronize(function() { + test.setup(); + }); + synchronize(function() { + test.run(); + }); + synchronize(function() { + test.teardown(); + }); + synchronize(function() { + test.finish(); + }); + } + // defer when previous test run passed, if storage is available + var bad = QUnit.config.reorder && defined.sessionStorage && +sessionStorage.getItem("qunit-" + this.module + "-" + this.testName); + if (bad) { + run(); + } else { + synchronize(run); + }; + } + +}; + +var QUnit = { + + // call on start of module test to prepend name to all tests + module: function(name, testEnvironment) { + config.currentModule = name; + config.currentModuleTestEnviroment = testEnvironment; + }, + + asyncTest: function(testName, expected, callback) { + if ( arguments.length === 2 ) { + callback = expected; + expected = 0; + } + + QUnit.test(testName, expected, callback, true); + }, + + test: function(testName, expected, callback, async) { + var name = '' + testName + '', testEnvironmentArg; + + if ( arguments.length === 2 ) { + callback = expected; + expected = null; + } + // is 2nd argument a testEnvironment? + if ( expected && typeof expected === 'object') { + testEnvironmentArg = expected; + expected = null; + } + + if ( config.currentModule ) { + name = '' + config.currentModule + ": " + name; + } + + if ( !validTest(config.currentModule + ": " + testName) ) { + return; + } + + var test = new Test(name, testName, expected, testEnvironmentArg, async, callback); + test.module = config.currentModule; + test.moduleTestEnvironment = config.currentModuleTestEnviroment; + test.queue(); + }, + + /** + * Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through. + */ + expect: function(asserts) { + config.current.expected = asserts; + }, + + /** + * Asserts true. + * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" ); + */ + ok: function(a, msg) { + a = !!a; + var details = { + result: a, + message: msg + }; + msg = escapeHtml(msg); + QUnit.log(details); + config.current.assertions.push({ + result: a, + message: msg + }); + }, + + /** + * Checks that the first two arguments are equal, with an optional message. + * Prints out both actual and expected values. + * + * Prefered to ok( actual == expected, message ) + * + * @example equal( format("Received {0} bytes.", 2), "Received 2 bytes." ); + * + * @param Object actual + * @param Object expected + * @param String message (optional) + */ + equal: function(actual, expected, message) { + QUnit.push(expected == actual, actual, expected, message); + }, + + notEqual: function(actual, expected, message) { + QUnit.push(expected != actual, actual, expected, message); + }, + + deepEqual: function(actual, expected, message) { + QUnit.push(QUnit.equiv(actual, expected), actual, expected, message); + }, + + notDeepEqual: function(actual, expected, message) { + QUnit.push(!QUnit.equiv(actual, expected), actual, expected, message); + }, + + strictEqual: function(actual, expected, message) { + QUnit.push(expected === actual, actual, expected, message); + }, + + notStrictEqual: function(actual, expected, message) { + QUnit.push(expected !== actual, actual, expected, message); + }, + + raises: function(block, expected, message) { + var actual, ok = false; + + if (typeof expected === 'string') { + message = expected; + expected = null; + } + + try { + block(); + } catch (e) { + actual = e; + } + + if (actual) { + // we don't want to validate thrown error + if (!expected) { + ok = true; + // expected is a regexp + } else if (QUnit.objectType(expected) === "regexp") { + ok = expected.test(actual); + // expected is a constructor + } else if (actual instanceof expected) { + ok = true; + // expected is a validation function which returns true is validation passed + } else if (expected.call({}, actual) === true) { + ok = true; + } + } + + QUnit.ok(ok, message); + }, + + start: function() { + config.semaphore--; + if (config.semaphore > 0) { + // don't start until equal number of stop-calls + return; + } + if (config.semaphore < 0) { + // ignore if start is called more often then stop + config.semaphore = 0; + } + // A slight delay, to avoid any current callbacks + if ( defined.setTimeout ) { + window.setTimeout(function() { + if ( config.timeout ) { + clearTimeout(config.timeout); + } + + config.blocking = false; + process(); + }, 13); + } else { + config.blocking = false; + process(); + } + }, + + stop: function(timeout) { + config.semaphore++; + config.blocking = true; + + if ( timeout && defined.setTimeout ) { + clearTimeout(config.timeout); + config.timeout = window.setTimeout(function() { + QUnit.ok( false, "Test timed out" ); + QUnit.start(); + }, timeout); + } + } +}; + +// Backwards compatibility, deprecated +QUnit.equals = QUnit.equal; +QUnit.same = QUnit.deepEqual; + +// Maintain internal state +var config = { + // The queue of tests to run + queue: [], + + // block until document ready + blocking: true, + + // by default, run previously failed tests first + // very useful in combination with "Hide passed tests" checked + reorder: true, + + noglobals: false, + notrycatch: false +}; + +// Load paramaters +(function() { + var location = window.location || { search: "", protocol: "file:" }, + params = location.search.slice( 1 ).split( "&" ), + length = params.length, + urlParams = {}, + current; + + if ( params[ 0 ] ) { + for ( var i = 0; i < length; i++ ) { + current = params[ i ].split( "=" ); + current[ 0 ] = decodeURIComponent( current[ 0 ] ); + // allow just a key to turn on a flag, e.g., test.html?noglobals + current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true; + urlParams[ current[ 0 ] ] = current[ 1 ]; + if ( current[ 0 ] in config ) { + config[ current[ 0 ] ] = current[ 1 ]; + } + } + } + + QUnit.urlParams = urlParams; + config.filter = urlParams.filter; + + // Figure out if we're running the tests from a server or not + QUnit.isLocal = !!(location.protocol === 'file:'); +})(); + +// Expose the API as global variables, unless an 'exports' +// object exists, in that case we assume we're in CommonJS +if ( typeof exports === "undefined" || typeof require === "undefined" ) { + extend(window, QUnit); + window.QUnit = QUnit; +} else { + extend(exports, QUnit); + exports.QUnit = QUnit; +} + +// define these after exposing globals to keep them in these QUnit namespace only +extend(QUnit, { + config: config, + + // Initialize the configuration options + init: function() { + extend(config, { + stats: { all: 0, bad: 0 }, + moduleStats: { all: 0, bad: 0 }, + started: +new Date, + updateRate: 1000, + blocking: false, + autostart: true, + autorun: false, + filter: "", + queue: [], + semaphore: 0 + }); + + var tests = id( "qunit-tests" ), + banner = id( "qunit-banner" ), + result = id( "qunit-testresult" ); + + if ( tests ) { + tests.innerHTML = ""; + } + + if ( banner ) { + banner.className = ""; + } + + if ( result ) { + result.parentNode.removeChild( result ); + } + + if ( tests ) { + result = document.createElement( "p" ); + result.id = "qunit-testresult"; + result.className = "result"; + tests.parentNode.insertBefore( result, tests ); + result.innerHTML = 'Running...
       '; + } + }, + + /** + * Resets the test setup. Useful for tests that modify the DOM. + * + * If jQuery is available, uses jQuery's html(), otherwise just innerHTML. + */ + reset: function() { + if ( window.jQuery ) { + jQuery( "#qunit-fixture" ).html( config.fixture ); + } else { + var main = id( 'qunit-fixture' ); + if ( main ) { + main.innerHTML = config.fixture; + } + } + }, + + /** + * Trigger an event on an element. + * + * @example triggerEvent( document.body, "click" ); + * + * @param DOMElement elem + * @param String type + */ + triggerEvent: function( elem, type, event ) { + if ( document.createEvent ) { + event = document.createEvent("MouseEvents"); + event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView, + 0, 0, 0, 0, 0, false, false, false, false, 0, null); + elem.dispatchEvent( event ); + + } else if ( elem.fireEvent ) { + elem.fireEvent("on"+type); + } + }, + + // Safe object type checking + is: function( type, obj ) { + return QUnit.objectType( obj ) == type; + }, + + objectType: function( obj ) { + if (typeof obj === "undefined") { + return "undefined"; + + // consider: typeof null === object + } + if (obj === null) { + return "null"; + } + + var type = Object.prototype.toString.call( obj ) + .match(/^\[object\s(.*)\]$/)[1] || ''; + + switch (type) { + case 'Number': + if (isNaN(obj)) { + return "nan"; + } else { + return "number"; + } + case 'String': + case 'Boolean': + case 'Array': + case 'Date': + case 'RegExp': + case 'Function': + return type.toLowerCase(); + } + if (typeof obj === "object") { + return "object"; + } + return undefined; + }, + + push: function(result, actual, expected, message) { + var details = { + result: result, + message: message, + actual: actual, + expected: expected + }; + + message = escapeHtml(message) || (result ? "okay" : "failed"); + message = '' + message + ""; + expected = escapeHtml(QUnit.jsDump.parse(expected)); + actual = escapeHtml(QUnit.jsDump.parse(actual)); + var output = message + '
      '; + if (actual != expected) { + output += ''; + output += ''; + } + if (!result) { + var source = sourceFromStacktrace(); + if (source) { + details.source = source; + output += ''; + } + } + output += "
      Expected:
      ' + expected + '
      Result:
      ' + actual + '
      Diff:
      ' + QUnit.diff(expected, actual) +'
      Source:
      ' + escapeHtml(source) + '
      "; + + QUnit.log(details); + + config.current.assertions.push({ + result: !!result, + message: output + }); + }, + + url: function( params ) { + params = extend( extend( {}, QUnit.urlParams ), params ); + var querystring = "?", + key; + for ( key in params ) { + querystring += encodeURIComponent( key ) + "=" + + encodeURIComponent( params[ key ] ) + "&"; + } + return window.location.pathname + querystring.slice( 0, -1 ); + }, + + // Logging callbacks; all receive a single argument with the listed properties + // run test/logs.html for any related changes + begin: function() {}, + // done: { failed, passed, total, runtime } + done: function() {}, + // log: { result, actual, expected, message } + log: function() {}, + // testStart: { name } + testStart: function() {}, + // testDone: { name, failed, passed, total } + testDone: function() {}, + // moduleStart: { name } + moduleStart: function() {}, + // moduleDone: { name, failed, passed, total } + moduleDone: function() {} +}); + +if ( typeof document === "undefined" || document.readyState === "complete" ) { + config.autorun = true; +} + +addEvent(window, "load", function() { + QUnit.begin({}); + + // Initialize the config, saving the execution queue + var oldconfig = extend({}, config); + QUnit.init(); + extend(config, oldconfig); + + config.blocking = false; + + var userAgent = id("qunit-userAgent"); + if ( userAgent ) { + userAgent.innerHTML = navigator.userAgent; + } + var banner = id("qunit-header"); + if ( banner ) { + banner.innerHTML = ' ' + banner.innerHTML + ' ' + + '' + + ''; + addEvent( banner, "change", function( event ) { + var params = {}; + params[ event.target.name ] = event.target.checked ? true : undefined; + window.location = QUnit.url( params ); + }); + } + + var toolbar = id("qunit-testrunner-toolbar"); + if ( toolbar ) { + var filter = document.createElement("input"); + filter.type = "checkbox"; + filter.id = "qunit-filter-pass"; + addEvent( filter, "click", function() { + var ol = document.getElementById("qunit-tests"); + if ( filter.checked ) { + ol.className = ol.className + " hidepass"; + } else { + var tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " "; + ol.className = tmp.replace(/ hidepass /, " "); + } + if ( defined.sessionStorage ) { + if (filter.checked) { + sessionStorage.setItem("qunit-filter-passed-tests", "true"); + } else { + sessionStorage.removeItem("qunit-filter-passed-tests"); + } + } + }); + if ( defined.sessionStorage && sessionStorage.getItem("qunit-filter-passed-tests") ) { + filter.checked = true; + var ol = document.getElementById("qunit-tests"); + ol.className = ol.className + " hidepass"; + } + toolbar.appendChild( filter ); + + var label = document.createElement("label"); + label.setAttribute("for", "qunit-filter-pass"); + label.innerHTML = "Hide passed tests"; + toolbar.appendChild( label ); + } + + var main = id('qunit-fixture'); + if ( main ) { + config.fixture = main.innerHTML; + } + + if (config.autostart) { + QUnit.start(); + } +}); + +function done() { + config.autorun = true; + + // Log the last module results + if ( config.currentModule ) { + QUnit.moduleDone( { + name: config.currentModule, + failed: config.moduleStats.bad, + passed: config.moduleStats.all - config.moduleStats.bad, + total: config.moduleStats.all + } ); + } + + var banner = id("qunit-banner"), + tests = id("qunit-tests"), + runtime = +new Date - config.started, + passed = config.stats.all - config.stats.bad, + html = [ + 'Tests completed in ', + runtime, + ' milliseconds.
      ', + '', + passed, + ' tests of ', + config.stats.all, + ' passed, ', + config.stats.bad, + ' failed.' + ].join(''); + + if ( banner ) { + banner.className = (config.stats.bad ? "qunit-fail" : "qunit-pass"); + } + + if ( tests ) { + id( "qunit-testresult" ).innerHTML = html; + } + + if ( typeof document !== "undefined" && document.title ) { + // show ✖ for good, ✔ for bad suite result in title + // use escape sequences in case file gets loaded with non-utf-8-charset + document.title = (config.stats.bad ? "\u2716" : "\u2714") + " " + document.title; + } + + QUnit.done( { + failed: config.stats.bad, + passed: passed, + total: config.stats.all, + runtime: runtime + } ); +} + +function validTest( name ) { + var filter = config.filter, + run = false; + + if ( !filter ) { + return true; + } + + var not = filter.charAt( 0 ) === "!"; + if ( not ) { + filter = filter.slice( 1 ); + } + + if ( name.indexOf( filter ) !== -1 ) { + return !not; + } + + if ( not ) { + run = true; + } + + return run; +} + +// so far supports only Firefox, Chrome and Opera (buggy) +// could be extended in the future to use something like https://github.com/csnover/TraceKit +function sourceFromStacktrace() { + try { + throw new Error(); + } catch ( e ) { + if (e.stacktrace) { + // Opera + return e.stacktrace.split("\n")[6]; + } else if (e.stack) { + // Firefox, Chrome + return e.stack.split("\n")[4]; + } + } +} + +function escapeHtml(s) { + if (!s) { + return ""; + } + s = s + ""; + return s.replace(/[\&"<>\\]/g, function(s) { + switch(s) { + case "&": return "&"; + case "\\": return "\\\\"; + case '"': return '\"'; + case "<": return "<"; + case ">": return ">"; + default: return s; + } + }); +} + +function synchronize( callback ) { + config.queue.push( callback ); + + if ( config.autorun && !config.blocking ) { + process(); + } +} + +function process() { + var start = (new Date()).getTime(); + + while ( config.queue.length && !config.blocking ) { + if ( config.updateRate <= 0 || (((new Date()).getTime() - start) < config.updateRate) ) { + config.queue.shift()(); + } else { + window.setTimeout( process, 13 ); + break; + } + } + if (!config.blocking && !config.queue.length) { + done(); + } +} + +function saveGlobal() { + config.pollution = []; + + if ( config.noglobals ) { + for ( var key in window ) { + config.pollution.push( key ); + } + } +} + +function checkPollution( name ) { + var old = config.pollution; + saveGlobal(); + + var newGlobals = diff( config.pollution, old ); + if ( newGlobals.length > 0 ) { + ok( false, "Introduced global variable(s): " + newGlobals.join(", ") ); + } + + var deletedGlobals = diff( old, config.pollution ); + if ( deletedGlobals.length > 0 ) { + ok( false, "Deleted global variable(s): " + deletedGlobals.join(", ") ); + } +} + +// returns a new Array with the elements that are in a but not in b +function diff( a, b ) { + var result = a.slice(); + for ( var i = 0; i < result.length; i++ ) { + for ( var j = 0; j < b.length; j++ ) { + if ( result[i] === b[j] ) { + result.splice(i, 1); + i--; + break; + } + } + } + return result; +} + +function fail(message, exception, callback) { + if ( typeof console !== "undefined" && console.error && console.warn ) { + console.error(message); + console.error(exception); + console.warn(callback.toString()); + + } else if ( window.opera && opera.postError ) { + opera.postError(message, exception, callback.toString); + } +} + +function extend(a, b) { + for ( var prop in b ) { + if ( b[prop] === undefined ) { + delete a[prop]; + } else { + a[prop] = b[prop]; + } + } + + return a; +} + +function addEvent(elem, type, fn) { + if ( elem.addEventListener ) { + elem.addEventListener( type, fn, false ); + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, fn ); + } else { + fn(); + } +} + +function id(name) { + return !!(typeof document !== "undefined" && document && document.getElementById) && + document.getElementById( name ); +} + +// Test for equality any JavaScript type. +// Discussions and reference: http://philrathe.com/articles/equiv +// Test suites: http://philrathe.com/tests/equiv +// Author: Philippe Rathé +QUnit.equiv = function () { + + var innerEquiv; // the real equiv function + var callers = []; // stack to decide between skip/abort functions + var parents = []; // stack to avoiding loops from circular referencing + + // Call the o related callback with the given arguments. + function bindCallbacks(o, callbacks, args) { + var prop = QUnit.objectType(o); + if (prop) { + if (QUnit.objectType(callbacks[prop]) === "function") { + return callbacks[prop].apply(callbacks, args); + } else { + return callbacks[prop]; // or undefined + } + } + } + + var callbacks = function () { + + // for string, boolean, number and null + function useStrictEquality(b, a) { + if (b instanceof a.constructor || a instanceof b.constructor) { + // to catch short annotaion VS 'new' annotation of a declaration + // e.g. var i = 1; + // var j = new Number(1); + return a == b; + } else { + return a === b; + } + } + + return { + "string": useStrictEquality, + "boolean": useStrictEquality, + "number": useStrictEquality, + "null": useStrictEquality, + "undefined": useStrictEquality, + + "nan": function (b) { + return isNaN(b); + }, + + "date": function (b, a) { + return QUnit.objectType(b) === "date" && a.valueOf() === b.valueOf(); + }, + + "regexp": function (b, a) { + return QUnit.objectType(b) === "regexp" && + a.source === b.source && // the regex itself + a.global === b.global && // and its modifers (gmi) ... + a.ignoreCase === b.ignoreCase && + a.multiline === b.multiline; + }, + + // - skip when the property is a method of an instance (OOP) + // - abort otherwise, + // initial === would have catch identical references anyway + "function": function () { + var caller = callers[callers.length - 1]; + return caller !== Object && + typeof caller !== "undefined"; + }, + + "array": function (b, a) { + var i, j, loop; + var len; + + // b could be an object literal here + if ( ! (QUnit.objectType(b) === "array")) { + return false; + } + + len = a.length; + if (len !== b.length) { // safe and faster + return false; + } + + //track reference to avoid circular references + parents.push(a); + for (i = 0; i < len; i++) { + loop = false; + for(j=0;j= 0) { + type = "array"; + } else { + type = typeof obj; + } + return type; + }, + separator:function() { + return this.multiline ? this.HTML ? '
      ' : '\n' : this.HTML ? ' ' : ' '; + }, + indent:function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing + if ( !this.multiline ) + return ''; + var chr = this.indentChar; + if ( this.HTML ) + chr = chr.replace(/\t/g,' ').replace(/ /g,' '); + return Array( this._depth_ + (extra||0) ).join(chr); + }, + up:function( a ) { + this._depth_ += a || 1; + }, + down:function( a ) { + this._depth_ -= a || 1; + }, + setParser:function( name, parser ) { + this.parsers[name] = parser; + }, + // The next 3 are exposed so you can use them + quote:quote, + literal:literal, + join:join, + // + _depth_: 1, + // This is the list of parsers, to modify them, use jsDump.setParser + parsers:{ + window: '[Window]', + document: '[Document]', + error:'[ERROR]', //when no parser is found, shouldn't happen + unknown: '[Unknown]', + 'null':'null', + 'undefined':'undefined', + 'function':function( fn ) { + var ret = 'function', + name = 'name' in fn ? fn.name : (reName.exec(fn)||[])[1];//functions never have name in IE + if ( name ) + ret += ' ' + name; + ret += '('; + + ret = [ ret, QUnit.jsDump.parse( fn, 'functionArgs' ), '){'].join(''); + return join( ret, QUnit.jsDump.parse(fn,'functionCode'), '}' ); + }, + array: array, + nodelist: array, + arguments: array, + object:function( map ) { + var ret = [ ]; + QUnit.jsDump.up(); + for ( var key in map ) + ret.push( QUnit.jsDump.parse(key,'key') + ': ' + QUnit.jsDump.parse(map[key]) ); + QUnit.jsDump.down(); + return join( '{', ret, '}' ); + }, + node:function( node ) { + var open = QUnit.jsDump.HTML ? '<' : '<', + close = QUnit.jsDump.HTML ? '>' : '>'; + + var tag = node.nodeName.toLowerCase(), + ret = open + tag; + + for ( var a in QUnit.jsDump.DOMAttrs ) { + var val = node[QUnit.jsDump.DOMAttrs[a]]; + if ( val ) + ret += ' ' + a + '=' + QUnit.jsDump.parse( val, 'attribute' ); + } + return ret + close + open + '/' + tag + close; + }, + functionArgs:function( fn ) {//function calls it internally, it's the arguments part of the function + var l = fn.length; + if ( !l ) return ''; + + var args = Array(l); + while ( l-- ) + args[l] = String.fromCharCode(97+l);//97 is 'a' + return ' ' + args.join(', ') + ' '; + }, + key:quote, //object calls it internally, the key part of an item in a map + functionCode:'[code]', //function calls it internally, it's the content of the function + attribute:quote, //node calls it internally, it's an html attribute value + string:quote, + date:quote, + regexp:literal, //regex + number:literal, + 'boolean':literal + }, + DOMAttrs:{//attributes to dump from nodes, name=>realName + id:'id', + name:'name', + 'class':'className' + }, + HTML:false,//if true, entities are escaped ( <, >, \t, space and \n ) + indentChar:' ',//indentation unit + multiline:true //if true, items in a collection, are separated by a \n, else just a space. + }; + + return jsDump; +})(); + +// from Sizzle.js +function getText( elems ) { + var ret = "", elem; + + for ( var i = 0; elems[i]; i++ ) { + elem = elems[i]; + + // Get the text from text nodes and CDATA nodes + if ( elem.nodeType === 3 || elem.nodeType === 4 ) { + ret += elem.nodeValue; + + // Traverse everything else, except comment nodes + } else if ( elem.nodeType !== 8 ) { + ret += getText( elem.childNodes ); + } + } + + return ret; +}; + +/* + * Javascript Diff Algorithm + * By John Resig (http://ejohn.org/) + * Modified by Chu Alan "sprite" + * + * Released under the MIT license. + * + * More Info: + * http://ejohn.org/projects/javascript-diff-algorithm/ + * + * Usage: QUnit.diff(expected, actual) + * + * QUnit.diff("the quick brown fox jumped over", "the quick fox jumps over") == "the quick brown fox jumped jumps over" + */ +QUnit.diff = (function() { + function diff(o, n){ + var ns = new Object(); + var os = new Object(); + + for (var i = 0; i < n.length; i++) { + if (ns[n[i]] == null) + ns[n[i]] = { + rows: new Array(), + o: null + }; + ns[n[i]].rows.push(i); + } + + for (var i = 0; i < o.length; i++) { + if (os[o[i]] == null) + os[o[i]] = { + rows: new Array(), + n: null + }; + os[o[i]].rows.push(i); + } + + for (var i in ns) { + if (ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1) { + n[ns[i].rows[0]] = { + text: n[ns[i].rows[0]], + row: os[i].rows[0] + }; + o[os[i].rows[0]] = { + text: o[os[i].rows[0]], + row: ns[i].rows[0] + }; + } + } + + for (var i = 0; i < n.length - 1; i++) { + if (n[i].text != null && n[i + 1].text == null && n[i].row + 1 < o.length && o[n[i].row + 1].text == null && + n[i + 1] == o[n[i].row + 1]) { + n[i + 1] = { + text: n[i + 1], + row: n[i].row + 1 + }; + o[n[i].row + 1] = { + text: o[n[i].row + 1], + row: i + 1 + }; + } + } + + for (var i = n.length - 1; i > 0; i--) { + if (n[i].text != null && n[i - 1].text == null && n[i].row > 0 && o[n[i].row - 1].text == null && + n[i - 1] == o[n[i].row - 1]) { + n[i - 1] = { + text: n[i - 1], + row: n[i].row - 1 + }; + o[n[i].row - 1] = { + text: o[n[i].row - 1], + row: i - 1 + }; + } + } + + return { + o: o, + n: n + }; + } + + return function(o, n){ + o = o.replace(/\s+$/, ''); + n = n.replace(/\s+$/, ''); + var out = diff(o == "" ? [] : o.split(/\s+/), n == "" ? [] : n.split(/\s+/)); + + var str = ""; + + var oSpace = o.match(/\s+/g); + if (oSpace == null) { + oSpace = [" "]; + } + else { + oSpace.push(" "); + } + var nSpace = n.match(/\s+/g); + if (nSpace == null) { + nSpace = [" "]; + } + else { + nSpace.push(" "); + } + + if (out.n.length == 0) { + for (var i = 0; i < out.o.length; i++) { + str += '' + out.o[i] + oSpace[i] + ""; + } + } + else { + if (out.n[0].text == null) { + for (n = 0; n < out.o.length && out.o[n].text == null; n++) { + str += '' + out.o[n] + oSpace[n] + ""; + } + } + + for (var i = 0; i < out.n.length; i++) { + if (out.n[i].text == null) { + str += '' + out.n[i] + nSpace[i] + ""; + } + else { + var pre = ""; + + for (n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++) { + pre += '' + out.o[n] + oSpace[n] + ""; + } + str += " " + out.n[i].text + nSpace[i] + pre; + } + } + } + + return str; + }; +})(); + +})(this); diff --git a/php/kindeditor_demo/kindeditor/license.txt b/php/kindeditor_demo/kindeditor/license.txt new file mode 100755 index 0000000..4362b49 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/license.txt @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/php/kindeditor_demo/kindeditor/package.json b/php/kindeditor_demo/kindeditor/package.json new file mode 100755 index 0000000..03181c2 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/package.json @@ -0,0 +1,11 @@ +{ + "name" : "KindEditor", + "version" : "4.1.11", + "filename" : "kindeditor", + "devDependencies" : { + "grunt": "~0.4.1", + "grunt-contrib-concat": "~0.3.0", + "grunt-contrib-uglify": "~0.2.7", + "grunt-contrib-compress": "~0.5.3" + } +} diff --git a/php/kindeditor_demo/kindeditor/php/JSON.php b/php/kindeditor_demo/kindeditor/php/JSON.php new file mode 100755 index 0000000..0cddbdd --- /dev/null +++ b/php/kindeditor_demo/kindeditor/php/JSON.php @@ -0,0 +1,806 @@ + + * @author Matt Knapp + * @author Brett Stimmerman + * @copyright 2005 Michal Migurski + * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $ + * @license http://www.opensource.org/licenses/bsd-license.php + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 + */ + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_SLICE', 1); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_STR', 2); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_ARR', 3); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_OBJ', 4); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_CMT', 5); + +/** + * Behavior switch for Services_JSON::decode() + */ +define('SERVICES_JSON_LOOSE_TYPE', 16); + +/** + * Behavior switch for Services_JSON::decode() + */ +define('SERVICES_JSON_SUPPRESS_ERRORS', 32); + +/** + * Converts to and from JSON format. + * + * Brief example of use: + * + * + * // create a new instance of Services_JSON + * $json = new Services_JSON(); + * + * // convert a complexe value to JSON notation, and send it to the browser + * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4))); + * $output = $json->encode($value); + * + * print($output); + * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]] + * + * // accept incoming POST data, assumed to be in JSON notation + * $input = file_get_contents('php://input', 1000000); + * $value = $json->decode($input); + * + */ +class Services_JSON +{ + /** + * constructs a new JSON instance + * + * @param int $use object behavior flags; combine with boolean-OR + * + * possible values: + * - SERVICES_JSON_LOOSE_TYPE: loose typing. + * "{...}" syntax creates associative arrays + * instead of objects in decode(). + * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression. + * Values which can't be encoded (e.g. resources) + * appear as NULL instead of throwing errors. + * By default, a deeply-nested resource will + * bubble up with an error, so all return values + * from encode() should be checked with isError() + */ + function Services_JSON($use = 0) + { + $this->use = $use; + } + + /** + * convert a string from one UTF-16 char to one UTF-8 char + * + * Normally should be handled by mb_convert_encoding, but + * provides a slower PHP-only method for installations + * that lack the multibye string extension. + * + * @param string $utf16 UTF-16 character + * @return string UTF-8 character + * @access private + */ + function utf162utf8($utf16) + { + // oh please oh please oh please oh please oh please + if(function_exists('mb_convert_encoding')) { + return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16'); + } + + $bytes = (ord($utf16{0}) << 8) | ord($utf16{1}); + + switch(true) { + case ((0x7F & $bytes) == $bytes): + // this case should never be reached, because we are in ASCII range + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0x7F & $bytes); + + case (0x07FF & $bytes) == $bytes: + // return a 2-byte UTF-8 character + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0xC0 | (($bytes >> 6) & 0x1F)) + . chr(0x80 | ($bytes & 0x3F)); + + case (0xFFFF & $bytes) == $bytes: + // return a 3-byte UTF-8 character + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0xE0 | (($bytes >> 12) & 0x0F)) + . chr(0x80 | (($bytes >> 6) & 0x3F)) + . chr(0x80 | ($bytes & 0x3F)); + } + + // ignoring UTF-32 for now, sorry + return ''; + } + + /** + * convert a string from one UTF-8 char to one UTF-16 char + * + * Normally should be handled by mb_convert_encoding, but + * provides a slower PHP-only method for installations + * that lack the multibye string extension. + * + * @param string $utf8 UTF-8 character + * @return string UTF-16 character + * @access private + */ + function utf82utf16($utf8) + { + // oh please oh please oh please oh please oh please + if(function_exists('mb_convert_encoding')) { + return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); + } + + switch(strlen($utf8)) { + case 1: + // this case should never be reached, because we are in ASCII range + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return $utf8; + + case 2: + // return a UTF-16 character from a 2-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0x07 & (ord($utf8{0}) >> 2)) + . chr((0xC0 & (ord($utf8{0}) << 6)) + | (0x3F & ord($utf8{1}))); + + case 3: + // return a UTF-16 character from a 3-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr((0xF0 & (ord($utf8{0}) << 4)) + | (0x0F & (ord($utf8{1}) >> 2))) + . chr((0xC0 & (ord($utf8{1}) << 6)) + | (0x7F & ord($utf8{2}))); + } + + // ignoring UTF-32 for now, sorry + return ''; + } + + /** + * encodes an arbitrary variable into JSON format + * + * @param mixed $var any number, boolean, string, array, or object to be encoded. + * see argument 1 to Services_JSON() above for array-parsing behavior. + * if var is a strng, note that encode() always expects it + * to be in ASCII or UTF-8 format! + * + * @return mixed JSON string representation of input var or an error if a problem occurs + * @access public + */ + function encode($var) + { + switch (gettype($var)) { + case 'boolean': + return $var ? 'true' : 'false'; + + case 'NULL': + return 'null'; + + case 'integer': + return (int) $var; + + case 'double': + case 'float': + return (float) $var; + + case 'string': + // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT + $ascii = ''; + $strlen_var = strlen($var); + + /* + * Iterate over every character in the string, + * escaping with a slash or encoding to UTF-8 where necessary + */ + for ($c = 0; $c < $strlen_var; ++$c) { + + $ord_var_c = ord($var{$c}); + + switch (true) { + case $ord_var_c == 0x08: + $ascii .= '\b'; + break; + case $ord_var_c == 0x09: + $ascii .= '\t'; + break; + case $ord_var_c == 0x0A: + $ascii .= '\n'; + break; + case $ord_var_c == 0x0C: + $ascii .= '\f'; + break; + case $ord_var_c == 0x0D: + $ascii .= '\r'; + break; + + case $ord_var_c == 0x22: + case $ord_var_c == 0x2F: + case $ord_var_c == 0x5C: + // double quote, slash, slosh + $ascii .= '\\'.$var{$c}; + break; + + case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): + // characters U-00000000 - U-0000007F (same as ASCII) + $ascii .= $var{$c}; + break; + + case (($ord_var_c & 0xE0) == 0xC0): + // characters U-00000080 - U-000007FF, mask 110XXXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, ord($var{$c + 1})); + $c += 1; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xF0) == 0xE0): + // characters U-00000800 - U-0000FFFF, mask 1110XXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2})); + $c += 2; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xF8) == 0xF0): + // characters U-00010000 - U-001FFFFF, mask 11110XXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3})); + $c += 3; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xFC) == 0xF8): + // characters U-00200000 - U-03FFFFFF, mask 111110XX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4})); + $c += 4; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xFE) == 0xFC): + // characters U-04000000 - U-7FFFFFFF, mask 1111110X + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4}), + ord($var{$c + 5})); + $c += 5; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + } + } + + return '"'.$ascii.'"'; + + case 'array': + /* + * As per JSON spec if any array key is not an integer + * we must treat the the whole array as an object. We + * also try to catch a sparsely populated associative + * array with numeric keys here because some JS engines + * will create an array with empty indexes up to + * max_index which can cause memory issues and because + * the keys, which may be relevant, will be remapped + * otherwise. + * + * As per the ECMA and JSON specification an object may + * have any string as a property. Unfortunately due to + * a hole in the ECMA specification if the key is a + * ECMA reserved word or starts with a digit the + * parameter is only accessible using ECMAScript's + * bracket notation. + */ + + // treat as a JSON object + if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { + $properties = array_map(array($this, 'name_value'), + array_keys($var), + array_values($var)); + + foreach($properties as $property) { + if(Services_JSON::isError($property)) { + return $property; + } + } + + return '{' . join(',', $properties) . '}'; + } + + // treat it like a regular array + $elements = array_map(array($this, 'encode'), $var); + + foreach($elements as $element) { + if(Services_JSON::isError($element)) { + return $element; + } + } + + return '[' . join(',', $elements) . ']'; + + case 'object': + $vars = get_object_vars($var); + + $properties = array_map(array($this, 'name_value'), + array_keys($vars), + array_values($vars)); + + foreach($properties as $property) { + if(Services_JSON::isError($property)) { + return $property; + } + } + + return '{' . join(',', $properties) . '}'; + + default: + return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS) + ? 'null' + : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string"); + } + } + + /** + * array-walking function for use in generating JSON-formatted name-value pairs + * + * @param string $name name of key to use + * @param mixed $value reference to an array element to be encoded + * + * @return string JSON-formatted name-value pair, like '"name":value' + * @access private + */ + function name_value($name, $value) + { + $encoded_value = $this->encode($value); + + if(Services_JSON::isError($encoded_value)) { + return $encoded_value; + } + + return $this->encode(strval($name)) . ':' . $encoded_value; + } + + /** + * reduce a string by removing leading and trailing comments and whitespace + * + * @param $str string string value to strip of comments and whitespace + * + * @return string string value stripped of comments and whitespace + * @access private + */ + function reduce_string($str) + { + $str = preg_replace(array( + + // eliminate single line comments in '// ...' form + '#^\s*//(.+)$#m', + + // eliminate multi-line comments in '/* ... */' form, at start of string + '#^\s*/\*(.+)\*/#Us', + + // eliminate multi-line comments in '/* ... */' form, at end of string + '#/\*(.+)\*/\s*$#Us' + + ), '', $str); + + // eliminate extraneous space + return trim($str); + } + + /** + * decodes a JSON string into appropriate variable + * + * @param string $str JSON-formatted string + * + * @return mixed number, boolean, string, array, or object + * corresponding to given JSON input string. + * See argument 1 to Services_JSON() above for object-output behavior. + * Note that decode() always returns strings + * in ASCII or UTF-8 format! + * @access public + */ + function decode($str) + { + $str = $this->reduce_string($str); + + switch (strtolower($str)) { + case 'true': + return true; + + case 'false': + return false; + + case 'null': + return null; + + default: + $m = array(); + + if (is_numeric($str)) { + // Lookie-loo, it's a number + + // This would work on its own, but I'm trying to be + // good about returning integers where appropriate: + // return (float)$str; + + // Return float or int, as appropriate + return ((float)$str == (integer)$str) + ? (integer)$str + : (float)$str; + + } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) { + // STRINGS RETURNED IN UTF-8 FORMAT + $delim = substr($str, 0, 1); + $chrs = substr($str, 1, -1); + $utf8 = ''; + $strlen_chrs = strlen($chrs); + + for ($c = 0; $c < $strlen_chrs; ++$c) { + + $substr_chrs_c_2 = substr($chrs, $c, 2); + $ord_chrs_c = ord($chrs{$c}); + + switch (true) { + case $substr_chrs_c_2 == '\b': + $utf8 .= chr(0x08); + ++$c; + break; + case $substr_chrs_c_2 == '\t': + $utf8 .= chr(0x09); + ++$c; + break; + case $substr_chrs_c_2 == '\n': + $utf8 .= chr(0x0A); + ++$c; + break; + case $substr_chrs_c_2 == '\f': + $utf8 .= chr(0x0C); + ++$c; + break; + case $substr_chrs_c_2 == '\r': + $utf8 .= chr(0x0D); + ++$c; + break; + + case $substr_chrs_c_2 == '\\"': + case $substr_chrs_c_2 == '\\\'': + case $substr_chrs_c_2 == '\\\\': + case $substr_chrs_c_2 == '\\/': + if (($delim == '"' && $substr_chrs_c_2 != '\\\'') || + ($delim == "'" && $substr_chrs_c_2 != '\\"')) { + $utf8 .= $chrs{++$c}; + } + break; + + case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)): + // single, escaped unicode character + $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) + . chr(hexdec(substr($chrs, ($c + 4), 2))); + $utf8 .= $this->utf162utf8($utf16); + $c += 5; + break; + + case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F): + $utf8 .= $chrs{$c}; + break; + + case ($ord_chrs_c & 0xE0) == 0xC0: + // characters U-00000080 - U-000007FF, mask 110XXXXX + //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 2); + ++$c; + break; + + case ($ord_chrs_c & 0xF0) == 0xE0: + // characters U-00000800 - U-0000FFFF, mask 1110XXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 3); + $c += 2; + break; + + case ($ord_chrs_c & 0xF8) == 0xF0: + // characters U-00010000 - U-001FFFFF, mask 11110XXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 4); + $c += 3; + break; + + case ($ord_chrs_c & 0xFC) == 0xF8: + // characters U-00200000 - U-03FFFFFF, mask 111110XX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 5); + $c += 4; + break; + + case ($ord_chrs_c & 0xFE) == 0xFC: + // characters U-04000000 - U-7FFFFFFF, mask 1111110X + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 6); + $c += 5; + break; + + } + + } + + return $utf8; + + } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) { + // array, or object notation + + if ($str{0} == '[') { + $stk = array(SERVICES_JSON_IN_ARR); + $arr = array(); + } else { + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $stk = array(SERVICES_JSON_IN_OBJ); + $obj = array(); + } else { + $stk = array(SERVICES_JSON_IN_OBJ); + $obj = new stdClass(); + } + } + + array_push($stk, array('what' => SERVICES_JSON_SLICE, + 'where' => 0, + 'delim' => false)); + + $chrs = substr($str, 1, -1); + $chrs = $this->reduce_string($chrs); + + if ($chrs == '') { + if (reset($stk) == SERVICES_JSON_IN_ARR) { + return $arr; + + } else { + return $obj; + + } + } + + //print("\nparsing {$chrs}\n"); + + $strlen_chrs = strlen($chrs); + + for ($c = 0; $c <= $strlen_chrs; ++$c) { + + $top = end($stk); + $substr_chrs_c_2 = substr($chrs, $c, 2); + + if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) { + // found a comma that is not inside a string, array, etc., + // OR we've reached the end of the character list + $slice = substr($chrs, $top['where'], ($c - $top['where'])); + array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); + //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + if (reset($stk) == SERVICES_JSON_IN_ARR) { + // we are in an array, so just push an element onto the stack + array_push($arr, $this->decode($slice)); + + } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { + // we are in an object, so figure + // out the property name and set an + // element in an associative array, + // for now + $parts = array(); + + if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { + // "name":value pair + $key = $this->decode($parts[1]); + $val = $this->decode($parts[2]); + + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $obj[$key] = $val; + } else { + $obj->$key = $val; + } + } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { + // name:value pair, where name is unquoted + $key = $parts[1]; + $val = $this->decode($parts[2]); + + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $obj[$key] = $val; + } else { + $obj->$key = $val; + } + } + + } + + } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) { + // found a quote, and we are not inside a string + array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); + //print("Found start of string at {$c}\n"); + + } elseif (($chrs{$c} == $top['delim']) && + ($top['what'] == SERVICES_JSON_IN_STR) && + ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) { + // found a quote, we're in a string, and it's not escaped + // we know that it's not escaped becase there is _not_ an + // odd number of backslashes at the end of the string so far + array_pop($stk); + //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n"); + + } elseif (($chrs{$c} == '[') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a left-bracket, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false)); + //print("Found start of array at {$c}\n"); + + } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) { + // found a right-bracket, and we're in an array + array_pop($stk); + //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } elseif (($chrs{$c} == '{') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a left-brace, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false)); + //print("Found start of object at {$c}\n"); + + } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) { + // found a right-brace, and we're in an object + array_pop($stk); + //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } elseif (($substr_chrs_c_2 == '/*') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a comment start, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false)); + $c++; + //print("Found start of comment at {$c}\n"); + + } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) { + // found a comment end, and we're in one now + array_pop($stk); + $c++; + + for ($i = $top['where']; $i <= $c; ++$i) + $chrs = substr_replace($chrs, ' ', $i, 1); + + //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } + + } + + if (reset($stk) == SERVICES_JSON_IN_ARR) { + return $arr; + + } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { + return $obj; + + } + + } + } + } + + /** + * @todo Ultimately, this should just call PEAR::isError() + */ + function isError($data, $code = null) + { + if (class_exists('pear')) { + return PEAR::isError($data, $code); + } elseif (is_object($data) && (get_class($data) == 'services_json_error' || + is_subclass_of($data, 'services_json_error'))) { + return true; + } + + return false; + } +} + +if (class_exists('PEAR_Error')) { + + class Services_JSON_Error extends PEAR_Error + { + function Services_JSON_Error($message = 'unknown error', $code = null, + $mode = null, $options = null, $userinfo = null) + { + parent::PEAR_Error($message, $code, $mode, $options, $userinfo); + } + } + +} else { + + /** + * @todo Ultimately, this class shall be descended from PEAR_Error + */ + class Services_JSON_Error + { + function Services_JSON_Error($message = 'unknown error', $code = null, + $mode = null, $options = null, $userinfo = null) + { + + } + } + +} + +?> diff --git a/php/kindeditor_demo/kindeditor/php/demo.php b/php/kindeditor_demo/kindeditor/php/demo.php new file mode 100755 index 0000000..c63f07a --- /dev/null +++ b/php/kindeditor_demo/kindeditor/php/demo.php @@ -0,0 +1,53 @@ + + + + + + KindEditor PHP + + + + + + + + + +
      + +
      + (提交快捷键: Ctrl + Enter) +
      + + + diff --git a/php/kindeditor_demo/kindeditor/php/file_manager_json.php b/php/kindeditor_demo/kindeditor/php/file_manager_json.php new file mode 100755 index 0000000..8ce443f --- /dev/null +++ b/php/kindeditor_demo/kindeditor/php/file_manager_json.php @@ -0,0 +1,137 @@ + 2); //文件夹是否包含文件 + $file_list[$i]['filesize'] = 0; //文件大小 + $file_list[$i]['is_photo'] = false; //是否图片 + $file_list[$i]['filetype'] = ''; //文件类别,用扩展名判断 + } else { + $file_list[$i]['is_dir'] = false; + $file_list[$i]['has_file'] = false; + $file_list[$i]['filesize'] = filesize($file); + $file_list[$i]['dir_path'] = ''; + $file_ext = strtolower(pathinfo($file, PATHINFO_EXTENSION)); + $file_list[$i]['is_photo'] = in_array($file_ext, $ext_arr); + $file_list[$i]['filetype'] = $file_ext; + } + $file_list[$i]['filename'] = $filename; //文件名,包含扩展名 + $file_list[$i]['datetime'] = date('Y-m-d H:i:s', filemtime($file)); //文件最后修改时间 + $i++; + } + closedir($handle); +} + +//排序 +function cmp_func($a, $b) { + global $order; + if ($a['is_dir'] && !$b['is_dir']) { + return -1; + } else if (!$a['is_dir'] && $b['is_dir']) { + return 1; + } else { + if ($order == 'size') { + if ($a['filesize'] > $b['filesize']) { + return 1; + } else if ($a['filesize'] < $b['filesize']) { + return -1; + } else { + return 0; + } + } else if ($order == 'type') { + return strcmp($a['filetype'], $b['filetype']); + } else { + return strcmp($a['filename'], $b['filename']); + } + } +} +usort($file_list, 'cmp_func'); + +$result = array(); +//相对于根目录的上一级目录 +$result['moveup_dir_path'] = $moveup_dir_path; +//相对于根目录的当前目录 +$result['current_dir_path'] = $current_dir_path; +//当前目录的URL +$result['current_url'] = $current_url; +//文件数 +$result['total_count'] = count($file_list); +//文件列表数组 +$result['file_list'] = $file_list; + +//输出JSON字符串 +header('Content-type: application/json; charset=UTF-8'); +$json = new Services_JSON(); +echo $json->encode($result); diff --git a/php/kindeditor_demo/kindeditor/php/upload_json.php b/php/kindeditor_demo/kindeditor/php/upload_json.php new file mode 100755 index 0000000..bca41f9 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/php/upload_json.php @@ -0,0 +1,140 @@ + array('gif', 'jpg', 'jpeg', 'png', 'bmp'), + 'flash' => array('swf', 'flv'), + 'media' => array('swf', 'flv', 'mp3', 'wav', 'wma', 'wmv', 'mid', 'avi', 'mpg', 'asf', 'rm', 'rmvb'), + 'file' => array('doc', 'docx', 'xls', 'xlsx', 'ppt', 'htm', 'html', 'txt', 'zip', 'rar', 'gz', 'bz2'), +); +//最大文件大小 +$max_size = 1000000; + +//$save_path = realpath($save_path) . '/'; + +//PHP上传失败 +if (!empty($_FILES['imgFile']['error'])) { + switch($_FILES['imgFile']['error']){ + case '1': + $error = '超过php.ini允许的大小。'; + break; + case '2': + $error = '超过表单允许的大小。'; + break; + case '3': + $error = '图片只有部分被上传。'; + break; + case '4': + $error = '请选择图片。'; + break; + case '6': + $error = '找不到临时目录。'; + break; + case '7': + $error = '写文件到硬盘出错。'; + break; + case '8': + $error = 'File upload stopped by extension。'; + break; + case '999': + default: + $error = '未知错误。'; + } + alert($error); +} + +//有上传文件时 +if (empty($_FILES) === false) { + //原文件名 + $file_name = $_FILES['imgFile']['name']; + //服务器上临时文件名 + $tmp_name = $_FILES['imgFile']['tmp_name']; + //文件大小 + $file_size = $_FILES['imgFile']['size']; + //alert($save_path);die; + //检查文件名 + if (!$file_name) { + alert("请选择文件。"); + } + //检查目录 + if (@is_dir($save_path) === false) { + alert("上传目录不存在。"); + } + //检查目录写权限 + if (@is_writable($save_path) === false) { + alert("上传目录没有写权限。"); + } + //检查是否已上传 + if (@is_uploaded_file($tmp_name) === false) { + alert("上传失败。"); + } + //检查文件大小 + if ($file_size > $max_size) { + alert("上传文件大小超过限制。"); + } + //检查目录名 + $dir_name = empty($_GET['dir']) ? 'image' : trim($_GET['dir']); + if (empty($ext_arr[$dir_name])) { + alert("目录名不正确。"); + } + //获得文件扩展名 + $temp_arr = explode(".", $file_name); + $file_ext = array_pop($temp_arr); + $file_ext = trim($file_ext); + $file_ext = strtolower($file_ext); + //检查扩展名 + if (in_array($file_ext, $ext_arr[$dir_name]) === false) { + alert("上传文件扩展名是不允许的扩展名。\n只允许" . implode(",", $ext_arr[$dir_name]) . "格式。"); + } + //创建文件夹 + if ($dir_name !== '') { + $save_path .= $dir_name . "/"; + $save_url .= $dir_name . "/"; + if (!file_exists($save_path)) { + mkdir($save_path); + } + } + $ymd = date("Ymd"); + $save_path .= $ymd . "/"; + $save_url .= $ymd . "/"; + if (!file_exists($save_path)) { + mkdir($save_path); + } + //新文件名 + $new_file_name = date("YmdHis") . '_' . rand(10000, 99999) . '.' . $file_ext; + //移动文件 + $file_path = $save_path . $new_file_name; + if (move_uploaded_file($tmp_name, $file_path) === false) { + alert("上传文件失败。"); + } + @chmod($file_path, 0644); + $file_url = $save_url . $new_file_name; + + header('Content-type: text/html; charset=UTF-8'); + $json = new Services_JSON(); + echo $json->encode(array('error' => 0, 'url' => $file_url)); + exit; +} + +function alert($msg) { + header('Content-type: text/html; charset=UTF-8'); + $json = new Services_JSON(); + echo $json->encode(array('error' => 1, 'message' => $msg)); + exit; +} diff --git a/php/kindeditor_demo/kindeditor/plugins/anchor/anchor.js b/php/kindeditor_demo/kindeditor/plugins/anchor/anchor.js new file mode 100755 index 0000000..55ab894 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/plugins/anchor/anchor.js @@ -0,0 +1,46 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('anchor', function(K) { + var self = this, name = 'anchor', lang = self.lang(name + '.'); + self.plugin.anchor = { + edit : function() { + var html = ['
      ', + '
      ', + '', + '', + '
      ', + '
      '].join(''); + var dialog = self.createDialog({ + name : name, + width : 300, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + self.insertHtml('').hideDialog().focus(); + } + } + }); + var div = dialog.div, + nameBox = K('input[name="name"]', div); + var img = self.plugin.getSelectedAnchor(); + if (img) { + nameBox.val(unescape(img.attr('data-ke-name'))); + } + nameBox[0].focus(); + nameBox[0].select(); + }, + 'delete' : function() { + self.plugin.getSelectedAnchor().remove(); + } + }; + self.clickToolbar(name, self.plugin.anchor.edit); +}); diff --git a/php/kindeditor_demo/kindeditor/plugins/autoheight/autoheight.js b/php/kindeditor_demo/kindeditor/plugins/autoheight/autoheight.js new file mode 100755 index 0000000..546578b --- /dev/null +++ b/php/kindeditor_demo/kindeditor/plugins/autoheight/autoheight.js @@ -0,0 +1,54 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('autoheight', function(K) { + var self = this; + + if (!self.autoHeightMode) { + return; + } + + var minHeight; + + function hideScroll() { + var edit = self.edit; + var body = edit.doc.body; + edit.iframe[0].scroll = 'no'; + body.style.overflowY = 'hidden'; + } + + function resetHeight() { + var edit = self.edit; + var body = edit.doc.body; + edit.iframe.height(minHeight); + self.resize(null, Math.max((K.IE ? body.scrollHeight : body.offsetHeight) + 76, minHeight)); + } + + function init() { + minHeight = K.removeUnit(self.height); + + self.edit.afterChange(resetHeight); + hideScroll(); + resetHeight(); + } + + if (self.isCreated) { + init(); + } else { + self.afterCreate(init); + } +}); + +/* +* 如何实现真正的自动高度? +* 修改编辑器高度之后,再次获取body内容高度时,最小值只会是当前iframe的设置高度,这样就导致高度只增不减。 +* 所以每次获取body内容高度之前,先将iframe的高度重置为最小高度,这样就能获取body的实际高度。 +* 由此就实现了真正的自动高度 +* 测试:chrome、firefox、IE9、IE8 +* */ diff --git a/php/kindeditor_demo/kindeditor/plugins/baidumap/baidumap.js b/php/kindeditor_demo/kindeditor/plugins/baidumap/baidumap.js new file mode 100755 index 0000000..12751c4 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/plugins/baidumap/baidumap.js @@ -0,0 +1,93 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +// Baidu Maps: http://dev.baidu.com/wiki/map/index.php?title=%E9%A6%96%E9%A1%B5 + +KindEditor.plugin('baidumap', function(K) { + var self = this, name = 'baidumap', lang = self.lang(name + '.'); + var mapWidth = K.undef(self.mapWidth, 558); + var mapHeight = K.undef(self.mapHeight, 360); + self.clickToolbar(name, function() { + var html = ['
      ', + '
      ', + // left start + '
      ', + lang.address + ' ', + '', + '', + '', + '
      ', + // right start + '
      ', + ' ', + '
      ', + '
      ', + '
      ', + '
      ', + '
      '].join(''); + var dialog = self.createDialog({ + name : name, + width : mapWidth + 42, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var map = win.map; + var centerObj = map.getCenter(); + var center = centerObj.lng + ',' + centerObj.lat; + var zoom = map.getZoom(); + var url = [checkbox[0].checked ? self.pluginsPath + 'baidumap/index.html' : 'http://api.map.baidu.com/staticimage', + '?center=' + encodeURIComponent(center), + '&zoom=' + encodeURIComponent(zoom), + '&width=' + mapWidth, + '&height=' + mapHeight, + '&markers=' + encodeURIComponent(center), + '&markerStyles=' + encodeURIComponent('l,A')].join(''); + if (checkbox[0].checked) { + self.insertHtml(''); + } else { + self.exec('insertimage', url); + } + self.hideDialog().focus(); + } + }, + beforeRemove : function() { + searchBtn.remove(); + if (doc) { + doc.write(''); + } + iframe.remove(); + } + }); + var div = dialog.div, + addressBox = K('[name="address"]', div), + searchBtn = K('[name="searchBtn"]', div), + checkbox = K('[name="insertDynamicMap"]', dialog.div), + win, doc; + var iframe = K(''); + function ready() { + win = iframe[0].contentWindow; + doc = K.iframeDoc(iframe); + } + iframe.bind('load', function() { + iframe.unbind('load'); + if (K.IE) { + ready(); + } else { + setTimeout(ready, 0); + } + }); + K('.ke-map', div).replaceWith(iframe); + // search map + searchBtn.click(function() { + win.search(addressBox.val()); + }); + }); +}); diff --git a/php/kindeditor_demo/kindeditor/plugins/baidumap/index.html b/php/kindeditor_demo/kindeditor/plugins/baidumap/index.html new file mode 100755 index 0000000..e106d1a --- /dev/null +++ b/php/kindeditor_demo/kindeditor/plugins/baidumap/index.html @@ -0,0 +1,83 @@ + + + + + + +百度地图API自定义地图 + + + + + + + +
      + + + \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/plugins/baidumap/map.html b/php/kindeditor_demo/kindeditor/plugins/baidumap/map.html new file mode 100755 index 0000000..b65ea1d --- /dev/null +++ b/php/kindeditor_demo/kindeditor/plugins/baidumap/map.html @@ -0,0 +1,43 @@ + + + + + Baidu Maps + + + + + +
      + + diff --git a/php/kindeditor_demo/kindeditor/plugins/clearhtml/clearhtml.js b/php/kindeditor_demo/kindeditor/plugins/clearhtml/clearhtml.js new file mode 100755 index 0000000..96ee5fe --- /dev/null +++ b/php/kindeditor_demo/kindeditor/plugins/clearhtml/clearhtml.js @@ -0,0 +1,29 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('clearhtml', function(K) { + var self = this, name = 'clearhtml'; + self.clickToolbar(name, function() { + self.focus(); + var html = self.html(); + html = html.replace(/(]*>)([\s\S]*?)(<\/script>)/ig, ''); + html = html.replace(/(]*>)([\s\S]*?)(<\/style>)/ig, ''); + html = K.formatHtml(html, { + a : ['href', 'target'], + embed : ['src', 'width', 'height', 'type', 'loop', 'autostart', 'quality', '.width', '.height', 'align', 'allowscriptaccess'], + img : ['src', 'width', 'height', 'border', 'alt', 'title', '.width', '.height'], + table : ['border'], + 'td,th' : ['rowspan', 'colspan'], + 'div,hr,br,tbody,tr,p,ol,ul,li,blockquote,h1,h2,h3,h4,h5,h6' : [] + }); + self.html(html); + self.cmd.selection(true); + self.addBookmark(); + }); +}); diff --git a/php/kindeditor_demo/kindeditor/plugins/code/code.js b/php/kindeditor_demo/kindeditor/plugins/code/code.js new file mode 100755 index 0000000..67fde02 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/plugins/code/code.js @@ -0,0 +1,62 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +// google code prettify: http://google-code-prettify.googlecode.com/ +// http://google-code-prettify.googlecode.com/ + +KindEditor.plugin('code', function(K) { + var self = this, name = 'code'; + self.clickToolbar(name, function() { + var lang = self.lang(name + '.'), + html = ['
      ', + '
      ', + '', + '
      ', + '', + '
      '].join(''), + dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var type = K('.ke-code-type', dialog.div).val(), + code = textarea.val(), + cls = type === '' ? '' : ' lang-' + type, + html = '
      \n' + K.escape(code) + '
      '; + if (K.trim(code) === '') { + alert(lang.pleaseInput); + textarea[0].focus(); + return; + } + self.insertHtml(html).hideDialog().focus(); + } + } + }), + textarea = K('textarea', dialog.div); + textarea[0].focus(); + }); +}); diff --git a/php/kindeditor_demo/kindeditor/plugins/code/prettify.css b/php/kindeditor_demo/kindeditor/plugins/code/prettify.css new file mode 100755 index 0000000..b8287e5 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/plugins/code/prettify.css @@ -0,0 +1,13 @@ +.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} + +pre.prettyprint { + border: 0; + border-left: 3px solid rgb(204, 204, 204); + margin-left: 2em; + padding: 0.5em; + font-size: 110%; + display: block; + font-family: "Consolas", "Monaco", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace; + margin: 1em 0px; + white-space: pre; +} diff --git a/php/kindeditor_demo/kindeditor/plugins/code/prettify.js b/php/kindeditor_demo/kindeditor/plugins/code/prettify.js new file mode 100755 index 0000000..eef5ad7 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/plugins/code/prettify.js @@ -0,0 +1,28 @@ +var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; +(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= +[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), +l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, +q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, +q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, +"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), +a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} +for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], +"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], +H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], +J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ +I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), +["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", +/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), +["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", +hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b= +!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('emoticons', function(K) { + var self = this, name = 'emoticons', + path = (self.emoticonsPath || self.pluginsPath + 'emoticons/images/'), + allowPreview = self.allowPreviewEmoticons === undefined ? true : self.allowPreviewEmoticons, + currentPageNum = 1; + self.clickToolbar(name, function() { + var rows = 5, cols = 9, total = 135, startNum = 0, + cells = rows * cols, pages = Math.ceil(total / cells), + colsHalf = Math.floor(cols / 2), + wrapperDiv = K('
      '), + elements = [], + menu = self.createMenu({ + name : name, + beforeRemove : function() { + removeEvent(); + } + }); + menu.div.append(wrapperDiv); + var previewDiv, previewImg; + if (allowPreview) { + previewDiv = K('
      ').css('right', 0); + previewImg = K(''); + wrapperDiv.append(previewDiv); + previewDiv.append(previewImg); + } + function bindCellEvent(cell, j, num) { + if (previewDiv) { + cell.mouseover(function() { + if (j > colsHalf) { + previewDiv.css('left', 0); + previewDiv.css('right', ''); + } else { + previewDiv.css('left', ''); + previewDiv.css('right', 0); + } + previewImg.attr('src', path + num + '.gif'); + K(this).addClass('ke-on'); + }); + } else { + cell.mouseover(function() { + K(this).addClass('ke-on'); + }); + } + cell.mouseout(function() { + K(this).removeClass('ke-on'); + }); + cell.click(function(e) { + self.insertHtml('').hideMenu().focus(); + e.stop(); + }); + } + function createEmoticonsTable(pageNum, parentDiv) { + var table = document.createElement('table'); + parentDiv.append(table); + if (previewDiv) { + K(table).mouseover(function() { + previewDiv.show('block'); + }); + K(table).mouseout(function() { + previewDiv.hide(); + }); + elements.push(K(table)); + } + table.className = 'ke-table'; + table.cellPadding = 0; + table.cellSpacing = 0; + table.border = 0; + var num = (pageNum - 1) * cells + startNum; + for (var i = 0; i < rows; i++) { + var row = table.insertRow(i); + for (var j = 0; j < cols; j++) { + var cell = K(row.insertCell(j)); + cell.addClass('ke-cell'); + bindCellEvent(cell, j, num); + var span = K('') + .css('background-position', '-' + (24 * num) + 'px 0px') + .css('background-image', 'url(' + path + 'static.gif)'); + cell.append(span); + elements.push(cell); + num++; + } + } + return table; + } + var table = createEmoticonsTable(currentPageNum, wrapperDiv); + function removeEvent() { + K.each(elements, function() { + this.unbind(); + }); + } + var pageDiv; + function bindPageEvent(el, pageNum) { + el.click(function(e) { + removeEvent(); + table.parentNode.removeChild(table); + pageDiv.remove(); + table = createEmoticonsTable(pageNum, wrapperDiv); + createPageTable(pageNum); + currentPageNum = pageNum; + e.stop(); + }); + } + function createPageTable(currentPageNum) { + pageDiv = K('
      '); + wrapperDiv.append(pageDiv); + for (var pageNum = 1; pageNum <= pages; pageNum++) { + if (currentPageNum !== pageNum) { + var a = K('
      [' + pageNum + ']'); + bindPageEvent(a, pageNum); + pageDiv.append(a); + elements.push(a); + } else { + pageDiv.append(K('@[' + pageNum + ']')); + } + pageDiv.append(K('@ ')); + } + } + createPageTable(currentPageNum); + }); +}); diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/0.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/0.gif new file mode 100755 index 0000000000000000000000000000000000000000..5be27cb0ecf9a21240e151962f59f94a2ce361ad GIT binary patch literal 1810 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 Shl-B7SjC>-k*5?OVgCTyq&`gm literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/10.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/10.gif new file mode 100755 index 0000000000000000000000000000000000000000..905c15be3cee3fca3e8f0e48f0ffcfeb911def34 GIT binary patch literal 3716 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 R>#ZWQrxckyZhN#X{wJwfMcn`Z literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/100.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/100.gif new file mode 100755 index 0000000000000000000000000000000000000000..92ad35d2bf72018f7b5bec0b607625ccd29f42bd GIT binary patch literal 1780 zcmZwHdsLEV9Ki7x@Ri%Ef+C?=+)TlH%2JOmLGhM`nyy@Bd9PLLxN6Hv?bSM5|*tMqKmb=B#dWi@kY95vI!5>wMuCL?bhJwAUu|9(He=lO+4hWYuYPyhm?-PwZ?cV+Riot%>eBnKWr{ zZ@h?nmyvOfOfvZRv^;JxLeN!L_OldZf&`XK{^eq0VQu^YWvoWL9iK32 z6Ulgd79QVQh%Tc*$4ie+7z}NB0S{j36h%d6E6$zIjbFbd8NxtMG7vQ>Zn`RuU$c1q zl@8C^yZdyyuKw|-Ee%G4p}FaiPOsmcQ|jnI6&?~d|K0icg}$x3`{s>my~!C6%54Qt{{ zk;kQumybFJZ`a&>Kk=V&>d=jNL1;pJ2ro9&+rtZmFfq}`%&<5>1h|>*rXf)P0Ikar z!D2~Xet}dbFH|UtiltGB5SO#TRuvDO^n^IvPm36y0K^n9nE*3N=?*f57Xcv?icvav zGAY8fLJG6OUm@^Zg{)smG#3aqDwa55%`=Ez=2$12t%ZS35H^s|9j$jLkm8j(gqd1?R`b9U&P*SbPhKN#DNKv;F-h%RO)B680#`5Ib?)Zq$)QEzS?0>3!5k}r+Zgk)kehSk!?JYFX0 zfL6*UT!5FG(Gl2nw8i?{7xt@4j^uqLC|jK1(gK3YX@bUS0#o&@!83Qcsd>%-+(eOf zaRhS)f-X@0I6F?AoQuL*G^dxeY|okLPvdH!6q;Zdg_MPcZL5>Sc~|j|vbGhm<(fN1 zCCmhjR|zsSTQPj za933h!G%Y%Fq$jnRKi{$VdK91XvzwUs07)bb0s)NSWzs!mX9MXquYaa!QDAip%iO= zkAfZyn=kX$IBU?Ma!Z`IrVbV52nX5@(=gbm#A`d+?J-mJr1|gN__01OQ(mBuP^rn{ z83S>0N#14z6^@6_PD#L2#O8b<%bQ_gt0(A- zi+xi{Z@I;-kQbM^NGblod4LT&cAuozE*(>XTF-ZU&P|OVT=2=q*adu3r?~ufImthO zRi|KB5f4t%iH?`lXkJ8Jd&AAkFS#F-zy(`jRw-}qw}%S~>@)LCO0zG;q$Kh7XCHJH z#Y2^IPLcrDJSh?TXSUdx>J86YHO9d92&&lL*&d#+#mWZ{eefEZ@}htW(SUEZFZ7cP zxLd2l+Ti|8OUMbcz-JFcN2rovB*uv}c(;522Jsj|ETvCfOI~i69LVatk2J$tJgJp^ zcR#YwgKabnq~*e=PX}cr*Rxq-s+ncZI3ibK`6y_0ha?Vp-Sn4MmtCNxc4KUj(G}cB z#Lh2NbiQRGu_PTOqw`peO%z7O?smFQr}g1jN4=WnBM;0TFW{?w|FBGWx2n1xs+db~ HW3bjH9`VF z0A@izbRrT&p+2kC-1qYbfO;Z%Yqy$YNa;4Avz_^)qoZIQq%_e3 zi_&+rVBAmH{yPlbkss#nvejpsPje_alSBfE#IcqFkV3f*0IRH4(XjePWGYCeptSW! zNF~+xJ;vam-(vt6FS2?rwPhI5Dnr?2 zLY6|I@ZvjHRaCsor6eRJ73AkH%&J>yh7Hx_^CHnu+U}W&S7RVJn!ZP!khsv(AAe5q zrZ+8?N{vdqT3gfDEc1H)a%!~U+M8+hWR%e)2o4O7bc$%5Q4XQUB3k9!o^1fsUDg3B zSDs0d4>cFWQ1LAD6(L6=6fwuU=#eGf11 z5C)@Dy3UMl+S>MLxV3Nwj}HtHjlBD$qEOP8;qLQ*g0v&0rKKKxeo1jDSnlv;>gKqs z8#rwD?q&arnlrA;^==vA_t^lC0gErUm>opI^z`)j#6(klReM{9qn*R+)*I?(8rZ|C zy}0-7SOt5d+rmuA_1xPpp7yrhJ_R=Dl>tCSMp)0ipPs2A;{f2q(SSz?t)|TVB9UnJ zGSQM`SpCb6k1zAU8qC~C^2Edh_+r(R3>Y758|Z7zw#Ck60!kdNSRcD>i*Hw13L1lJ zQk@`Ta8r4V;{fnx;I1=AF!QbgysXi5)j#oU_{V!?%B#xRmX^LSO-DOk+V_I?Q2gYl zPfh8;(?Vg^aaYjH+{MXd=G4!J4g{)-iokD&2I_e5e7w1APu@x^YmLPr259pzI2-^0 z*5Z9}NeBRd00B^&A}CZ=#~}2V?`|y2s6B($4q2O0=;w%cJq-);mJ`=FBVwD96=zc~ z!r_tfc`dDr*S>Goy-W1n7pG(9K5CbSL1~pkS0C(kKs54FtxaoEJvkLB*w%G4BsSjEUV13(s< zuB0OX^A$UlrlU$KAnsG&j})TgXqwz5q&l`zP(`u7`UbZ%jxAGe_`xe19h;kMyqsWY zY&A@Wa~1D@zbVi4Iv_Ma?L+M?im6WEIO>{F=BPuuOdvk8icgZew+l8Q;jpiS+9qEK zApjgO0I-XMN52xzO-R`igg$cJxkIj3^g%zSd+)nC9M#+7h`=e3UX3!m)aNM7=fo~C zhWk3fvpFh#wY#ri{x&rJ=<3Qpl3j`=^$Gpq5hc?T-H-I|1Y#G2%~V(p>}>SBCIsIt z#%D`tVRvr!-1e`P8R@L1etU<;UquN!5$o+GZCH*$=p|2W^%rNmA2!5Ivd!q#1Y3b0 z(Iv+D91^`ANugy^$b4T)5eCYWxQZ*?lP+&l3DFRHmv&DKU7DbeL7`|691Umr#duw@ zf7MRuF-_LGtTCRBB4(G8kbxe=I2c=mhemvekzmYsp%03o^*+(S{InQ2mkoc;GA^h5 z*ptDH-#$B2ZNbfKX@#k+V3Yi`u*xO&;E)ORo@yg3=jDNc9}k?*X--+ar|%q5LjWUzfoaRJ_zQP`Xym*r#6E8JmV{Lt;2-?Udn1-idjxslx z2G@8(&tK&~M7)&)Wmbg4k{%$9FB?}Xqd&gDmGl#FEVGIhNonF@dY3s?{x2mvHO+l$A?SsBs5>;vCR#7@7zA>;qD3idVn0=SEh*V4-C!YI;0r`b>BD^usnSD`^mq_S&q%4jH~rJ5BvJ32mS7BmwXg!v4+UA&eI84`%eJnAN&9S literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/102.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/102.gif new file mode 100755 index 0000000000000000000000000000000000000000..748ded1ac4351e1ee26715098281d70099355c20 GIT binary patch literal 1446 zcmV;X1zGw>Nk%w1VHf}y0Qdg@784Y{mRB1ZAO9H{F)lQU7Zer}8zdDL2nPub3=<V;{P+IG!Mo^*2l;e# zc!Gp_dwOkibpOc#(<399B_(%xdqGA=8xO7mPKijCsw>b-D5A{ZS> zMpE_g=?@VU|KBsxbRqEn|AQbG(~wS@LKFJ`|5{mUz{SVI!pGs6T=Dn*mYbdC@&BW# ztNbD&ZY3o;HAU5B0BCM>b$x-`nfW}~w076EcHqH|=EaGrr?36_$+nYD%b{ZC)xpc9X3A|E-@=ERo}T}^I7LWF z#-Cm0%&&135bD^O?Ax2pt8Zv4E4v;Zmlzevoo$~S79tfGm>3pBMM(DW=*AlwrWh8Z z8yo-s|NsC0A^!_bMO0HmK~P09E-(WD0000X`2-0l0RI3i000007yuXm00{p8{|OvO zu%N+%2oow?$dKW(VxAHz+u_5200M0ap6a6s;T}wdM6t7W?UJ-|`o1~hL~WEVTLo1} zfklWwEGKo=xH3d5-X>7BW_dG6g~WpgU>=Y#kRVJoc#)zhoRLTpuTZieJxGuM0mEI+ zkX1;Qs=@~iV;p#0SScT=3I|?kdy;0$87OoX-UE>99GN`El!Pb&!bOoQ3L8wZbj;nO z0tM*tn3#$Y2SiVi$U?$qGWrAi7oTD;KEfCLt3;6DKY03rDV1t>3Lg45qtk<{ zSQ8{b&`eoIJSP>^n4ovB%rY|gol?CLAcPcU}vEa3KAkf zE*L+40(c7(7EXxZ#^4tq5v(YT!A4FL9e9%5sllO3l@xGj@j^oc7HHss{{#d8JFMlS A?*IS* literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/103.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/103.gif new file mode 100755 index 0000000000000000000000000000000000000000..be9eaa05445ef7dbb0c709fbca695bbf06c47ec3 GIT binary patch literal 2166 zcmZwHcT`hZ0>|+b%F81HDZIpxkS;~Q(8hoWB3%XPT_K<&u&7~l6g!cGAfSRU9vnew zBCd#lD+oA8LK7GZO;A=@LgFlnN?=@ID0v%a&)Ku%&i(8D{kh-Y_4f7RI||4MGGYNn zn3-Ex+SwftgwZK%oF3@(%_al_p|6K0;wW4ehk?VhC?)2)v8|-bZ?bqUshW8>_Mr3#*LJxTOlMmw7PdBMt8dH8H2JS@~f<}r@OM|axR+1F3<)d=ISFV#eGWhI`*dDHXbsO~j zbrCkD(&2U_l|b$vovhc5R#(3~kY30nQIsXS-p$PQWe2_3i%=gL??N4;vpH$s2?oW^ zD+}r&RAwLY^zzmU4$~5^kDFhH2M;sVxg&Q?qi8fbi?Ny2-43<9WY}PT-q`Bz?G0BVUkv>`{_5${5n%ZQW_o7E7&2BU z6nAvO;2KmInF8tR z&aja;O4ZVmy|wKo7v~$`=9_vha4Y|L3XTGT!>PsOFXhf1|Q0(%=8Lg#~zi z{=A8aY7tibz2l9@zV?`}V(Pt8rH21u2X`A3C40}$&p*uz9m?~EM=f8D|Dqn^%~o?) z@0cs|8L{ik-_NNRir2EJ7VxBl)5eXH@7}MBew6psPCl(GB10!){jXD@p`jsoWyQ_Q zdz*zpMEJg_$Ydj|feMBp9Cda%p zD_ri)Q+|K(_R-M+mX?-U!qHY{Rv}h~!xb3=@yL$$$C3>3Sy9&QXnMzf`qQV+>+9|- zE}JwqHUcz@>*J22KtB8eI~1` zt3F;4{yRbmII{5j?@169Ms#Z)S#y}Mp1)^Eu)AA;r>!*)jnvf7{7nl(M8F73&0RAR zG6Dh2AYcsDr><0%0T3)=dg{tLq=wq_)1=v}nZU!dewA|7xD)nX(T+0KUY2L(TVB5f z_fln{mMIA$3nwmP@p?XaJ=_{*23pqxpgF}wyQe^ukU&8n{^s`3<2IkUeSU?M>wp~L znfzEkbCl)52x9lL!)oI#0~-#ONdU;@WY*kdS0~p1WfdZ1x7jv7iFq&~{-F3t7SL)M_M$O@eq zxuYr|A0No-5Rwyr03Cz2X&2}@VEMxBI_I=GKFapdJedeB^8k#T;@a91hUy{{13V?> z+l#G3lbZSiv;zYtZ!LQOx@JMW<5nN~OJzA`FO-|(--5fbTqF_7XS=!ew%VAS1PX=Q z^D%@{&%-uapn-9{%gKPEHWB*_Zq>I@Hc66nVYJC^XE_b7F_uxe%cPC+0=8Sq6&^Av z;m5A#61amJhqx^twuyE0~ zzI7q}&p_a>K|0Rd?H-Qruig3Rv;oP6Q76zwIgpa7bw_`AnUrc)UpODc>MDgW^lNE4i@?1_@SV%J~SS*|2(kg zB51@{<%xokKnmGrhHVdlJ<9f$eB0oPanx!B1!?Kn0&$Bcz6b(#!k83aH>V3py zWj%pmRpU_j%~sta`(smkX6@P|-1Qk=5$5;0v6pcS{_A-JOH&HN8Q8a|5YK5!DPEKd zb)-aeu&_v^DJ27m{6eA){*mPCR+t@vQ)4#O4pm=Bs`vkwjeOZ#faZ@#k1R!xTiQe$ e?@94nEypxIE?Z90HwUXGgh0i@41h)l&RS!Wv$ueHqELvrGzNsL8Lv6 zmX#K*+F@vA4bveo-Mk@D4;Km4Yag&fg_-x4f9in^4)zE1-K*<=s1KD$K@((f%$^{Vamh3fDnp+gvt|1(CELwlFx0JCW8Fov z7ZtnF=)OJ+UxA>#rZ)Y{FN-u99s_5;#~e7yJf~17vk#a}cg?2OZPJLz`}ZHGV{Gp3 zFc_k-vGJfn-El^F+?8Zl3w^W^a(*4lyn|I+eW{8>3KRy_>#x4pi8?{SbvJ0ICnq~Z zK^7N$GmYwor-(x%A6aeSFX4bF*|OE2i$kNA2^RQ4A+s~(Ogkcp00{7B@7X6I0{~(O z0Fm?veWg)}Ak0f@(N~%CaTL=)SB@e8(Z`-Q#;$~v@(^2q>$d0$q=tDs#X0Cw)j?6v zZc7U!R{_C#P)+03%IZ~6n9RRuljW$-s^&b(*28^CV$9L-zSz#Uq>G;?tk}PMILz_tO>pQA&Kcc5-wotw*i*k%*D6@kNXQ=TSmV`y~OQI+A2*=j<@ykvPF zD&qo|xO~JnvSc}%+%TZqO7Yt$j=jU}PeInIeoU(go=7t~q*NFlHdLi>ZZZN=-*n%6 z58p}qjAXAgn%SC_{srMlZAr-?f7E{Jf7?6xv~07UHeSWyrja;nP9(um$QGrNO-i_i zDO9ZJ@(Zb;2W=b#Oub4t0<$u(yVaJX_yRLYseg5^v|cVrOcB9hJ*LcG+do=?Y^v0Y zZ$%qIkY>yIwSHgBPmGVqW&saQ$QnJ-l-rL zXBo8a8GGfYhj0Ijq3}Np?fUB97`{&3bxw0LQ4dh669SKD6XWahFx23K@Rxn>?}i1h zO|yDMC^HYMGE>JyH9Kv))!ml~Xv803fWO1whZ~MZ&it@&$VC+f>6;Q=H8=F&qIJZd zLpO8opA1I|Q!@LpD`zn{U7Xx-IgEU&MVCc?q9G;lI_)&v)(0nA#JVNtoDNp`(zR1l z3oU0+bgt~EpH2?Vrvz&BHLWUhUdi)-?LF~rJrWERJ(QFs(@KgNXUY9l#xraz_56YY zN7f-f_AfAk|NfER!^l5{8TxHiU0og~Q{|1PeC6kDY|6(9 z*#3LAgv4surJWV{0b_!B?{6?qd)8fF`3Vf3Pxm;o#Ta%nsu*A-=Bgc*q9|6+D>5cB*{E>h$3+oud&Xv}QQ&k&t3yj)GXhH*HezH9>ev02-wzwoeBFn$B zkM}DKy@T4WSD4W>X?#boK2)56p)D$zdoAXS$jn`Q46BRTB*o`{mO4gmQ8phc>@~YP z{Ch7>&i|jK%A6hTB^TBEYQM<`&s8*~Hvvi*+%D<~=TDjS$+4^rn`9S)V>mq zGK|o0r8{fHH;gJcl^icaobGh@7BgQ`2wR(O-#~sN;y6^J+{6c_LQH*yRW3Bq?pkBN wx|l)_O!d>nn461#usIsNIVwg@@Rz#Ds{zjGp0s$8P6SQugT>t<8 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/105.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/105.gif new file mode 100755 index 0000000000000000000000000000000000000000..2f353cadc85e447155e636b50ab392a99b36f664 GIT binary patch literal 1277 zcmc(e`%hB`6vrbhS8{tfMJMok#=|m6!5{*R&2Whm)qWZzoY&W`<|2UIX`~$$vHV% zb!ysY5kv$*Qv`e>77GO7v$w;yvfFr00WOR4W`S4noQm_Rz-hqckz_3vl6YDIkBp}` z^UP+BPKGy)XVSQZEnw2w`K`QX8@zJPBgaApyO05IHatp}$p)*2H;0{HbS=kd!Q}GZ zJTN+*G4LJ(+_AhX7XQX`&UkK4!p&~NoD{P%uS15p6woQGI~DX+xaEvPj#&lc%)-11 zb2*sJ^*FSkb*wuN^9Ia_@J7VhMR3KluM^-%gd-WQE%a3Cf;}CMOt_THj1n$2oEo@v ztW%HKe9Rhow-M9pF(u?Cgs^YqY#Z?^#ycJZyTmgsfjtc~Tj$4Bc$1461Dr^st2BpAfz;4E^gEYcvMM z7?imCHeome!)iRu!HCw;rzcx=%#&T**a3JZK!$R?D_L?S+w&eC3So`MKsu;wP)ZCa zU$=>Ew_;#TL7yDfEc7esk>j-EG1`{mj(~3u;@g59t>L&Q9%%d!q!isU^k(v2H*N>< z_Y~;Po-i+)ZjquZ16>MqD$%8UX=xy9rR~+iTfbL!-)?OAaqlmmMAVw3WUXoNF-6m~ z)9JL?Y$Qqgj_-d}6oU1t!tL3LeATAJB!9ofFi}iEU^hV#@xEZbHz5QdnuFGATFf0) zg7DZC5pj>jhF|4>f2>I=J|Caha!FA&Wo4@^s{}RjT^Ur41*~-rb?BDL8fg z^w5$r%SDO(+~x2rgUX!hAChpsbp?4mx1yn`#!zL_rNQ z>c!omYlk1z-z-@KSy1@bF;QGZk46v{jh{Qcj`dR0p_9u?i=Erw4LkIN=bB$%ZPj0{ zURhCW*)BHqn6-6XJI|Lre8lS;ddLcEf1_dG(x*QS$;ul~ge81lB>tlE%B~C7AJpB@ z-wo{jx>|QT<;dRNkl3o^`fm>II~;oD%>A40^6~=**ONuYou++{ip6XCe@Lp_eTLL* zsr#s)GakQ7ft_rb{x3^#1_qV3B(O literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/106.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/106.gif new file mode 100755 index 0000000000000000000000000000000000000000..51935349b48efeac0e0d50a2cc809817015d32b8 GIT binary patch literal 1041 zcmeH`&ubG=5XWCMtq)V>HED1w9`Zt4UCm|b!9Ep?k0ec3@W&P{E)rX|C-+qLVC){$ zWE&!^+LVA+7Sup)#s(x3(S=x>A|BRy$+2KB>&X;6Y`hpZ{u}z8VP=@`=`%2sQ;7*O z#{dR6BIx!6+~@+(D}S3ivMj^0m{P*?R1kPk6fDb>Wl2>PUDqm=vSn=wJSwWt&`_-` zC^GF@pjLzx9h!!_XDC5!6WBGdX}Adu)wNJrLy~}Wg%NqADV!>EjtO)HO9E3fcugUS zh%{9ys)TTu#f(lN#YhuKciU?7utmT&g&GUnJgN{Rv&fN2OBJ1((I&ulT>^?MY*A!V zrfZozi*;3%CCPCd+qO;9Gz>%2G(}NF7s&;4@hIgu4r9zPOz#%|^)Foj|MGeO5J98| z-TMgue}Ec1lB_=ekcENck$idX<5K_H{AzO0w{dUi^+;iGPfp|NB7%@%i;Na zVdTPCJ#?Ao)`zb>Nj5wq`v5r9xOpkLCy^a{Hm!hn=f2$^2&N`F1D*`5ve)l)7E5m$ d2Zp27yXjJPDbROiqyFjr+n@GUu-^+#{{e{R)%O4Z literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/107.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/107.gif new file mode 100755 index 0000000000000000000000000000000000000000..70d38d3bb278969ef82a3c666c5e85192ad65948 GIT binary patch literal 1058 zcmeHGL2DCX5S=8ge2Gm+HA2v~Br&$#SR^YR8mfhEOWLLsLJp-Yf`&zjZVs&rQrUtr zE|S73wth+v-yue#1zCvNKtL8+k+fbG@v!uuu|y$)$R1a{#Kga$?+x>YIn8@8lhe`R zNYV>lFz2D!2DI1&Xt%%88fBUF`@I+ogoqU7r)i4gSe8u)0*|q*C`C=H>KfNR@QCJ%uI8tR=9_76~u#43;^SAS{cT3}q1& zi7Ybiasp`yP*@rZTr~m)13cw6I9e@|W}{|Apw=qJZ6y3$j4^q}lsJ<}G(|;dnu$bs zjx$ZO(P-3aHC@-W)}hs^s;Y{j5JE71_lb_)OT?)nNgc zhoQFh_D=w6!VAX|1tLE*2k*tTSX#iE0#g$#XLVhx)u?4Pm;U9FZzu+N^W>%Kh7h!n# zbZc{=T=u6kdIxy@l|2vUc~4bI2O^{68x`Mtm>XIuXmgv3^}(1YamkyU3LTCQkK|w& z2aZPXjUZ1Irf$ZQ8uZj*mg8cHPyG{buRj)YKXSiADPLdU{PUMrtL6RvgX2-DrPj+q zj^_pz;%~n6#XcXn(EUTdy$+v@9BYZG%Fv;)Lg&o-#JNZQ8<|n>^6FMo-uQW<^Ys1J z$2;iAHE;LwQh)HuS1#M#dn>eWX07n7I>|MYvrp!3555Sl9#7rF*G;fQH_?ckSA>bLY+-J9cdE-o0D5Ze6=}?b4-7=ggTiWy+MEo}QML zmg?&2;^N}$?ChwhsGy)AkP}D2Xb8|C1QdU=FfuThGw6WK2IUC`j{gk#95Nmo794Em z5Y~!WaiNu4j62ZAM1q;2K}g$ZTZN#rTaUPI*aC?_B{xTL28R@f1|?PoVU2(p3I`vx zun95*&0*Pau&HT=YQiD~#^9r@TnqtkSQ0m~bO|Z@%&4%u!otR&&9!gCiBgvEZk0W5 zx{QkxdRE3?uH)5OynttYyt)Ca!9&MzVZAfUVlN0E=-`#xH|vDggtl(s_(DB~1q|z4 zMfCkHwJ>^g4+o{~w8VZ@rIoUZ2$_?t8T6tRxBBsoUJJeYEN+aYF?8Pc^ZSR#r|0(@C@@$90Ddaf2mk;8 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/11.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/11.gif new file mode 100755 index 0000000000000000000000000000000000000000..b512dd5da196b15a6fa31115da13cb24730c14ef GIT binary patch literal 8033 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 JL>v}y{2v!$l}-Qv literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/110.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/110.gif new file mode 100755 index 0000000000000000000000000000000000000000..e253abcff6a046ec78559c5403e2e617a268ecb7 GIT binary patch literal 1082 zcmZ?wbhEHblwgox_&%NCKL{`Y;eQ4O5CNuuOnyGLqf7Z$Pm(ydLG{9B?Mqwr7xw6! zS|xREy~_Hj3KuqMUEHj5WQA6YzsSk823NM5T-{-Mb%)uN?WU*Jn_Syzadn6Jy6O5i z_SnftaNOKue{-+H&ApDd_BkD1WqoU(^X&s}ODCAt^Z=2loF`KT_e zb6ni$x~4aLdPBIMvq7l0MXaZWy^VQoRq6Zp?{D3@b@1T9UAuP8ojZ5Jgb5WD6^V(7 zhK7bpN=iaPLQG6dpeP&#WQBm@PZmZ7hUpACAl;xm!NBpKL7!8`W5a@j%^bp7F()=G zJlxdCWZNRaF=>8B<3EKXCkzFY85l%Z9~D3EbLnVhd%2QXy-&t#vI1j<$ciPN&5ay_ zw>}^DoozHx%X3zxhTuHw3O_y`6^;p>X4!`(6mH>Yn5&=sYf6Zg!Q;7h`P&LCo74Oj zyC+>*v9fYpBWyBoJToj z+fsJlEpTLRw6lnFN#xoFT{lJZs$-grm4O zARvc9sSFTK34k*FU7?gEl`$kG^*j;;v{V|M&+Rz`v_102l_x%h}660hDdZ$3HL+B)=NYPLRdA({W0gLfX#{_$M?ZdF%ZGd*kd zb;aH_9y>GsacSaP^~~eFFIn&AfKmsW8-L}W$M@WCJu>(TrPn&E>Atx(k~ma#xkiEU zzTLISnyJ{x{MN&!iORaB*!I|?e9dg_(9Ws8R63eFadUq%wI12|Qr|JZ6#uaP?AB`g z^{uVl#q%@M@W&^mr!of*K4}?Q=zKa|i_fv%mCe!WtC7wdDRtv@x}~Ww7g_wSr|uo@ RS#9k1S66;+R#bq~e*hcZ8%O{E literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/112.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/112.gif new file mode 100755 index 0000000000000000000000000000000000000000..c8ddce88a45b7fe4703a663ef2e6a7044c977601 GIT binary patch literal 1111 zcmeH`-%C?r9LC={*WQ%rnTl*8wNq+NMUJD3ExVZ0X{MB$7O{q;laNGd9SfnGnj?+v z!p#Fo?!q6On?leyhY}{Zh!K>dAYTmX5U8B1T6EE|F3z`k)gMt0JlD_XdEn{jY_~fG zOvr>3Kaypc5W@3(I2;y5F%Sr3H)w~$0SZba67aJYG6-Y@cPZFnfX9%=uxtl`NpPIi zY9)jNwN{p!;1vS|ku*yPtH=~ch-5^s*9$^K;(b}3W?5DeUFme1q-OC*yE zhon7u!y{!f>Q<8QT!v?11;e}t_8G-zQWQ*9c(TGt(epBEh0lz-y#>H190e?;3bSg+ zLwr`4w@c9g%-UfCL&!;@BZ`k!lLFzQ5b6XDtJ_J)A{e1KmleJ-5VC`aA<2M`k|aq{ zlx#K&Pz!({=l}XQ7NDW|Ud#iqX1P~Y4*>>8rq z&eeE6^i8nU+B(C`j<8me3YGQTsXKjtb9Yu(Tu~JpwzN(anWJsuQY?ba#omPj&+^kv zlVcn|9K3ANXtV{D!*BLSKdp~`EkAHR>dGrP`Mcm)_m!K@zpy%_MFwQd!H(x(_ns}f zQU-15*gIQK;ma_k8w)b4uC~UjXYNr4%!x_8zoCEcN3gwP+T7b)r30;$27cO56K39^bAfM%|N=FE%vj HM9qHy)!-g@ literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/113.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/113.gif new file mode 100755 index 0000000000000000000000000000000000000000..272710453f6b8f6fc9b6c34192c52dfe5a538293 GIT binary patch literal 1015 zcmeHG%}W(g6u;&($4Ikh#E>s^3ei_mjXcP~5}kaegGoLJ>z{|M6L!&N6c!Nc*kr>ARidJMy8`_K{CrDEGEwY;$Ds^3wc| Mo!79ZK>|I008m#NO#lD@ literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/114.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/114.gif new file mode 100755 index 0000000000000000000000000000000000000000..53918e2ae600a026da6e13bd2c26cb49c309f026 GIT binary patch literal 1003 zcmeHGO=}ZT6n(KGi4cgk#UMqK_z|ZRX;jc)l{jf*8dR{<8bTMEtaMyhW}^&9Y@ean zp@cAtF5aRp9;omjiw=k|P!YydVW?n(ZU(W1Yzk9X)zxw0-_Ud6+{@uE&OLCij^{3< z??y?K>`oDMLHq(CUHaSnky3+mQ=>k0D8~eaV(h96k^)&nNk_$i#-SRnVIrlXKz-3u z7^r~8T%B2x>Th;b4o$$Ypy`}wi0hCUCOCo=Q5|W90*7cLZXo6B0;&bqgT#>LC(L4ip>IfzgJ_Z9`aX4;34l1HBFILUEuvV6Jb&=B7ot z=>d#$E(BwYQrf-$KmOGO;=lI>2$>>7-2l2jL4qwJf&=;H^1HcU@8C$Z{9b+*Pt+nm zcVhDkeW!+B=GSLy`wz?azpvh0u7!>bTq~yISH?pJb3@gTI=Z$m94S7op3U|zCWr6* zy2s~c2Pdn!`OM1JYVV=b=fs;mwQw{!l39A)q~W8P@@Pul?72-(PJe06^gPgyq#Kuy ze=ge#=K12zdWt8W_nn#ky76MO)kyZ=T6y?1+lrjHUXMv@k3Q5tWg8jk)sL}y?9x)~ X+xFzxfy9j``I(PzO=U3OUr8Il3G`5#Y1gbvsMo+n>l-EvovdIJ=A7p zv~(`4t*L1jyz(J@its6ZT)bfd;stLZ!UPqt=r8CG=$!4G^KhPiznzSuNA{#-v4IUP zA*}iVf4BIpE`fmjfOSEJlJe5*8w1J_2SVU^)V<5irSyaW+`kU}l4n z4L@06V8I{@`dOf7f|dyyCJ;-y9j(tCb6@SF*?!~j;z>z>BA6R81j*V z^sOgpLrF3UNfAP-Sx2g;1b&T=|DKW2my{qX%gb)J+vRdOolb|tVYl0DHrw3X-0bY^%*@Qx)Rfg~ot&JUn3xzJAGcU6 zqobo{v)N=a8I8t~k&)ryVS~XiG&D3gI5;pc(BI#$*XwmUomQ*WXfy;tsMYG8o}TXR zZXCx|DwR^HR45dkot+&W9T2+eeAQWlHLe?31B(M3!&IXKjSef7ubpA$+=EQl=G>go$mswvyx)f?+=wkUy6R2 zTE|Jr_iV@{cWFf1SJZ zI9fP3syR5W2?(4M5I80vuvb7}tAM~-0fD6g0`Daxo=Zr~5fHd1A#qJY;+%v;4^WMS z#9j%Btr8O76&2qrDy{{pQB=IAsCZ3L@xP|#dri&fnws}CHLn5LhKA1#4gXtOUIQ{L zE$>-c{&#YE@8q-=DCp(&KPc#)m)HBCpld)fD(YHL(DSIM|HZ}stE=A^7e5CwdV2m( zneuN zv0=f%W)5Mkm=hZo9&YDI-|)fE;COetV;_&CV6tbsh^B=J&mm{eN%B%E4J@5W3k4)O zMHm(?Japugh>Dd`%EP1+{nDC#F$V-5rLoOrm5hjBWKM7AmRGXjNNhUNDJ-fZ(KGSt zG3G@Q3OXGd9yT#^i#hmMNGxU+RP`vCQX#;|6v{6y72uGy!JU`IHKRe`pkgbhh)~jp tRO`bWeY4f9bo?Zek9ACy5^;_ZTI|{*JK4Nj&Ue?AmzP)Yv#~H(0|4z%v4#Ku literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/117.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/117.gif new file mode 100755 index 0000000000000000000000000000000000000000..14611b6ef950a82aaf12e5c183b7c4f0edc7c243 GIT binary patch literal 1041 zcmeHG-)qxg6#XozMy)z2N`$J5n`l(Tf`VZBg605AVFPax6ph8|Y`-wv$ znF6SJ$X9oI? zvl$9dppgR2Hb9F_0NUkmYmLZM8$PxTUQ<|A1hz&YNV^7uHOAKCrpmx9?HH_U^0p!P zSavMg!)oAYF4mep!YV)tFlAt5fhGY(05&8og;Yh-h8>PZnF?iVG={XJGYB%S5w~^L zGkMPveI(h2=pot1N?^Bc>J8UudZwe%P@*toyw>E|_>^{lLqZO(@TW_rcti zSgtJ1Bnsm0;h}Tm`E9ZD&w9gCD+IZfh)$k(tT literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/118.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/118.gif new file mode 100755 index 0000000000000000000000000000000000000000..8c255004ceea385e7d193d36f9791885db5de933 GIT binary patch literal 1012 zcmZ?wbhEHblwgox`0mQ^9|RbH@IM0shyYVS=KJsei(95_J$CKh`~S(+J=If|w#->O zXX~-O*Pb7{_ddI2N^#Geo~2u-tlhiy+`V(pzh8U*zh}N#tHdgkms*D_@eQ0w#W z|C3v$WcSQzS-Q2lXUdeNYv-)py7kz(d+)zjFWuU*c5iZZOUs<4QN`8SEj`6OQ>v%T znX-24+GFRop1XGL`TOcQOOsoAvU{c!PXU^+wrB0ubMLC&xRL7o`}qai?a2q^w!VPs%%WzYfX0Obh=j*AT495Nmo794Em z5Y`gWa6IJHDqM6V{5OiPc9rvnaF8oqH*EI zfrTeIbu%(1d~9evJ>AxAONQek^$T()ITE50i`ctFyt_^AGMZ-bOKYwYd->py>+xmw zK_4^@9XQf1$z%2H#l+H9W)^t^mk+-#xbw?vMrC{u_};|PqR+&?rSN-e8<)Dl58EGy z+#X0dvIwnv=)}y*Ef6KPMX}`p_b!vFJqZny@*E}DJXa`edc?+|AXzs_B1maf?qWtp G25SJxwBaxS literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/119.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/119.gif new file mode 100755 index 0000000000000000000000000000000000000000..65bb468b950af19bb195dbfdc7f13c07d1006ae1 GIT binary patch literal 1101 zcmeHG-%C?b96#C?n-;BY<`PSWE8P-9=s}5ME?u*h#fl1_%K1?2A>l>@mtwlx72z1B z7m>J7qptSQ0Shh^b-|_{mE?wdxb{#7LGaW=U5elm6sNoXjOg=)?=L>^<@15>@veAl z+vNZV04ohx3BV2pKq>t#cB?7~3Q(36UXUb&GlC2ijTc}z#c>i6WYm^{Ej=8M^fXj5 z_6A|7>KwFbYFnD;kPa~orZQohqg%X21WYrs3N=I4sbZL%q#$BZi=_lv!UR)GHyI~D zgPNSddL#r1lXQwGOB*a>Fo7_cSPEqV(qwFC)WSBOFy5vSOQwuR8q{>nWW-_;Wr$j; z$#_}O2!-}&GQ(oJWuFizV;x0BO)vQdas2;9_9WRhyW3_$KG_Mf{CZ`MEpJ>1eP$H&9*^no16| z##cPm09;x17M?r?&8Vn@VVH1&v^d{_XK#7819`P9v|Izrluo5sB~8ydEo!N z3Pdq?wma}~W`4<6*O^StfOUsIckuS66dO2J`E-ADsWrB+yf#=m@`?ds_V;oR@d5hHSZA5zbyI=cwL_O52v^M?Zm7j|Lb*6sB5IQeR3Uq z-w^%v*W7XErN`H|@40nh@kPs)Xhq&ppC}vc7#jT$?S0>Ws?%KvH-W^}u~+IyAPy$M z-ftZ%4KZ&bGJ7wy>HfNP!L!^v7W%U7Q1EE>`Nn*;qv1w$_}#NdbK-Aj<9gO{cc%v& F{sWN6MD+jw literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/12.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/12.gif new file mode 100755 index 0000000000000000000000000000000000000000..547529cab6ec7ccc19719487e644b132b40f9d9c GIT binary patch literal 2247 zcmZ9Lc~sKr9>#ydF9icZL{rBF+_Ky=9V|x?H(Z)rI!&34W=__$XtnE zBme@_0kc((U?pApOdUuriXUtq7Yu`OI#@gn)@}mv;qI(&xM7fNhz5G?K0I^>ADpT+ zU^!P~#tV8JL8xGQtqk4+(k0NKKaocOq91^q51!+|T-ZBr74V8wpGW|MyF}fGz?e4} zb{^7M0VnCxIki>%* zM6eVm9dMP6_;z2?Dhx#fd1qd*Dj1;w(E%_U47#o5LoR@)yH<<=ZDwG|S=4_Aw3{tA z*>+zwd!McN=q{N2e&(STXf*|M;VZvuNZ;&SZMW%QsmWVRMIH3sZ1u$&6CiK{!!BUR zN7Q@vwS$VN)fIGDw*3PIstC(mT~VdUa;0uXoIa2w07+~<76R3p(~k_nr2mVP*uJjz zzV6pk&Dn>IA<$*Dwz?|(I5^n%c6wrLsJ{nvTY;%PVDfND2(<9pwL6`rrSZ)pD-HMXb zdA46Rs!6hz%cQ@b)g2z_U2L+Kir)>~CXbc}O>=`LhC7Ro;iiRyg4!!fZH{HJ7WJ20 zilZ%G=KM6p&*{IZxh8lh9WUXtU8*vIfAfJ?``u@257xvJB~9D=%T9jeo?U7>DB&OK zV4xP}=l5_b9c{#|pjmaNZd?d^Ayzp zCii@LLK@1|7Cf>P@oWTnCZbv!@wHPq>d<_BITs6yeIao{29VyHKH~^zk*a=#XUdpLUL1}ES zW~*K+@T$IGSI+hkQ1|gN9FB{R@=Le*hK`5O{ZyVKPtBJ)LB=qAREa`PbbLCX1nCmv z0ys)MC4yQ}`1`m{+EZkh7HZnKUOCyqH=ex`P2cb4UGqrk0Mu-lYl?;!rc|TSbL?=t z)O$3i8EKC4(F(hKMDd`e_Wj1Y_Tv3&j;ik)(PJf97_DSQyRNr?6!c1`3Qu(K}5n@2WxJTw5Be;psTSkjGPvVH{F{9Xlw0;>V~cC&Qk04(kx- z@p(1+V7pH0R))Gah4-6_zej8{^{PKD6-kEby?rg7H#Qq+X9V(gbd1pO=CdfWw*!MQ zqJqXRcfB_FFi1_=ngciVQEwKWQ`Pp$I&p*>&TR7)P{#rm9elJsc@|&zQ>!zv(SiV zyK$jxSBf9JG>207vjgeyY_7RHi+9sXy&_YCA9fFGdFm6MqE+K8uGW|k_J~2!pB^?r2vUQM8OwEE|B2+ zEPaJ&(R)eR>!Q&k@JvRGSx9LB8Dgd(QCI>!oaTkoF(dQ`us_p1n5hLmUjk861}B{F z>OQNBb;mK$DD!Z4T1O*O_=lRub@nXP*n>z|juM95AR%hx7LqrU?v=`>mmCUzGJ2Ur z!x*5;B!+GE8BW^&o9reCRsgRfUsfbbEIbpQ!9*#LIRPUXHk;u^b+XvEQ9lxI%@E=` z2+Ut7^#eyDukak@K@}_Csy*~&ogRhf`;Il#-nRciZPwkqgLD#cYeDasJLh(iQ8BY2 zZ7eTyeRZ*Y0i?@MkTE7btGG039HMI5Y$uyVO^YnspQ@Cfug5ZZAK?(Rm=?lXB`CxH zFY9{q=^L_&RTRyGaUB$yTyG8-6yn7Z5;IfV{^uUP(UDs6H|_+Mq@;{>zES?| ztPp~-T_in}wNw3Ew+UDDF^8%CsU;!MhW0YaOFp$5C1g+%PW;HykXX0W#Yx3n#)zpw z&EEypMRm3@sVa$!X8vNfV7w7$(0=C&Be|iDvBBo`*O1n;i~TyJ&FgGVEn96pXe@pC ziHr2Puym3NjsKW}_r~lW36)wjbZJ^(RY=h{jwIjo+rK97WuIe3T({RploHIDMwi!z uq?0^>q-i1!UeQ3YIDcF^4%d(H%LZKu{)V)bX6ANJ@{hP;`ltg5+Wj9mJt^G) literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/120.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/120.gif new file mode 100755 index 0000000000000000000000000000000000000000..5ce77c05f0a63219bbc4623ae223c5b8cd6942c6 GIT binary patch literal 1008 zcmZ?wbhEHblwgox_%6lp9|RbH@IM0shyYVS=J)U4-@kwV{Q2{H_wHT0cJ17`bH|Py z+q-w~)~#FDu3fuy>C!oK=1iF~rKhK-rKP31y1KZyI6FHVWY#Dc4S}H(0*XIb7#SF( z7<52R2IUC`jric2;GNIT{NWxps5tn=l;MsLa5k;HZ`{ z;h+K=o2Wp=9|<8xCRQ=I1dR$KM%I4aShW=w4jlApQfD;jIAE00v{*nvXrTT#wK%Ho4MA;I`y4g@(*OH)fU zROT%0uBZnftCad@eT>*FgOTI4RV;HDrf4vg@Q~Mh$>(;VpGM| z!P1Hv&eV$AAVo=21w-Mf7G?@i8HmgiMKBd$G8htIi8nO?$zdviF76-_uO$T{0v0(+ zDK5H1NZ0jJUjOm0BoN#z^8k#%q0&L6p8&1^AGtt$`tjSVT+P8i|M$TM*L~i*!p7nH z`IKb#f6ewLYHH()7hbi;K1@xWed14b%%!*Q_02@XFB;$94xAXb?yO{E*(SbgbS%4? zt_rjbEJgP;lxLfE@kcY!mARWw+lH5xfBss&&s9e+X4VEfs-86u*Rgef)?2wd(0Hz{ zT-G19K03cP<~h05>yHnzOa6CXs`qWQa$!%ZH_$%5m`P3h(iOFD%-H(3bnpIqeFK+$ zeb;t|j*b6Vm~0rzwA7zooB!0gaI3CowE6dz(5Z^o-7hOQC)FFVmj36_NY84z`arFB aVrF<-{7mSxZ{mu0WY*0uH-%oG&y8EHY_;U%pt60 z@+1G@p?U#Utpba}2hD6kDt}hL*s!pP1DNuEs3$f$v1+hR5|IpYYHs5b445JC>EMYT z1I@H44M9#!z1*33e>x{FXX>$(OiP)t@gVbbmDy^lKh`q__wXy&l)e;JKg8;@JME9; z)NGgLa8;WfCqf%8gfOk?B!X=!Oda^}pLX=!I>&isGo%;U$8&zu1=fdW7opiv-4jDpb+phE~K{$ycf zU@&CR0oeu06AT=G7?L?;JT@#i*vuiUrSfC_!$Zxy|9b-rlpZ-Z{ui2Y<3yoLQ$4@& zKjV!Fjhz#vwe|jNZ*b}8&=K$Xvmzj=gGH{;%w^$3H79}p1_=?0Q(kZia87FSInl^^ zQB+KW=dZfb!G@(A|JVMw&UDzG!EtX~&%uM*fua%t0!L>F9J{b6-*C#0=}8N@`6cH3 zOE$dH%pu6_Uy|`+kyERn=RpSYUC7{l9(b8==ga* z8?Ro4S!2RyF8&;Dw$zX12RSFnH?`fEaPz^XdIhs-5{XF+ZbBOstr9LYx^(fY7^s4q>gB69ozFd~yaAFD^__XycJE4q9{L zp>rF*oK3|Ufkg{BdSr|$R(vQ-a^{tf?DL5%N@Sm*Vfp8G!$bLwHW8P$FB2S<+Gg=6 zb}=X}TFJpCJvoVmae-EYfP~hhiVDNU?X!d=f*3w*&}k8nGV}3}SmeyXt+*y^uR&;H z6OW8W!UX9?=AdmtHVhdb7G!nIkMcB$c+;@)nt-y1#f&=%pE}xLdGaGq~K@=4-w2{e328CI)K&RF;t` literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/125.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/125.gif new file mode 100755 index 0000000000000000000000000000000000000000..e2c3c11c92c14fa76e5ae842af7e4b51a4cdec70 GIT binary patch literal 1013 zcmZ?wbhEHblwgox_-?@P9|RbH@IM0shyYVS=JG{Ljg8aN(q=Lk&s0`XV=zu*jNXzq z^9*Cd7sc8m3^V_OC1=i@nRe#P%>Vz-oJnIiGc)b~nVCMGZma4-&!idu**xv{p*3fW z8TRhlDayxlvNB~R1A{RG!x^Bd#>W3aTGP(VoC(wl1YjOe*cjxRQ7{?;^a=sRpDc_F z3mEFS`IQE>2Bq8^hi0txX4jJ!e+yd4~Z>D8zrq6 zUR+2#+R7(scPL>)QfsR?kHDUSjSnApbBn3{S-fE(>zRHYyFbnsoEo`Bb<}E7KAu0+ zC8(np6Vd3T=_0BXmG!`Y=|~5+mQIw!$AwQ>g;net{z@dZv~3b+@Y%Ym$c0-})XyM5 zGoa-@566tI2d~Xp8xAw5@%+;`)XL4E*Y@kF_rrKj!T(~b|4cvN*euSg^r7{mzY{a3 ckV40^-HI*U?A-rOKC`ag^7b}6GZTX~02q&@4FCWD literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/126.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/126.gif new file mode 100755 index 0000000000000000000000000000000000000000..24105c988898cc03bf21c4ef26df1f7fb6f34824 GIT binary patch literal 1030 zcmZ?wbhEHblwgox_-@GX9|RbH@IM0shyYVS=4(BZ{|v@IHlAO;XlYv7%rj^HE32rT z`TyV8m|^D3wEt%q&dg-^x1C{T8pHpY3}@09(u^5=Jl$5+h5k=t@KWQ=4RrmVX1sUT zPEkIdUmaCv7#LA%Ky& zr9)3hX@bT=&DLd%T7Q%q6%^T7nB81*v=o&(g*ieLdS)y-(!k=aTqV(Pz{RauQi+Md zAn8cM?sE4fC6SvKxG-pMT2=9}>0tLxhNwNNKf)V37!?J)@BKWV@U*@-P{F~V^4-Z( z?CxdL{wS<;5|VT~e>6erAuE@tRnN7AhfdkeqB<}31t=bBVincPSy8)t(Z|P(j11NQ D*;J>x literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/127.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/127.gif new file mode 100755 index 0000000000000000000000000000000000000000..0cead364a05f031b024181e7c778f8b206763312 GIT binary patch literal 956 zcmZ?wbhEHblwgox_^!n89|RbH@IM0shyYVS=1d0TGzQ}{X*16N@yxU{XJ-EYf9C(0 zwEsIpugnjfnPz-uX4?NVGriP!|IbYOvw2!>pzH5LYxeHic?PK07^pEV&DeNmTH2YJ zAONys6pV(z;0po8pDc_F3`z_-Ag6)y1OvxR23HOlj|~eBHggDT$*frL(5aQfOrc`N z1!g9G5y7Y zXcctgg91|vhnSL%z^et0%xt`3IvlemHZcqEnlvmhNOU^RAHLCShrz>?V_Yhc>q=&Z m=|*qWaZdR%!9n$oK#^vhhrnf(dwWFwbFq2uC^*=_U=0BHNPF`D literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/128.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/128.gif new file mode 100755 index 0000000000000000000000000000000000000000..3185861818bab566315b08e4484ebe313322d779 GIT binary patch literal 1022 zcmZ?wbhEHblwgox_-?`Q9|RbH@IM0shyYVS=JG{L(~Q%M8PaB^onc@AqL~Z~X$%a; zuI^Wijc2B%otZiFe_GniGiUxY7z5E6<1`>S(>U!+;kw_`w%ua@>H=z?`QI35z|1o< z&-`a>_@Y>Qgkk1?u#x|bff~>JPy7Er?aZ09nLzpfGl4dpnfd?!86Qu#+(6g=XU;r+ z{P+w|2q=*TR0wj}C>RX^>V|;gPZmZ71`7rqkg=dV!N75wp^!tyW5a@j%^bp7F()=W zbP_Ym*|R`#gB!23o{Uw+gNDOgeB5Ft1s#tWn*~+9mPiyPrZ}^kF(f!JHXQC0;x#fk zGokTt+XRQ`eP;@im{}Q&6FfQ=OipAIV{kbm@bTf{CTTe-GX}$l&8?Ci=_&;~4Val2 zWbJ%ds~2Y8~0`r&V*oVP;YD0ZwC$41r3PW^Mry6TcIO8hIEt=-x_rbD@=|!%X4W2FFd?-{0p0 HT4N0W2Y{>5 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/129.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/129.gif new file mode 100755 index 0000000000000000000000000000000000000000..ffd7c6ba331d56153f3366f181bd8ac78c845e98 GIT binary patch literal 972 zcmZ?wbhEHblwgox_%6lp9|RbH@IM0shyYVSCWG;RolVg}L*t?%3j>3SUB!h1O|6~W!VVua z4lZWpWbkY9;Yd_=n<5re<+8yjiFLACYE(snqLXivkhaT$hKngJQv}uisLXiKcwx4= zvP(fiV$-Eo?s;B!XNfd1xABX4gfJ|8eW^*3&q(05fb*@^e8F9^6^;*X?<(ehbajFl j^Syo5{J%sk$_pOu;$+W0;IQLkQpW^k?|FL+6d0@l-`aWZ literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/13.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/13.gif new file mode 100755 index 0000000000000000000000000000000000000000..34753001ef80a38a08e8a75f23482f528313fd1b GIT binary patch literal 1736 zcmZ{jYgp3v0)YR-MNm`}RCJbMYG>ZXyfmGGC~8?#Ys0?8*@jT*?#g56@UTePd(20{{O z#Z`W}2Y^BFIt-{;@2m8|PKsvO9mo^Fo6|tk4Hju&=2Oi}zv2kEywhd(Dfa!sz|QJ; zHXWv!^4T3d4947~eP2jlgpN1lfi5eB(BXBZY2H!zbiSVWCp7Ph7t;fZIslCcJ0^yD zf$HbJg0rA=@5FE)SPKQ~$0ZXZg`qI88Vt1BnaR;t(&gO`AM!)@Xw|!5HDqZ{0yxG% znF`j9gXiY&8_cRAA@v6(5ZkIYmz&drz_4>msy*0FSZs{=&}rB8DB%tJn5qdcd%FR& z>Q_q=jq)|;I(D@L*HfLd@cb9)?BMRgAMFf+Li80Fu&;{301keo(r&4OFgHEk%`g?; zw3vB7lybe*&A8?H8EGW}{0BcfH8x*j12l~_v3S+y%B!`NRz_e;n&&Ha!~%;1RJmZ- zX=-$UlY6ou*`=C~``y@qP9^rxeT@472r7OyVO0YwVf zxw7=HeXBKA{aFSZLnmbAdQ%nt9XFhJ1TK%Gabtpix2BS1^;V$8u&wYydn#7`ZtKmn zNHF9iZ9XV%v6~#}2SO{rH3wolphyF=e#+L5z}DG~ZXeKVClydOL_SKkg+_7&%=l>< z^fV1vpzQ`4wRXx|{urwj*=l?2ly6s5Z<*uC~@ zX;?AyBqtK~O!sJvN>B4266^lj8fBMre8f2mQf*?a1D~l>_nb?r;Txr01 z5}r8)N96V!&3N9PF3Rj;@oISI0-2Y)Yeym6;~Y=3YjhKJS;!2MCQ6cL;9y}UNoM39 z$@lur%^5f82B{c#I)c)=4L)t%oa09QEwM9pz7F+S)|yOu8Igss{@+AXZIq?{P8~(HtPAx`6D%({k))w5yqYLlz}|G_KIJA z&kbD2Q1tI9%B2K(kk7jbD5dRXx#koK>`__`l*qK`3x)UWLoi`Mgx`sU>5l$~4rch# z)5C*&9aT=Ffq`@AJm26rI!qsa9m}8@ zV^oVGa!hksmZiC?Yv+MF^ts-EuXA}iq;CT<#f0(sXdO?ICKh8Bg3X|L9qDzepu%AP zO^W=#Nx|PI>l4da{yAtJ@||y%PC0+Uji17ei|K-l3yhffEPgsezdGf@lDu%}H#n)l zwWr%g^fSu7e(ham{jF;FO8jUv-2hgW?BCi`esv|y+-@gIgG zpU3GY@^ECzkNX2e;n|Yx&=M{)nVu6}W)zG|6lK6ZgM5iek?Xh$Sn*!h02A{n+dxA^ zw>3^i5$}D3?#9WX(!MU!b9Yd6XQY`DV>B#I(};r@PDy@(@U5$xeYZ1iP~CvyPkYw(=_<`$KeYvp9N1K_x-T& z?dR84XG=!DqaLN?TLxkiI)Q!ZW>`k)`BGCwO9o4AN3;``vgbN0(e6xnMy_qF7ugg1a6Ln4K`WNFu>9# zgmhwKo{xZU3}!)Nt_9uuy={yNUGg3Abcds&LKxiLcQJ3jFin2j?3|1mY%w%X&i3%0 b%wXQ%bA}&iOq(CqqD1myE4p=^k{ literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/130.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/130.gif new file mode 100755 index 0000000000000000000000000000000000000000..d828e3da103099151b00c5e700302d8d9c69f6a7 GIT binary patch literal 980 zcmZ?wbhEHblwgox_%6@z9|RbH@IM0shyYU{CWG;RhBP2yoc2F$CXo5RaNTdl=q)qP z{AXsQAA^h@1*0J_ zh(kc}CkrD3gFJ%{$c>;p!N9SR!Jb3LW5a@j%^bp7F()=GJlw=7C*&gVk(sGcR6gy+ zf`!RV-F(6-4>l}(!p18ho24;R(bgC=GMei@e~5)T<0`WYlLN^S_McuW+QbYu9?fAIJ;4e50yD-}{sOym(}2-uKt z&~pyA?z=UWlO0dB^1A%%X>fSv-YF!@;Hq&&#e>~Yc-@v?fmvazVhod}aw)C|T_4x4 e)^cFM+UV`lp-vqJ+x23*Dn7rud)h#O!5RR?AYTyx literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/132.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/132.gif new file mode 100755 index 0000000000000000000000000000000000000000..1b272a690b6740b94956037d021a9f0aa7136b64 GIT binary patch literal 936 zcmZ?wbhEHblwgox_%6=y9|RbH@IM0shyYVSrm}WOS{j3~F;L9-|NpfA*FFCq2>rh^ zGz};+)7Zz;%}b5<|I9Q|J|1I`K9IIiFd70wE(8>RvM@3*h%@MbTn@?;3>>Wt`W!MI z8x|aF<`CA3Ik92k;dbu-jwV0)n~rocYnx5rSg7p6Eh3{b!Qo+}YdeRNS;m6}2R+-w z6aq31EKqA^<5w`4^78>>Gpl|6tDF@HX$-TSq2ftn+(f` j_xE!N%K0cn1u;6V=hF@_=r&Bgy}jV^skzYx3Jlf&(}Y^Q literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/133.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/133.gif new file mode 100755 index 0000000000000000000000000000000000000000..0d0e864264353800e362f1e7b160d9be9980a7b3 GIT binary patch literal 1012 zcmZ?wbhEHblwgox_^!SAHXQs{kf9Aik zids^TV45*d)_7)`@&7Y3eLUU%r!jb`@y;}6$PIKoW6U7R$MfHqA&r5-n1Lb97^n;c zjE#*!){KJD5Ex`3p!k!8k%2*(K?me6P@Z7mxX9qnA>*-O!NFz@VXc@G8xjxmO3OJ+ zc@gk{jZ@IX#FI38l=m9jD7vHZlyI$gk|qC&yxAv2r2Rmg$^lha$- zIVEabb|f|ia5301cyJ{&H?s)}ol4oTIsJTxoC=Sr#UiFQywg24xA!aQMV%C zt7AK#*crJqw-gVvua0MpyRhNvgVuT`*N}!CUmIJv_{zV@eq6XPK|n;U;RM5?MIB3R tr!$>+Ai&~scD8Fs-i*d34pt5kod%nQn=>y6YqYHJ*uCv-8zUowH30rSh)Dnd literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/134.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/134.gif new file mode 100755 index 0000000000000000000000000000000000000000..cf48356e334edfac6890439290f2b5d8f109b594 GIT binary patch literal 968 zcmZ?wbhEHblwgox_%6lp9|RbH@IM0shyYVSrg7Stw3+{vRn&})8IpnoXQnZv88iGp zGt*0rccwAJpUu;916@V=c#IhsW*Qqme*E~%nKQ=5#vrps!Dt8!oe)s`$->CMAjO~q zaxy4SFmNnoFy)Z(*s$PWGl#HN%!v((hdBk5ok~_5WOU&aQt>PBP;6>p=Qr|7`LUkq z#AHchw}cHB4mS0xCtGz~n8bKyhJxmX5R1=@4fPC7Otl~Soldiv7yirs@u`t{Ccl)4 z3zyNMGt2pPELtX*JPGRhZ_s7x75Jcuhf86C?rg?}CU!1{lm#;u=0$TBy*0|IUbz15 dKJh1dIo*mH4J;g7>~o{HZG3#3otcTj8USjkX+Qt~ literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/14.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/14.gif new file mode 100755 index 0000000000000000000000000000000000000000..6a788f8be067976a32bf37c13482a2d41d367ba6 GIT binary patch literal 4006 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/15.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/15.gif new file mode 100755 index 0000000000000000000000000000000000000000..debab8ed082d3e38ac6a824193311c20f9584a45 GIT binary patch literal 1562 zcmYL|YgCd47{^}`^hM1O2~ADG3y~M{R%x|F4R2Jk?3}D@YFo9nE?RDDCp+O~d5M~~ z*=1`>o3$)gP@RM>3pMdt0+A-EsNuCFED|p-JhQ&+`Sg7FpWm0?{~sG46BeHCj5s4k zK)`tT<>hGjun!tMs&y_KfnRo8hV*+@nCxXVAS8#x}xG9JKoiGhC)+LD2gd7_-16 z(Vn$|=Rq^|3^3gSbvSf{!gN7#f-Q_Cg46}fjWAmVH6)Obp=Q3a*lD8L0mgTlG|{*A zxJ*CxG0OZVA26^xB+#sxyl|f0Ji4o6XNchkNC- zO@2KU9#8qG=#bygMbemfqq0H#zE?QfREiDWe0Yqdt@gRPo%rwvO4H3VW3RfKO4i)m zMH+m#c3jNuFQ>m3ISpQ6H0Dyx?Muxj?1kvt>D!LVGa-|*Erxd!Q!T0W+4Fn5o@>+{ z#-?pu=jbKt5YVtk1_!XwT{pHO4S(+YP_v}D>iCoDJmZ5ECJd|I=L2SJ^6^q_U(byU z|C%GgFwE764}dmC*Bk*8X~ImpuEtx}d9Jm9E+ce`{zdDj3DUTPKa)C!t&ZY)X_IZ{tdMv^?(gMN*LEK zU0vrclF0g_ToYE)_H8}P#h+rurigj6b)5vt_rY|3DmTA?$@L{w3AHGh=#+dpGmDfX zVm=8L5IYe*f3HTS;xnogw{o+|J>kKT#Su%CJA~+PnL3oo#I5sWjvFS16x9!mk33ZcLSRF3$I_W!+UH0L8z(zzY5c01biQld~I2Jc@sOuPj#3c zl}oS+c1|v#Dc9q?nCW&uJw3<@l%BHhyA~>PoYCxc)z^67LZX4t$?$dD_cb z70F>qc1<=-7sbag^=SPMG!2`Gep%>nc6ogU-> literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/16.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/16.gif new file mode 100755 index 0000000000000000000000000000000000000000..ed5d29f428799b04d07715ccec87fd504d5325b8 GIT binary patch literal 1413 zcmV;01$z2NNk%w1VHf}y0Qdg@)uKApq*VU24*&f2|J*wG#xVc66aUvW|MhL<#A^TW zUD?#n|J5QMjYNWGVJ>gVL+-`w2S)Bpef z`}+Fb*wl_?LI2`H|H~%-=uH3VP5(JBq9vBgh~AH*2{?+r(h7wiz4pAQhRSB&VUI2`t1z?Wz6?(Fu)SzcC=TGS6;@zAd{oh2%sfO;kHtok#^|>?j zrwj0~AI^jhy?-wM_H<@oCbMrE*s*Km;N9lp-~ayn{NF+U>QRk%9slc5^U*fhq(a=K zM5<#G(v~x~f_8G0;5OaKv7&)tw=$LMI%-PY9U$(r$DePSFBi3LWlqZRmS`v zoTjP3xFlK>WKp0ciI5BobSXP_&`_HTiB2F8@!=hUEJx0{`{5bYT(E$HTDS zG2Da=OeM(h5-DD8aVU|-pOhtr$?S15(9S%|PaOMw0@~jk1HX(69EPp0;|CaQss4cj z%PSxQIpL$G!&whYEdq4_fvOWPAJ$x*5wHfhKy5Mz2sx4kL5OuCo*uRlLI8;b2+5eq z78pq#gA78h<=olxCj%-Pu;h>xWuTlsp-@1;6iQTK#T7~f;Zi9T7;wWOUBp6A81+zb z06r9qphgiz1c3w<6+l1(DVXFU*g&7e@rVSFynsYMMNATe1R59s3?O+J!Nfsm%)$-~ zBy12w5NAMu#RS__0z?xDmGR6nrqp1-43bQ+#TSk&AdN+06w}QqgYdydA(sGw3ndl_ z?aW2REs12d6;^kND-;_ T1`??H&;{Fp8wOrI7!UwEF@MpF literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/17.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/17.gif new file mode 100755 index 0000000000000000000000000000000000000000..85886fef9d4aab3f4b73d2d24866c444319c69f2 GIT binary patch literal 3366 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/18.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/18.gif new file mode 100755 index 0000000000000000000000000000000000000000..b6af2189c8c6e5edaee66142a76d2ca56b45e8bc GIT binary patch literal 8137 zcmeI1d03K(zQRB%Pxu&l9k3N=eB%e2fol^|}pV_MociEHL$ zxlP$j3o0(DO=xDet65rB?ujcGtY(@sGo5qpx%WQzxzGKNKY8Bo`}uvB*TvPDV(p_2 zr~{K?K>Xp5c)n5m()C&_qqjbA{+VO3H(Wftt@@~OOQin8v&50d0>R%@2d~l}wBHdA ztQFU4J?-ikyK3;}#gp;-dq+!E$65nlG)2Da9Fo9-y;^cHASlz`(heT z7|v8Fy}I{v-2vpx9n0*Mz{Jm1qJf67nkC{^(wqLimgDl`Hw^Jpn{Iwmui$V;qUuPK z=hIs|#r629k$&-e&qsxhPqT62sW|c6wf6dI@l0-C(W2L$KwsVWHxH>kuR8dkX!ms2 z*3Nvx)-%0;sYT5SgC##WP9O_S7_4Cl;*$?Br!lC+|r9t{PcEZa- zjNc2>r=Ns~=gP%xro;C#J_wdf);Jagn0F;B&P-4Dl{t$Vmd~iL@jK6#EtTRYE4mAx-Hk$vMStrS zc+JmE3*(oz6#DblLf`&?8!RS_ces=vz*R6|qN|$EtF7O)m$zp)KjasRnSfXt}hIlYQS#zW@Hi zfN=U<`{ZEQz>FlIshOfoXFznWxN^=LfHtJ zesVogcG2c7LZV9#f5{>`mc%P^GF3|RUF9WmZRea?3@s*PupM;`5ndS{wRsKf@2orv zc5`bqv6-+5vM;9fc_Fbnxj>_`L08?$f`=i|WjAZ7!k0{qP3Fn5OZRkixS6%aERQ_G zSXIo0H7ahK?|!zLXryB3guZluWm#4e1BWLcn}{{yL(5QGsS56{^;8{GokX*~A^X@C z>x+G(YHLQ2L>)b3l&W=bh9hVNgzoXOi7jBzR;q_{(gF9N!}`tK0C=*c)!W|t0_GJe zRHLJe-+nmoD$ur|Qw?$Ugt~Z_!v=ZioGSK;*}dyIS$gu*hN5G;ehFLFWj?ND zKys~^nLLHiypNj6Uz{hapJF?mC~Vn`Sk%>mn7+tjDJILNv$Wm14#e2e$62j0Hu#>q z2<)TW^^jw-mXS(UBs2R^@2W1}(8Wa*`=~{#JV($jL0Tn(`>PMg(zhqErkF(Mn%{Z33L4kww@hG3xCIM78sLG%Xd1c zibek?qzuUaij?*peAk`8o+2ePlNw?^H2bI8HW>^iwiV2QX^y@Xn7 zKoSafA&o?h1x}XWYAzmu?Sg~%rz+u%)@Gj2-KPJD?U$5w!U0Po*8(4sf|N=ZJm$!V3b(Y2$ENfn$>SCwAEm4s_@?^AlM`okY(`8{V`9A|Dz5f6 z7-y|P83^u6q#US>_63_UW0k_Pdr(R+y->W;d?Gnl8#!zxM7VYE1c_wW13?OM27Ge+W^kCioRmDhx9eN800i9wrWo-RTMG8ZZ5iQ~| zELzhsY_Osu0~V!PAIPBoyE1}RQ5)nK4o2XUwj0n_j4nhuC4nh>%INp?>eNVP3U7P_ zdYQLYy98^yhBA}v$niU=L`JI8MHv%C@6rAtClwj*2gMgA{6EXc`QfqSzH4b4AU&FJ zI#_FOcyKrUH^|_oc`?NWzW5Z?V+Xd}Zp#f(G_F=$e9lMU5XBba{a!y90&CQq+>uGJ z(cirw;|AgWnn*nuebRy<2(yEtEzMY_3|h#weZO*2D%z9@iHHt} zwZ(KBe3Go-KyGeKfqOs?0<_MPC6NrXTF#;X0fIOOnAgS`s4hr0>_EN>Y+z#uPjYMI zGKHQWCF9zzp~7uq)Q3TY@l5+hZnTK${;OopajMZ<{(Z^*@`(1x|Ne+tmwjlKu&AG=f8&lMe V_d|8L= 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 Mr@cCoVQ=Ms0K+&lfC4>M083F{Q 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 Rn>5}2?ku!H@QL_0{{v#zS@-|| literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/2.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/2.gif new file mode 100755 index 0000000000000000000000000000000000000000..40cfda436f3087c561bbf0dfe60d2591f8f11e71 GIT binary patch literal 1804 zcmZvbcTm%L8pgkn0}}yB0t+GFLJ$#!aUtL$AP8Zpp$eW@DdK?z6~$3cT?oYxFQ)`GXd)(nQ%QF9i_n*Lx_l=G!?DD ze_+|cu>-MY04-H62qwU#6L5BPu(t!sI$@(O{HP1jYB=o**O_ac0FGG0wFq>=z0C~3 zl{xrY^?QLb>@|Z@4t%2qhpiS}0qiiIqJhbb?NE56F_H|I1Es!zdwmzI*J@_dA(xCw z#SnH(KH9ogw-e5K$wuwqsO`{wB?-?AqI_h~ZrL3`Bopbd5ViaaCAa3EX^44y##6MX zv+-~_2u}FJVOL>o4D2vjDmuDRYP9ssa^V@dzpEAc0~iGQyW60wX>xpIdAL!!u`&HV zQ#?O5I?y}P-?Qogp!mjI01#Hw%P*19c=xGihQhjlwHouq8q3wOlJTLws$10WE6aj< zHiZ4$M`1`&0xFrG`}Xx+^xkh{ou6*1wBEqMJ_~7&E!uBY{1?^bB4Sa*&M#$$y3@?3 zi}#8foYorXYgM~v`AId2egmmLEG;gy{!Rb=ZFP~a{Km>RsURO&>O-bpm0mS2IEmvw zw9B#q8?8T0*a0#BxTHC7u;jvc^`&>$)!SpXetZ(qmFh1V$msr9Ep85*n;a2vC{3{% zEiAIM#dI*8!he-E+g4n^`S{|Ik;7o7zjeA$7d|@Lco8QPxU83}jSYSlyiFFw=m;L1 zL|dJP@&Y$1sYtmE+C-Cf-bA{YuWRI8^p*0! z^DFS}52L|gfcu;mxrKKX*Lod0kxGz?S0KU}tGw582m5<%3Y2D}rAkb5P#*%|AE7`c zFDHLLM+YA#>RwZf8~}i_{wD=>0D;Noy*UyR09XhhPRF%`(-4PM+oMi#Kb%j$ZPK=a zcNf_EV95;7Aa`$viJwSvG`*QuLLxqKO>AJ?RXuUXNY8`AI7Yst!oBTlX5c|qQz`UJ ziR#4c_f8-q*qnSXl|1*jT25mj=P7oG{WW8GvVlpURhH+ zI}nM4a9>(s&N~qng5u?V_8>mE%%R1e*2G+Rsb$15dSAU+n@3M1*wb=8UuBT0J1b|lGLPigKH|oOJ6oV38f?{e3LrtqzFI3UBI>k|KcWA7$HjWVEB6rH3 z3UJmIj1H?eB|Z$N3OwK%<>ldVV1(oAp{IfS2iGuy&rnpl>d!s>IEtu_|Bp%xPyj@L z-&9!$V1zks*RjWnt+Ji;(`RCn6#Hau9vGGP53WV|p!6NvX#3g91~PMbM*9Or2U@ZP zYsJ};)#8)$S1uSm7)Cwog7Y_!@ z5aC>iBpV-HLZ-)Gix0E^Z+rqEY~p7Ec$SmKJB~4RlC5n`;r$YKu1AJqzWwGCr|VFG zyzpHPd8kQzt@X)#vMEj#hO)B=iw=qBVTi@~r3s!T2`=pB+{{(Rv!H+I{1V$!iM8Xd zexkg8PMWc4I+C*CO;6foXh4l%a1&qHFL$=bt*AdLuqXTC z=RH=d9pi*58q&}#RsA!OBPaL2yu?l3tp8UxO8?(7-W`SS`4ZR@O}74pw5uz={Y5~z zD4FjVcI2NHW%stzD~krp18xQFEZd`N#Ttkb*)#e~4zXOL41be$1mY@a$Vnrn#;Lcr JtTFPy=3jH@t1|!q literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/20.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/20.gif new file mode 100755 index 0000000000000000000000000000000000000000..efd650f5598c031ec3a205351c95d9d83bada14b GIT binary patch literal 1808 zcmb8uSyWSZ0)X)ggph=U1c+&Xa7ZG^QUqj^MKEFCr9el}Dod@@gH^ORwWHWTB4QaW z3`oJT0xAqr2E$Saij@??8X-`WWdKPa?AnNIN$$;m@XVPxorigtx9|OTzTnUx56@&O zM1{5hv^?_p!Y>C_8Z5;eoRV*$>Tr;inmj&-ho_>!OP9^DQpJ6J^+?bV&rl_D9L{H~ zRPI7%V_w{#Xb@N~omL5~Ww-RF?wEtch{d1mL7x>o#$K&qs-D<_3D192`fHjDK&vs> zy0|cqAo`l{FvSR&@>Bh63+6+bvx3yaKFVe*<>X&mF1vJO8iV1z0Nw;^e_HJi1nOc< z7XxgZQTOcw%_M*{s9*SkX&>n=^6HOf&1txXlNfk1u>Yzl{K98^WKdqB504*&XQJTA zPWDrJakbi)lA9TJZY zKL;X<$2pQe6<-{^8tjrq&!oHzU3 zTXSP&4KdqYzOR3d-|9<+<&Uu?)Rci~#_R9L&+wHzYmDq84QQrQ2s_5<)wO?4(rQ2_` zy1aYlfh?vWvyswrM*kIz^x2;^OQ}x^KARqY@oM7bmM{>WIr65}eNir3?eU(kp~GFy zK$*Kb6a^0**cO<*so6DOW(dIOVyml07P-)5z0m5gHhA#eW5(NBL-00ny&B)~N8EZN zwfSr2LKl0!#sX}9xh7%#T5Qvt$y%E#>%B%rCJ$<+e35#6q#ln<$IB{c%d?Z>Z%CSz zPnC_v%0@CW6M;w%4dj^t02n|&DljhApB)|O?BJxM1wjx)iNfL_0NL;K&LmU_!T<E~Nv7hGSrv16dS*k% z8F%PQCFH$1#kmP7A$diPSl5fD7xG2cw$9rMt>~ZtLO_`CX?cNdjPRI9c1r4^4Ouw2 z+*YuQZXS}HwxAitk#JWTZjp}#ySewn^GtIlF2;ADw5|PgP8kaM0iAf-(T3B)eg2(B zc(3E|_~GygR+tyA;KPoq5tK6tccZm->om-fZb5{ADlT7&zBDbpWX!!)m|g&Q?ef$a zUE-NE*Yv_`VR(-}Ff+I<-}e$e$V5kll|NwXcwbzPug~5SX@1%V1?eo^em(V4v$u!}5_GXh6 zaCaw5ggB$PeP|RT!{zS`oNJ#K6qK8>E1Q`wl-_%h&ZUes--z^az}IeF*P}HRN|_fr$1Vde%AvMJI=x8miRO zMZIU&{eRg5rvEqln5*yQx`LzUt;`3`njW~})gvn;`{o8IY(hAk=lfDUk_$Aos9E$yPY9qqk}(4bE_*?@N=-JC?0y4nVoz+*Tkdw#P}Ky zM>V0gwQb*jRNRzR)JA3=&I#xG{C2nPy08!H?N#U>r|n8Az3CVJ%MP+$;=hosm4`5& zTtOdKaPIvZIVaKFW(PUxd`DneR-utiufoz|$5@5TjzLyC$S12fAsNSJ^x_g9L?=+B z!9Nh#27$@5%NT;a+{Wk*tEIY-g?>*=Qi@_C_4H^JLh^n~!w9<0()sI-zb8J&^N8T_ zS^6cgU%vD2iIa)Mh$Qx)UAu?z7>m^uOEl6=r?ZJZ0w**vmM7_jinkddY>m?lOAk%s zd`COqSwW!e$A6SF6O=S)_>bmu&!FWxv1f5 QBu;etXZK4eWD?~4PyES!QUCw| literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/21.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/21.gif new file mode 100755 index 0000000000000000000000000000000000000000..cb8cf6d2a19857f6f6a13a16ce84b907da7b8500 GIT binary patch literal 1864 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 E0ebcLc>n+a literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/23.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/23.gif new file mode 100755 index 0000000000000000000000000000000000000000..96516b8d9368ae6562b4da1541b41390d56e4931 GIT binary patch literal 1950 zcmd7Ri#rtP9>DQ27Y1XQF{VkvjB#0p+)`SXxwxlNN_MIZgZ8o6wzhUVQfu5ARwAu% zdUDC7qztyQU0nv#P&0|J>zZq-iAmF7_#N42&-0xB;JoiY@cn&$@9XRDv)MJAj36UE zNe~N9qG7phvLzZ83#KQ>;JNLaGE#Fvj6!G&V)J)*w}Ij~e2j%hHp_K7b0W_20DGur z-(X*NM>-8A{F>s4Fdd|N>8fb-yOZeK^StBQ0nLHSM$mae*1D7E%( z#Ef0is{PUCegp!BLZE-kl4K(+)x*2JFysM?MX)S|2E&dN5=`!Z`$QOUhna&gf3_oe zJNmPi_ToKbhg zP|^CeQhacFv|lw|t?13~{mq~+kFxM|(}H~Rjnk*o6AW-@vGsT@iJu{1^ zZbTBM;Z95`6Y;J=Obspn;h;42B-&h~m6ET&)uQQ$<*u`wQ+4U0sP)mo+vux8bZL&PX17&6mU?e3{6z`eF6u z99NM$vA*X`ygk_0eaG1>r{$@6CuUej{+`VqIZlm1+j#ZSL4!J}S7z5iAEyC-E;DFvfVVO{C_wuF5N z%hM~Q)G|bEG!qGZg~*KQ#p7Ez*i(FlXNZ*%b^)`_(bI9*(X@%c z+fUZ3oYjwD6>d%UVBagvW$fD-8gOn`1HbD==&b+{Si%z#r zycOS;RQc>)=U}>8M*K&LxGL52Un%;P?!TpUPpwMjhJKd99$l59pPayt8E5Klo$gD* zofGF+6+Ts7os{H$fw&`81!JOEuKKvxod`riqHSv2F(FkdbmCUToybcc%QWC^i11i! zIm)c%ZrkiKf*Q{!A8au-lq0#gbr(Zqrc5rMYj@~rDlb8VN?c{)EeuD^<_st{fX(P%s78eAQZ=|m7~pd$sDeyzJlx0My#!2 Ml_pW68Hlg`1F!UCz5oCK literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/24.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/24.gif new file mode 100755 index 0000000000000000000000000000000000000000..5f925c7bc15698964c943551584ed856aafada3c GIT binary patch literal 2257 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 ZAe=XE=`EVhT6UAy5GOqlm1`-s@L$#RTl)Y2 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/27.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/27.gif new file mode 100755 index 0000000000000000000000000000000000000000..bb468901e4a9412da4f5fc0c4edeaa73b3acf570 GIT binary patch literal 2893 zcmdtjX;f2Z9tQCDE?EgAgaDDHULs&b#RObHC?^S9Si}^y!&q!1iVL8o7L``!n1n4L z+F$`u(E^I%N}^c6Wlk2L;8+co8F2vvir_jdvM-q+J*Uoe=F@zbp1JqjkMF(jd;Y)Y zxuIbpKECUjfC)?hn5HJOyus9~RTIt2?>FBz4R4=p4>|4!M$2udI>Jp8`^UBOhGby; z&+fx{gy9oZ)7aiAWAJbRdH5#VGKBjHutzJM z#wwjA3`@ICyHDQpF-_eat#lkZfE%oy`?R6TG*v%T%YL^Dyvcyan>ZIG^BXtdO#NSs zd`}zv26P)@rn;i8%0eDyQcXh%gV(%AA0K(y z58R(Fr2Sl9`=~syyPp5D``OE$t{2;ofhxDx$80r4oBO^cpW9&5Up~vI4S6AlYW{#e ztS)~25mPTdxttntJD1g{ z3^={gA}7**}PXs?qSqsuc}Vm#n`Gz%jWvh;E_XdA?YZ* z^8~6k>Jc}tWhcklMGmZRhj!9vP*56`ep-1g*g!ohN`OzvO0YDT7-1RH3(^YN>rhh> zlk+r83jEot8^Kbo6i*G9rz?-gimmWyt4K3P>cp^RFlaPa;2xC|eZYYkr^P`yFA=kY zjLV>SwP&`%e{9((D_BImB#lEm?VuB}F`~q~b3>x>V_P_w)`EDnYpuLjw;e&vyLaJ8 zatIb{l5bdwyU)L?P8a8k^0I4rtSCF_bp;3yiFRDSAMNWXLFv)$d-8k(<75h=cc+xD zJVV}3a`YDoD0>^_T3+hyJ|5Xdg~_4dSWLIiQD_8+Fv+XV8jb%%kJz|!`Liq*7!Iwp zKc{J=GXakVl3Oq>p6H{7NJI?dlPDENohvHYVsQAZRbGtDzo6Mb@mpL1Cv886Pl^e8|AH zD6UioS3>vSU+OO^ioYM79*Xk}WAjVN*+eD%b=g&{@RHaKkG|jg`%SQHR3Bg$?;(*0KjSS%9Od+yMq@loQOruMNxwZCNl|E9BG|iF^NX2!s})-WQv64xz7T93uld+qzZ!#lmftt7O1!{efb9;Z^ASf> zELI#spppz%CQVe14@sHP_OEQjAF_#URF&$pXmi4ggBgObgW+5UfuicE$zr0^xLoOrv+$})3AC&O1T z-xHtt=nNCP-vtwiw1@WZn9!Mvf5XJf2%qiS;7Il;VOrM&OIcqo`O3w35>lXxu%OQq zNji&~oz8V2P#o@RE~pYqaVUg#Y$0jcr7RnW6%~sVa9i+%i^1{{u?{rZ!W-`-U5>$6 zx?CUcf#f*udW6!pw@_^K?&jx^76iqbnV{pAR3Af|?Qfar_EIVgC>99*nTfgIGCajB zoGo>l$ydIho=nN7nVA?Q01#sPm9!n`J@c;wsB~7IRbssD$H0Khr_Iz;hj6Bz{OrCq zCuU12gh!Lk%B-&^H=PVkvI=S-sdcedJT;8C)u{q)j?zkGp@JLMLVFPa8uI(JFaHl|$N!pkzkdL5 C&j>*P literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/28.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/28.gif new file mode 100755 index 0000000000000000000000000000000000000000..f59dd58257545068f230bb6515c053a38f47d5ae GIT binary patch literal 3262 zcmds(YgiL!8iv1_B$Lw+LI@B!nP7y7fC0ec03H(5HtV5HKwYY+v7(EpbtVZ1 zQEE_YEm94LUe;4_wcx3m5KdC6fS_n81dxJ4Yj9OS(QK%Dt?llw{kz}%|E}wu`+e@` zn;SPr5~=0^960o<-v=1$PbNjuF z5OA-t-mU^~x)#{q%(P$iw2v;Z_bBX_J?yVzUtaWh-5zhR64`G@)M)7K_gi`!rEktV zy=*JA-wY|+;Z^Ur>bJl2-kkeb3ErGzwCr-T-Rodz+a^EAqO}}+f8cg}kI}c*kl1}XxW9l=mcf61oN;3f+J9wcf!x(jXh?pW4P zo?VTwszK*ruijg8N3IHgyOL-h9U88f+j)Rv{hZlcUEbZ%_Po8c<-G3Iy_oxI(0*}E zpJjLBxvasTDtCQ6=UG?7EKBH4Eqg!*=C>KE0KNe4gJ+v@16I}e-l2ux}mQ`(BIuQ&|2TR z*YnMAzwJsw&DL=*ewzQxB&pdWGp*;mxHRd^nnf;ZdiMFujkOs_n!PHZO!x8K0nlUL;1^L?k`;(c3XP4`9w|LD*LO% zhbKj^A7B46hSE}o4SX}cLci?pv7mvrnYM5JhE6$mnAhGuI^S-e{-k+I`Nr8JHM54l z^8)|BM=(OBpr9NG?92tRix)|wCES*BB)V-nP@SA-;zVMY+^i(Bs1_zF_X4X zJTA5CQ=0{XBi(tlP%}<=!?Y5G$y#?9LWQ_41+uQdWvCfUz8 z`WZilyb(zW>9g+Nz9$g5ESQ=1X}B$}Y&c2@5{m`eMmj>K@io>D2z|7ZQtWB2&{GmN_@!n{!0&ylBDEmYi0Tl)4su8dCwT^I66_-P6}kHr+s-n$+b+ql`&9WxrD7TbM(AkMB(;XleTZY{M(&uZ9XsbW zO(E^N1<|PTi|XW(xawtd6EPek@C4Y`SxieR5x}#9=mrfLSxNI>=MK!3VVvvp*bhquLCQFNZBmVkQl^J6}6Pmo`a#JFg zyxH(HTqV$U(p`^mT9;X)#|6zSV<@p!js8mR&}xIYms)t1H=XVGFy-K}#u!QLbW3>! zof^TCi@3(JUw?vpLq&4I9ul^Y4+hn%DBA9ta`~eR1XRHM$h%afF;ek0Va?}i$zNQVs)Z@EFD0MQlE{8q?g82!p1|l&9OiLxLuHSH442lt zycEL}Fqb8&)%4_H)6@BEcDTwkk)+(Uc*!OZb|^WA_O~LFX75F>Qs)q&;)P9reyM3UvC&*;bJ|zBzd1O_;_$r>Tf? zGKPPYBl_^V!!u44;UR0c3U#IwfRv7N zJMb5-lo0&0#tL<&0AX-IZDJSkiW7(kbIwWY_qmssG&dMNB6EkFX@ZLFob*yN)0?kh z!c);Ai1hU(gGnDERA3ZGw`Y@vBg3Vf{ak}Nhr%87ddtM;KbV|p&Br#*gQVz;0V{$| zk(h{a&Tl>NyS#&7@JA%v^p%P+B>bDtIvY&c@M+mfibK%wPT>ci!1*c$ZRgB9HrBK# zkg-t9BXUd&V_~63tuPL+AY{vZKTC(9UtkjA4_5GTpeKFUPAk#%(lcFVJ30P)lt>Xz z6`oga>L-!Vu|PEhYVS`=j$_kG%u5^@;o?46u?1XkK`siyRA;sDs#2R=gFAABL|dKI z7{)s0$*3QJ=1SF&B4D0R#vsta0p86jqcI@P812N4$kh^hF$=hr&co5wUroKKT4IRO zdQgLManZU0;e41X$3?cxy}Hl{2A6?-f8{yIWXRqogMy#g;@KnpeCt1E$r>N&D#DBnEDR9)04)j3cui5`Q|?O09@nSZjM zeW9c(cv6JO2r=GwM4Jdf&0w?dSohP~v?f%VV!{zmk>hc}O#G`B-72wmL`@Zj#zEss yWM7j#tj6EFKi_qW$Xx5;w%o>Gg^hK8QDItw_aYP9!kTdjvM^a16(WToFyo(6p0-;6 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/29.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/29.gif new file mode 100755 index 0000000000000000000000000000000000000000..3c5227e8e7796fcbfdfb8aece35232df864f5f00 GIT binary patch literal 5861 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/3.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/3.gif new file mode 100755 index 0000000000000000000000000000000000000000..6d6f7629968d979878a2defb2d66ece81bdc2af2 GIT binary patch literal 1852 zcmZ9LdpOi-8^?d<;2eWdljJaISVoSuNQ~o*$U4js zWqFg+grS^<*C{5Zl|#}vGmUw6wC{Dj*Y!U4KhGbZ`@Zh)^}WAD2YVA!UkrqSHUYFa z-p!1V0sIy%W0Rvpx#tWvncg5Zr1X-!pdAZ1*8KJPu6WGIo2I!BY_NPCtVe*Z z+jV3$@R(d*@eH&nj~D8^2-*kU>IlY6Cu?s`)LtdK;JV|mJ3I#9p669cZ)BK)1>f-^ z8_ui5l>+&hXSkU>^bQjbzMP$Ix2cOIZkM@jJ-t3M@OJXC>iowKJyGKCN-k{tl?C`~ z^E3l6cPcB0AlTs#S5RJ_Jp$M#+LF(Mr+Q%K&YQCM_0<(ljn?A)4A@Q()S|$@(O}}z z#=_V}VT%15IAb(*uI^-#|BRq&giexPl2{ z7xe@Xu%3AxT>tYsz{>>b=Z5de^9FBhPyF6m{{qaA+HRRiOop%;D%tVX4rE^JQI|GKF%5h-!6!@C|mB$nC zszB38u=Hb3M+^JUqaZ0`zCsuDp4^;I7;AI_y?*>5lNC-8sJ2^rp$}?QR_Ka?3`a2G z1Kybd{^msOk6d=R>zmr zfXS-s^Gxc?yN2sI0qqpq{#4C{;r1^RoqcgAR;tqHdPn{YeY4f>3%jQw(LFbWSaw?G z>-1Aj-Q8Js|HkN}4yu1!RuFe-kS+0Mh=#>&Oc@Q6NK1cD&-Z3I#a0uWyK7ls4_LE-=c63Qfc zek)mALA!kU6GT6P@NbY~I8C?sA@bE(EjI96w8Pm}H%!-XF~R>@u|^HVdh|;vNBwOW zfn;f-Lzv@}<5T5L#+n+;5~YCpsY(GvwdTWmO~ zRxMfaw#I!q+heoE%Glco=A?~nud1O^wkM`DrjKwT5mwPIZXuCj@Go*^8Z;H%JKZQ995EL0{jFro(VGUS4)i|s zLg#-s>!=$DY>$PWl)fu6PNVTNB`C2aGn$yHM z@n7uCvB*+M*lb+^C<|cpWw<9O8?-rl7F#8%CdYB$ngRJZ6ucqBT0+~4TiAJ0x0-5= zOU=Ic2C_kUv{{_dmqTip|fqsEf?m@&ZDVQ!%|jQnF<$P8#2c zVpt7E44Fu(n1N(VB3vMN0CX?G@_-hIDyHrHt>^AQYaCJqdH6>%Wmg zB7CU?Q@jFEM6bw|piJzY53~{y`R1$tuCH(i0ihu|p|5=q*f|c}yWc{FjcH*#_Rv}+ z3eWJvw*HlXI(-V2{ODJjjIxcKvUZHSSUlr=N18NQp(2goxNmBT;1)Y#h53WOeSi~^ zonYZ?9?qlcraP_1>@1@1jH9cMHeP|@R z`)xzbY~SMuZZsNcY)yjoWm^<;1~nDSkT_Qw)?qgKn?}i9jS@nQV$dF;#{Ijud-HO> zRj{anwl|YbV^9RQOokrlt9_%3{n&pBwoGSjG;t7 zi}Ep+3tbJ)w~6&pkx@oCbDEV9cr$a6A2?R`Wc5tKSNn4q9x}dZsBAr1QVLI$e{Rza zTM^|LD_we}y7gGDQYTdF>0A7|!2aNw{wxnQilkAF!03BX2Y8C-HGEp4FFPe_UL(C> zBdL=STplNBd}w)`fdV-mTiW^w894=<(~t%={$0!uQ-Ye+YgP7Qlk%hce@;kY8`zv* TNrDGC#Y$|Xkx1CnqWKm_sF_!G;)K#=!I4 zFue6zksudd$WJ&4+DiNfo!&H!5_6TM|U_Nqw_Sy8fLLq;g?j=t0sa0a-D$+3e7d?LU}@l_MjAYM|GZinu6-H;+Em^0 zlcjox1_n{N*J+wUuxsJc8;VLM&nuGhX;e!1{Vy6gP3VyW5n z-Y3Sl|3s}h##>*R9j^KF{G3Yi{h`(2f9h+DyR%L%wfo*rjF}X3Ri%zgoq{(jue4nU z#zuz5pFVk0X8gS4LSuI5oNB6?iGj_2(42TwdHNBXuB)SO>UFTG+bAs5bRD{3hQG}= z9B=$;q=-8+HLg?alC?Lg8$M_wVt+Zo+^i#y6L6c8f|hRr6gPww35<=$-VIs7ug9vj zqgU1xC7{!QPJQ=65)>7|s2_|6z^el=8=)WC`MR9^>ZXZ0_2kS|dgqR9EA3vO6OWa- zz)aX$Eo1Et6Yep`E>ah82&lqgZ09`R6E=#W-v!2n@FH^TGV=izyDV{&Wi#R3xM1{$ z;62fTz{p?^S2rw*AP9F2M`9v?Y1iT$op`Z2)+zSelBTnX zUs~SC4Dhf~c;$?sEXUGC?xB$A?U@0q?)DuYMfiK+giOZK9LW`5DTRBfwwhBDF55y} z3@mhZ+eSv@^GHWBm}1KSwvVDd1pK ze=MYyq!{mc!VjSz-F+Pi>7F>-Xcxpzl<{fgE5|d35<`$Fq2ly`OKDBCSzI0twV6<{ z+hfJIcN2t&kZ$hAr7+C*ph6tsyyy)1sF!=B%l^+3GH^k(%s>*0Hp$2DSfJspwjCbm zalr**f($WUNHA{lJoX@}6(hO4vg)kxcr5u+hnY(v5@`5(0l^r!aFAS!6AK>Mbc3kY z5Zh1ZYOw~+96oBwi18#+MfSJ|3-9t;gxgZ+DYeT;@sN0sNWw6)VX-WS6MtlqOl=r6 zndP6%`>T+#(>McX8@c(Da}bLD%8dVQW(FZ}_|~OcqF#m2qy8TzQcgg##s4s~{_f2A zf9BuyiTtwKTtjR5b-7X3itfdH96cA4aSZ=+D2CCUZzoLG?Q9j4%6ZXW@*Q}ril`6M z5C2V9ZNTrMS|8S{i|OSQ>8D@xuD4zg-pXkRJtAH_aVDq20qgm^Gt(?L&f0RqZ&&fP z(|5h^5qka5bME^b^rzI(Cf*_kYIZZn!kLF5?DJjkOskPzSV;2?BhB&idJ8gRB)*Ny z8B#wpo>yhUL>7+jO#AWFL|cOR4k2j8A*BW3=hg3S`$SHcaj;p3`zwqp9R(Pg)0BpsDUH1x)r5y+|Imb k{n_ye)X-{yMt$E}oY2c`*&^xt4eO8Jx86gUe`mepKi~&fM*si- literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/31.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/31.gif new file mode 100755 index 0000000000000000000000000000000000000000..073e743ce5f5611321cb04f9e6266024db0070e2 GIT binary patch literal 5174 zcmeH}YgAKb7KXob$;p*)0x<*#m_X17s1dCVig>~`;w>m@tachKt!TYOYpYdjPeQn; z*ak(#%3y*}X=OB8TxPT#PZH6H+ER-at(U|rVmqbQ0**)~1ZQcTwPt=yXU&?Kp7Z}* z`+N7Z-@P*@WGE7Ig+K_r2q+#2yg$6udr{%-?eVs&AAgnLy{+;(BbFvIzBzZ+dnDM~ zxx(A?p|@?4_h!aJ=OFLngWl7FygzC$fAe*@D!{7+k6dxR&BJSQkS&=kZ}%GOJmx2J zFmJER+uK~3g=`uFKm3$my)M!Fu=rvwXxD(=2JY?a*Dlqjx_3!$e=^Xqc0gl+=*S{Y z*S)KiW5N2DCElMG*XISdx81t1RoHgxdhfN=^E<-5k8NKV*gYK=9$w!0uu*>a?U2)Z z3;&SE_4agj9(|$nh^)CP_U3lh{k{CdYZ5MPVl`GR_I9m$P{;ZFZT?r=MmD|6uo)*@ zIyCLpnL}qR%Ubum*jl&p&V@5AhjxE^FzsHg;Lg?N8`m!Pv?vbgGrW(s?#rclsLU^` zM|PebeX=}m{}Q36aaLEO{D)8Fo@1qVU1jGQZ9TX4|7@Sw*}CKI-gs}1`Fq>M&(;ln zjEie_NMpPW|GToAoi>O|Kj+d(Bxg=%hj5eUS70pERe}hjpHq z-DOYz=|IRIOQyR_$t%-?54;(7W@FSY4ev_jz>5`#GniCX%O^mprw6TCL;tYxg)7^T*_+YH+V6GUH9*aOzwYo7g zhBUIerNRmoakqifdL)7uO+rHjT$yIX9CI~19dUngWQJo3#N$?Irila_=Q#)(6fJI`o{Ci!7ONaL&9k0-3bjfil(azy-64 zW~&L%*F~DIi}5I+0UQMST9)B&nNF)W_*#~eueCUf>5*BLbyldccxr;$dS6apu{j9} zO}-eA5CTwL+kvdDoVXCo=4<|@
        WnIIQGm1g>+S$^r%K51EpgOZ}bv2#_;u(KG+ zev4FS?_z7oPXoGn!?mU6(FOS82U?H_S2GO&9I&3 z*R?{ag^`i0Qdqn5NKy zZ3aCAJzFpW7=G0xaOjDu&tv2HK98BZ^32*=ZJ)Kc6lf^`APh6BYqKyoYAFE3?k`UO zd2S&&0Do4H2KpTs?|0S;{Bt(9L=LBFG?7_(b-8w!$&AT!;cl}53y=YZ*lh-M6c)-= zR&pYn#}y~x({J0!r`{%mUPJ=KA%W|0{puWFKf`nj5#FyzTWFaGvE3)d` zQ2jGiG6CjeitDR#JP3JWB^E%%l2%Dd4mWzt+Rc)Jtp%ZVYKzv?PpM2OPTd+Cni0g& zApnHM(vum)$lKI&nwVd6G}!XD_T;{$a_RI%(h*Wlxk;Y_Gy#k}KoBILL$IQ+*QXdf zZNw^_8}ygQWc5wc(*SJrPt%hC^qW`^o)@3T!#vfIqXbdyl8?pu;qy?wR;Xpr46n*c zR>>S}8pA47lX{>`6~Eq7!GZ58vq&^R({SyNwb1Cs|#h{sz#fQ0g%{3sojI=U*L=yhRCi#;@Osz@|+MlRvU!~ZfEz+iyy?~isq zLpr&NNHNqcXh=Ot6(b(hV@W3)VS%x`3@I~5M2-%_g%>HZF(5&t6oHcTiZV#55-!kY z2Zp^V9(P%ZWd}}Rk78`%xi<-KRlg@$pG4S9~*)WD{2#j!{f zM7Mb|ih22Gz{b#38dEuFFHQ-G|~ZFM+d}5JWt*W^!lod6X%06fZM^S=n4hZ0mL#B_h-ElY-S!xiV%V zcN8U^JxO~D9o*8K?QhxhFmC@l7>n`ftV-1ZkZuSZwva{2jFuSt5PTn6oRkSyu@!$cjP z!ofiU95cH+K6cI2n~!kFLd(Qp{TmSnL(O7iP!w__p){!7{BiMMZu@!FlZg1W@In~` zMfry7HnG}Pz^RVhEXWsz6;L4~U>0A+n;@=Dz!<17MbAdC=o4z(WA??h%u2n4oFGVA z)MsiE=pmYrfirxWcO={UbZeXNNu8ML@VNfb{L)Ig6IfF ziHFf&eOCjIAw0U390 zz3+U$0VdYs1S8EQSHXi<+;m1J)=xV=2@-vkCVES%PR)d8Uv~;^Vk*uOV_Ey{iivHw(v?fi#yWql`?11E+_8bT$tH1>diiTkvMl&=Fr)F0_= z2Xrnv5LXk+JTN&GgbS8;GYN4v5DKpLF!#1i#YN?RS({yr*0YdUlj?|$Dh{bqV*J=0l0la%A3s_nVuYWn=7q-ECq8HOjf-fxKg&+f@6J6#ax q3u#Jh935TLptU&QRR5mz2iW+3=bk*P=--q5Vf)(|_TO@bjr}V#m8a?e literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/32.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/32.gif new file mode 100755 index 0000000000000000000000000000000000000000..772eff23e345569189e0dd16516733f20d7b4442 GIT binary patch literal 7189 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 E4n1?-W&i*H literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/34.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/34.gif new file mode 100755 index 0000000000000000000000000000000000000000..e9d42131a9bdb8556647e91fa3915425ab730102 GIT binary patch literal 2140 zcmZA1dpy+X9>DS6n86sDW=0pGq9WH-xvY_x8TUaUZFJe4N}aYgx03cmW6b1|S16Ri zBBbP$qWhL{ZPIcO-Q3F*k)5ewE`EOBGydwF^WXE|_x<{Qp6BuL^LD21F+dCuIUo}c z8~}X`b9baA`U7uz;PamMmu#ThR#X%Nm%CDH!qs$!>VOqc49cbXZS535R}1 zNyAQ%9RXQl)jsOn025SvwAbau>E)nI$68Hcwm{MLGvw~Nm+S+Dd{Mj=3~mBZ1_;l5 ztn&s{oO1L&$oInt3vJ)fk*o_-98^95=#282J&Xk^uLr?LU-Yq2W4a3{6XAuqcw|u7 zR{&GNFtQ19j)8O=JX!>=?WZ5wgE;L?cRMBygaK#hbD0}vL-BF=91LG~Lc2ep)ld}& zeY@sr7QnbK^zVhn<=8z6oXLT*DCj!`HxsdUn?Qa9p0Z)kA7)NZKX(LqJj|6t-wC*t z42nB26*zj4Bo#V;{xk|R1)$7>OBsNcd=Z_3ZvUBQJ3!2Y*(|7wh29IZH}#-%9ZYS9 zJRWrX2Cb1GJr4g$hYx!J&69W0LF@}tMesfVDt=eJ^8i%|^w_}@a~KVVZ;{xD546*v zWhI=A8m#i3ezFF}z2NInm}Eo8Ug&lJp&``xfIJ%NmVd3H$a7qv*lj3nCDiBiW>P;E zQ{b5`)NO)mZqT*uMIsRtWi~>LX@1 zqitkgrH@WJimoPf-H3l%lPG(2Vfwyh+wF^3u0QlJTPp>#BNeFlR&A7Fd%Bsp!UC@E zkxWf0THPL>+dqe*uRB^UvNVSKUSHd-1F134#s%34v#|+#8gSpBq4y;(j7;)vBbbq2x^ey^!UH`H9AQneAjMZ|Q6Bc@qo~wvLr8a6a5GUC zp;2ZIc@WyjF67v5KNkO)fVg|FVGosfroJrq&lA^&InRQ*&PcVT;>uqn?tpixM1EjP ziVb$$;r)o+z?G$hEUEO9$7y#m_LTVM!V zNVdschKi#jW7m=hI{AvS(cx<;n;o6>LiZ;vpmR9}4|2BW>-5KOX4pzoqxe=llAi0q zSn>7x#DJb?OYu&_t5j0-o_LDnq{%5!6e0kbjP8;L>4A*iHTlUNs$z08S0!I7!P(L$>m4xPL; z?xHRh@qlse*#!mbR(Y*TuTBocy9Y2^HS2562RSvnzSLNI!J#wBEJ8pF*gy}HwK@JJ z$j)$Dis-W(3B-Np7_S1FNH`BYCWGwNF{P}N;|^IZ)N&Uam4=x34L z>b_EMHM>xe(&WiI>8hBG&DN%HzZe?GBrU~=Kp*W5Go@rPxHv4vVa%@4-x>r8YK{rh z&qL$WuhQJlztFiFU(!h?LcV4>WXlj!$~MEe35VZ}#>R%0uhH!|VwA=nXsJDD^oQ;F zd$x^a8eZeOihvN*CbC-fn_7kX?Bf*kh}tYaQB7%6D*o;MBnwIVid20AmA^B4xRpEZ z8Y`8w{DSbpQ8T)rr8t*+6;l>08yTqx!3}{hw@%z8p#oOC{w+ z=}2YOIYELn!D5R;1Ej9BS4rOicr}2AP}G1@1mo;i z2gwOJ--b$gS3POR%4NlmT+N9j+QG_xp$o0{&_G+9brb*p?-K=Cs3shqC!{e=(s@L< zOOH+SZd~OZh8QR+x6oXOIWp7rM4zQRhvOE@@+2!4tzfXLJVj9zsYW{M6o4kLgs`o~iX4?aowTJ&_1)Az`3)J&Z z&Ceg>lr(UqdMs*KL&iluXvG;kXdGgY@wH*-_K0kT8q_?N}*?t3wv9piOvLKo;BwZu`Em$>Mf Xuxw23Rfpg9B+Sr_#wQz+kd6NVg=R#0 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/35.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/35.gif new file mode 100755 index 0000000000000000000000000000000000000000..d6da2c33ab4139ac5ec7becbb7221008e0805034 GIT binary patch literal 13392 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/37.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/37.gif new file mode 100755 index 0000000000000000000000000000000000000000..92efec6ae180c7e685512017cfd06f75c36afa39 GIT binary patch literal 1195 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 x2->BLyW(_(N6e(g7IB0|H;fd~Kq literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/4.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/4.gif new file mode 100755 index 0000000000000000000000000000000000000000..6ccdaa2c9cf1cb656c0306f6a396f1f765d01786 GIT binary patch literal 1977 zcmZ9Mdpy+X9>;&0!7$U#3?oA{Gm>LVE~(r)G1C|n#Yhn`E~jXTI=gAD#f)1cDQ%nF zHj|BMvo+Fb2gMk-iI#|R3*)kekh@`+XGdpy?dzO>p4anw{`q`ApZDkcIJwZQZ36KS z9$E&FzP9qawpVH27)wTnEKIgMV>!vC6YI~gi}kyfDvX;SCNEX)YhfYf>ucccUNCle zcBBK$3B?ce!AGA_aX*lXW(tw=0m|y!*xF1dJNXD$Tb$t$z|=|5z8j3YjdwN4h5BIW zGH5meLlhs+-SZ{bh56Z)>C(cVxqz<$mcHf&Vufi3!Kl-3v6e0A27P%1Ao~&Y9{{r4 zbsnm_qZLfJkCf~HE2-c=Xn$8NX@dpmvmMD&2i-Pcf)09Y!1@y~a~jA8L5BsX)C3L0 zu&}W8wmm?gJHBfwOZxY2H+nF(eCK&}1)7u8hfFI#xH)awG)3g-G^dNR~O z>&~hB7%)%n-+JHGF+9-M_wEf~ zKs|XzMP5o1-Vm7doSB}?$+`QYs`mSMmLTh_=*GdRD)0Gz9*sup@9tcwH+vCp`XU-9 z6YW}R@aei^5bcL6y6z{gPG4?1dnqRFQIv^?jp}&G?%6JyuQ%EEbcpEj?Y{fecMtsX z@;RviTZf*|C;0R-Uua^u&xdaLo(x!mHVuOjXk@}w^LIQ&; zGymm(Y+HLhe_WKw@U`cjR-1lvZJ_7v>ifL;p3p|tmS(nYNyH9TVq*CfPtIXz?TryF2bNHHRrFUP&u(Wp@ZbCW^aaN$?Pa z01!~qbLJJ)BqB6-_Cd`je}yB%y-wXGiv=f<_zPcI4m;g+Qp4;xB}r>bMq8baz5IHb za>FZ|Mhb`6sy7_;Q>Z%a;uNHYeaQvPH?Qy7Z%W(G;m~PRO{=Jk>^W6IKnY7_Eg$j{ z5sEc*LqfSfG~VeDdBhVrER&K!eQA6NN7jxL|t?pFwp!6u|oJG)Q#GEn$C zA6z=if4G^wf+VJ^osCr)%Hg;`rRTyc9LOYUdV;fo*&0a?8Oq z=CU;<;&9oa!4mVGta`LKp?kU2QUZo1BxTgSL{Bbwe{nwV;^&CXo580f&go;|``&FijrY?-Ho3IDIFq0sf*sFCy|tcD2Jyd>35Cb9{ib=gCv z8m^oRgEnlmkp^4hpcr7u*8f%U$6TvOc(r2`D>9oF4vu>tFPEJ&advQfc z>2Do41XK9KDRjaWIymcyqt}@T%`cuaXHtbs&21{*{?{LY(ro>ja3BNJJ@=Hbf-*KE ze)L{=V;1-u(+~G7Rx+fr&F+%Q(ub2FNgDcyT@IpWWuYE09f#v4J9!O`VV0IhC8~Re zaVX+lGPLqB>3@yFAdOE0#B3N9{rbB=u`m73qL~2I6novj0@hp)#2FI<(J54T5mtn9 zM6l=fuT{>s<})u}{8}&l;*7g}gm`tf_s%1d+JQ@~o;IT>7lhUpf9H~AwBC!j$O^YU z)q8zO@sTKAt~a^P{@kX31fC>#xO&r>6+;x_?>u0NJTQtxAjH{?ajYX+6yu=d@OVRx zK<$gIwx4+iq2`Dj409N6Al>6Z%ZSIwGrRT=5wjAbr$cJr)E=V2hVxtvRSj|-!s+S6 zNedpjz{xsOBry50TFu!B1bPtLsjnFB_?FW zYr_4VKX=IghKmRL0;qvjb0oShX!lqa|yEO_DAiF;S DKt8j- literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/40.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/40.gif new file mode 100755 index 0000000000000000000000000000000000000000..24a8eb69149cc1b139e24d3ada04246c42e05c71 GIT binary patch literal 10092 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/41.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/41.gif new file mode 100755 index 0000000000000000000000000000000000000000..99139e1d1ebbb9123de502b7b8bc0127dc55334f GIT binary patch literal 3368 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/43.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/43.gif new file mode 100755 index 0000000000000000000000000000000000000000..43504910020ead31098a489ea1e2b6fa51e8314a GIT binary patch literal 4327 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/44.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/44.gif new file mode 100755 index 0000000000000000000000000000000000000000..650d3dd84026c33b31712f94d1c189db2b3e7295 GIT binary patch literal 1571 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/46.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/46.gif new file mode 100755 index 0000000000000000000000000000000000000000..f3cb0742d7f2c12475b1fdfca98a46ce3d1dffbc GIT binary patch literal 5162 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 MvAwGZTHVF}1D`W;)c^nh literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/47.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/47.gif new file mode 100755 index 0000000000000000000000000000000000000000..5b3057ab7eceb885238c9308a9591b118213703a GIT binary patch literal 3685 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/5.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/5.gif new file mode 100755 index 0000000000000000000000000000000000000000..ab0b81ba4dd535bbfe38ddd6bc5b35ed85d22a0f GIT binary patch literal 1866 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 Khets$pML`I4Xz0Q literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/51.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/51.gif new file mode 100755 index 0000000000000000000000000000000000000000..69f183f043a276acaf62658536b0c4561492578a GIT binary patch literal 3731 zcmZveX;>3?9>*t{frJoZxFjHw00Fs_%LC=e5H3*=5UW@(P!!wsNR_HpYZ3wkg+(lG zi$x^h0Unh^w8m;nf*e6PE!L4EI}} zM1d&KIDkMM4fL&ic{yaN$+xrAaYE{Jb-Ni*Z=2{S1TAjhsW;G$fzH6Lwln+~YtYRE zVzW_+>m6=5(ADeiS%QugV=~{~0s?ryLH>)+^Y#`n^)E2G7mObUy4H^pkI@=W-EGoD zoi}(D0Hy?BS_G!WikdIMlf|Hx+RQOh-*EuHlEK6IV1f^(Z|Pq6foF?BZv+@W(j{9B zCbBw3(Y@Clw14`6DjP8M7!d?st0MyeNqMvsX~bCr<#_VQfN8KkI7*4(uj`IV}uKd2D8 z>158|N11n?vzn;1czgm6THQ2ao9P$+;J)RwkhsMWDvCs&wKanNsB2#s0@W4(Kw~x& z48{W0=4Vfu{`ksh@J(;Wvp-+S+ovWcd%8Nb?AYKd(6$gfSqKKA!T2%oHvV;Y z*Q@i?rW?F**(PmY#i(@k(_GUhKl*A_f5}Dv&^+4q_@vF~JzvRBDeuIqKU8}4U2(pb z761ETi|$)%2gPgObhavr>4QBT(^{==TB~|LRDCMw-5&{~cU|TGvTV$DNTfqk%F83e z>Wp>f06bGxBGH{e86;_TJnzXH0&s`nbjYGdq<6 z`-xi5&gW0NUi>vK4FfuDecIds*_q$ji~9Sz#~&;cr$>%IN|9CkD9a1_*eTrQN$6F) zy0O>kCd=bVt@!RSpDCI9tMioU4#w+iRL~z?zQss%(7kfM4H%4TxSFYugty&1q`c`h zaD^gFF&SxG{_x~N#SIs=m_Bmfv9Ta%xY`@kJA+2&>3Uc2Hg2k2kMcNp6*N+2JW@sk zFPFb6q=2bnFc9@oWCgSW^$j!eHb@V`9vH6)TNfV^92@4d$P30m5M)1r7+636^3cEQ zLqdTdygnyJwkw4KDGzV%w%N-y-+O(b%kmIbq!LYN%v9!8(;i#x`E7mJCYQ+cJg9@x zXQUFOVZH8z+XrN>4uu#Lovnr^je!ga<$0#xk}+A(N)j~CS`PE!mDqI&XG`0EN&7Xx zNPSSkH=fT(ZErmwY2i`gTk*6o)rJCy;wPr5t80u;Ec#V0s&o#{_9-Bk4ACnh=ix%P zCdB!aAg2CoAGy&F+jB1Ogc;s>VLj7{=06@hHg#xE z)PvUm;9w-k{3Sr@J?sYe@t+g6F8(WUQml)N_K0#jg?p!AxS&1@lY!~e`|Rw zk(OqAX_eE|?K~{xdRypdY(;?xcA0dGhGlMN+vXV9qu*d`p9Wl%I?g?3mWyV&+u0C(qVx8>-WZF{0wv4LI%~FQw4T)tX z5+gg^5}|Jo^{#0)^0Rv4L;V97%hU2`tkNcdbBflx;H+!>HS8R@$e#6(L9N)TE9{Qn zf#c>TFCIDkew$f_BdUQpEE$8%fpNO}ixJgcfTSL%ENCfV57x9t7IbG-h2~7rhwqXy zVw~agh|RlXj(^2I2NgN~61qGCgZY1P=6Z2`v*PkFdbfT|ZQu!&3?gDW?JFlYFlbnR zt-lwmEtmn0~+1F9T zJ&9#!P+zcCJI_A5&Iq@`aMir>)7>c1cC(7NF)iJgM8Oi1?PFVt?jAkS&oaKN|B;7E zwT1TN26rs{)^c5TQVZiDZ0Ru&+*+K0!wh>pGFJo}7?^5JYnFvpR<#HMtpqF;uPWrY z;qda_{RR&*-L+1G56fa4*k2j?(VsO(3cA*Kbg*1lw*INFvvA1gly}W2&kCXC=&_QL zF9}PCT=q5X>h3pPS()(iRLwFT%nXCf*0-$<;p-Qq=D8^UeX(tZb`>#T2QI|WA76O; z8#MHa#PHCrp@xTvXHdgiyU(*&I|a9?uytrtWf?Em3f_5$a!s$Z;wW;|V9FE248x{4T^M6=-Pnq6;b=A>8U!F?4U3JX>QZzRyt?7UBbHEL>wrq;Rg1e&p?#Kkajx zduBBIc^T_z-?QILk+f6=;&e&q$Z08Ksj<-^i0QSGkftVSSn4^CCGZKm8V&z7Et2b` zc`Dyt-)xiioi0_5stip1fe$o2p1C!DDXG06)T@Zem$C&5*Qc zdAGN*+m326F;( zhLIz&!NCX{QJYAIDk@W&4P0!s3jJT;9w$v~!t7TP*e54d1NpLTKVz&L?i@5LziV#1 z%!goGPbylj{JhKiXI;L(c_zXR$u-f6zznjvU5+2ClgQ0Q+?XziGLyOjIaRr1K@pP% zhVB1`xHkiJHyKLRLq(J(oc|fi*|$vj2G%zYsPOzRKvC_8sBoB#Bm7O2-CFxgRLKtt#h)&S9kr%4betk zhOaFwII3q`QC*pb}79d3bLR_NTcnKgD%%?ZgscexPL$fnHsOLQk^fm>n{Sqs&&7wAg7^> zPvH(RnF%+!fG4=fMpsa{r|4(~Hx`-nANOo1h7oIyDk4=uW@nkZkJZDPdA?ZS(?@HZA)rZ-D z%Quef&pGG3*S6f-TgaX7NO0BW&)y2_b#H8_cQufMV0%ndYi zxVnA8DU<|ke|LcXx_}yD$Vr+FeKGo^50m~c=>$G!EaJD3e(YNF6RN{mEocy5`wOR@ zl~EP?y=Ek`*RzR}+52L-QE11>jCpgxKX>q(&)0H3*KcoT&hO9 zI~IG89w14|jOXevHpn8Eq=)EFTN&GL;Lncj@2TPeH|;}7iJ?(}r{V4{DE4-j%4cMy)M_I?74P`qRu6TgR`^QyOF?Q0`orcWLE99BFx&UC~`#Hf%iQWmiviPeT!Nl&dte zvh=C6@+e0tMlAX=&?6rGHVCp^Aln1A%R$Ej&21Rj0@85MRe(AfT3w*Z0{9f*Q$bq@(k(C) z0#!uN+yaR==&Im*B(%6d%?cP}2uoZ+TQSPpI?LY)S_O#yY)@a~UeO1$or7 zaW;ZesZ<0#r^G#LsC(OPC2H0zo#K#ac_Y&FL9Hu%SVvq)0sz|?YOC~ zwQa5Ey*{(Bv+c9uU0`eOT3H!c$PIpa&`exJ*H;lAMxn~CTPkt>%d62azC*9m4&<7E zrm%;1Tq9Vm6Z>k1N+0bu*7OxgTXsx5bCU|LYTMRLPs-Jk-)hb;l>PXwDJ3X*mg8@j z-JR`CS5^v2b4N#p>hH$rI@kAAr_I*6_7zg6ADUL4bBAu9p0C20cVRV`eN^?XBSZa? zeDdro+s4O9pW^X~SLa<$WYd><>@OkxzR7>a&80?jBVr)9fk17Pe!)V0l zfLJRNc0Qni*lW1Ir({2o8y{Sm5ID{YYtJwT?F`{SYLq@CC(r z;R8Eikv%BR>A4G}qHO5#)^~bB0~I>f>IF9XM%&>MGKe<_E18npBuPGLs)E#*yh!*w ze7J-HJPT=qx3J7pKX-!{MByVR{a4TGlL!D%!8AN@TV#MgBhcN&4QqfP2vvnMG(iAy zn%i@ckPrkv*NO4+kg~#eY&_9%BVUki6n4)=g@9QGsP3$K57!BwFO* zWk;uY{nfwSn0Pw(gumxMVO(^lNjgHs8K$AzHggBq!-a(m>g0uyfqO|;7WVlZc97G^ z`Ek^cb=g;=P)yc> z^jcoJZ(Q?pPKpzaZ)&9I=8|}h{8XAlj&grwT@MlCz@W>I2Kd`pV5OcXk^Lb^TvHn7 z3k5}RY0Hk-vUxIZ)0Ng}hrFuxN`9nPGhq4ty3ezoiMn<;GHw~t~2F?2!{ zi+nWCy~8i5=|mC{?-bjG@hodjM7Hkg4_)qzJApd#n*wlH!a~199G3Bn<<_2s&}rP9 z7M9TxH-7`8VJi%%vV7mT zp38XalQ>DWE!I^(H7_Q)I??f_HlR5BZM79V*P6b_wO`Cyr;lhK&b0FX17nUynV7v* ztUb6lu`8SJ7&~Hg>6EDn1HwZTB9`G>-ua$qXanU=St&UzIr9~xZ+sM2?{tiQfW_ut WTLS2#EB0uYB#v;55Kcmo4gUh0RX4N% literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/53.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/53.gif new file mode 100755 index 0000000000000000000000000000000000000000..56352dde46f7f530c7f4e9cc71a49a8db2e5d525 GIT binary patch literal 2056 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 bLsE#_O3>i{wNn!EA3LMRFhuj(&iDTfDU)yz literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/55.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/55.gif new file mode 100755 index 0000000000000000000000000000000000000000..e18da84c6e550fea8f3cc25d7d64188816f641fd GIT binary patch literal 1582 zcmciBYfMvT7{KxOwCA*kw$chMw-GLaMJ7xH12_;tEYw9tK^(3_L#J*)aPz*&l(Amu zg#s-FY+FC&!$op-4wsEBe%Tk#_w(faJ^%Mj z+>#KvUgQScz>^TbOU+1rSA+qOo^v!Jj=$}L1Id}W+js4KGW|^WQC?iqJ4rjUPhYfe zNf!+sL85s{F>j?#*>>D}G>Nsfg+<2;GIPH?b55nHEY#NxjXnDQ=7{}$Qun|JcKrD4 zeG-`%`4NN2ok4>~@@5eNnTjP(h#6--?t4FGqR+=B>>>CP;z?90#;E<0C zif(@b+q(NPCR0~$!?Lol&Q2^n9lY|-_c@HvfDrg%^tX9w+v4K{ywEp7$Pj*zAmT7Y zCP1|p2*nbqtWYjtausSR%%sA_Y9^pTeq}lt3oNUox>i*S0YrgJz+6-vO(!E1Is}5v zrxZa>Zz8s)v(1L$Fn83&!N#GRXw;~4va4%Dg08heXK5@ZTkZ5Zin~0_ifJT)3lgQ$fK| z2;JE;Zt0C!?N#rl+Hbjo$QN6`QWAGHb} z#hn|aR0%n<;37>CMO$9M(4;6KnTLj?HC0$nDZFKKKRXb6U$W%*#U)E&MUj-LF4btu z%7Cu&q~1_f&8@D{Gvtt|uD+qMNgE%bi{C797Jj8`k*pE(c_$-yB)+)4aLHT<_qhO9 z{7@srTqZ1$E0jXKT%k%M#M4pzO0{x4T{+cNZy?Iy$xUVzk*>Zm__UVj)1{pL!p;G6vVBe9Jzfg?K;gn-Weeg*Y3aMJ4?t3FDuM7NbtmTBQWVTbB`0Rz1W!3 z2o}vPHlnfQ3XZ;tTx=(v=6vKq1nQed_l();w-(V;t!)cvw=BC)aXJ}w6cjwA3Nlgp tnME>2kh>go3*_FHku9Mo?Cw@_GC%BdZl3SDl!}$BV`gT?rUgDA>M!*I5NrSd literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/56.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/56.gif new file mode 100755 index 0000000000000000000000000000000000000000..edf96f0a63e79e6eb80e22a0774137dab2852e5d GIT binary patch literal 1170 zcmV;D1a13ANk%w1VHf}y0Qda>@av*qqBrpW$N!g+$mO5Z?W|4B#0*tze)hmpT_|3yUlL_hdNKmV|$sT~>iFE98yH~&{p|GKdMWmf-ZSI*zW zx+Wsc-oyXm-v5(~`#e1VuA#3oB>$9(|EZhrA|wBOXzd^%?ja)oZ(IMUnerkd|Dloa zAR+NNGVvxR|4T{#w5kN(%! z|GTmOcxU)AGx%O!_KSG&G%&r=ec0vD|Fx_C$ie@1VDu|3?y!8zT}$M6XYnT}|4m8% zva0`IRGrFow9R(^j(h!WYUc3a|Dl%uhjaggfA?f%|7=$OP)qM4B=IjT|ErwvNlBm( z4f;1Y_)SCqQsZR1JD*te3@H#p5%%J~cRsV;8|BH9O(tg23 zIPgYC|A1@%TT$=Ul>dQj|AcSDRsVQm z?I|gRvr_v_MsurC|C52sab)>AIng*W|9fWc9v}EzOaE0)h|9ob>JuctfQ1TsG&1rK zqCpSLQcQSM(c(ZpGc?)ALan34YA!TnlU0vfm=7NNEukYyM22$2Fvu8Xu|^d`*2IXz zqYq275XB&>k)Q)sDqXFhB_VPTF_KBEv}xM6g!VG2Ya{O$hX^C! zu;8(SSD9-Ep_yY41O^xib}X1tfk~N{F3zH$F*t?EK6cRD>4UJ<-=5z}LP6?q%$kLcHam$#1F$f60a`VE| zmTgiB$vLvZ8!BL0ED0zO;L1QN037&lDT3nCmqp_Q0g9)<9jEO9IuH!7AVGK^LvWqQ z7tB!$HbB7FL_tCXV2d6A0H6vN@cfZZ9H$T=009Oxa8Ni81dt0l_9dtd4o*y1p+bEi k(1`)}%(B1_rH~QJ0pxge1`>DdG6+5gJg`AbJO%^+JI{4q@c;k- literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/57.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/57.gif new file mode 100755 index 0000000000000000000000000000000000000000..3f0e2b9af46c46a72bb935137f139294f16ab7eb GIT binary patch literal 5072 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/59.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/59.gif new file mode 100755 index 0000000000000000000000000000000000000000..918288b007a2b32426fdc06ab03f5567bea96e1f GIT binary patch literal 1533 zcmdUuSy0nw6vb~sfPYBDKmb!Un2-UHfDIZ)T!3us5m^H$Vh}5~wiXAW>VqaM3T}nM zP{(3TE$)K}T|ltXuo@gHn-vf!i9Qe!BTGmK2EIb4&wcNCxR2+Y`Q15T5upLw(rG{g zvj$KapuK?h1KJ1k34l_;91Eu1fZ9I(Q~Pcq5nhapS>iwu3g|U^E*2J&U?>D`u)%Nv zP%@xBV3mL+9>(68=HdXQz(^P@NZ{8m*i#W;ih>Ct^aa6(L}(0xmm+vt5w}N14_1FjfLCE)5Q4T*IUE9ACk1Z>&{`N`T}mGwGxSwkZaG^MphgI9q5$=I z)&)avAdCltDF!CPz;e@hw7vvA_e33@6C!wV|5SB6HWmTD@S%|pZ=<1K1gM44R-Aye z>~0ZQR8*v6KMR6)u~5f@;cueNH{@u+Ln~Lt$XayoWWoeEp1(fO*FfZ5Axn1m<)$HE=+umvnZ)E>9o01c5t4fvtq)}df9o{1iPtQ_xZm^k7!+w};c z`Poc58uYVN$wwQNbGN8NkCeJ5h&_7v`4+`f6k=$@nB{b7%p)Q zWtrOFm8jp#v zcxwZ)DCfE=3(iPWw&!*x`F*!8Msv#JCZ(DENq|$}p}cbc3~(86DszZ($=~-^mW=D# zg2&+>IC5;gR+M_#ZuOU`AfHGkx&f3(s`I4hF#I%6Ex1D{qPF^QWMA&jz@<{kvt_c& zX+M7UoK}0m;dT3ArjV(BO~~I8-)Su6=%3lGz|r2@$}(0q@fzG2DZ)Ha0miAQlI@e# zoOP36({b5qbv}6&rlO?d1P%_WE!fOVq4Xlf-LW#2QzGXdcjDf=t)1jYROIbFk$O)! zb}n0=iczE-yP|KM?TJl7ECg!~&t6H(0)Mfh)JBGVdQ9ZZGHPuwhDM>mPKlh`1?4oI z$bLon0MCB&KzGl1Uk?|`GH~1f1g=prHxV#N0Jlipbbcq5C`t9#NkZk=@Xo6Yrmm*! zYTC8*%?F>{Ub8ja%QtuWO0l>gMtw}naJ;^ah~R#4Iv;G;#aRCZ?k45PnN9eNcJNlQ z4!Kr%+dcYCH|ZfCBoq-a^>&%t6|U&2i?|h<@2(=b4G3&Oy{FcJTwV z1y7DUjaHMid5TIK!f{cN_Hcft&)3ZR*T{v8@2TXMV*kFdX2p&*v|s}Xp19}9vjTa& zX9>lBa4LL{S|18XY{II$+oW3lSrQ?+NToP&qA=xjBjut~bBmm6w}~T>ZOpUFaabGV z-4T}+bStHYIBOX*lpv^kTHa8 cmcA*HM#?!*K&5jT2W;q_(v~o)Edh4?4Hk?_%K!iX literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/6.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/6.gif new file mode 100755 index 0000000000000000000000000000000000000000..ceab12242b28bf9746b67d7babfca3d5909985f8 GIT binary patch literal 3556 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/61.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/61.gif new file mode 100755 index 0000000000000000000000000000000000000000..034933ec3e3fed2ac2df7b7370289ec2e8feeb13 GIT binary patch literal 1136 zcmZ?wbhEHblwgox_`a6m?c2Ant{vZ5?zVL4(r4%Q-oJnUL>S|~RHcIl557FO_`-z? z*RNkcl<#;%i(%WgZKuK*F0_Ok*JU^t!F+i_=I!a3n>KB_P;R->n&I;0%XjuH{@P)_ zef#!52m4MNG8_+KJgUWTr$qB%GS7o}p4~BOhk_Viym;}s%l2mm!CagKM|zUJ%#FI?!E@4>;YI-0 ziv;0s$qYx29=#XC@aNB;r*+yl*3Z7SVe*$Q^UqBt-=}!Id-rZ@w8W=+t#c*}&-@vl z`ZD~PYIF7K)!R-CuYws~ma9H_^5oH@NAC;7zE5(z>BV#2l;K{X&hFj2za%oe&J}x< z!t*#!?6M`p1_y?>Gypc}*8I?G$PZk^9m zef8?qomkF4O-kG2^gl#1e5}{J>A>(Lne%hE?dwp6quLBttQj_EnS7t+wvLkY5y2ZBzagQT~KQ(AQS>1Hbl;K7s`>%C{=jXNkIoS0eo&U|7 zH~(sdA0~3%ym|AK0mFw6AMVHV+*#NAzT4s3?0{qOa-U)u=9@9ROp{rgp!Wa&e}<6? z6o0ZXGBB)V&;bPiC{HkO{AY;fl=0ZG;9xUzsDi_Z2@e|V*033PZB9&dZW8s{kffUB zFBlfb79%oaA=8T9HR~3N~;_Vt^(mTX?o!k(0; z{)~xX;{1kAZNlBopc-6MoFsO3%pv@W}euX#x|dYP0^%F znB@|eX+qr&&aV$!m5mY=WPB7>`iT3hGZjjfXgW0;mj%pWsx5Gm7OS5nF{yFIVMQsg zRXj5#Yk9-eac_b)o?5Ux9lG#InkulpQy*-gj zUjA)#F<2vXz~dcfK?6hZ8YP9sf1C~u3|xE`lN$LpF+FTz5lV4xkrX?U*sdTXBEVn` E0NRwC_W%F@ literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/62.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/62.gif new file mode 100755 index 0000000000000000000000000000000000000000..8d5c4fd39a08d0315c14c963336f079fef8fb380 GIT binary patch literal 1269 zcmd6m`!|~h9L8V4P>%DW7u`{#Qr08djGoc;vPk3Bb)9x?$2P~MdTQztdO4-mlM5QD zOY}y>DxtyDjG|Mq_6t~j z35-`@7zTZXaECRX>J6$ocu*ow@rLd^Xg&`OX;5<#E9V*nrTQY#Xm1-d{VGe^3IH`b z5nV~~aPXE4F9aGhpp~t^asxh0$vR-N3M3cdX=_=KEesVI4F+h-hskO~nMguIV6;pe z_PHzsG3fR9-}fTi5Iz3}443F$zcTb)(*IUDU7CFV_~tr#@KQDX?VP4QIS_80$F%o* zS>bb9&HdxsbdN`7^1{aWsaRFPK)e_Jav0MoJ7UQOaUwLZ^cCrkC&yk3j$*e&n*1a9 zvpaLbcpS&!Lx-woE9p|+32A~aCcMxTO@dlxT_SBHnLL#p3ay#9*fF4P#_EdTNrR%c zaDW><*LGb}!dU6fmp0unmR~iB`7rgTu|}Y-WNK=%UX^FxjQtXNO0oGdV_BZQ?BwJA z+lIcDrK;q<6J*7?uX_{y-nKBL2|J8aN(ud|!4yB^^4poKQPYnmpqJNu`80H1TbO@= ztD5yK1=v*YV7%u9d+#KBubT7SOyOZIKXO_72v@bYN0RXQVQA!NxchNc!V9Q6Yit!O zxknzJq0AQi&>l(F@nhbV9z*_TaeZ(0pAqRJKYjwS1SHYYDY#xJVOu&l)4EWT?p^2N z$0!^%E%OK~U3Y*H626AoL^xC|Q@e0o+)1^v*jdGDYX^7BM|LiUL)e}fGY3^6H$MwvFr#;q{U=t=oN+xbj9NmDpxFF;rY6sJ zgMDa#H(Qiz`u#~_hI571#+9O~^*7h;cHuIe5rnZ*uXW4d*&zbuO>uo$x$D)6j_I9UK!l&7Nixjy}tCM{nU)*Y4+(k9>kR4(Y)+Y#+l)Gxt;M$!WR8p{UQO2@15sJFpd~(A=*GhIq4cK}$ zQF?4?on2BiU5f5?u-M=;h+Mxd>9daW>*0EQv*>MOPIt|;MzZ1>hEP*dO4esR2`&Lv dtCVPvgE%yFpQ%%=KXYBi((l#&CML*^e*q`iZGQj& literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/63.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/63.gif new file mode 100755 index 0000000000000000000000000000000000000000..d58fcf671bdb51457baa9a88c599e5d4ae9be4e9 GIT binary patch literal 971 zcmZ?wbhEHblwgox_#VLEa6nefl~2-BK-N$6m5R!@&Mwmi743MX*D5MfUP4m^1p8Rd3Eyhr|j{yoTKQq((q<+v81Qq z-_!_(Q7{?;NFkv3lZBCiA%H;#BnHY83>+&M7IMgVY*=uxnL}8s<&ty4q(&AoF_%wA z4)(K2>A6g?5I8njU9^M2QK0#;gRuO3nZUrLCeKE@AiKa1j7PmSq*Kx?1Rtd}ipyI& zEI9B`Z3>e@-V%;WM>Isl#cVcMTsX8sKsBI1MdDC$d$5KjTaD}wheHtzCI%g)Tn9QB z1x-2J9-K&NWRwl)>WN@#ILNh}Dd&WO;p5c}8=2=Sh)EE6_t-lN_Pqi-^Is&^Kxt91a=6V0fmiyirBvdUp066&0)HGFJ=@Kf5~`HYsQ(Dzu4-#WsfbGBEU9t6U@}moz0( zFIMf0vT`2-!zT~VV-NPfS5mTEAYVJHQZruR|D?|8e0)v2N~QgT|EESUjDpb+z!3t9 zKUo+V7mEFVoq#Wc$k@a3XjEu2?`Ai%*+}qHJ&6L zWN?*HQ!Ko|&e-arWbpFh17;Rs7S1OT7Ke}VinzH*q-+pqZ0EH}2r*cZ(#XKbE;uJ* z(~`CpPD3s&!3|1`mzu<97|9-d)E=T{ZKPr_!|AnZQcSgF;c!J0ygXbcIFP z`VCk=GH|eRm+@OgEMjctlQH69F_UmnXm9M&4YP@GIGEDR#TBE+k?{G^S!r8i9u5X; E0PG>1$^ZZW literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/65.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/65.gif new file mode 100755 index 0000000000000000000000000000000000000000..da23bfaac75af2b450692e93890435fde4225efb GIT binary patch literal 5285 zcmchaXIzu_-p20?LIMPmuvbYSK!At{5dlS#umU1PqzH&K2q?H1E=1IX5yB7yL<&@8 zD=JDDMYPy5Wh$eHtRhPpjv@jT3ArB}r|pZ==RD`l^X`6of3E-Uy1rjWCkG2le-%Il z_yYvQIR@2X%3x*X^!+X1t6gHAJ}9ax3nx7;OA-w^fHN~-p}AOi0$e(JFUDcI=3DVe z($w?8+T&<(Me@gb=Qai!Y}6e1UgcwpFSwcw_H7a$RbQJ60vFGN6ZEySny;!hthyM9 z#cS_wD}eKUPajo*%QqWx4uNSF;+u|OLxYYC0CpLH*NLlbA>xZ0cWOz2%coWsXGJW% z$|LBxVr9|fEpe6x*o?p7ivnLThC_|TQJbIjJ_av4_QokZGm`@Ec-5Vj1I1n7@bGT~ zeM3cdgT>^jTm?|v@@lYIl&Ar&B&=59M15PqH(sLid$Vm};vndsLgyJ3lGlh1i$yWEeQcD zO_xT?-`|i~{Uzm5jDi>iZ-|yJ4VIY~YOS$@#pj$~a@E0KRNp_`(3`b+tox^z6Qj)! zD!_#W@m*u^A-N({b+LYv_-3w{p(*}7Y^p?8oRQqlm46eV{_&prQv24A6CrOh9Ypc_ zM31+=J)k!Gi`COJ>W>OfKaNFr=K6OesZEs`K88ZYRkDwh6vZJPV58+krZhNWwOp$w zF4J9m?z(b7VdjiE`0?Z7J%cyB`@pudYeP0Or=8|wEEZyPs>5V|zMwhVc+UX3aU%H&xn8 zJvI$Ii?$@fVvXiZUC>H{?qHgnxa$1)cdKf)sG(+=HH6u`zPGc3qoZvn>}MI z-5RR_cBH+}-ZpYoOT@;A(y`#1{AXP)y=S*fkDnb&-Sa}={i@=|^fR}Kw(H`$2jE!V z!lTW3c*XhyGH=37-~5mc4xVbcO#Us_8hl2XcgL;yW5CW%5CjRJw5z?xZd)4D-qhFx z1_1zoumVR(0U$tL|6V^56#zhj0Ep6H2=nS=k@AMVt;{?{brn))gl&C%)-m+an)?&P z)GHQh4OLM>$9zSZJx6A18r>5lJ=JbWoMkiN&YJLR{DGA?wydSvD6$}g>7sarsMge~ zR0u)kmiCTinHA^BV5*UPUOh2(kKU$hQ3HPF)X-&nY%EHWf$Qi4C^OYg zqQQ|m7jv`Ios`D$X17b67hbb?{}j~adk9mN!~C+h`!=$VNmo^N#r9YGO>%WjmM`Y- zrVBtboWmdQi+ASs|FqWGlD%xUk0Ml~I>*4>9dl4=ti<%C-Oa8%C6cYrj}g4!O(@B1 z26cyIMsRqO#7@B;XduiW0HvKF7`M|bo(i*rmer=$VVkq^pZmcQ@f@XUHY)+c-nO3$ zKc(T`qDZ&shQ-0W^ONQIGcoOE7GowCbuDLllQy!WIhnLVW^WRv0KX|l8SPV;yphqJ zhold6vru?_i!iF}0gW*kd}eoE3Vj$qAFnuK$F!5PCPzS_L|FyQr#vP8AMy;`JH(E2 z^9%{=%ywrYkbB{Xrm^&VqYM=oQZV#2&zMLY+X;Y$Y1IUEB*n+8?XE^oO~i3?6>ZJ~ zYUxcIS@j`g3QZ7%*R_OrmSV#7fC@sI{+`sic#kv=YYKzM>cn!0ap=HShlx~;C+DMN z$Suw-83-4b#>aI<_41l0H$*~+d-JZI`^KTA_04APZn;48Rh+vhH_as688!GsSKSLW zY!H6?@T_h$@%Qm1v*WiL;Gyr3>hFnz_gxCujzP2|J@p zG4Ix?9f;sz9y6F-@f2h@Z$m8)hddvJuG*m|?^hRtSS`wWB!SaNPc)WY92=t|;R`O7 znO^M1R3(*(c+!hb978Tx)gu7S;l(r|{V4SEh!StmLT4{$W!xTOU#;|3nK1BrDOhUhWNVngbe|7(D4R^QTM0!bbqmlc2 zoM^DaMbZdegbVAo-~G%;|NJeXb6tum=Um9>huOuX`MO~K9B^o9<6})Id34MKKGU9` z4ZFN@lRHQ6__jp6f@&6iUwnb$(@UM0CT-h?3*Oro58O-%7$)l(?%#y}>*xQWj6?^U z5eTWu5oQ?S`Y@eiKH?jWb9B8z@%OPFDD0Nv8daYd@xIvzyM69yj5U=sK}14fjG1UU z5O>8m6#ke(LZqYuL}=jN9J9I}ip5J80}{-xQfpU%D3VWrX_xwN_M753c`6J@V5wKQ z9vcD+c~%|dpZ`d36n5VNg@+R@mI<2K{{KWK2YAZU5hQ5f(W4;w^O}3 zfMsAK*N&$c^G`szm{4I|143OmkC3IyjME(kM;EL6V^cgmkBquW^OphF8o?gyw7Ly4sVOF^S%dd4kSWpoA}UHukr~O z0EXzRIN8xazi2RwhzQ3~;SaY3&!J~MA!uurVW{2F7)B4(xzu^5SBBxYJnJLG;)0Y^ z_pfs^Eekhr?`MvtL?JXSbJrGCyi%WDRW))y>%Q%p;nSgUZ^(Yj^#u-L<=;m(H6QxLKpfg~I&ndcoozAhr?x7r094gaRJf^yGQuPzPa=2G z{p6(}bk!34JA^cO1cQ(c9b-2cqo~?V%HEiwi^lr|`5jx7##luX+(-gVIpKA%C(R}m zZwGwdoSpOKQs@NuLVSQ^h%H~+r`~EQkz;$qz~Xl&1LQN~psM!i(8I7e<*VYGABFz5Hl{U!XoX!)?T*O6 z$oY8)Z2&)Eg#ZEhQJ**%^9K zyHivv5l97B?|Y{%&&}qRs;aZu@<`d%JlY}fMaU~`7S(NIKK0Dj*x&IFnIFz<(-$&# zT#j4*Ip`LS-h#e?sJ3t+m5;V>^Eq`SjR|94;Gs~&zJYQh9ymc}=cTvw_o`bIDh(hh zmo5bORBy9BJLd4)1{;exbWd9{8Z;-PY&A}*?a>PCl12W#z98!)CI6MBMEZ0HRze#g zC9p3d=)_B{-ORRFZwF;eWZ11Dhj=pY9qHCM96~p?2Be}t2twtuV%5~S4mdjF;pPs-E&>H zjfNje*f-uhl?sstU@t>n+qtS6My^iZ*{E(FwX(eSF*K|0@S)e|N=y!_QZ+m=%A zLTh;CiNsx*(Bz|1WJn#Z4t=?1$b#rTKelw1KMa=~hvC99RMz7p&7{q}jU1 zUSr^O)oy8jk6*u2bw#GN+CUFX#6^d^-tD*ppx_><<9zFBnskBiA{83LL>Mw^>*;ED zM}(c~7WncVP(JdVz0$*7B|DUZW)?0=SSW;iYWwbHf|XzYWCqj0;Dx}$Gvvi(PsHD_ zjJICEKDfD768;X_x@TU!B+o4kK~c2t#dVlq<$aD4BkzTkQUZ+ zZ1Z2b9MRlM4iDi&fNTX5Rv1A5)v(eGRXDVV*(_~MN$AgU?jyA*O)uWpX=S;_TiPx? zRp0Vf*-|Eq`fYH&;Hr%_bjy!fmBnwB&Up!sRQy!@&G7L&fhcxw$u4Ut#Y5k=CI|V- zDl3k804HH#X&1D43fFGl&9r(n+2;>PILhtaem+XHs(;%=)55(i^|t+D@RQwakFx4Y znL|wF9~Y)>`uG&D@36<=3_Rp%=`-4X~Mb9WGsVi^dB$ zQYvJjFvZBfmh-uuIWTKv@Ob=#6T7&^+%bHi1ou-K^gNaNB&9=z9Z34u?M*OVe*(^O zN%J)Y<{V^r3`}y0^$5c8#W1iV7Hv9$;V^j`)_Rdi$LmJU79$Twsebl?|JC#U{qX)X zS{2Dc-9DieH9-UY8Lh4-r9z0?gF4ndFA-wpTwK5DpfgPsAA?0=bg0}i-v`Hj`{D)7 z)PnJY&6l*;GAgWBO2&VB9$V4K?h0z%^Pbnm-Y};X1+RMnoDtZ;Vj(LC2-85Fb&&dV zcoS6w846Eo@4r9zCtB$VUL0WcjwQ-^o_+`*NzNu9FN7o|m@ygfsHp1&0Sn zY($)0tP}g{XtkwwlN)+t^p$-!lL?>DDk37XAwyIIVY@1BCHUmYpn}4Hix|W5z+{X@ z?Sd12_A+0B*7KRF1Ud;C)xzFRY|x1a8lE$M?-{jaCW4{)0-44|gb49X`d3e2c_i7z zc^0i58O~5X@5P46DltsD$oPIIVZ-r^S+Pt#HRKPcXR8|6Pya);97?%w~%P;Wmo)ZNJG%zr5!ksu9j&o#*eY@pQ#;A98k~rZW zx)NNXfd-|&ZcNh9_*uZkpu#W=JUFY%M{;U=6W0Nm|0tPU%ZbHYt;O+R)=UPIlHiMF zpq0k(>-bcPYgJ5u_r`il7|8Rq7;tT=&!K8@@Z*m7d07DNHG$5Gy*z?0*;N_fDIb3XgnxS0|kTz;)z0@8_y&J z$cdp9Ad*knK)a*j3gjR{FR=^HBd<{Q#Kw3WjP3jVem5W zo&|nq5c3Coa!lPe9>ZVHl3gc=dZ9Yf26p9d{d&vVl5VXQ zKm}(to`%;5Q1Ra7+DusJ2HPd(fe!TQ85;eDtO{G?zh#yz<|t)j_!evw==pSQB!Dv`cvS?^RY2%f zg!(1^;&)@_LGnVlA=B6N@N2ZB!t?g%qUmHumX<>!&IGQPMc@}Wiz)6aofUcxAg2aY zk+$UZLSnGRoJ57!@)nZZG*L8loD=-2$WX%Ftl|@G=_V0vL-rw>=*K?>t5P5IV>{kg ziH1AP6Axiavbn3wm>+~DzSVPWkg{e;`o2c!f`0CVV>d|&g}5yz&a}$*8@%uf&abz7Agk7EbxCLzj*@C5%|H* zJx19*T20^On=z^E8LOwB&EWP^k|>JeI%?a*iRmcu)Zm%f8;{eR2Q9onpy=i*Y-J`W{_5 z^7!+de)=DFtyzj1%;~w<)g${+iOr)7%emybZcG@@h_3MH#;fVJHjdJv*VuUHVVZq{ z+!=7OeA_^(NO|#zm-kWD{*YD`6=N_&>=7F`lSc!+G<_0BZ-WR60HAzXnZIwnvqf7(hlU?Oea+C|ZRHtH@LDP)9aWaag35JecHmmu z73C50Niu3K-eavHclA6~bJ_)5S&-Fc&ZPx{{B$`JExVinK@j+P7AP5BuFq1XIDq}1 zgDS;TIBqqA47IZ533wS5kl(F_+KZvrL(q?X+AFC`!GLCFY>{+Otbwp6tSG-qUvmv ze@dGPG*q&}6bwK$I;4Izs0;_>3^-VquzF_qGACu4X}@|93ocA9oC#k&`Tk<4!ITdG zHnZlEyp_G}Q$Z+gf*Dxz0i@N;1pq4kIrZc}7P6zEiI<>|r_H6PB7q4XV5K5$I?PnX z{Xlj7^a>4tE|8!bX{)<+q!jepmp7mvpQsWorx-R<{<`wQXlVAecCc-c41hHsf=wCF zckOaIN?DTz{`_>p7pCP#P3}Q}l~LMP{fpW0v;M&Hb(ZS#hsu*X=J&wVF^16Bwc5O3 z?cMxU7E?KJAG(^fe#UDlg`|Am3w2b^rR>tQTv|H#)=a3eG#I1K^a9t{)J6N`VZhAM zceNLGLYc0!kv1D2xh*j;V08=xYNw-}HQboxaKyrXoIDB(ikdX_shTL=$v`w%6{DG( zoIU2Hnf_%h)fE!*H2Gn(0lKOSelvkc<#D`5Bv?A`u4V#|TDcqwXtH+BFzvvSy($K< z(NY9*52__UC=Xj{Dvro1Pb)%z>HW^@-K{fBg8U*~eNbO{w_FveE4#pucQh#mA1H6< zYg+Q4o~HE(J#Dt{1lbV!stj6?s9*MJo_8-~?o$a{CifVrdhROdfTAjKBf}T0O4L@x z$dlhz6dwZ1ne!C5YCkX+X}NiI1jsOg!rUK7W>7p_-E?&T03aygC|dvmTsG^?C&2*# z5&|HU4Yidg%te}Qj}>r5ZAVYI$nezTd)v0h12*)YIhdu-tz(vEBP9$A14o0_cm|hV zO0Y3ski>txw>e@zM=>W0A1I`DBW?Ygf)GAvOSh3a4{2DrpLr^m216srhbhHDg>iue z93=8*`~YPvw;p!SNoYUt4(DCCHFH4g@MNgU(JuJFXcPL`c2;70$9em0bvt6J*P~mj z=%TX21L7c4vKak0%u{+#>i8hX$H+b4i!Pmhz!sZ|3?7#171!+2CTx5U>qU}KwP+&m z5)1Ec=UwW5>JB?&@uzh3FwSXQU+5Jpkj$(;DLm_tolecUiMH^yGJK6Y^zEr&Sh|gO zR@&o68o&);VZLbrbc}5%>u2;$F+2vFeY!NRD+j?N1Q52BV&H+$BX^iBCZgTI)xnJ_ z)~!%n?$WieSOaXU(nt6O_MGJLB4<}~%$gPh zP8Vzt_@j;oU^(Wdd9rXlWcteVFI$lZa{{)w5c`n`^C%vY-RKs8L2Fn0keNZ=gWEew z#dxww(8?j0No9KCfbDE$+B;~}&)~<~e~QTxu?;x8gWIh`Urcl1-cRC$$8NSs%7iw@iHa`aH+5ep z)iO~)Bo))`wFTcb`WPbT`nSRvR6WB%ca{#4!-z2cH*v{unb~cLM?fCj4}&t`6J6YC#|Al zRwom>-YFSQ$^D`Tb%Hux)e=~Ak>)z!-ygwj&U+@_@#NN0OxeY2^w~nmxCzk*S&xsZ zl6g-HO|6iYi2O?-fkwXWZV$tqk-RHkQRiE^b;~AQZdj5xf%?v>_R z2zAGM?b&;Hp3DSkNZs_c%9t4|K~7) zd@P$0PLAC{(ZC17S9y$zf@f)TwbxKy#|e)l($!Pl?8b{uT`AGn<2hUMca0DRgo%;G0TPV#NS+pEi)Y7OJI`AT z5qZT-5rG;QwcfzYm$WA7sjM;}yBgR|##P563`$ODs`}2-}9%#GSUycvljYa~yegg~|^Dh7Z literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/68.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/68.gif new file mode 100755 index 0000000000000000000000000000000000000000..345cb439104d5227534ae2188471176cdff04264 GIT binary patch literal 4148 zcmeH}|63D>9mnr3-!379kOUGU$^}D+h!_wpL@JjM0$S=55fByoB$!gfFNKy-+Pe0V zKtMzq>{_W)8_+pLrbulcsuvk zVDS3AW5Ew@T^p^C_8EdlE;bIFMVuXx4=)DXyB0FM`qkT8(Hq&Uhll)s_z1eSpLu6y z)WBcqBdzmCd%hg%itN5HwTU(e6;`SP|ln|mGD9pW!Rt`S)DpmJ7c&d z&v|Br<8?-F>&hRtvxh$2_3*9DL#ICOEnn-L6Ef7f&;AjmYZui~%l^rz`sr2u(BHD| zZdouknV*rq0wfV%lE}ShJCS%sl+A4SSeXvWsT@6^ z=chKQFBwTBB7oy2!8qQLF^XCA1oo_$Y)K_X@bHl*}pO(JhtQ)*_I&JLyES&N>@RKY(no65BYToD)pA)%HHXWSQuJ92A0SHR=tHpk@pp z?1M^|Mbzp+<{m6B2fLL*NIjLguAgMw9!{mvC6+6w4vKuI5w%`F3x#B;yAL_dy#|`k zZsF$;()tuqnZt7n>p8?8g@TMc9(>b*wi$Vggv|7B(pzq@>56Sram`Y_2Un883%^Dv zoTo|=?gTRvNwkp;u3vN9GKPPIaL~$0>rz>D2xeCL%%^jhE|Ao5kWWG?cMoZXEw>8< zAi*L|V`j~n?Ysp!SFkU8#}95UG)(@6W$4^lK1Qi4K18M?V5I{`LO1-P<5Q!G|%0u96&Aw(6^BHu<_#fw4nYAggMrGNue9F{ZMtGZ0*0PZihMw*-l0r(L?y5j^|)MrV-X%;A8dIJ?Px^ zERI-hKC1itXNPh=eJCK(pVM^nQj6?+&qa9lRne%fon8dwnzeD|c4FqLE4fnHEe4~Z z6>+o}iaLp*g;f_Y9egz)G0B1f#U-8mY|8O(G#4u9Y>`%7VJ6Rr7H74~5@(C#L}_Pg zQ8i|MUhe@*v^J-}I&1P!r3@P2ihaB*_OIB`$=C-m^T=>kN}m-4!Re^te@xx1gV`df z$|R5#Gq_Nq5U}WqDV|4}h3Xnb8JGPQC)aeqvV-bHb~g5FCaEG07uC8*P3FrqU)ma& zn0b9E08`UGobyQpNF=SOKjGY|MlmoARIl5XDg)u=mXw9{sYk%0T2D0nas1Jasqs(2 zo`p7d(Gni(7Gmu3NjGFs3lMt!v@Yqr)*$e!R zLRp<@ayn$zjgW67Co$LhnZZk#i2nv_%SKPD2dB6G;d(DsZA0U>dy2R zO~NSzFchHphGaC`H8n;$Zjw^Tii9$nr--JmJTPt&{|zgqH3_RoJB>+}s?}&mZSrYl z@pwREvt0rGi|$kRfZF?}Gf5pT=Sh={%em4IK3u1bqt9T$hqly#gH&>$G|I*@6nS|a zPFM_dV`&=c*-6WU_@($XgGvHeO8Adcjb1n-&t+HEpx358luO}9(#w%&f!c}ge0G+6TOWak?(K(>Sb znyP(CRi!eiXu#EZ`{~7Zy=O;k?evy;aD29DFf3(eac{Mf$A5cRQvQ9*9yk2*^0nIU6NkU^>$yjS_K< zwuhO3g?A0d&ywhigr7^)WN}GU^jM-2wS6+C z=@n+Br>prgSM`Zfy!tMtZxgx9a$cpw;LbD?XBsoH$S~KdNf$>AVuH}qucjwEqR@Ru zaKxCprIJW*>2*H zIHno3p?gUsurSx8R2ibhqIr!R4PWoKn?Y1m*2-eHBK>{)ofRJ}QIJ`JzbBlTxeK0H zA0*cppKcxgc23WeTCkL3!beWWM@M&#dGnOZPO}bOqr)}0r>?`&Lyw)_;~1b`niNpU z<=T1KViN*xqKuCYv&-pgxP_BWXD6r(p5w1aZ+7+Kd>;)Yh~T|j9pl>B`S{L`5A;Kf zDP}alYhU2(!o)URoYKn0Z%XiX%?(D5+uRt(_~fR~yWbSwhGqbCZ9{xzOl(8j@%{KV f3_eP2t87+4lnp|byg{?0C}7R`Jzq-@VDWzdo}+Pu literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/69.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/69.gif new file mode 100755 index 0000000000000000000000000000000000000000..e0f28a0736509c3e339f72c7f582db36bd52ad70 GIT binary patch literal 1015 zcmeH`>q}Ds9EQ(1+uG$Un@yLcAM64}7pW|ACAEvqOg|*JN~!RY6cV~zNNIvOCAG|3 zXj8+cXBThydwaHad&P#)*|=bmTb7`1BGr!uY6Mn}b_ znGX+gLK(JMb8hIi&Uja7#hbFOe65R{Dq;7QUjnoAM*)L;&VjdlsAt1BnI;Sa(xQvS zz;t4+ibGW~sjdz1PBy4s550026MHp`wsE2j3_hU6!Qcvg{I<-a{kQ14B&Mx|0kte!9iAmYKdSM%WcinLx*>tqS(cC` z!C=%MCUQIC=-DA&`4Ix3enK0!{vvIr8i)B$Kw0gN7)8O@;#e&JApiHz3v6AcqX?ox z_O6-NK7p`|2$St~N^7b}XYn_3c@m8wGwg={ZI8%wH!r?BCMwWKdoz*?%exOw$A}U6 z?#@xM!7M@oIHITmrm9bjw7Tsd2^`2T3obpcP-t>_VxPlCVPbS%8q@o1fTQrbD0`3Z z7QX|(?gVT`!*vez)$QC;&xio6H9t+_B@9XD5gsw8OLpSJj}%H%CcP*$|7JU%5aqe~ zbd$UEcL!1L=nF31%`z18kBN6_q7gZ$pXVW8LUTC-AHZUbXS!*NPXxy!bpis_Tg1wQ JNf#D!><`;@O+)|y literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/7.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/7.gif new file mode 100755 index 0000000000000000000000000000000000000000..2f4539998426e7cbc4114eb8809b680566a70129 GIT binary patch literal 3929 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 S1FMLNz(F?Ns}TVX4AuY|FMf;w literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/71.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/71.gif new file mode 100755 index 0000000000000000000000000000000000000000..a0ccf2edf5f3c1760323012456f57ddd8e31afd7 GIT binary patch literal 824 zcmZ?wbhEHblwgoxxXZ-wpMhcO)T#gf|BsA}tgNie%F3$G;VmmGYj1B~(#94V8oF}j z%AGrRCMG7%=(O&sQM+*A!kag5{+~H>=gysH7h|?eQ}5~NIk4LB*hcfW*K>Dm$hdbh zWAF-+kB7o51+y?Sr)r+@eezclI4(W(WvlXYsBOWMGeG zW#nLCXA;zCjOJxzWak#CK*+!*3Ur``i$H7l;z=hGbfz~v zW%<>k*9=n03GyA1SBzj@SyFT|$7=qC6(v%v0pSa#mU2nvEsTF#TEjc}y!Pb?rU_FR z(==}PuDg8^Y$3!LCI&_ZAqFv^h5cY-xR{SUnGg`5CfL-tnWNQXxl>a^qeIfx?xUrv zQad)TJ|t#P#>b-2z_eDt;YP_pmJ2>Y93G{D3=CeZj4T}NOwH`AUf|GR;LTuW?qJD) z21cA0I4~B~YOA?If@9)Z1|erqfNXV=Wp{3I1_sFiPxW0+{7R?hva!u|!s&Z+SUBDVv>{uPCoK*knC9EiWy+ZAYcQ>>766$t*0o z9Tj!{c143+t`IbKK5XiE*3p-jUDnz2Zt16@v95V`PI0ZQE;XZ|XJBmT-Pdz5sa<`N zp?=A!lk8T}^Usstq~BKp4xIfsF*~=Q_#hd7J1Twnu!VCjO)@_3y(j3gsQcWhBqsC3 z)bwKb(e$q8!wCsFtxx+~9(CvB6d#Q^m!ESzEj^p+w4WWH86JMZdb`iQfRpb=KUedG z*=dCX{o{d$&rW<^df6k{w=dY+=ivSW;a{hv7M9fMZ_8t!esqZkW7!#%l@G&?#=jf> z($?{MW_C%os3@;!Jai!Z{O`%J#_2Y#f3jW=e)PzexK@rnmWv5OR zB&J-tcdyOMCp$ToS zGZ)&yW4|S~cfFaLTP(kEUn*VTS2UfE;k5~Rqt9gS^$l!o9TE!qs%sjDhbLbTf4bY) zx=xE&ly`H3uBkK4?>E-D)6sE~4>L`VyR5C98t#ejR6m-X``OyoRbBh|ZjG?Ay7B(~ zCpI?DH*Pib_P^ijA9R;5tgUOglvQfJ)lIf2AO9$w{4{-#5xa+eG$br#;fK8Pb`#CT zyQ|}kvFVOoy94a)y?i|n{9P$HAtBKn9dEn3 zM;4csdrG=eQ)Vd%mT|RzoRAxYuEz z$T4GoenO}6iaVMo@CE0U$1h>Xo+J)_{i%FWj|)Te@WgMY!$<n;7=uR>a+d$QCec0_);e%K8dN90hsuU3 zHzz=J=mgL&eaYP%u&R3we6wlyb%3E}3nfio7pd-~Q;@FP=Ae!ZbU~g(*ST#js1mt@ zQA#9NjA;b*8E&5u-@%cghDHBxVqgFmpbo(Pofy`L!4rVJ5I8Hk%Fu255ok_!gDSi! z(K-0i_iNBJp}Gq;#vE?qQ@)x;LNAF62BLt_9kTc3s!E8J226fk*Ym;ybnYmcE=j?t z#%p=8Hv*J!C)h6f{-J~-YV5Wmhf`KrmHiwRgG$c(m~UY4BWDn|NGzrzC`B^%Xj#B| zl+u;#r3*xttsFBG?@90*e zFS-NKa6;M|*hRUM1&N$F&kYJPK_h02#C)a0V>&-&!;1{Pwh}sL zp6*bD)WOaz@;B}t5$dH!H2oo(&1O*6pzXJEn>10mqh9OAFImhZm{0e(II!FEFu07$mWGZ7OhS$FBE6+4X6Q`ANvOMW2U z@lR+6*^GI!)@)nZLTxE2l#8%i5ryHz@qQ5I1fI&ZkR|}ZQxT{Z?lrIlOc6(uiFpT7 zIhZa_pSU)E101rVpf*=Bg5~J2G~+N119lo9DtuPL$SH9E+n?kuWFd`J>Wr4Rz-Pbp z#E~MPyKFL10xouwDKqM0)g`rc9ye6N1T$zw+$e#_rD^)>;JXZ%6}H|Uo`(` zt!Z~4Yy51C0or1|L`#i-HlPgPTBzjwnc@{{Bwd^0V+>94?UCScPOjvYUhZ|>yfdzy ziIugtBJ$a>#3b;c*Kw_w{>h!FNvM7n%C{&57lk<Pn9s!54d)vGOw%(Hen0jT2dmwjoCHXTM&Jc@RRve9;^15aVA-%T5jp%E!I&A;g z^8Z(F(F~`!q+zE$f9lOv_d&Xd&rgPc@xI7?XHwTcv6crD`|iWw7pQctNvoNvtJ|$+ z8}KmzCI`EgZskdLbEg#8MYq0P)f+YO5U~##?gY%VCx^2j5Bf!&_b484wFx38&fdLP zP4?ZeMybd}%PJH6lIVJVz$n70s_;p4kqtYRUic}EF=%&X~Q3cBy4&|8n|Z{PxbbYQ#1e8?zFg^NWNEp+Jqf_H>M_kR*eOfH;W$}`YA z&I2JqPXX;96#?JTfBE@bmP)64{WIepEH(4LTKk_s@ieJUrP(wSi>HsZiX3kiCHU8s z@{l^V8bO*CW*2pBAc2dm;c$Zv9T3zXN+d~& z8a=FySc5j691s*rMurn9aDo&2K?D6k>3XWkcYHsru7 zF~8>K8v&pC5ib07!$pc#Z#V~mY+W)Mz{wGLP1F*7Hm}}r-Q??#tQ>8z{Fcvk;fOV2 z?DVDw3u}Zb8Y$7hY&1l4ZQFY;Ay6PJL7~7ElOT&xKOLB=9x?%>)c$BQ*q+Xkt;wq2 z!H4^OzhOEcV62DNkoV2sCfqdfpO9PDOAi&qrjnI?b%^40ZSIhw(36SCHX#Ola^GA( W!5gs$c6vc*pd+9Tgpv{jVEZ4jVr)SG literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/73.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/73.gif new file mode 100755 index 0000000000000000000000000000000000000000..c0293c3ab0750b5a1f654fcd1851c5565dfd1199 GIT binary patch literal 2195 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 Cul<<- literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/75.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/75.gif new file mode 100755 index 0000000000000000000000000000000000000000..9cb9aa7961f87230f198c3f85dbd14e5999af3ea GIT binary patch literal 1222 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/78.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/78.gif new file mode 100755 index 0000000000000000000000000000000000000000..d0d0856045d240cd96871afa4fca7c48d8d152d9 GIT binary patch literal 1565 zcmd7R`&ZIu00!_EfeBu}A|NX*Fcs#|(KL^C*}k9@nJ!Hy)>bFXm9^|tYp1qVBQMiZ z6gpX{HO-kawS{SA!%?=T$@*zioBEUtj^hf+HZUQg6BM+^Q>FH);~Z* z12kZ01JQlXl3^cm3xIPuju`+c2ee!Oe-*A#+avYBp&7uDP&mMg(a_0K0FAjTx^29> zth~F3OWU!C5*VLtnbU?wbSyHob72dUmJMJNoq7)RD7QL21Z{;IcJwnMo-QJl0#X5Z zlDrB|?hH5+0Ox0q>Db+QJa#b!z7$4Q@)(Z+QVHN}rm$~u-*Gn7AA-Zdw0uCi36N5- zkcmzu)I=k90I!4tr}uu^ycuZ#aCifpzYbM?x}pQn)QH>!P|Gv?#DHo)*zN@%`@F0Q zK&k+o+6!l;@R1i(uW&8{zm>BTNpIc}b9$;mkYZrc2u(x5CgV&;E_(6BN_rW#E5n{y zKpHG$&ZvWCdUEEc2OS@P7nQ6bxy$_Q)Y$EfCgW^hwj-SUgjNWsSwJ_`3WwGqS3&DZ z8f;k7ql_JI@F_TIH&(&q+^~LG9i4N)YDZ1@Wz~hA>aU^6I9U2Vy&cPF$F=3JnEQRI z=>$dJvYIRhy+5Xp{i24=%Up`VW*Oe_fYW!;ZRta-PELQ4Mb@j%vr6peCN$HPw9)&S ziSwI5a51wrFTh(Bvy%IJ*XBfY|A@86)TZu=i!DH;2e7c@&2AQ~xWz@)kswtB$1%p7E)C7&!;dH#dnFAp-TmGNIfYu-IBO?O2Vf=T!Iatg>H^vN(NCs_yZSHBl2_Qg_ zM|2h_@@o?<4HwXRVHzT*Xe4O)V4Ns0LBu1L)D$M+gR|&c56Ov%HbQL9y=X?t#%$ST zcGeM0EJ5nzzB66s`>55)13Oi-iITGJT2S%YFK=xcsJHzP-DjNPj)oScoyxc(ZP%W7 z+tc!tKQU>@)niwD)EQ0q0Gdm0+9bg>jtFE+n|E>ur!P5NlI^-CRJRomdFZU3k&5pXp#!Aai@{q?Zk=+&zd+Tow@0nZKVQJ_~H=NA``C2PNe$@;Jz1 zh@3h2zUzwZvQ5b97eUids>TyhY^>$itj}BRIeL?I8f7p!>{~UzPq*{ zg&S29rx^Q;$OmNLMi8K}NXbfHfxYT)=xZ&=s)E{b)3tQ24IkU+nw>SbovON8eW~fRsZhDIHu0s?W7;C9WAdel zR(%PZnvG;_eOv2Gq#6|@4MNc*XtkqRiV#%S)|Zyxwe}C_Z~I|;{rLRhdG~zWy?p(A zT=&pzkPUhzL+~J*AtKgO5IibestJU_bWkNJ&LWs-g2!b+S$3eiwIT@vZIv_%fimtk z4Z*lbL`AO}sGw^~zJv9|BbaI%_z^V(Ay6m6SOaJTpsj$Jt~fCUGo3>$B#%b%Vk}#O z{XFiLJLINHeN)m{HtE}&h?FU4U7ZH%w3QXZ`e06E*~k4%hqjYQQ?M^Zflaouqbr?Y zx&xkEA1xv2OTLB&S-QILi6W2TLekP?KMb*;{|q&Ed*d;bB*)geV(&1V{}vv5DPe%N zdcNlZXe(bXEPygzo#_D6cUJp2hW>oe%iu|sBpm6k`Ny|l%i`nk*Oj|Dl-_iQmov=`ft5$o$68{=NQYjQS$U&>9ZYa=n;g=uBCWC$A3v3OX^&bgZHlxjo?*PQCc4s zU4y0dVyA`Jq$r9tfW4j_9xL}BFFvr=9Rp+aOeF@7iaKM_gG}PAz@H((VEAHpvYoE> zgyGL?Fx5Jo>$q@_H+L%rCR?<8&$Tz9u6b6HtZ#~$yg^-EdbT*xH`m6v&)vSLbA5Fg0MP&W?7=d?n-X}y^N9EE&s|K6-fXd7-eA5N z$N#ttv$xZ?G<@kvoAvPFZ}v&-jmxfA5yiLK7VIHbEhw0av*8!I_sm!173?&j zQ^+VVyC=u3lO$ILm#fq~8ZihLTwUd-Vpp41?pheL?K8i= m&vHrPCKWlCX3;&!AxzpkmC0ZJ7nG0wo62TnN1hEH?fnN<0-_`U literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/8.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/8.gif new file mode 100755 index 0000000000000000000000000000000000000000..f6c883447ca373fecdb60210e27c858844add470 GIT binary patch literal 4679 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 OtDG`%76yX`mj42tdy*3X literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/81.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/81.gif new file mode 100755 index 0000000000000000000000000000000000000000..2329101a71efc84d76fcdc0e0acab11fa4b832fd GIT binary patch literal 1591 zcmaiz`CHR<0DwP}L&lIuF*#H&O|Aezlbj_?5G=)s#*<+N0zN*8c|ifW$T?*MMCdV={!Xi5#LG40e4#>0i)q@ALlpK5xW<{lTBaI{*i;3;}$} zo2&VJ?ru0bb{CFO;ar!l`5Sby0ghKma=hOt`_WMkPIQLXrf3z(gKut4Lv*C23L3|6&JQ*MX zbb<*roc1Ijyb9n=;j92^T1=v>f03ktRQuT~ z!a(*`lPFW)U9jAE(!f90bsoTHm9k6#ry32yV)(3TIM+jzr1oB2-*eq*vFSUwC=#Vv_T3;3rn%|c;?#vKVA_qQ5Eo}x7aX1H4K&+_?L8l#2dP@f#e< zg^Oa-XqBpx0B73ZGz%48LHn<-h>P`Ixy!9rjDwWL`_bA5F=$^3R6hm)xItW0__3q= zLW$vlegS5fcS>iDwFeORzU8-*H~?Vv_7m*JNTi0BW3|rvL=Qsi%(o6A;m>9tv*n);d&Gsf8@<-chbWwt5gg<#MUjXc8KAc(0k)( zO)d6)Qr7A$U;h-(9G0lO!Fkt?ix@Vq`U^lbAK^|N78ZYpzh+ezBIwy}gI6PxX_3o1 zms7oc2#-}<>beItmJkx7HsTH~s7(2%JDY<7@4Z22Ns-F-J-wdRN2h>Gwywx+-}LlB zrR=IpTuhzijrF@$ZFLQeCOdmOaW2aWa`}A922Ke{xP{p5d1N0r#|Ho^})r`0x6f!&nrKuefeESr>H6W;o@;$Sugb3eS`&?dI) zkJyjw*<@hHMEK_G5=*&OOJ%H8n>@s{$xtu4ozU4aDlWv@(w9K64zNO^2-XO971o3R zGaJ7cn##wtON!9qc?%A3|fKf8MozIWHuB(tmRpWu-7~ zzZolM?=PPg1PtVD->{Doe0;6i;{E+OWgPkMVUw86fMM_Hx+Nlen8k}Z0B3`65CIb|6Tc~Tad44 zKhCo6S)1Ek?GjzkUzk9{e%k?SPq4ZM^E);YFWF#{r!DLP*Yb}Ab0b_`Q@?3NF72p$ zJn#5kV*lkPq1^{QDds9e;MT)ieVV_wa#^$u4~X7dlJ34OGLGz@`h?+~I9ssfu}r;) z(Dyy35qDqFq&h|Vc6pm`7ysoRkkm)sY3oo{=*H(6$shS;Fr@C_V?t~e5{`3A7l-0b zRf-9rJ|xVIZRSkw;a%9Fc#*RYE%C$*;<$b{C^QfUv~fi literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/82.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/82.gif new file mode 100755 index 0000000000000000000000000000000000000000..644748a96ca06c8518ed8618b9df99265748558b GIT binary patch literal 1547 zcmV+m2K4zyNk%w1VHf}y0Qdg@^Sy1*hbF{v7S)Oz(t{iAty=oLV&}GV>Zw-$>cr}z zLI3E%|Jjk&ls?LREU{Gp^s!d^%8LHYb?2c<|Jj!E!h6}4GymhV|KO+p)`_ll;@0_ST~O(V5nfGwsi#=d)|?uVUqw zHs6yv_Nr62T>!yq0J&cPy<`BpVgS>C0KaDd#B2c6fdIB!0L*p(v{?Y}(xcLT0RQB* z|L48Uc>vLU0LpX##%}=o(3bJ9Sk{jw|K+#;)Pcxy0J2vA|LDK{$7}!OwEx|o|K+ym z!H)Q{S?R=%+?PWC*o^qmnE&Cd|KhCAdjR;-n*Zm#`Mz)K#g6>KXaCT2_0N+0(wYC^ ztN+e%`M6*9t5o{Oh|Yr^@3?B}rAq(l!snkz>&&CoiYEWxquq)s`_7d9)Q-}NG~=#i z*OW8*$&9^W0{Ogf{L+&D;HdiZ>FmFK|JRV)n@9P#UdwkI(T_~-z8EW&PNq)}CDc(1QKep!Cm`^SENxi5BpnMc;@c-KuEtwO#$ncHgso`@m`7uzu{e zXU&2k>a%Onf++vjjPbg1{m5?kym;uLNYtNb>Y_}^b|B7v82{q0<(D|+m^t>fSJ;pz z{LhQtrd{gFqwAnO|JH}=%%#+cBKN~>{@}0Ws#NpNnCqrf%5DnSj2rE(R`bS$*o!an z%#r@ieCxPy?!R{a)Qs-1UjNsR(~dLOi80iTH2>9#`oM7W!+!k4Y5m1&*?SZ7tx(&e zSlgpq>6|+J&4d5vzWm2<_`Y}l<+%IEec`EI=crl!;jr$|qwK3w^wFF4)t48pl>h($A^!_bMO0HmK~P09E-(WD0000X`2-0R0RI3i000007yuXm00{p8{|OvO zu%N+%0-GdB(xjk5h6o25Nr1yhK_lr{Sd94336=y-3OZT9B_u~Fm$-ClGq6oDDB+}V z{CA~-8D;|pUNL0`&Xt*C27G`MWnh$QxgaAd(3JFso!WIbWQRoJ$ zI6@)|;dtc8882Rr%mWwUNHQpT5*$HD86T5LGr93^^Di--Zk*f{1Asf1-dZ6dRNU zIjBSl1PI(dDZyrFMVT_ZM0_*m;2@J-Oa#aTEwP-Ffe0qN!HOl2lycAv9{d8&2`j8X z!UiS0F-I2${IEqt4`gFa7uVQwLJ9^Lpn@12JTTJ(o&X`^j5E3j*Np)I03rDV1rz}P z04x9i000;O7ytkW{{a6997wRB!Gj3@HA#{LN5X*%lQbb{1Q-`14+R=YzyjkyCsm#} z$@ovojWrg`4U`g63P}r+o+$cMgO#Ds-eZ{KPnTz4B7_j6c#L0%<4iC0!jlUi@dBs;#7#= z9`P*E;|J z&>>HjAP1EwR}m0Ofe$5r9sy9bA&UqJq?8=w7mb7fCQLk};*_O?2@R9bLCFjVZBd6C x`_$qCGH+<0!5m%C!NC>}JphCwZlo}Q0UW9zMja23WFZhFmPlfVW~CSq06TQmCO`lH literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/83.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/83.gif new file mode 100755 index 0000000000000000000000000000000000000000..fbf275ba500778d06fb2709e0e5556ae8afddc16 GIT binary patch literal 1591 zcmd^;|2xxp0Knh-*fjIyHfFb#*haHtN91rYwM7hmPX@Om0UXL``w9%D z18B&ctrWniD{%14dvz3C{NqjA;a82~u|gYYNQ1-K@XyZW&Twcv`?tOh4kYT&0Qj^H zK2@rs!Lte!8ZykSk#H#O<@5t+YBHAdhcV)E!5?iBC2j;Lj0(`s+*tESMYYCluSj-`=?xz3n}>C|^OrKTz#9Kqmp^W4>tsf%CE zDFsWHM7mTkUF!d&(0lRv;jzon3$0;rBxn9w*mN1|UVe!7doW(^H{Nl6zBO!F74^I` z!I0xHS``9Km)~jg=LhQksuC<|F*tEip9XaD%`2Li;o78yp*o|2yK1b4vv=NhL`>E0 zgin4}M^i?!aIbz1UA`-u?TC9h+6?C(!hxhWJ<$(Sz<2>?>?hyVC(S0M;O+Hr^(pU_ z-k4ibusYTN2UCVJz~dq=9Isk^R1F~n|8H2(dcPo4%nK9=yguVv;QqD2dW*NBf=1x^ z(agt901<+NR!+her8)~=K6V3ZVX4>cj60oRj?YrMtm_xWn!5#!d-AtA<1sarX2s&u z{HLun#LccDjZ|S)2E`^lwyVZVthBK8qCs*eff`tbS`I3|rK^?5dNF}RRZY?gu^;715B zC=@|L@&-apXb7)c1p>&-rdcui08jLy8ImV7xhl@FL&`xfHR8tRdmi%5uKkc z7f?rJpNwrQq9{WFo-4uoI?tS3L$$GULW^tpMFbmrxBhw$x$};V_A@8BvW+s5c~I=e z;IhC?&)BZ%6wZM>jFv`9 zP^h#SxZTb>OvT3T0*8<2UwIFfMzae3Y^baj)LU?R?C zmQ(^LjsoBWZzmJGRwZ~5{V5jY_}ELAQd tKmj-!d5DiM0f7LA>RJS!QnJ}9d#ZshLsM5S_rdBrGb+*a-wgZ52jTY*B+KA}$SrHrUWqC9I+X zqBIRE!3ctaMpOhr3HuhH5D-)v3JCimF0J4M?&!=pJ@(AYoMX?^^nJhg;XB{|{de7Z z$2C?S42S`}e*?X{v9&%BD)fNrPC#Xcp~`O|xi{4KJp}slTTloLm4dM*i46XG=2M9MQmH_su}$D zyWB&dzoP&D|H9cT^5lD$WYf6f9-sREBDF_!P|>;x?$FkA(? zq#qu7fU(A&4A;KP0`MecNG<|Bxl@n)K}%>?+9uGIt|~oPe2m%sCPg==lDe@w-WvRTZARg%YEJ39C7fzxo z{o?v`TN)TDYmDTouz1j)|E?(!DDMr|Nmb3sig0dE>LxJoXzcN+o{TLc3Tg9MZmA#h zS?r3LZW$OZAAWeUJN4`K)5ZY5p{foTyt%vStj$PO!gO0ofAP7Q7wLGsRhM+j%c_{^ z=D4~D8!(RjtupXM40rhc(XqT^<0Z&&Wx}W&nRuEzD*vG`KWL`md(dA9I;9`VLX{6i zp!aTT9CxPcCK!19i&8Nq4*|m!V61+qB4P63@met#^xRfq=Vh+Ye|Zdn)@BFSt@eCp z2eTC%65-=D!zr?cF7yUk_UVaFV**hDG@xPNB$JegsdG%-t7U0rk??|^^*k=WJji{i zw_J3!HY|z`vt(FblsM9aZoo13jHO-Cp~4u z77`qycO*C1BleEsxsF224a4beJW`FNukJ0BM?0RY>$Xd7A8js#jZInDPC`K6g{I5z zMNTxLrfx7xrqn>cf~o91d1$;fku=Ncq_!b3g?SWbFv_c-FsBE}1?D^sZ8qg(QGjGC zifX{&-;j)y6sA}dluezG+93(r#A6WuniJwjXrW~oawA1o7I~g>s^L{&hMJnKNBBHLvvi&GDkwA^S)-(c{a|>M=RnC&|O4NxPufUTe z6!9d&$F*7BlH3@oc6*CAsY=dTOJVW$?XQK{B9B0htT&x>S(ElP!Y0p$4Ob^IbQPWs z$fCK#OJ`tT64l6ocwUR@#hDdtrTbRJXtv)#F^!2nd8P#wdz0SmU;zQ-PAa zyhgQO<>KhJYjj;2tmMZ)Jkqj27!g8RMW^Wo5@AU=fwan(A#+3}gpJF0%B^7nU4Pbg z2Fmy3i*39}8b>7e3H(n=CjF`;XQeCZ0Z-C{`NkB2n&w*A?RA)Z5tVFIe53WS4xf~? zTM#ABaGbw}LV3l72s(>*6b5M1%Eah`l?w)4g+ihr?HNKXNGq2J7yg;3%7pR#VaR+Q zY@#D~=Pec=a#Ey82C9-4{?*Kx8xSS3v)mPDVHwXt!|6-yFhP@#JsVd+~+h0)dyu=vt4wbyzR z&OI~+Ia<^GwJR$zV;y-f9L?vUqS@p`Tf+%;B3gI%$cbbDh8&!yZ6wQTqMSqd!8G@L zS#%)6iF@Y`jDRM3qGslIVq*d zC}>xkoJFzPshPPPPb=5w%)6IWPf0^c<_Y$}&Jvu2F4;o0Ep$MjJbyBc={9O)M_y(5 zT+WrNUm@&&RjJQmM5vQ&_E=+Caygmm*UZQ-2^hOvV!NF@>0&6ap%PXj`(;Zd-${RC zBH_m~|1|MGMKt`aiEk&Gi(Pue3cH}mHzQqyzJ2A$A0GZsJp7VX^G72;Yoywjko?!b K=l^qQlJ>@a;;dZdr&ZaN zGSi1F_Sd7YYjT%ZvZywA76? z@484A^aR9bq1GZfO|LxBI>c+xt0p6ZS?66+{*_{5@n$mq2{?wQE zv0(q}$o#~0{KIqJnl;;_T=%eE;gdbFS_J>>%m3=d|LDH|$Yj$jVIfQBI2Y*xn2PO->d!Bp7zzB^2dYlzIX1wb?&}$ z!g({#eh~JmSFv0K%5MVcnnlu#ILv<;vRwoAsaF5tt<-@4|IdT}&Vc{ovD1J6|Ivr~ zx@!N}nD)ea__uG&cL4wB!O3#~_P}xf->LuLtpDP$z-R!@c>wmmZMtOwuUZ88w`Kp{ zsN|bDykh|WB9EHcImx@`PQ5J)|>g!l>5||`_7Z^uvq`*y7Iqv z@wjQSR{-IYFYc;Y{@tne$Aj3BJ-%oG!)pNl<+}gdp#RK$|K6$p&4Ko;S?{r1^vQ_d zoJHflm*bW-?5a@uzjf1zGyKJQ>9u9ec^vAhQS7W$^2UJq!h_wKMf1ac_QQDRuv*@Z zI@*UG@w{*OxM%Uni0Pz9(1a_#Zx#REr~lfX!FD3tlseFRAmhTL=(1h>&5-}$u+NZ6 z|KF_CgCgw7m;K0l|I2;eqDs(o1<8Rk;+aD9%Zb~pegD;w;G8-6)}Z*eXxWoG#&sCn zmp#&%T==qJ`OuI5(~SAloBGt4`onzt#ee(9i2TQW_tBO3(U$tsl#}fSoW@5^2LDo&yd-ZF!|G%z>%A^!_bMO0HmK~P09E-(WD0000X`2-0R0RI3i000007yuXm00{p8{|OvO zu%N+%2oow?$grWqe_JB%iMXX9f-e|d*kJI51PP896Ix(ELV*n&OepBXaiNqM7fTu( zMBwBO1r98G4OzqI$P*2M?r=b0u#J*B4Gi!rcEx~(9u0gD(BQO98mPoIwEaVZrQeQJoG18L>#D29lW@UK~u>AfVEe1>MdaTf>MTn|y4>h}k_x zgaZg3Y9PY`C)oitYzX4XL=TTB6ez4XFk-}x^?D%mB$0!M;4K=)E^&RMLubGWR-PtJ zLc_k9D^$MDl22naz? z#WFBF^2!5>bm3taDgZ$PItf9c%?vQ`l0pI%wD<@M>=d%lEQLrCM>L0op(8Zm$k<_#wjDpLTDU{h1J=PKbgX(j|f<$IJ~c9t0f7 zHbwJ^MQb_~{DJMq7%`~Fc-SDsUyTJQTJccxqhOG7pQ!Lap~uPy2p(!6n*t{mDO^Dc zb^I zLOSg0cVth8u!9iD2SW-EbfHKW2zD`!3NJvAP$5;!FyI3TRAAvFEW}|71`0uefh2L% fa!42?rXo!ig)me=7Fm$NB8y~%QUF8^1q1*)ck41~ literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/86.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/86.gif new file mode 100755 index 0000000000000000000000000000000000000000..8f09d336a30070add12af16be11397ac97436234 GIT binary patch literal 1519 zcmZ|OdpOg390%~PWrc;3Sn0@8opid;dgSt`7!HnvbR?0>=91i&lw86_Q_(tEDVJi! z2^HOp7RE3kw+@Sy%_WyOq#c*v=J!21|DXRp&-;1*@qS*<^ZC`@*2L5o5Aa|ff^W~f z<&EKRunbB{p`--;RD^yihM(?B?pVN&x7v~oVDB|vsD`W|W}z||sq&e7;@%z$+G4;| z$Fhkm%FYjW>yKchnc-R#SJEBEb4Und^ zo>YUjR3g%FMpjLcz73t?#z>w9O%=QMJUZVHiW|+f9L+g6nr%LE$E@cju_2!L!X3cj z*R9c@B^uNQfj54DcLr4X066*<;rhX`+Si`Tg;)Hu0FH3#LqJ0q;QE8NWbiHuG@k>F z;mdhNg%{{b05ySNvLdp~4SYxf(_L&h`K~$ubSHwP-h!q`0NbgH9B*lDe0K)1{5YsQ z4Fpusl}_Y%gU`23JLADnCJ~NQ$~tbtp%-wnRa$*P+Lbr=A$P9yIGk)*60&D2LqyDd zlNAx;59~YQz*65MR8kHHpTMD)@Cz4yW>51Iq%|?py2~#;z;yY^MSeIG-Gc)~vmC#< zH$Ku=rzZ+*;rqz<@!O}L9q-R^fZfTkJ!-zpYq-=K?a73qtm(27vu{G@YJz)jTMlMh zBfJPym@DH`Wlagv3g3YYlc{3YcKXigr>?LkeV~*qZ%cs_eEIuyc{}qvCs0~RMg-@P zx+pQr431ULmwUj$r^vfFwD+#8@dErngZ+1r<`{V!18u+5ebrFT4}p?rvsFQG;2|96 z&AjlNc}YfEljJRl9jUt!{-p&@Kvm%S%7BgB;Pq8O8_`y(v?g{u-%(x{D694#DDqlr zrizzm@Pp^x`Y$zw!0}os_q>!FJ(@>C``Pue#-e++P?Q7zN?mw$s*OS9#~F|2TJ_(v zlhucP%Cp&dJ8@ z7|GJvX5Sve6$(G1MMY&z0Ku;1d-+N504PBKl{eXyJ>b!l*6nmNvALRQfLnLcgWcp{ zO?L`gh@gHG=lpWuOVob60-1gjyRD;=U`a^dbe}396OI)o>6mKlbRpR^tL(S1c)6DS zP;K2dB_3Y^vr=Wv<|Ft0c&@2RT6Ei1j?wdx)HV8XVTMMSRqAW?m9Aw9+_(1KHMhB* zyVg~ar^;D%bWB*HulfoTziM>{ArL71v~uyE-zW+vS@wE|-3Z%?kF&J!vu;Kg`7U|q zqJJ+pFZkOI3wkof%)nO$Pgm7v=S{;kUEY*d z307E#FD0~l7U>CTOon^VExluefF(y|YMFXAl{vv<5bAZSEO*#ymaqtTD;?C8F*ak@ zpopC&`wEE7ZbMd9UJLc9T2BR50>UBr%wgm2N-vx>QF2!P_KnCotb;aI@dq&W|ABE% zH@8q6>aM`j(oTP@pViL?;!MgJ5v?p8e-qv7Ge*gFG>tJ4bB4K6Ex^R@Ib%b2t?DM_ zTYu*NLB?*()9qu}yI!%^pr0B95)781Ug%U4XFwXp)olw9?fOV12{aBK$l8@eyCTq_ zlN`o$wj2?p6FljL8&(zLr|L7Jj?}Bsyq#FHgFg3Z z{{b6KsqR(7aq*>*lNtrvh1pDJ=b%%MPdw{MIT1oNRH9Q7egF^Y?hce%GjWH5@pT7L zaf%o$13T@wUS?-%aCRBkc!BLeyt-8{ZLbH}S8bo>niVeEXjy)P`XO?yWW~uSo{J`$ P8RVDdk`v{67?}SHC9xom literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/87.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/87.gif new file mode 100755 index 0000000000000000000000000000000000000000..df70756f0c74d0aa64c84efe026966e941f40aab GIT binary patch literal 1558 zcmV+x2I=`nNk%w1VHf}y0Qdg@{LPC0&vfLWPTihLp?a$?-P~o0N z@Y=oq+nUvdE$+mL`N4Vdzje=n9P7Go&Uqitdm+PZ3G1Fl*^@fhkvX|v0Mm*nvR45A zB7Wp0K;nlyJ7&kU;w{o0KR4bz-R!$Y5@P` zxc}07|Il{Kb^yyvBGyT?@{o1Ad+NSo_p!v97|LVm5;;{eJg#Xor|K_^?-JkK_%>UPo@ywX?)1dv< zm-f+@?7D6I#A)=^rsuI~`nq8K*rME(I?;?X|JjoN=)eEuwg23j{n(@b*pUC%jOVgz z|KqXuv047oiS*E#*N`^iz@GZLV*0*l|K6kj*p( z(R%;nvg@!{|K+v+=ez&sy#L&u|I>v3)Pw%nq3oke{>^j$&T;(6c>KzJ{?B;Wlt8y# z0RQK{1<|KYFx-mKx7LH^Es@VjyI#eDn9iQ>PW z^U#|8)}H&%mH*Ox+L%M#nnBBa9Ob7>?73_G$8GGlX#d}*{mOLz;H%u2KJTnk__}ZY z)QBG>3 zEB@T1|Ln~F)`#@GWA(mg`MF^DyK(={bN}6-*polgjx+4CTK?Uu|LVrljWh7PbMe1( z|KhRvxn%s#j{oGe@xgc1kTdwQS^ddx&3qiqeICqy9ov;a`o@C#$AtdNZ~3}s)Q>vw z-pux@Qvd(}A^!_bMO0HmK~P09E-(WD0000X`2-0R0RI3i000007yuXm00{p8{|OvO zu%N+%2ooy&S0qZ5A`24^p<`x9M1(L}B!OXY2@DuZ6f$|yf{8&USw@&lD1@XCgF-aE zOn8Lk5rZ{b+)Sth5E~^1m5^xxG+~S~HDV|YqcmEKIWuA?yppHE3OIJI#92@w-5noS z26A}vM9jb^UuF!dfd-ctFf~4i@bP5ejZ+IU+z@y}*EwGATKKtf!O@HxjrI=Y;Ym|A z9{+fZiR25K0|z_`Y{Og(GQl1AEcMy3;{h!bAQZ^ip#i{ZMmr1=QD9{Tf(Idp5J0AZ zh=5hooOK{#&7Qijd=A2?L@yNeHxV0J#)fwrpKM^@fXzgZ)Uf zqqJ+%8bQlc2@@nijhb!~5GFXlV4gT20A6AYfB}HwjWr3e;Ez0YU?IbUh{zDiHF$V% zi$YHL?bSMiA;K*}=6A>BV&xt3VfT9r>wfIj!03rDV1rz}P04x9i000;O7ytkW z{{a6997wRB!Gi>gM2S)ap~Hbg=$IMu@F9#ANnjXU0t3d9hfQ9zXkxHQmJuW!QV~hT zAQg-)9U>8l#Nf;pH5~>4#3qQrAY@wjbm*c?4HrnmAdTl@&I}h1tK@000*;+3aTZi4 zcgIJSfgGSf*)tHzml=ai@XDS zkm-Z2$G;xABH4qGhFy;fuF~{?<(Qz3e3)wJ&|yWL30Aho=+NL!^)MXT`If~}>3UtA7u!Mn8$|7`uH=q&JICun-~a#s literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/88.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/88.gif new file mode 100755 index 0000000000000000000000000000000000000000..4d8b15e7e625ddb98838f58ca001f3163c5fad45 GIT binary patch literal 2134 zcmeIx*;f;08prWB5RxDfSu%0He1Jb%FN;&Z-_?>-+_ zw_pok0hZ=K-3id}C8!Mq;&AZzBzWH#(wjnQ3I+F%gNGrYB?8DYC>rT^16L{1R7xj{ z(tjCraVYIqD8i$l>KIsjS^-}c4KM+mt{-Fp*mrK`HVrD9;pDxJa{#J4;8Y!)Zh-wP zMXnc=XXxbFaO(bQ54R_g(i;oli=sE}iRw~cD2alyIK{*3us;sUVwc1x;Q)K(@p+Ae z|1y=JF7c9bw~z4Lmc_wK;!_&&Uw)|w)V7~qtfH&SKZWv4@!3sqC~b8x?Oo-u)y_++ zPfn@wUA2;A<-RRes3?OYg4U=_vIL;*h|oQ~ z230L^{D+>)HWLDG*caWMK!PK=P}Qoe30I`s!P!T{-%{qEHR&V?>hk^L0&k@-r0)_K z;eQNY)x2+Is~Y0r&k~*DC-|a7ReurAKGuzv!O8o-$eUD+T=;YESjmw$-C1z@!BD#G z@b$d|9HaN$SKH14Rqbg_4-d|Y`r-|jAH~a(i1X4S8Os<>)%S6U?`lu4_UEk*<#$B` z84Eiq@O)L5FkkuAo0lzfy+zA&W7=nhLp;h`S>78_oc3w{!f?~dlPg;Joz=mc8rgN# zLnc(Vs_HIi$Eug^oq1W4u=F5C-58^l3lu*Djplx=s*BNdXFkoM%>NiV%(qike?40n z2CMuOSE-xg22$;09D?peg;riP zRdE8&G-`)S-rYR{{)Zz%qeI?Dk9gAjy`6WE^$~xcBCa3}abONOtWQl%+TplGjvOm8%mS9{W_!dxdHu+9kJ*J6y1 z1sJpt(TxHW9KtmPAgnzDrU}AD?*jryFTeU_)2RYr^H*fb-m}(R1B+cd8A$hl=~kM1 zW+=$5o=qZb-QrTaaG2Vi&BX=L+AJ?E@VpV2<|=PfoRf>#-NeUX9EmbO{zDY}j;PDO zL=__CnyAAGcI0A#18VE9(Jrp(EPG#)Q7Pzjw58b-4maS-(`a`74L%<&NSU{`)9u2B zRP~^@_@L3o4CiBxN4?O-I3~~2kFR(9r+{trFluKqA~Br74i$-*HF;)t2t1TNN{?iH z%$lJzN&W=+9X=z{&V%&HH>-Gy^UQD4c3o6)U3nc0Hf^IB*?FM#Q?}W@uszIk&CO|O zleTCTWGLEUi@0rH4N>9~ETT$iL64H`(^N zabrv`9%Ju}?h1IOvi$Md`aQ^@uS4)|d?P8HbiW{|o?d*}J6b_SU?R%$w}E7A9w!l% z6K~;Po<#ljyXo05Gf4_q75d zM1-gsA;NkCV{0n2gO}rmiHJ8fFI#77w&Svwn*&I-L?~`z+=CH52eB5ct2wbzJPBzt zwbbbW(JvXb{)2d&^tBB!aeHWE6?#J;j`45KR|<~Fp~!!78vI_EPQT^+f0+Lv%r(i~ Fe*@T%#YO-C literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/89.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/89.gif new file mode 100755 index 0000000000000000000000000000000000000000..05726dc4abb26afda444aa8b059006bff0af1bec GIT binary patch literal 1219 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/91.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/91.gif new file mode 100755 index 0000000000000000000000000000000000000000..608d0ad87c31a4e2ac8a28529c7af1a08a0abbbc GIT binary patch literal 654 zcmZ?wbhEHblwgoxc$UT>DJ1%zf#LuE|7&H%|I5nUHZsywQhm|M{`lRmIdkUxmy^A8 z=lzvb#)}s&|3AdY&B^)yLBzg8r@sCEAL1A2Z=n2oqh3UK`hOlCU+-uUK`9|VK}C7Z zoQ#59i8>Z$E+2mVDzz8-e%9^Gk?m*Cp1m}qOiEmF>5^qn=Eg=z$#k~1%SkIedi02! zgZBal`^yb=@0QDK(b4g9cb}@R{y#szt*ND@sYQ^ROGQcN$&;r?Sy@aBZGF9?q9U`N zudA)AX;zfel#)<9%*herAE+oQe)#a=V`r|pItT47a1x50c?DGz zbwd5aM0xlWgvGXR+qJ|*Xj0#Vv+Y*EuwtMdQ2fcl$iR@spaU`z6ekSquN%^unp;}i z+B-VCx_f#U)A~DO;yrW{485BfXV30PVi03kWX7-7G-qy`h19}D47^PIyvtX%nI^7V z#KgdFH>)!scISE~cE01?UQ&k_C9|LJGUf_mzIu&Wmzljg(24bP%N|W<4I=~A zH*dnimAjqH0$0LOp4Kfr?l^5_GZf?6uWBFp7VSD>Pz%Rrcsr<j!>0PZ-p&h<- zX*o@|TUafn=4EL+uT_U{=Sy9w)pgl6!I#vz3%A>}g!rxgf&Bsd{s*7WeZEP`#HeUJ z4sfvA1t5gO+5XE*i)6*&pBW&F1vtVJM$-t*cd42z;&L&R_hzd+EhWWrs$q04ootgH#g(^L02nzP)O zF1;(+a>JX;L}-0<>=lc(Uz^dznfuhJOxtqM`n5VeJew@1Eg3Ch}mhNAL15Eg{&+M|NeIJ0idGeT;#}DszeiZqn z3`B2>NmC?^U*HV(^}*$3Yc%~w1cN^yZWe1W6L@M*j^u*1Cz^64W9-Rvw-V?xvljkZ zow|C;s$;+8^ABd{6n$LuvXL`gQ`2&;^-yuigvAOsY*=1fb2e=C0MO9bG)tyrQQ4{S z3WsUS(?u67E1Q{_fzO_;x!urY`ukz`AAvzLFV>^{p6=#3^V9oGpJ~kqoR(*`ru$N@#0toiKM!T zh9%?;HEgPiI*_R|8VRH**+SJB1s!CBxgV*c9KGvQzEm~Aw%_YiY_-pIWwC=e|8V_R zJj1|Pr5CX{qr0b~ZEpq9jHd`5n~{nsto+tUe1V>Xlm=_<#(ep=6fCT}l5IH*BpBuL TdA22K#cA)aAqVW03PJ3@f(O+M literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/93.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/93.gif new file mode 100755 index 0000000000000000000000000000000000000000..7f71a8c94cde07ca85f7e7880732cb41f02c053b GIT binary patch literal 1119 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/96.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/96.gif new file mode 100755 index 0000000000000000000000000000000000000000..2b709e15bade2f707632e1a4bdc2b7e97521b4d8 GIT binary patch literal 1796 zcmeH`{ZrC+0LMQ(2w!=SuRw}~^UG<@kQzF5nyo<4$TW2`Pn&CE+U#o0T4il!pkk(` zSX;B*F0klfs~_-Tsf;=_OdDIGS=losF3K%aNkz%;s&%)!tsi%{U-teB-tX7F-piK9 zMMlY3fCVOZ11{5R+&Me57dJLGcIu17XKbIM!jkDLTW?oL>@9_ZkEdrX!8V(1mKS_{ z4r4kzVy2+rLTA?x4En7?o)3f7*W2faPei}Rq7+J<7jrT%&(Yh|)ZBbk9#L0U_pHl% z;Et`Ty873%l{W@$ED{MdV~%N$4|6ygHsu1r&BR487>r^5eAJpg5FWvxdiGN(H?Q}j zZ5Z_C>XmVE=po!T8jPAS%92u^f8b5!B6}sVO|Pdww6FysdKtg7-O!(lxhsF`;qdUP zq%?{rJz%b%)9KtK|I#@**>a|B#^o9r8F|{Kw_LlwC_HiqMO`zlMs1~pU4kwkfKJ<*{Xd;gQ1n`arL%s_T+a{cg?PAH&7G#wjvC5xu%BtEth&v zgzzRNr_RH$!Pq%*EcVfUTF-XhhC^km(lbBLOn5RnT2)Z+IGEpUww$Renlzgyn#1)i zE$8$tGe0Lz7&BYmT|$8%^ku;R`A-ROQS!>z)c3`r^1UB^w)R%+Jq} zl`~mc(tH)S1jllF&uXtw5dq)}vhpleQAyN7z)aZ>gT0)@)RXx#5e^@nTxIxu23xIW zuw2rE9B?VS6!2gnZfBz!kQ!5gP6eQ_oIs*#i_(~^%vyvz2`#+{=KFtZuS;GhQ+biM z2Ix98@x>wJ)%c77QFqM)OMQ|(zd`?Wc;FNf|2h`q{~n95u(9lAd+G1wWWrgd@)!^n zsj(Nw$Pbdk@tS-qfT)1j1`rue%y#z(&B@ms5t0CCMI7L3Hv)yqUToQb5!S*au`RE- zUQU2MI9IC3#&^{!KXqm8u%6g51SD*_@H1>l?otdhrs*ZrC~Q?z=Evz4ENyA%7i*p}%uDzsKDluD1-j z?StU2k_V=WJ1Un1azb~=@a2B~MRG?*NTdK_>xu<^$>+r+BI3O20;0S@X){2M;L>@_N+$`Y&`YR_sB!dcmK*!#&H{qoLZhw1&@t@0K|2QP3zKhKEM844&N8Oa(yAmREKx56t1Hrs7 z6UM4tK_VO!I8yp@)!tD@1RK|nYik22N!Zb~CYtKN?&=_l?7UVzN18SjvL4qJ0|Ioq z48hv6!_gabAgEC#@ra`1Iq5$VS3v&2>l`w=%+2qOz{RDS@ja4EY-6 pdy_y~NrNP&ELe=khAb%N|AyH1Jm^usxwTxXZ+>{0fWw05KLB@?Q566H literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/97.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/97.gif new file mode 100755 index 0000000000000000000000000000000000000000..cf29be87c890a6633eda84dacba996a29183c09e GIT binary patch literal 5300 zcmeI0YgE(s8OQ&@5E6nc2?+@yAy<+RLN1VmV1ncVA>2a{0tg`pB8p|v=@D9`34}`p z5kwRyR6&N;gDv31j^d64m{g}GMH$we0wY?SbI01XN@dO1&V0c+o}IpL-u+&G&iC{E zJk5yqKP5QaM_l4I-Z!Ck{=N!2=&S!Kcz#9Jcu0P7s66b8X%nC5dCRBIH|>(^3r>6kZmk zIYOc5=Ir^GotqLtd$n-Ob%znJ-sW1&4)7=W`w=5Ws-G71uO8i7F!R2y;xOr4ytnrf znRJ6rzsg`-B4Q;X)#&Kx+S==}v9VZ{R+qkmLFZDC$j}gx)A^|Ca7|zU^&n5&*WFXa z3r*J=eqfLt_SqFO>He%^?e*H~>M9l);DbcHUR(RpVZY-Au|vI@nwx*yKd}1prK>2z z6(_tpI_8o|Gt;tWXJ@yFB?0@$m^7eTL4sqoC}@)bz!H^K=5` zivY~E@$tOvdyp9H$0+pISWKN*5U0|at1KgzM`vbkR)&T?%Zzmyl1~QUPqv-vYH#oD z>AQvSd5py_E-d^YKf z3Z=EV$zgZwGaa~pe@-cl?#E*DIT7dasP_&XQ7TgAaQ;V0R0ok*keU4~gn67B^6Oo@ zGt#m@>^hs1nw}TKD=?G^_|im8+E!`eFb4hP$R*~S7xac4(QPiL1lIelvC#x#+*@`0CHnfUDK(+VnWWcYWnO0D^D z)vOQP8YV0*+^tb(>e7v4qo1cJ7uycsd3vfR0?feIG4W(1ONbK6%2y_ zE`YQCUY7(10MH)+7mT18Iy+GV^<(GF3>8i)jx6@$(r1pVEbnn!u9GKPTG59H&6VGJ zfGlKX6Am^q&vuVBt|W%}sq7taNh#S|NtOh!-apY{$6)eoUtk-L(Vh)l9<9(nH51rp9?{_Lp@ z<`IA|)xJ_%>io$p2o3BgnepPoB^5c!n#t;*-_V(dmzEUZqO_{gY{U}ibZvt1dg(}C zeG@VK0@;GxN%<8czNAe)d%FDW3JsgowUx?3SXN#~SA^mo0o0O@12=*G3#B z)<0W@RS*oF-^X!IIH4vK zG>dHR1$!T_jqG2vw-(jCBy2Gyd;flTczpG{mD^t6x8eDIBc7q&$$GD{{>k=G&rAD` z1vOWm0)ZefZ>v?_KiCU+@ie$>IlTc4FUF6)`)%JBH&3Dbx0OmPkKcquIk~;*K-`Z` zxZg#cGgp{*1#V`Sj~fJ=w6U|cy?^^}BnBUl!qxA{FF<24P-t=KS;Z3E6Q9esf`;de zeT75ahk?uHn$y8T2?wx!0J>m(SXWVjn3!)P;r(M*kmZ!o3{av;BhQ^~gMh7J$x0t} z8z#CKOqP4Xnpp5ke$-#Pz||P2k!7(JEo}~w9B_6_$m)Fw8Rhcs)N5l0>p-Blk#Kvn zp+?-^xV`yV-nfJEe}m$#l?}Dx{%_vQX>M=a-u(PA*6qz3Z`_5tp-|m5vav?IH*Ukf zTyH!BHj?;-d*jLa4-PN@27CeN`k6$(zWA>FxzN$@zUjq5oCKjiio{aC{M_7FcnvMm zecxDN`Ka;TO{<0DrsK=C{8vBS-u~dyAG?k)@}YlMXPilB=F0!HH=Wsd_e{=8!w}PM PZ8)cCg}lHb0O`L0!%Y2- literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/98.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/98.gif new file mode 100755 index 0000000000000000000000000000000000000000..c70e7d339fca9d0d12b9e66a1fbb6a68f4c6f4b4 GIT binary patch literal 1629 zcmb``=~Gi@6bA5n69`%1hU^O_VUs1YNKo85LD@k-ML@-o;D$O{A}%mRNgzPbfT)au z0}6-&gS0Fv7O^6mK~ZB_+%Xtzp|n5|p@G0#=yayjPCxWRpFiN7Ilp<1ufLDS3JDWp zLQ?}!gG6XaV|MR`S>`mLjWjnUw>@ZN>^x2)IwKpi-t!8-M<`VRJ}05sRIi0VOO#5eH8u;CUP#ht3%q9cPeP0x|`S zLI*gQeFWfI>2+W*9FpZuPELYF7R6-b$D4_OKxk`uI35r(m}xQ>A3s-KQ9`AzboUr) zNPc_HtIC2gYiIvXA^P0g2m%8OzuH*l>M&<(_qK3Pe|}Wo#i*XH$0w6g-zz=U>W=y2 zXAFk-GUwTcj2Q~0_uW9h!dW*s{7&WDcT(7DEtqw4t4iNGr^*^Bovj&kvZ>jKqp*@MCS!|$$hXVp%_We+uykX;pNWES^<>uzL#1)jo`}Te*Ad~Me;w|R#oEAIA5eSo0 z`iA=YtH%PqYp8!}f&t&4T!bQoNE}p|lrUL_83Sm8iDYvtCTH?w^46H0mJD`RSC@Wj zDl02X^Yr;8F16m)wtzz$=J7xSJWQu2P^pbPUQ%>O3l1xwQqxiu8m!5&qsO~FR!~gI z2@!r@C#@fsNK|yj^vczsnfzwy(y7OfK><4dfFJlH^9cWM1b`6i9kywmXQ=m5Cl@q4 zKV6_V!kIw>kZ@ts!ka+YIj952^{Xy=kcy=^M5(KbTQaa^6E25!tr&M?w}$^g&;|*t zE_fW-P?Rc{^4eKra)tLgpA@mGMPt-*$I4bC>Wo4Arc3?X)0DraAe?jrAGS}^gcSMb zq>IPeLOZSas}A3k6$`L*r*^tS!u7S!h;~%F!SYYLjNLcmC`OUd{*SJ>ZvQ#I{jCvRc<%R5{3wV@EaJif%GTGVfWLEu@@p6Q94dGjdZS;=5-Ah>T*Ydo4ShRxFgp5eh7^;;mpsoo%SUuvcd2MZ zi4&3PUN)VTM4gigVjB6a=>i3+5fM!H+}K8& nf|?2vjZkXVvPb9>MGz{H?Jm^WG#qu_Ej(q+3%Q&mhF1L!e4&X{ literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/99.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/99.gif new file mode 100755 index 0000000000000000000000000000000000000000..05c18635da1b3258e044e30de4f7a72058bfd6c8 GIT binary patch literal 2261 zcmeIy`&X0q9l-JLlRODYAQwm=PeKAoxCO`{gou$=7jgp>FkDo?C<%(As1z7g>V+j- zBt+CqprWWv0@YY*8>_OmoOa<-q)dBg#e(*@1?(JhdN$BbYfs@BP&VmK_aE%}`TP9v zeSJUgPjae8w#I+}1fbzyZfh< zePbt7dw*N`ZFKbGiJOHI3EBsBO8urE&kHzF(=hHE8297YJ#kPa9aQ3e#I(In| z9i-0R7B?L~Udv;mPoF+zG8YWaDCh;@kp~VQI2{%?HTCFrNC^5F^hXv8MUV(i@JAnh z%x5r4!@`D!{!~LEJ^I_!QHzyLB2^!*eLOqc)%EVy0zClGE$gQ0eN~3ctP(Dl$qnjb zu?jYA(Qe$>6B;pfB{fZ2dg$6@MaPZVkN&ETpuFIEi+!%_Bi;I=6 z630q=n9NhHXWmDU{8({^<6@bF?y$f0JH3zdXgv7;_df*q&tW11H~=5@&QRxME0eTp zNsJf^EgTmu{<4?}AfP}^7CabdaH6~^-??Q@RZU)dxupC%t z6tF4O?`5%GZuI_@2-eApB{jjO6p~PDOfuCHy@I6ts)!mReLt`=u49y@i?{%htc(Zu z(kU$^{vUt=BsRXn4aM2smj60hxAV^1sXUx${eaFit4?Rf@Ba4M_-#|xNkU~erM#k! zfa7Y~t~EZvlh0GQY@+n_@3N0VQYURZP5${V>Sp}S$Q@Rd1;QRGyW3~GPG)WEOJmu} zfW?>0F1~XBug27esODxyKyN7>RH^cEaVb_G*87N;Q9j@oxr$L@F7If-i8-=dCJm}j z^Cgp3rx4tqe0-1?C>VZoBdV8!fAcL^;TNQ+%T|o~2dO3^e)}P0$i?qx5Pb-~JbeQo z08UBh?>#06i_sMu_?{X~!%CU*@kg+F9cGJO=)UT%!Ff^YXjKBtrwj_nq4CNfbKLe_ z-x#rlMs4P)d6yH|qQTlyILqx&-SkHaMmyuK4rbV)(s}Dt)O4MjpK+XKxAha66UzT= z>y6hNg$=6rUZv)gI2+%_$?Yx1Wn#5W z#Ut*nv3Q~1S%yq8N~Mx%;|Y*4x#d2l3lLB8l>rlgX3iD7g|8sTm44>}N3dSrCYzNS z>42W&iO`o_1+j+yzZ+i|K?_FoC8H+`^E5Eq>4vef>j=6bt=j*TL62O4WJee}% zHbPL$H5aXn-ysjhF@$cLySENYJ=3-{H0{enqg?CDG3SHArc=!RM6p=Q(Dc z1rrcf_^$hVNBFVRt6oby1mv6Dw1{N0cEnJZ+Ae!_q>j6F-y+0gKWpO8AkaAnhA3COd8|^gBe+m(2*$cJY zOl+~1FYkV*Lv=RM_|M)V@7g~k?5rg2(4P<{gs`Q^Fw@OSNK`NOkW@equTuGLTJ8b= zQxDRC55DNfAQX-Wu2EbtA0hi;oZD~Z_Z?aB#4lFHre9bYA?wekWKJHnc!}5QvE>?y zHcSNpt%9aP3SK5wx|~XtqVdj-3nG&yx!w{t4%Q1$Pm9j%wW8jmT?BrW;mb zl}n<}IDI7l@Zu`Ey1a_YmsXK@8`t(2O6rkURLJfVMwP1Y-y>LX6t$O55EK%#)kl2`WNaZ!~XyP literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/emoticons/images/static.gif b/php/kindeditor_demo/kindeditor/plugins/emoticons/images/static.gif new file mode 100755 index 0000000000000000000000000000000000000000..b8c444b5a2e0e25d8bbc988d8d72d1582e15e904 GIT binary patch literal 35504 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 +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('filemanager', function(K) { + var self = this, name = 'filemanager', + fileManagerJson = K.undef(self.fileManagerJson, self.basePath + 'php/file_manager_json.php'), + imgPath = self.pluginsPath + name + '/images/', + lang = self.lang(name + '.'); + function makeFileTitle(filename, filesize, datetime) { + return filename + ' (' + Math.ceil(filesize / 1024) + 'KB, ' + datetime + ')'; + } + function bindTitle(el, data) { + if (data.is_dir) { + el.attr('title', data.filename); + } else { + el.attr('title', makeFileTitle(data.filename, data.filesize, data.datetime)); + } + } + self.plugin.filemanagerDialog = function(options) { + var width = K.undef(options.width, 650), + height = K.undef(options.height, 510), + dirName = K.undef(options.dirName, ''), + viewType = K.undef(options.viewType, 'VIEW').toUpperCase(), // "LIST" or "VIEW" + clickFn = options.clickFn; + var html = [ + '

        ', + // header start + '
        ', + // left start + '
        ', + ' ', + '' + lang.moveup + '', + '
        ', + // right start + '
        ', + lang.viewType + ' ', + lang.orderType + ' ', + '
        ', + '
        ', + '
        ', + // body start + '
        ', + '
        ' + ].join(''); + var dialog = self.createDialog({ + name : name, + width : width, + height : height, + title : self.lang(name), + body : html + }), + div = dialog.div, + bodyDiv = K('.ke-plugin-filemanager-body', div), + moveupImg = K('[name="moveupImg"]', div), + moveupLink = K('[name="moveupLink"]', div), + viewServerBtn = K('[name="viewServer"]', div), + viewTypeBox = K('[name="viewType"]', div), + orderTypeBox = K('[name="orderType"]', div); + function reloadPage(path, order, func) { + var param = 'path=' + path + '&order=' + order + '&dir=' + dirName; + dialog.showLoading(self.lang('ajaxLoading')); + K.ajax(K.addParam(fileManagerJson, param + '&' + new Date().getTime()), function(data) { + dialog.hideLoading(); + func(data); + }); + } + var elList = []; + function bindEvent(el, result, data, createFunc) { + var fileUrl = K.formatUrl(result.current_url + data.filename, 'absolute'), + dirPath = encodeURIComponent(result.current_dir_path + data.filename + '/'); + if (data.is_dir) { + el.click(function(e) { + reloadPage(dirPath, orderTypeBox.val(), createFunc); + }); + } else if (data.is_photo) { + el.click(function(e) { + clickFn.call(this, fileUrl, data.filename); + }); + } else { + el.click(function(e) { + clickFn.call(this, fileUrl, data.filename); + }); + } + elList.push(el); + } + function createCommon(result, createFunc) { + // remove events + K.each(elList, function() { + this.unbind(); + }); + moveupLink.unbind(); + viewTypeBox.unbind(); + orderTypeBox.unbind(); + // add events + if (result.current_dir_path) { + moveupLink.click(function(e) { + reloadPage(result.moveup_dir_path, orderTypeBox.val(), createFunc); + }); + } + function changeFunc() { + if (viewTypeBox.val() == 'VIEW') { + reloadPage(result.current_dir_path, orderTypeBox.val(), createView); + } else { + reloadPage(result.current_dir_path, orderTypeBox.val(), createList); + } + } + viewTypeBox.change(changeFunc); + orderTypeBox.change(changeFunc); + bodyDiv.html(''); + } + function createList(result) { + createCommon(result, createList); + var table = document.createElement('table'); + table.className = 'ke-table'; + table.cellPadding = 0; + table.cellSpacing = 0; + table.border = 0; + bodyDiv.append(table); + var fileList = result.file_list; + for (var i = 0, len = fileList.length; i < len; i++) { + var data = fileList[i], row = K(table.insertRow(i)); + row.mouseover(function(e) { + K(this).addClass('ke-on'); + }) + .mouseout(function(e) { + K(this).removeClass('ke-on'); + }); + var iconUrl = imgPath + (data.is_dir ? 'folder-16.gif' : 'file-16.gif'), + img = K('' + data.filename + ''), + cell0 = K(row[0].insertCell(0)).addClass('ke-cell ke-name').append(img).append(document.createTextNode(' ' + data.filename)); + if (!data.is_dir || data.has_file) { + row.css('cursor', 'pointer'); + cell0.attr('title', data.filename); + bindEvent(cell0, result, data, createList); + } else { + cell0.attr('title', lang.emptyFolder); + } + K(row[0].insertCell(1)).addClass('ke-cell ke-size').html(data.is_dir ? '-' : Math.ceil(data.filesize / 1024) + 'KB'); + K(row[0].insertCell(2)).addClass('ke-cell ke-datetime').html(data.datetime); + } + } + function createView(result) { + createCommon(result, createView); + var fileList = result.file_list; + for (var i = 0, len = fileList.length; i < len; i++) { + var data = fileList[i], + div = K('
        '); + bodyDiv.append(div); + var photoDiv = K('
        ') + .mouseover(function(e) { + K(this).addClass('ke-on'); + }) + .mouseout(function(e) { + K(this).removeClass('ke-on'); + }); + div.append(photoDiv); + var fileUrl = result.current_url + data.filename, + iconUrl = data.is_dir ? imgPath + 'folder-64.gif' : (data.is_photo ? fileUrl : imgPath + 'file-64.gif'); + var img = K('' + data.filename + ''); + if (!data.is_dir || data.has_file) { + photoDiv.css('cursor', 'pointer'); + bindTitle(photoDiv, data); + bindEvent(photoDiv, result, data, createView); + } else { + photoDiv.attr('title', lang.emptyFolder); + } + photoDiv.append(img); + div.append('
        ' + data.filename + '
        '); + } + } + viewTypeBox.val(viewType); + reloadPage('', orderTypeBox.val(), viewType == 'VIEW' ? createView : createList); + return dialog; + } + +}); diff --git a/php/kindeditor_demo/kindeditor/plugins/filemanager/images/file-16.gif b/php/kindeditor_demo/kindeditor/plugins/filemanager/images/file-16.gif new file mode 100755 index 0000000000000000000000000000000000000000..2cf6e47ede1f2e26bd3452c23176ebaf79a5fd57 GIT binary patch literal 170 zcmZ?wbhEHb6krfw*v!B%b?Vgb-@jkGcJ0WKBYXGm{r~^}(&bC<-Mcq)=FG>BAFo)o z0w}_O1QdU=u!=BnGw6WCKxQzogcqFjTf`mx3xJ)z~&)qMzN*+PXmCFv_ zx|XjqoqOKda0QQ+4FQRnJd@^~*7*Emjpt%t9)?{u94s1A+Z8leL`2ty2pB}H2yFbl O_W%zE%L5fA25SIajYC=h literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/filemanager/images/file-64.gif b/php/kindeditor_demo/kindeditor/plugins/filemanager/images/file-64.gif new file mode 100755 index 0000000000000000000000000000000000000000..2e211da0eb40f61300841085bb83d410e8b5e741 GIT binary patch literal 1149 zcmcJ~jXTo`0KoCzm`y_}qBt8uDQ|hXyms7;@aPUtkL0{;m%N;phuP#M{8sbYHt(?! z!$KI7w>(+R%gFnCGd<@$PwZwZuSMssKjOasz~}kiaB;GHF#KwxT6A-^@PLZLf8 zUa3R7F~v_CJeX@q!_N0sAu{mcXla^#pmqZN@6f&?*$?O#O~)Qv-4>nE(GuE zzj1xN2!tKF^^#qlbIRop#imT%8k-7Nfiq^4NcGadj+!$X1T8*Qq^Y&pAa8=r_|Vf5 zm7#gJ2u1%an-1go-@LYB6@2m~7mAaWN?3>JD5+lmuTYK$GPBw_aoekABVGTIa;jyJk?A|UqY;AYaK&|{or7i-3stM3IABYFo{xmH#G0yG%N!i78}Mb62zj5%Njd|*ke?v3N;vm0}4V`GIc#) z`e&dJ)ys~T`a>$ScAG;kkfsOqR;e17Cs!!YF3VBsgPr2OY{6W$;A|+>jiU_TB z1-hli9N7?u+l-2SxaQJxT?;Sk+jTP7`N_h1HjbFb!aO+#Rv}CP2(15W9l*vuND!7` zH;3$@s<&p&LYuO*L;w$&=*d*_j)Ftv?1gm0<{7oHh>EiZ^vDiI=|}yNmt`61&lT)3 zL@3oXCzOqSONX%z+J8@v$^AKpCt8X97<}%c$$PH=o`k)=OTm zd2vA*WVRcwhrC%Ylvc3?9fplmJ#epQ^AO$8^O&6N(|Ab;zC}iJ352Q2Cy~0N&>SbY cie<#^tamVL_nq&3(Jmj8ZrDET001`s0_4gG<^TWy literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/filemanager/images/folder-16.gif b/php/kindeditor_demo/kindeditor/plugins/filemanager/images/folder-16.gif new file mode 100755 index 0000000000000000000000000000000000000000..850b5a350d8943232c10a12e42b3edf0c0d78472 GIT binary patch literal 226 zcmZ?wbhEHb6krfwIKsg2ezM@^&6}Ui^7?nQE{`KzUoAE%4&*|X=z-JL(SNB_Mr;oCgrA4~N9-P`o{c=fjh8he;ee>Up~G!%G< zIEnFf6rD`5l9;-p#46Rt=t_>Nv1J6;gAEcnmI*p9wnX(V)VTMdVos6ejrSFQT%BJ0 X{$DR7Ey&o~*4`?p+uhTn$Y2csGiPY9 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/filemanager/images/folder-64.gif b/php/kindeditor_demo/kindeditor/plugins/filemanager/images/folder-64.gif new file mode 100755 index 0000000000000000000000000000000000000000..e8a1b09c04162bb4f2e9a2c195c61c9b753d30e1 GIT binary patch literal 1272 zcmd7PiC5AG0KoBIK*Yk8n%6QE<>%FOIcH_%YhXUZu!gf0Yp!dX8R~nqj#V~?gn6Ul znI|GDDml{@UKt))UV%E%npZJFg#-i-3i<8zU+nuAeBS#W4G!`XhFK1jKcv=ox&K*Maqa4{ri8N|8JAai|? zwecd}^!)bPb0*aD>v9icwd=M?6s;BAF+7RVbzC#GUxeDuPIs^kZNC^=E4em+~F7c{UslN0V*wCi%!z{C*aTm5`7S8yicb(Wq2v zL_`DxLBRhwCj(-$6+i+!KN>$i0k%MN65}p2;a*}=a!P7iIx8bHi=Ca5o0ng3zp$vd zq_m7v&aL28R#o$BYU_%S)|iHejTp;Kf?Vqzt!?dXJ0A<#&elE8dV8OCW;xpoy%b9v zME&VF$+!fA`)6`$dS-S8V_qnoP|PnZj$`KR)Ee!wPQS9M#}&G+88=KiSKn7;LIbDs zE^5c_@B+y_SLY+n$BKy$xzAGVyew;SI^l^K4go2`y0}5%;`b!h|%_raSgv%gv*kAIiF~ zgyJoS^AqO=3ciY(9&EX)=y1l~Y9_qDrx@jjUH#(sZaDbq-izbp<83!Cz1r)GZ>7g3 zs%J!Z(T*qDZ(f=fNpf++Z0^kO$O*9z{<>grIE69KRI8}2N)3Oi0bRgA_ukn#C9YyIzMp}VCV9}>*+2?HibTy9iDd!L{rXS`w(Czje(~1 zdMJvoNiQo(ek+y85o~_|hH~-qnCCEUsPpAXTfgrr+fE!2A?@!-4|h}wlM znftKGFm<#>!RO^s7i;)cwTnpggl#aamEt`hcqFANA3Q$8A;H+Y%n1l*;UWi_s!0;`xz{5LPy6#A!qc9xXYz*fop3hphZs15=!}PN3#nUbRUK5~;V_~l z9bqN-S^Z>PUZ?Ibz9td8*jDBN$j|gqnoiVA5dpOsq3X6Ef>}&UtJBfi@1EIR5@>sE zNohS6hkZT!U>=B2riFX8V7cE@s9GNIvb6}@il%%E!2A>f-An&9l}`M1YRHfz&^AUt fOmuso9|_t2PCrUM>b3Is$cTvXaLwRrlOX**u!PuS+2(IcSY)xF}7f9oC(wHtC;mR-I7&MR-0VMts5rYB~}i!-{mRnOY{?&FuHWjFR7K7Huy zT~ULmyq?vfT3)@&&X&zOUpi%5RQ)yqMX%t}CG0#RvzP7cT64-GvRlqF!76#}|Ns9P z1}jkf$-*ka;KQH;av&&97})z8e43hl92{CYT4dyOZ8|$Fy*>C%MEaW<4Vamkw5I#$ znX#*?va`7N8*wUWuGO^jV(k<)cH-I2W=jzf1_d#3N51(!5@OP(R`2F>iJ2-|alO|Oe(i8$cZw1- OH?vCJo@faU25SJW- +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('flash', function(K) { + var self = this, name = 'flash', lang = self.lang(name + '.'), + allowFlashUpload = K.undef(self.allowFlashUpload, true), + allowFileManager = K.undef(self.allowFileManager, false), + formatUploadUrl = K.undef(self.formatUploadUrl, true), + extraParams = K.undef(self.extraFileUploadParams, {}), + filePostName = K.undef(self.filePostName, 'imgFile'), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'); + self.plugin.flash = { + edit : function() { + var html = [ + '
        ', + //url + '
        ', + '', + '  ', + '  ', + '', + '', + '', + '
        ', + //width + '
        ', + '', + ' ', + '
        ', + //height + '
        ', + '', + ' ', + '
        ', + '
        ' + ].join(''); + var dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var url = K.trim(urlBox.val()), + width = widthBox.val(), + height = heightBox.val(); + if (url == 'http://' || K.invalidUrl(url)) { + alert(self.lang('invalidUrl')); + urlBox[0].focus(); + return; + } + if (!/^\d*$/.test(width)) { + alert(self.lang('invalidWidth')); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + alert(self.lang('invalidHeight')); + heightBox[0].focus(); + return; + } + var html = K.mediaImg(self.themesPath + 'common/blank.gif', { + src : url, + type : K.mediaType('.swf'), + width : width, + height : height, + quality : 'high' + }); + self.insertHtml(html).hideDialog().focus(); + } + } + }), + div = dialog.div, + urlBox = K('[name="url"]', div), + viewServerBtn = K('[name="viewServer"]', div), + widthBox = K('[name="width"]', div), + heightBox = K('[name="height"]', div); + urlBox.val('http://'); + + if (allowFlashUpload) { + var uploadbutton = K.uploadbutton({ + button : K('.ke-upload-button', div)[0], + fieldName : filePostName, + extraParams : extraParams, + url : K.addParam(uploadJson, 'dir=flash'), + afterUpload : function(data) { + dialog.hideLoading(); + if (data.error === 0) { + var url = data.url; + if (formatUploadUrl) { + url = K.formatUrl(url, 'absolute'); + } + urlBox.val(url); + if (self.afterUpload) { + self.afterUpload.call(self, url, data, name); + } + alert(self.lang('uploadSuccess')); + } else { + alert(data.message); + } + }, + afterError : function(html) { + dialog.hideLoading(); + self.errorDialog(html); + } + }); + uploadbutton.fileBox.change(function(e) { + dialog.showLoading(self.lang('uploadLoading')); + uploadbutton.submit(); + }); + } else { + K('.ke-upload-button', div).hide(); + } + + if (allowFileManager) { + viewServerBtn.click(function(e) { + self.loadPlugin('filemanager', function() { + self.plugin.filemanagerDialog({ + viewType : 'LIST', + dirName : 'flash', + clickFn : function(url, title) { + if (self.dialogs.length > 1) { + K('[name="url"]', div).val(url); + if (self.afterSelectFile) { + self.afterSelectFile.call(self, url); + } + self.hideDialog(); + } + } + }); + }); + }); + } else { + viewServerBtn.hide(); + } + + var img = self.plugin.getSelectedFlash(); + if (img) { + var attrs = K.mediaAttrs(img.attr('data-ke-tag')); + urlBox.val(attrs.src); + widthBox.val(K.removeUnit(img.css('width')) || attrs.width || 0); + heightBox.val(K.removeUnit(img.css('height')) || attrs.height || 0); + } + urlBox[0].focus(); + urlBox[0].select(); + }, + 'delete' : function() { + self.plugin.getSelectedFlash().remove(); + // [IE] 删除图片后立即点击图片按钮出错 + self.addBookmark(); + } + }; + self.clickToolbar(name, self.plugin.flash.edit); +}); diff --git a/php/kindeditor_demo/kindeditor/plugins/image/image.js b/php/kindeditor_demo/kindeditor/plugins/image/image.js new file mode 100755 index 0000000..4b82431 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/plugins/image/image.js @@ -0,0 +1,328 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('image', function(K) { + var self = this, name = 'image', + allowImageUpload = K.undef(self.allowImageUpload, true), + allowImageRemote = K.undef(self.allowImageRemote, true), + formatUploadUrl = K.undef(self.formatUploadUrl, true), + allowFileManager = K.undef(self.allowFileManager, false), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'), + imageTabIndex = K.undef(self.imageTabIndex, 0), + imgPath = self.pluginsPath + 'image/images/', + extraParams = K.undef(self.extraFileUploadParams, {}), + filePostName = K.undef(self.filePostName, 'imgFile'), + fillDescAfterUploadImage = K.undef(self.fillDescAfterUploadImage, false), + lang = self.lang(name + '.'); + + self.plugin.imageDialog = function(options) { + var imageUrl = options.imageUrl, + imageWidth = K.undef(options.imageWidth, ''), + imageHeight = K.undef(options.imageHeight, ''), + imageTitle = K.undef(options.imageTitle, ''), + imageAlign = K.undef(options.imageAlign, ''), + showRemote = K.undef(options.showRemote, true), + showLocal = K.undef(options.showLocal, true), + tabIndex = K.undef(options.tabIndex, 0), + clickFn = options.clickFn; + var target = 'kindeditor_upload_iframe_' + new Date().getTime(); + var hiddenElements = []; + for(var k in extraParams){ + hiddenElements.push(''); + } + var html = [ + '
        ', + //tabs + '
        ', + //remote image - start + '', + //remote image - end + //local upload - start + '', + //local upload - end + '
        ' + ].join(''); + var dialogWidth = showLocal || allowFileManager ? 450 : 400, + dialogHeight = showLocal && showRemote ? 300 : 250; + var dialog = self.createDialog({ + name : name, + width : dialogWidth, + height : dialogHeight, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + // Bugfix: http://code.google.com/p/kindeditor/issues/detail?id=319 + if (dialog.isLoading) { + return; + } + // insert local image + if (showLocal && showRemote && tabs && tabs.selectedIndex === 1 || !showRemote) { + if (uploadbutton.fileBox.val() == '') { + alert(self.lang('pleaseSelectFile')); + return; + } + dialog.showLoading(self.lang('uploadLoading')); + uploadbutton.submit(); + localUrlBox.val(''); + return; + } + // insert remote image + var url = K.trim(urlBox.val()), + width = widthBox.val(), + height = heightBox.val(), + title = titleBox.val(), + align = ''; + alignBox.each(function() { + if (this.checked) { + align = this.value; + return false; + } + }); + if (url == 'http://' || K.invalidUrl(url)) { + alert(self.lang('invalidUrl')); + urlBox[0].focus(); + return; + } + if (!/^\d*$/.test(width)) { + alert(self.lang('invalidWidth')); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + alert(self.lang('invalidHeight')); + heightBox[0].focus(); + return; + } + clickFn.call(self, url, title, width, height, 0, align); + } + }, + beforeRemove : function() { + viewServerBtn.unbind(); + widthBox.unbind(); + heightBox.unbind(); + refreshBtn.unbind(); + } + }), + div = dialog.div; + + var urlBox = K('[name="url"]', div), + localUrlBox = K('[name="localUrl"]', div), + viewServerBtn = K('[name="viewServer"]', div), + widthBox = K('.tab1 [name="width"]', div), + heightBox = K('.tab1 [name="height"]', div), + refreshBtn = K('.ke-refresh-btn', div), + titleBox = K('.tab1 [name="title"]', div), + alignBox = K('.tab1 [name="align"]', div); + + var tabs; + if (showRemote && showLocal) { + tabs = K.tabs({ + src : K('.tabs', div), + afterSelect : function(i) {} + }); + tabs.add({ + title : lang.remoteImage, + panel : K('.tab1', div) + }); + tabs.add({ + title : lang.localImage, + panel : K('.tab2', div) + }); + tabs.select(tabIndex); + } else if (showRemote) { + K('.tab1', div).show(); + } else if (showLocal) { + K('.tab2', div).show(); + } + + var uploadbutton = K.uploadbutton({ + button : K('.ke-upload-button', div)[0], + fieldName : filePostName, + form : K('.ke-form', div), + target : target, + width: 60, + afterUpload : function(data) { + dialog.hideLoading(); + if (data.error === 0) { + var url = data.url; + if (formatUploadUrl) { + url = K.formatUrl(url, 'absolute'); + } + if (self.afterUpload) { + self.afterUpload.call(self, url, data, name); + } + if (!fillDescAfterUploadImage) { + clickFn.call(self, url, data.title, data.width, data.height, data.border, data.align); + } else { + K(".ke-dialog-row #remoteUrl", div).val(url); + K(".ke-tabs-li", div)[0].click(); + K(".ke-refresh-btn", div).click(); + } + } else { + alert(data.message); + } + }, + afterError : function(html) { + dialog.hideLoading(); + self.errorDialog(html); + } + }); + uploadbutton.fileBox.change(function(e) { + localUrlBox.val(uploadbutton.fileBox.val()); + }); + if (allowFileManager) { + viewServerBtn.click(function(e) { + self.loadPlugin('filemanager', function() { + self.plugin.filemanagerDialog({ + viewType : 'VIEW', + dirName : 'image', + clickFn : function(url, title) { + if (self.dialogs.length > 1) { + K('[name="url"]', div).val(url); + if (self.afterSelectFile) { + self.afterSelectFile.call(self, url); + } + self.hideDialog(); + } + } + }); + }); + }); + } else { + viewServerBtn.hide(); + } + var originalWidth = 0, originalHeight = 0; + function setSize(width, height) { + widthBox.val(width); + heightBox.val(height); + originalWidth = width; + originalHeight = height; + } + refreshBtn.click(function(e) { + var tempImg = K('', document).css({ + position : 'absolute', + visibility : 'hidden', + top : 0, + left : '-1000px' + }); + tempImg.bind('load', function() { + setSize(tempImg.width(), tempImg.height()); + tempImg.remove(); + }); + K(document.body).append(tempImg); + }); + widthBox.change(function(e) { + if (originalWidth > 0) { + heightBox.val(Math.round(originalHeight / originalWidth * parseInt(this.value, 10))); + } + }); + heightBox.change(function(e) { + if (originalHeight > 0) { + widthBox.val(Math.round(originalWidth / originalHeight * parseInt(this.value, 10))); + } + }); + urlBox.val(options.imageUrl); + setSize(options.imageWidth, options.imageHeight); + titleBox.val(options.imageTitle); + alignBox.each(function() { + if (this.value === options.imageAlign) { + this.checked = true; + return false; + } + }); + if (showRemote && tabIndex === 0) { + urlBox[0].focus(); + urlBox[0].select(); + } + return dialog; + }; + self.plugin.image = { + edit : function() { + var img = self.plugin.getSelectedImage(); + self.plugin.imageDialog({ + imageUrl : img ? img.attr('data-ke-src') : 'http://', + imageWidth : img ? img.width() : '', + imageHeight : img ? img.height() : '', + imageTitle : img ? img.attr('title') : '', + imageAlign : img ? img.attr('align') : '', + showRemote : allowImageRemote, + showLocal : allowImageUpload, + tabIndex: img ? 0 : imageTabIndex, + clickFn : function(url, title, width, height, border, align) { + if (img) { + img.attr('src', url); + img.attr('data-ke-src', url); + img.attr('width', width); + img.attr('height', height); + img.attr('title', title); + img.attr('align', align); + img.attr('alt', title); + } else { + self.exec('insertimage', url, title, width, height, border, align); + } + // Bugfix: [Firefox] 上传图片后,总是出现正在加载的样式,需要延迟执行hideDialog + setTimeout(function() { + self.hideDialog().focus(); + }, 0); + } + }); + }, + 'delete' : function() { + var target = self.plugin.getSelectedImage(); + if (target.parent().name == 'a') { + target = target.parent(); + } + target.remove(); + // [IE] 删除图片后立即点击图片按钮出错 + self.addBookmark(); + } + }; + self.clickToolbar(name, self.plugin.image.edit); +}); diff --git a/php/kindeditor_demo/kindeditor/plugins/image/images/align_left.gif b/php/kindeditor_demo/kindeditor/plugins/image/images/align_left.gif new file mode 100755 index 0000000000000000000000000000000000000000..ab17f56797aa3d6e54901251faa46a1d6a82ecc2 GIT binary patch literal 639 zcmZ?wbhEHb6laiRc*Xz%|NsC0`0~w_!xw)2{{Q;@?_a&NfY0z5d|Swfi6U&e?h5*55TdugqP( zd*;H87jM76djIpEzyB>GCR#^MvW=c(7cI+l#-3m0}y zcJ59}OkpzDnv~J$$H>AGkq{Y`Dyz9*QTmegj1G+QjN!@AF|o4h>pJZ^-9ysiBZ<4U~gn1Eh#H-meJE9h{xDp##LCC|K?)G$u@y(readQX2D_;9K@9y+PT?P z0vw!B1o0RN>)3}#UYWYsacTM!QqbB%B71u_a>d%Vtz8! mdxmkb+nP*aA-}msk>9>>^1Sd_=q&ls=hvqR!OI&N7_0$|A|OKm literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/image/images/align_right.gif b/php/kindeditor_demo/kindeditor/plugins/image/images/align_right.gif new file mode 100755 index 0000000000000000000000000000000000000000..e8ebe6a6367b8f2abe19eab1e888f62b31ebcafa GIT binary patch literal 636 zcmZ?wbhEHb6laiRc*Xz%|NsC0`0~w_!xw)2{{Q;@?_a&NfY0z5d|Swfi6U&e?h5*55TdugqP( zd*;H87jM76djIpEzyB>GCR#^MvW=c(7cQXIJ30E;dRiOk=~#A7 z?se`?N=#ug*IJU%Ic>ThBMVDJLS$5`tmgWO4vg}Q;mOf4v9jv>r)*-h>vRuEi;rWL zRXx+|#po7bZ)74ZDJyVhQ#zxkMG%j%zl^J}F8{3_n?N>GF)3fOU~Z2&#bU}0?cD4t z0S-<_x;U!4<3x5eC@{8haZL;1G`tYRAgdkb;*iMH)GWyB;LxMO8D?B!Fqc*1=%lAh jW?1N-Es4Cm?DQOq@NY3C!WupcohPc<9@&zqz+epk_}(0^ literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/image/images/align_top.gif b/php/kindeditor_demo/kindeditor/plugins/image/images/align_top.gif new file mode 100755 index 0000000000000000000000000000000000000000..d8826a5bce1462216379abff027077225394620d GIT binary patch literal 625 zcmZ?wbhEHb6laiRc*Xz%|NsC0`0~w_!xw)2{{Q;@?_a&NfY0z5d|Swfi6U&e?h5*55TdugqP( zd*;H87jM76djIpEzyB>GCR#^MvW=c(7cI+i_?yPUg| z5>uGWwH9Rb_%X7uL?lE;rOIlq?r~t0XADn{j)|33-`Q=~=^m06AIB`KdaTQf(JjE< z$V6IFR^U>nr$rEtvA>L~urB|7Mw>u3Q!y!DvtVwOH-?OI;_N~q9vu;a2j96ia&rhJ ztXPoXIaT0I$(jg3##T-aJ~tDFgL;!x!WhqW$arpAa>8YyP1T%~O{$(#6hharyxgSb XGgB+_T27_#bNBi3{G7HT91PX~icA-s literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/plugins/image/images/refresh.png b/php/kindeditor_demo/kindeditor/plugins/image/images/refresh.png new file mode 100755 index 0000000000000000000000000000000000000000..77e12d1c6acb7ad8defd5410e695d603097fba04 GIT binary patch literal 800 zcmV+*1K<3KP);XHLv^X{MWe`Tlinj{a@#N-#PzxnA+M}IA}100Yb>4X_(gy!}zoRE}P9-Gcn=d zkLP%hWjQ4)@@JM~+i8G(XAfenZNtG5HYNzd8%dOYyWMWnOnF3+72tRd!jUi}2NK|K@I&8)OF&qx6p4}p zNk|SR-ebsy13*!0YHDW7YT0sZYHEb3naQ_!H+||v`?BIuOy6N2+`4@WqS457TO^h) zm&>rVwN(K?sZ?EUrDdq93cY>3t8LL(cd1me(hdXzFq59yt*$=OA8Cm$X{rYHyV)7A z#X?cQ`YiyT&v&O(EP<};pb-roKY8>C?|NIBLs@#ZUja+Twe?j%i2xe~G);pCbMras zNLeT#2A>Qz9?$BUE+N?{W;%*H`IOjtzBJ zbcqY1Brc%;m;*rB&UK$%qceTbLcVYjRapQA4pnLuP|^uxzK1(Rn)UJR(iAxgof;y1uelRaG_g>g8*| zAi&Pe?eA0t^n1W zX4Kl&3PZywBhVa}N1wF+SVMXH*LDTK>)l&an7)3`#Be)-7DtoN3TR7cbNHakwn95Q eJ67C30R{j{$`Q#a2a=)y0000 +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('insertfile', function(K) { + var self = this, name = 'insertfile', + allowFileUpload = K.undef(self.allowFileUpload, true), + allowFileManager = K.undef(self.allowFileManager, false), + formatUploadUrl = K.undef(self.formatUploadUrl, true), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'), + extraParams = K.undef(self.extraFileUploadParams, {}), + filePostName = K.undef(self.filePostName, 'imgFile'), + lang = self.lang(name + '.'); + self.plugin.fileDialog = function(options) { + var fileUrl = K.undef(options.fileUrl, 'http://'), + fileTitle = K.undef(options.fileTitle, ''), + clickFn = options.clickFn; + var html = [ + '
        ', + '
        ', + '', + '  ', + '  ', + '', + '', + '', + '
        ', + //title + '
        ', + '', + '
        ', + '
        ', + //form end + '', + '' + ].join(''); + var dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var url = K.trim(urlBox.val()), + title = titleBox.val(); + if (url == 'http://' || K.invalidUrl(url)) { + alert(self.lang('invalidUrl')); + urlBox[0].focus(); + return; + } + if (K.trim(title) === '') { + title = url; + } + clickFn.call(self, url, title); + } + } + }), + div = dialog.div; + + var urlBox = K('[name="url"]', div), + viewServerBtn = K('[name="viewServer"]', div), + titleBox = K('[name="title"]', div); + + if (allowFileUpload) { + var uploadbutton = K.uploadbutton({ + button : K('.ke-upload-button', div)[0], + fieldName : filePostName, + url : K.addParam(uploadJson, 'dir=file'), + extraParams : extraParams, + afterUpload : function(data) { + dialog.hideLoading(); + if (data.error === 0) { + var url = data.url; + if (formatUploadUrl) { + url = K.formatUrl(url, 'absolute'); + } + urlBox.val(url); + if (self.afterUpload) { + self.afterUpload.call(self, url, data, name); + } + alert(self.lang('uploadSuccess')); + } else { + alert(data.message); + } + }, + afterError : function(html) { + dialog.hideLoading(); + self.errorDialog(html); + } + }); + uploadbutton.fileBox.change(function(e) { + dialog.showLoading(self.lang('uploadLoading')); + uploadbutton.submit(); + }); + } else { + K('.ke-upload-button', div).hide(); + } + if (allowFileManager) { + viewServerBtn.click(function(e) { + self.loadPlugin('filemanager', function() { + self.plugin.filemanagerDialog({ + viewType : 'LIST', + dirName : 'file', + clickFn : function(url, title) { + if (self.dialogs.length > 1) { + K('[name="url"]', div).val(url); + if (self.afterSelectFile) { + self.afterSelectFile.call(self, url); + } + self.hideDialog(); + } + } + }); + }); + }); + } else { + viewServerBtn.hide(); + } + urlBox.val(fileUrl); + titleBox.val(fileTitle); + urlBox[0].focus(); + urlBox[0].select(); + }; + self.clickToolbar(name, function() { + self.plugin.fileDialog({ + clickFn : function(url, title) { + var html = '' + title + ''; + self.insertHtml(html).hideDialog().focus(); + } + }); + }); +}); diff --git a/php/kindeditor_demo/kindeditor/plugins/lineheight/lineheight.js b/php/kindeditor_demo/kindeditor/plugins/lineheight/lineheight.js new file mode 100755 index 0000000..2125587 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/plugins/lineheight/lineheight.js @@ -0,0 +1,38 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('lineheight', function(K) { + var self = this, name = 'lineheight', lang = self.lang(name + '.'); + self.clickToolbar(name, function() { + var curVal = '', commonNode = self.cmd.commonNode({'*' : '.line-height'}); + if (commonNode) { + curVal = commonNode.css('line-height'); + } + var menu = self.createMenu({ + name : name, + width : 150 + }); + K.each(lang.lineHeight, function(i, row) { + K.each(row, function(key, val) { + menu.addItem({ + title : val, + checked : curVal === key, + click : function() { + self.cmd.toggle('', { + span : '.line-height=' + key + }); + self.updateState(); + self.addBookmark(); + self.hideMenu(); + } + }); + }); + }); + }); +}); diff --git a/php/kindeditor_demo/kindeditor/plugins/link/link.js b/php/kindeditor_demo/kindeditor/plugins/link/link.js new file mode 100755 index 0000000..f707bc6 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/plugins/link/link.js @@ -0,0 +1,66 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('link', function(K) { + var self = this, name = 'link'; + self.plugin.link = { + edit : function() { + var lang = self.lang(name + '.'), + html = '
        ' + + //url + '
        ' + + '' + + '
        ' + + //type + '
        ' + + '' + + '' + + '
        ' + + '
        ', + dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var url = K.trim(urlBox.val()); + if (url == 'http://' || K.invalidUrl(url)) { + alert(self.lang('invalidUrl')); + urlBox[0].focus(); + return; + } + self.exec('createlink', url, typeBox.val()).hideDialog().focus(); + } + } + }), + div = dialog.div, + urlBox = K('input[name="url"]', div), + typeBox = K('select[name="type"]', div); + urlBox.val('http://'); + typeBox[0].options[0] = new Option(lang.newWindow, '_blank'); + typeBox[0].options[1] = new Option(lang.selfWindow, ''); + self.cmd.selection(); + var a = self.plugin.getSelectedLink(); + if (a) { + self.cmd.range.selectNode(a[0]); + self.cmd.select(); + urlBox.val(a.attr('data-ke-src')); + typeBox.val(a.attr('target')); + } + urlBox[0].focus(); + urlBox[0].select(); + }, + 'delete' : function() { + self.exec('unlink', null); + } + }; + self.clickToolbar(name, self.plugin.link.edit); +}); diff --git a/php/kindeditor_demo/kindeditor/plugins/map/map.html b/php/kindeditor_demo/kindeditor/plugins/map/map.html new file mode 100755 index 0000000..033b60b --- /dev/null +++ b/php/kindeditor_demo/kindeditor/plugins/map/map.html @@ -0,0 +1,57 @@ + + + + + + + + + +
        + + \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/plugins/map/map.js b/php/kindeditor_demo/kindeditor/plugins/map/map.js new file mode 100755 index 0000000..38521cf --- /dev/null +++ b/php/kindeditor_demo/kindeditor/plugins/map/map.js @@ -0,0 +1,137 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +// Google Maps: http://code.google.com/apis/maps/index.html + +KindEditor.plugin('map', function(K) { + var self = this, name = 'map', lang = self.lang(name + '.'); + self.clickToolbar(name, function() { + var html = ['
        ', + '
        ', + lang.address + ' ', + '', + '', + '', + '
        ', + '
        ', + '
        '].join(''); + var dialog = self.createDialog({ + name : name, + width : 600, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var geocoder = win.geocoder, + map = win.map, + center = map.getCenter().lat() + ',' + map.getCenter().lng(), + zoom = map.getZoom(), + maptype = map.getMapTypeId(), + url = 'http://maps.googleapis.com/maps/api/staticmap'; + url += '?center=' + encodeURIComponent(center); + url += '&zoom=' + encodeURIComponent(zoom); + url += '&size=558x360'; + url += '&maptype=' + encodeURIComponent(maptype); + url += '&markers=' + encodeURIComponent(center); + url += '&language=' + self.langType; + url += '&sensor=false'; + self.exec('insertimage', url).hideDialog().focus(); + } + }, + beforeRemove : function() { + searchBtn.remove(); + if (doc) { + doc.write(''); + } + iframe.remove(); + } + }); + var div = dialog.div, + addressBox = K('[name="address"]', div), + searchBtn = K('[name="searchBtn"]', div), + win, doc; + var iframeHtml = ['', + '', + '', + '', + '', + '', + '', + '
        ', + ''].join('\n'); + // TODO:用doc.write(iframeHtml)方式加载时,在IE6上第一次加载报错,暂时使用src方式 + var iframe = K(''); + function ready() { + win = iframe[0].contentWindow; + doc = K.iframeDoc(iframe); + //doc.open(); + //doc.write(iframeHtml); + //doc.close(); + } + iframe.bind('load', function() { + iframe.unbind('load'); + if (K.IE) { + ready(); + } else { + setTimeout(ready, 0); + } + }); + K('.ke-map', div).replaceWith(iframe); + // search map + searchBtn.click(function() { + win.search(addressBox.val()); + }); + }); +}); diff --git a/php/kindeditor_demo/kindeditor/plugins/media/media.js b/php/kindeditor_demo/kindeditor/plugins/media/media.js new file mode 100755 index 0000000..ef1887e --- /dev/null +++ b/php/kindeditor_demo/kindeditor/plugins/media/media.js @@ -0,0 +1,170 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('media', function(K) { + var self = this, name = 'media', lang = self.lang(name + '.'), + allowMediaUpload = K.undef(self.allowMediaUpload, true), + allowFileManager = K.undef(self.allowFileManager, false), + formatUploadUrl = K.undef(self.formatUploadUrl, true), + extraParams = K.undef(self.extraFileUploadParams, {}), + filePostName = K.undef(self.filePostName, 'imgFile'), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'); + self.plugin.media = { + edit : function() { + var html = [ + '
        ', + //url + '
        ', + '', + '  ', + '  ', + '', + '', + '', + '
        ', + //width + '
        ', + '', + '', + '
        ', + //height + '
        ', + '', + '', + '
        ', + //autostart + '
        ', + '', + ' ', + '
        ', + '
        ' + ].join(''); + var dialog = self.createDialog({ + name : name, + width : 450, + height : 230, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var url = K.trim(urlBox.val()), + width = widthBox.val(), + height = heightBox.val(); + if (url == 'http://' || K.invalidUrl(url)) { + alert(self.lang('invalidUrl')); + urlBox[0].focus(); + return; + } + if (!/^\d*$/.test(width)) { + alert(self.lang('invalidWidth')); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + alert(self.lang('invalidHeight')); + heightBox[0].focus(); + return; + } + var html = K.mediaImg(self.themesPath + 'common/blank.gif', { + src : url, + type : K.mediaType(url), + width : width, + height : height, + autostart : autostartBox[0].checked ? 'true' : 'false', + loop : 'true' + }); + self.insertHtml(html).hideDialog().focus(); + } + } + }), + div = dialog.div, + urlBox = K('[name="url"]', div), + viewServerBtn = K('[name="viewServer"]', div), + widthBox = K('[name="width"]', div), + heightBox = K('[name="height"]', div), + autostartBox = K('[name="autostart"]', div); + urlBox.val('http://'); + + if (allowMediaUpload) { + var uploadbutton = K.uploadbutton({ + button : K('.ke-upload-button', div)[0], + fieldName : filePostName, + extraParams : extraParams, + url : K.addParam(uploadJson, 'dir=media'), + afterUpload : function(data) { + dialog.hideLoading(); + if (data.error === 0) { + var url = data.url; + if (formatUploadUrl) { + url = K.formatUrl(url, 'absolute'); + } + urlBox.val(url); + if (self.afterUpload) { + self.afterUpload.call(self, url, data, name); + } + alert(self.lang('uploadSuccess')); + } else { + alert(data.message); + } + }, + afterError : function(html) { + dialog.hideLoading(); + self.errorDialog(html); + } + }); + uploadbutton.fileBox.change(function(e) { + dialog.showLoading(self.lang('uploadLoading')); + uploadbutton.submit(); + }); + } else { + K('.ke-upload-button', div).hide(); + } + + if (allowFileManager) { + viewServerBtn.click(function(e) { + self.loadPlugin('filemanager', function() { + self.plugin.filemanagerDialog({ + viewType : 'LIST', + dirName : 'media', + clickFn : function(url, title) { + if (self.dialogs.length > 1) { + K('[name="url"]', div).val(url); + if (self.afterSelectFile) { + self.afterSelectFile.call(self, url); + } + self.hideDialog(); + } + } + }); + }); + }); + } else { + viewServerBtn.hide(); + } + + var img = self.plugin.getSelectedMedia(); + if (img) { + var attrs = K.mediaAttrs(img.attr('data-ke-tag')); + urlBox.val(attrs.src); + widthBox.val(K.removeUnit(img.css('width')) || attrs.width || 0); + heightBox.val(K.removeUnit(img.css('height')) || attrs.height || 0); + autostartBox[0].checked = (attrs.autostart === 'true'); + } + urlBox[0].focus(); + urlBox[0].select(); + }, + 'delete' : function() { + self.plugin.getSelectedMedia().remove(); + // [IE] 删除图片后立即点击图片按钮出错 + self.addBookmark(); + } + }; + self.clickToolbar(name, self.plugin.media.edit); +}); diff --git a/php/kindeditor_demo/kindeditor/plugins/multiimage/images/image.png b/php/kindeditor_demo/kindeditor/plugins/multiimage/images/image.png new file mode 100755 index 0000000000000000000000000000000000000000..fe79cf0ad566d774635ae23fcd10722361d4b56d GIT binary patch literal 1862 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 +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + + +(function(K) { + +function KSWFUpload(options) { + this.init(options); +} +K.extend(KSWFUpload, { + init : function(options) { + var self = this; + options.afterError = options.afterError || function(str) { + alert(str); + }; + self.options = options; + self.progressbars = {}; + // template + self.div = K(options.container).html([ + '
        ', + '
        ', + '
        ', + '', + '
        ', + '
        ' + options.uploadDesc + '
        ', + '', + '', + '', + '
        ', + '
        ', + '
        ' + ].join('')); + self.bodyDiv = K('.ke-swfupload-body', self.div); + + function showError(itemDiv, msg) { + K('.ke-status > div', itemDiv).hide(); + K('.ke-message', itemDiv).addClass('ke-error').show().html(K.escape(msg)); + } + + var settings = { + debug : false, + upload_url : options.uploadUrl, + flash_url : options.flashUrl, + file_post_name : options.filePostName, + button_placeholder : K('.ke-swfupload-button > input', self.div)[0], + button_image_url: options.buttonImageUrl, + button_width: options.buttonWidth, + button_height: options.buttonHeight, + button_cursor : SWFUpload.CURSOR.HAND, + file_types : options.fileTypes, + file_types_description : options.fileTypesDesc, + file_upload_limit : options.fileUploadLimit, + file_size_limit : options.fileSizeLimit, + post_params : options.postParams, + file_queued_handler : function(file) { + file.url = self.options.fileIconUrl; + self.appendFile(file); + }, + file_queue_error_handler : function(file, errorCode, message) { + var errorName = ''; + switch (errorCode) { + case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED: + errorName = options.queueLimitExceeded; + break; + case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT: + errorName = options.fileExceedsSizeLimit; + break; + case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE: + errorName = options.zeroByteFile; + break; + case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE: + errorName = options.invalidFiletype; + break; + default: + errorName = options.unknownError; + break; + } + K.DEBUG && alert(errorName); + }, + upload_start_handler : function(file) { + var self = this; + var itemDiv = K('div[data-id="' + file.id + '"]', self.bodyDiv); + K('.ke-status > div', itemDiv).hide(); + K('.ke-progressbar', itemDiv).show(); + }, + upload_progress_handler : function(file, bytesLoaded, bytesTotal) { + var percent = Math.round(bytesLoaded * 100 / bytesTotal); + var progressbar = self.progressbars[file.id]; + progressbar.bar.css('width', Math.round(percent * 80 / 100) + 'px'); + progressbar.percent.html(percent + '%'); + }, + upload_error_handler : function(file, errorCode, message) { + if (file && file.filestatus == SWFUpload.FILE_STATUS.ERROR) { + var itemDiv = K('div[data-id="' + file.id + '"]', self.bodyDiv).eq(0); + showError(itemDiv, self.options.errorMessage); + } + }, + upload_success_handler : function(file, serverData) { + var itemDiv = K('div[data-id="' + file.id + '"]', self.bodyDiv).eq(0); + var data = {}; + try { + data = K.json(serverData); + } catch (e) { + self.options.afterError.call(this, '' + serverData + ''); + } + if (data.error !== 0) { + showError(itemDiv, K.DEBUG ? data.message : self.options.errorMessage); + return; + } + file.url = data.url; + K('.ke-img', itemDiv).attr('src', file.url).attr('data-status', file.filestatus).data('data', data); + K('.ke-status > div', itemDiv).hide(); + } + }; + self.swfu = new SWFUpload(settings); + + K('.ke-swfupload-startupload input', self.div).click(function() { + self.swfu.startUpload(); + }); + }, + getUrlList : function() { + var list = []; + K('.ke-img', self.bodyDiv).each(function() { + var img = K(this); + var status = img.attr('data-status'); + if (status == SWFUpload.FILE_STATUS.COMPLETE) { + list.push(img.data('data')); + } + }); + return list; + }, + removeFile : function(fileId) { + var self = this; + self.swfu.cancelUpload(fileId); + var itemDiv = K('div[data-id="' + fileId + '"]', self.bodyDiv); + K('.ke-photo', itemDiv).unbind(); + K('.ke-delete', itemDiv).unbind(); + itemDiv.remove(); + }, + removeFiles : function() { + var self = this; + K('.ke-item', self.bodyDiv).each(function() { + self.removeFile(K(this).attr('data-id')); + }); + }, + appendFile : function(file) { + var self = this; + var itemDiv = K('
        '); + self.bodyDiv.append(itemDiv); + var photoDiv = K('
        ') + .mouseover(function(e) { + K(this).addClass('ke-on'); + }) + .mouseout(function(e) { + K(this).removeClass('ke-on'); + }); + itemDiv.append(photoDiv); + + var img = K('' + file.name + ''); + photoDiv.append(img); + K('').appendTo(photoDiv).click(function() { + self.removeFile(file.id); + }); + var statusDiv = K('
        ').appendTo(photoDiv); + // progressbar + K(['
        ', + '
        ', + '
        0%
        '].join('')).hide().appendTo(statusDiv); + // message + K('
        ' + self.options.pendingMessage + '
        ').appendTo(statusDiv); + + itemDiv.append('
        ' + file.name + '
        '); + + self.progressbars[file.id] = { + bar : K('.ke-progressbar-bar-inner', photoDiv), + percent : K('.ke-progressbar-percent', photoDiv) + }; + }, + remove : function() { + this.removeFiles(); + this.swfu.destroy(); + this.div.html(''); + } +}); + +K.swfupload = function(element, options) { + return new KSWFUpload(element, options); +}; + +})(KindEditor); + +KindEditor.plugin('multiimage', function(K) { + var self = this, name = 'multiimage', + formatUploadUrl = K.undef(self.formatUploadUrl, true), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'), + imgPath = self.pluginsPath + 'multiimage/images/', + imageSizeLimit = K.undef(self.imageSizeLimit, '1MB'), + imageFileTypes = K.undef(self.imageFileTypes, '*.jpg;*.gif;*.png'), + imageUploadLimit = K.undef(self.imageUploadLimit, 20), + filePostName = K.undef(self.filePostName, 'imgFile'), + lang = self.lang(name + '.'); + + self.plugin.multiImageDialog = function(options) { + var clickFn = options.clickFn, + uploadDesc = K.tmpl(lang.uploadDesc, {uploadLimit : imageUploadLimit, sizeLimit : imageSizeLimit}); + var html = [ + '
        ', + '
        ', + '
        ', + '
        ' + ].join(''); + var dialog = self.createDialog({ + name : name, + width : 650, + height : 510, + title : self.lang(name), + body : html, + previewBtn : { + name : lang.insertAll, + click : function(e) { + clickFn.call(self, swfupload.getUrlList()); + } + }, + yesBtn : { + name : lang.clearAll, + click : function(e) { + swfupload.removeFiles(); + } + }, + beforeRemove : function() { + // IE9 bugfix: https://github.com/kindsoft/kindeditor/issues/72 + if (!K.IE || K.V <= 8) { + swfupload.remove(); + } + } + }), + div = dialog.div; + + var swfupload = K.swfupload({ + container : K('.swfupload', div), + buttonImageUrl : imgPath + (self.langType == 'zh-CN' ? 'select-files-zh-CN.png' : 'select-files-en.png'), + buttonWidth : self.langType == 'zh-CN' ? 72 : 88, + buttonHeight : 23, + fileIconUrl : imgPath + 'image.png', + uploadDesc : uploadDesc, + startButtonValue : lang.startUpload, + uploadUrl : K.addParam(uploadJson, 'dir=image'), + flashUrl : imgPath + 'swfupload.swf', + filePostName : filePostName, + fileTypes : '*.jpg;*.jpeg;*.gif;*.png;*.bmp', + fileTypesDesc : 'Image Files', + fileUploadLimit : imageUploadLimit, + fileSizeLimit : imageSizeLimit, + postParams : K.undef(self.extraFileUploadParams, {}), + queueLimitExceeded : lang.queueLimitExceeded, + fileExceedsSizeLimit : lang.fileExceedsSizeLimit, + zeroByteFile : lang.zeroByteFile, + invalidFiletype : lang.invalidFiletype, + unknownError : lang.unknownError, + pendingMessage : lang.pending, + errorMessage : lang.uploadError, + afterError : function(html) { + self.errorDialog(html); + } + }); + + return dialog; + }; + self.clickToolbar(name, function() { + self.plugin.multiImageDialog({ + clickFn : function (urlList) { + if (urlList.length === 0) { + return; + } + K.each(urlList, function(i, data) { + if (self.afterUpload) { + self.afterUpload.call(self, data.url, data, 'multiimage'); + } + self.exec('insertimage', data.url, data.title, data.width, data.height, data.border, data.align); + }); + // Bugfix: [Firefox] 上传图片后,总是出现正在加载的样式,需要延迟执行hideDialog + setTimeout(function() { + self.hideDialog().focus(); + }, 0); + } + }); + }); +}); + + +/** + * SWFUpload: http://www.swfupload.org, http://swfupload.googlecode.com + * + * mmSWFUpload 1.0: Flash upload dialog - http://profandesign.se/swfupload/, http://www.vinterwebb.se/ + * + * SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilz閚 and Mammon Media and is released under the MIT License: + * http://www.opensource.org/licenses/mit-license.php + * + * SWFUpload 2 is (c) 2007-2008 Jake Roberts and is released under the MIT License: + * http://www.opensource.org/licenses/mit-license.php + * + */ + + +/* ******************* */ +/* Constructor & Init */ +/* ******************* */ + +(function() { + +window.SWFUpload = function (settings) { + this.initSWFUpload(settings); +}; + +SWFUpload.prototype.initSWFUpload = function (settings) { + try { + this.customSettings = {}; // A container where developers can place their own settings associated with this instance. + this.settings = settings; + this.eventQueue = []; + this.movieName = "KindEditor_SWFUpload_" + SWFUpload.movieCount++; + this.movieElement = null; + + + // Setup global control tracking + SWFUpload.instances[this.movieName] = this; + + // Load the settings. Load the Flash movie. + this.initSettings(); + this.loadFlash(); + this.displayDebugInfo(); + } catch (ex) { + delete SWFUpload.instances[this.movieName]; + throw ex; + } +}; + +/* *************** */ +/* Static Members */ +/* *************** */ +SWFUpload.instances = {}; +SWFUpload.movieCount = 0; +SWFUpload.version = "2.2.0 2009-03-25"; +SWFUpload.QUEUE_ERROR = { + QUEUE_LIMIT_EXCEEDED : -100, + FILE_EXCEEDS_SIZE_LIMIT : -110, + ZERO_BYTE_FILE : -120, + INVALID_FILETYPE : -130 +}; +SWFUpload.UPLOAD_ERROR = { + HTTP_ERROR : -200, + MISSING_UPLOAD_URL : -210, + IO_ERROR : -220, + SECURITY_ERROR : -230, + UPLOAD_LIMIT_EXCEEDED : -240, + UPLOAD_FAILED : -250, + SPECIFIED_FILE_ID_NOT_FOUND : -260, + FILE_VALIDATION_FAILED : -270, + FILE_CANCELLED : -280, + UPLOAD_STOPPED : -290 +}; +SWFUpload.FILE_STATUS = { + QUEUED : -1, + IN_PROGRESS : -2, + ERROR : -3, + COMPLETE : -4, + CANCELLED : -5 +}; +SWFUpload.BUTTON_ACTION = { + SELECT_FILE : -100, + SELECT_FILES : -110, + START_UPLOAD : -120 +}; +SWFUpload.CURSOR = { + ARROW : -1, + HAND : -2 +}; +SWFUpload.WINDOW_MODE = { + WINDOW : "window", + TRANSPARENT : "transparent", + OPAQUE : "opaque" +}; + +// Private: takes a URL, determines if it is relative and converts to an absolute URL +// using the current site. Only processes the URL if it can, otherwise returns the URL untouched +SWFUpload.completeURL = function(url) { + if (typeof(url) !== "string" || url.match(/^https?:\/\//i) || url.match(/^\//)) { + return url; + } + + var currentURL = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ":" + window.location.port : ""); + + var indexSlash = window.location.pathname.lastIndexOf("/"); + if (indexSlash <= 0) { + path = "/"; + } else { + path = window.location.pathname.substr(0, indexSlash) + "/"; + } + + return /*currentURL +*/ path + url; + +}; + + +/* ******************** */ +/* Instance Members */ +/* ******************** */ + +// Private: initSettings ensures that all the +// settings are set, getting a default value if one was not assigned. +SWFUpload.prototype.initSettings = function () { + this.ensureDefault = function (settingName, defaultValue) { + this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName]; + }; + + // Upload backend settings + this.ensureDefault("upload_url", ""); + this.ensureDefault("preserve_relative_urls", false); + this.ensureDefault("file_post_name", "Filedata"); + this.ensureDefault("post_params", {}); + this.ensureDefault("use_query_string", false); + this.ensureDefault("requeue_on_error", false); + this.ensureDefault("http_success", []); + this.ensureDefault("assume_success_timeout", 0); + + // File Settings + this.ensureDefault("file_types", "*.*"); + this.ensureDefault("file_types_description", "All Files"); + this.ensureDefault("file_size_limit", 0); // Default zero means "unlimited" + this.ensureDefault("file_upload_limit", 0); + this.ensureDefault("file_queue_limit", 0); + + // Flash Settings + this.ensureDefault("flash_url", "swfupload.swf"); + this.ensureDefault("prevent_swf_caching", true); + + // Button Settings + this.ensureDefault("button_image_url", ""); + this.ensureDefault("button_width", 1); + this.ensureDefault("button_height", 1); + this.ensureDefault("button_text", ""); + this.ensureDefault("button_text_style", "color: #000000; font-size: 16pt;"); + this.ensureDefault("button_text_top_padding", 0); + this.ensureDefault("button_text_left_padding", 0); + this.ensureDefault("button_action", SWFUpload.BUTTON_ACTION.SELECT_FILES); + this.ensureDefault("button_disabled", false); + this.ensureDefault("button_placeholder_id", ""); + this.ensureDefault("button_placeholder", null); + this.ensureDefault("button_cursor", SWFUpload.CURSOR.ARROW); + this.ensureDefault("button_window_mode", SWFUpload.WINDOW_MODE.WINDOW); + + // Debug Settings + this.ensureDefault("debug", false); + this.settings.debug_enabled = this.settings.debug; // Here to maintain v2 API + + // Event Handlers + this.settings.return_upload_start_handler = this.returnUploadStart; + this.ensureDefault("swfupload_loaded_handler", null); + this.ensureDefault("file_dialog_start_handler", null); + this.ensureDefault("file_queued_handler", null); + this.ensureDefault("file_queue_error_handler", null); + this.ensureDefault("file_dialog_complete_handler", null); + + this.ensureDefault("upload_start_handler", null); + this.ensureDefault("upload_progress_handler", null); + this.ensureDefault("upload_error_handler", null); + this.ensureDefault("upload_success_handler", null); + this.ensureDefault("upload_complete_handler", null); + + this.ensureDefault("debug_handler", this.debugMessage); + + this.ensureDefault("custom_settings", {}); + + // Other settings + this.customSettings = this.settings.custom_settings; + + // Update the flash url if needed + if (!!this.settings.prevent_swf_caching) { + this.settings.flash_url = this.settings.flash_url + (this.settings.flash_url.indexOf("?") < 0 ? "?" : "&") + "preventswfcaching=" + new Date().getTime(); + } + + if (!this.settings.preserve_relative_urls) { + //this.settings.flash_url = SWFUpload.completeURL(this.settings.flash_url); // Don't need to do this one since flash doesn't look at it + this.settings.upload_url = SWFUpload.completeURL(this.settings.upload_url); + this.settings.button_image_url = SWFUpload.completeURL(this.settings.button_image_url); + } + + delete this.ensureDefault; +}; + +// Private: loadFlash replaces the button_placeholder element with the flash movie. +SWFUpload.prototype.loadFlash = function () { + var targetElement, tempParent; + + // Make sure an element with the ID we are going to use doesn't already exist + if (document.getElementById(this.movieName) !== null) { + throw "ID " + this.movieName + " is already in use. The Flash Object could not be added"; + } + + // Get the element where we will be placing the flash movie + targetElement = document.getElementById(this.settings.button_placeholder_id) || this.settings.button_placeholder; + + if (targetElement == undefined) { + throw "Could not find the placeholder element: " + this.settings.button_placeholder_id; + } + + // Append the container and load the flash + tempParent = document.createElement("div"); + tempParent.innerHTML = this.getFlashHTML(); // Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers) + targetElement.parentNode.replaceChild(tempParent.firstChild, targetElement); + + // Fix IE Flash/Form bug + if (window[this.movieName] == undefined) { + window[this.movieName] = this.getMovieElement(); + } + +}; + +// Private: getFlashHTML generates the object tag needed to embed the flash in to the document +SWFUpload.prototype.getFlashHTML = function () { + // Flash Satay object syntax: http://www.alistapart.com/articles/flashsatay + // Fix bug for IE9 + // http://www.kindsoft.net/view.php?bbsid=7&postid=5825&pagenum=1 + var classid = ''; + if (KindEditor.IE && KindEditor.V > 8) { + classid = ' classid = "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"'; + } + return ['', + '', + '', + '', + '', + '', + '', + ''].join(""); +}; + +// Private: getFlashVars builds the parameter string that will be passed +// to flash in the flashvars param. +SWFUpload.prototype.getFlashVars = function () { + // Build a string from the post param object + var paramString = this.buildParamString(); + var httpSuccessString = this.settings.http_success.join(","); + + // Build the parameter string + return ["movieName=", encodeURIComponent(this.movieName), + "&uploadURL=", encodeURIComponent(this.settings.upload_url), + "&useQueryString=", encodeURIComponent(this.settings.use_query_string), + "&requeueOnError=", encodeURIComponent(this.settings.requeue_on_error), + "&httpSuccess=", encodeURIComponent(httpSuccessString), + "&assumeSuccessTimeout=", encodeURIComponent(this.settings.assume_success_timeout), + "&params=", encodeURIComponent(paramString), + "&filePostName=", encodeURIComponent(this.settings.file_post_name), + "&fileTypes=", encodeURIComponent(this.settings.file_types), + "&fileTypesDescription=", encodeURIComponent(this.settings.file_types_description), + "&fileSizeLimit=", encodeURIComponent(this.settings.file_size_limit), + "&fileUploadLimit=", encodeURIComponent(this.settings.file_upload_limit), + "&fileQueueLimit=", encodeURIComponent(this.settings.file_queue_limit), + "&debugEnabled=", encodeURIComponent(this.settings.debug_enabled), + "&buttonImageURL=", encodeURIComponent(this.settings.button_image_url), + "&buttonWidth=", encodeURIComponent(this.settings.button_width), + "&buttonHeight=", encodeURIComponent(this.settings.button_height), + "&buttonText=", encodeURIComponent(this.settings.button_text), + "&buttonTextTopPadding=", encodeURIComponent(this.settings.button_text_top_padding), + "&buttonTextLeftPadding=", encodeURIComponent(this.settings.button_text_left_padding), + "&buttonTextStyle=", encodeURIComponent(this.settings.button_text_style), + "&buttonAction=", encodeURIComponent(this.settings.button_action), + "&buttonDisabled=", encodeURIComponent(this.settings.button_disabled), + "&buttonCursor=", encodeURIComponent(this.settings.button_cursor) + ].join(""); +}; + +// Public: getMovieElement retrieves the DOM reference to the Flash element added by SWFUpload +// The element is cached after the first lookup +SWFUpload.prototype.getMovieElement = function () { + if (this.movieElement == undefined) { + this.movieElement = document.getElementById(this.movieName); + } + + if (this.movieElement === null) { + throw "Could not find Flash element"; + } + + return this.movieElement; +}; + +// Private: buildParamString takes the name/value pairs in the post_params setting object +// and joins them up in to a string formatted "name=value&name=value" +SWFUpload.prototype.buildParamString = function () { + var postParams = this.settings.post_params; + var paramStringPairs = []; + + if (typeof(postParams) === "object") { + for (var name in postParams) { + if (postParams.hasOwnProperty(name)) { + paramStringPairs.push(encodeURIComponent(name.toString()) + "=" + encodeURIComponent(postParams[name].toString())); + } + } + } + + return paramStringPairs.join("&"); +}; + +// Public: Used to remove a SWFUpload instance from the page. This method strives to remove +// all references to the SWF, and other objects so memory is properly freed. +// Returns true if everything was destroyed. Returns a false if a failure occurs leaving SWFUpload in an inconsistant state. +// Credits: Major improvements provided by steffen +SWFUpload.prototype.destroy = function () { + try { + // Make sure Flash is done before we try to remove it + this.cancelUpload(null, false); + + + // Remove the SWFUpload DOM nodes + var movieElement = null; + movieElement = this.getMovieElement(); + + if (movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE + // Loop through all the movie's properties and remove all function references (DOM/JS IE 6/7 memory leak workaround) + for (var i in movieElement) { + try { + if (typeof(movieElement[i]) === "function") { + movieElement[i] = null; + } + } catch (ex1) {} + } + + // Remove the Movie Element from the page + try { + movieElement.parentNode.removeChild(movieElement); + } catch (ex) {} + } + + // Remove IE form fix reference + window[this.movieName] = null; + + // Destroy other references + SWFUpload.instances[this.movieName] = null; + delete SWFUpload.instances[this.movieName]; + + this.movieElement = null; + this.settings = null; + this.customSettings = null; + this.eventQueue = null; + this.movieName = null; + + + return true; + } catch (ex2) { + return false; + } +}; + + +// Public: displayDebugInfo prints out settings and configuration +// information about this SWFUpload instance. +// This function (and any references to it) can be deleted when placing +// SWFUpload in production. +SWFUpload.prototype.displayDebugInfo = function () { + this.debug( + [ + "---SWFUpload Instance Info---\n", + "Version: ", SWFUpload.version, "\n", + "Movie Name: ", this.movieName, "\n", + "Settings:\n", + "\t", "upload_url: ", this.settings.upload_url, "\n", + "\t", "flash_url: ", this.settings.flash_url, "\n", + "\t", "use_query_string: ", this.settings.use_query_string.toString(), "\n", + "\t", "requeue_on_error: ", this.settings.requeue_on_error.toString(), "\n", + "\t", "http_success: ", this.settings.http_success.join(", "), "\n", + "\t", "assume_success_timeout: ", this.settings.assume_success_timeout, "\n", + "\t", "file_post_name: ", this.settings.file_post_name, "\n", + "\t", "post_params: ", this.settings.post_params.toString(), "\n", + "\t", "file_types: ", this.settings.file_types, "\n", + "\t", "file_types_description: ", this.settings.file_types_description, "\n", + "\t", "file_size_limit: ", this.settings.file_size_limit, "\n", + "\t", "file_upload_limit: ", this.settings.file_upload_limit, "\n", + "\t", "file_queue_limit: ", this.settings.file_queue_limit, "\n", + "\t", "debug: ", this.settings.debug.toString(), "\n", + + "\t", "prevent_swf_caching: ", this.settings.prevent_swf_caching.toString(), "\n", + + "\t", "button_placeholder_id: ", this.settings.button_placeholder_id.toString(), "\n", + "\t", "button_placeholder: ", (this.settings.button_placeholder ? "Set" : "Not Set"), "\n", + "\t", "button_image_url: ", this.settings.button_image_url.toString(), "\n", + "\t", "button_width: ", this.settings.button_width.toString(), "\n", + "\t", "button_height: ", this.settings.button_height.toString(), "\n", + "\t", "button_text: ", this.settings.button_text.toString(), "\n", + "\t", "button_text_style: ", this.settings.button_text_style.toString(), "\n", + "\t", "button_text_top_padding: ", this.settings.button_text_top_padding.toString(), "\n", + "\t", "button_text_left_padding: ", this.settings.button_text_left_padding.toString(), "\n", + "\t", "button_action: ", this.settings.button_action.toString(), "\n", + "\t", "button_disabled: ", this.settings.button_disabled.toString(), "\n", + + "\t", "custom_settings: ", this.settings.custom_settings.toString(), "\n", + "Event Handlers:\n", + "\t", "swfupload_loaded_handler assigned: ", (typeof this.settings.swfupload_loaded_handler === "function").toString(), "\n", + "\t", "file_dialog_start_handler assigned: ", (typeof this.settings.file_dialog_start_handler === "function").toString(), "\n", + "\t", "file_queued_handler assigned: ", (typeof this.settings.file_queued_handler === "function").toString(), "\n", + "\t", "file_queue_error_handler assigned: ", (typeof this.settings.file_queue_error_handler === "function").toString(), "\n", + "\t", "upload_start_handler assigned: ", (typeof this.settings.upload_start_handler === "function").toString(), "\n", + "\t", "upload_progress_handler assigned: ", (typeof this.settings.upload_progress_handler === "function").toString(), "\n", + "\t", "upload_error_handler assigned: ", (typeof this.settings.upload_error_handler === "function").toString(), "\n", + "\t", "upload_success_handler assigned: ", (typeof this.settings.upload_success_handler === "function").toString(), "\n", + "\t", "upload_complete_handler assigned: ", (typeof this.settings.upload_complete_handler === "function").toString(), "\n", + "\t", "debug_handler assigned: ", (typeof this.settings.debug_handler === "function").toString(), "\n" + ].join("") + ); +}; + +/* Note: addSetting and getSetting are no longer used by SWFUpload but are included + the maintain v2 API compatibility +*/ +// Public: (Deprecated) addSetting adds a setting value. If the value given is undefined or null then the default_value is used. +SWFUpload.prototype.addSetting = function (name, value, default_value) { + if (value == undefined) { + return (this.settings[name] = default_value); + } else { + return (this.settings[name] = value); + } +}; + +// Public: (Deprecated) getSetting gets a setting. Returns an empty string if the setting was not found. +SWFUpload.prototype.getSetting = function (name) { + if (this.settings[name] != undefined) { + return this.settings[name]; + } + + return ""; +}; + + + +// Private: callFlash handles function calls made to the Flash element. +// Calls are made with a setTimeout for some functions to work around +// bugs in the ExternalInterface library. +SWFUpload.prototype.callFlash = function (functionName, argumentArray) { + argumentArray = argumentArray || []; + + var movieElement = this.getMovieElement(); + var returnValue, returnString; + + // Flash's method if calling ExternalInterface methods (code adapted from MooTools). + try { + returnString = movieElement.CallFunction('' + __flash__argumentsToXML(argumentArray, 0) + ''); + returnValue = eval(returnString); + } catch (ex) { + throw "Call to " + functionName + " failed"; + } + + // Unescape file post param values + if (returnValue != undefined && typeof returnValue.post === "object") { + returnValue = this.unescapeFilePostParams(returnValue); + } + + return returnValue; +}; + +/* ***************************** + -- Flash control methods -- + Your UI should use these + to operate SWFUpload + ***************************** */ + +// WARNING: this function does not work in Flash Player 10 +// Public: selectFile causes a File Selection Dialog window to appear. This +// dialog only allows 1 file to be selected. +SWFUpload.prototype.selectFile = function () { + this.callFlash("SelectFile"); +}; + +// WARNING: this function does not work in Flash Player 10 +// Public: selectFiles causes a File Selection Dialog window to appear/ This +// dialog allows the user to select any number of files +// Flash Bug Warning: Flash limits the number of selectable files based on the combined length of the file names. +// If the selection name length is too long the dialog will fail in an unpredictable manner. There is no work-around +// for this bug. +SWFUpload.prototype.selectFiles = function () { + this.callFlash("SelectFiles"); +}; + + +// Public: startUpload starts uploading the first file in the queue unless +// the optional parameter 'fileID' specifies the ID +SWFUpload.prototype.startUpload = function (fileID) { + this.callFlash("StartUpload", [fileID]); +}; + +// Public: cancelUpload cancels any queued file. The fileID parameter may be the file ID or index. +// If you do not specify a fileID the current uploading file or first file in the queue is cancelled. +// If you do not want the uploadError event to trigger you can specify false for the triggerErrorEvent parameter. +SWFUpload.prototype.cancelUpload = function (fileID, triggerErrorEvent) { + if (triggerErrorEvent !== false) { + triggerErrorEvent = true; + } + this.callFlash("CancelUpload", [fileID, triggerErrorEvent]); +}; + +// Public: stopUpload stops the current upload and requeues the file at the beginning of the queue. +// If nothing is currently uploading then nothing happens. +SWFUpload.prototype.stopUpload = function () { + this.callFlash("StopUpload"); +}; + +/* ************************ + * Settings methods + * These methods change the SWFUpload settings. + * SWFUpload settings should not be changed directly on the settings object + * since many of the settings need to be passed to Flash in order to take + * effect. + * *********************** */ + +// Public: getStats gets the file statistics object. +SWFUpload.prototype.getStats = function () { + return this.callFlash("GetStats"); +}; + +// Public: setStats changes the SWFUpload statistics. You shouldn't need to +// change the statistics but you can. Changing the statistics does not +// affect SWFUpload accept for the successful_uploads count which is used +// by the upload_limit setting to determine how many files the user may upload. +SWFUpload.prototype.setStats = function (statsObject) { + this.callFlash("SetStats", [statsObject]); +}; + +// Public: getFile retrieves a File object by ID or Index. If the file is +// not found then 'null' is returned. +SWFUpload.prototype.getFile = function (fileID) { + if (typeof(fileID) === "number") { + return this.callFlash("GetFileByIndex", [fileID]); + } else { + return this.callFlash("GetFile", [fileID]); + } +}; + +// Public: addFileParam sets a name/value pair that will be posted with the +// file specified by the Files ID. If the name already exists then the +// exiting value will be overwritten. +SWFUpload.prototype.addFileParam = function (fileID, name, value) { + return this.callFlash("AddFileParam", [fileID, name, value]); +}; + +// Public: removeFileParam removes a previously set (by addFileParam) name/value +// pair from the specified file. +SWFUpload.prototype.removeFileParam = function (fileID, name) { + this.callFlash("RemoveFileParam", [fileID, name]); +}; + +// Public: setUploadUrl changes the upload_url setting. +SWFUpload.prototype.setUploadURL = function (url) { + this.settings.upload_url = url.toString(); + this.callFlash("SetUploadURL", [url]); +}; + +// Public: setPostParams changes the post_params setting +SWFUpload.prototype.setPostParams = function (paramsObject) { + this.settings.post_params = paramsObject; + this.callFlash("SetPostParams", [paramsObject]); +}; + +// Public: addPostParam adds post name/value pair. Each name can have only one value. +SWFUpload.prototype.addPostParam = function (name, value) { + this.settings.post_params[name] = value; + this.callFlash("SetPostParams", [this.settings.post_params]); +}; + +// Public: removePostParam deletes post name/value pair. +SWFUpload.prototype.removePostParam = function (name) { + delete this.settings.post_params[name]; + this.callFlash("SetPostParams", [this.settings.post_params]); +}; + +// Public: setFileTypes changes the file_types setting and the file_types_description setting +SWFUpload.prototype.setFileTypes = function (types, description) { + this.settings.file_types = types; + this.settings.file_types_description = description; + this.callFlash("SetFileTypes", [types, description]); +}; + +// Public: setFileSizeLimit changes the file_size_limit setting +SWFUpload.prototype.setFileSizeLimit = function (fileSizeLimit) { + this.settings.file_size_limit = fileSizeLimit; + this.callFlash("SetFileSizeLimit", [fileSizeLimit]); +}; + +// Public: setFileUploadLimit changes the file_upload_limit setting +SWFUpload.prototype.setFileUploadLimit = function (fileUploadLimit) { + this.settings.file_upload_limit = fileUploadLimit; + this.callFlash("SetFileUploadLimit", [fileUploadLimit]); +}; + +// Public: setFileQueueLimit changes the file_queue_limit setting +SWFUpload.prototype.setFileQueueLimit = function (fileQueueLimit) { + this.settings.file_queue_limit = fileQueueLimit; + this.callFlash("SetFileQueueLimit", [fileQueueLimit]); +}; + +// Public: setFilePostName changes the file_post_name setting +SWFUpload.prototype.setFilePostName = function (filePostName) { + this.settings.file_post_name = filePostName; + this.callFlash("SetFilePostName", [filePostName]); +}; + +// Public: setUseQueryString changes the use_query_string setting +SWFUpload.prototype.setUseQueryString = function (useQueryString) { + this.settings.use_query_string = useQueryString; + this.callFlash("SetUseQueryString", [useQueryString]); +}; + +// Public: setRequeueOnError changes the requeue_on_error setting +SWFUpload.prototype.setRequeueOnError = function (requeueOnError) { + this.settings.requeue_on_error = requeueOnError; + this.callFlash("SetRequeueOnError", [requeueOnError]); +}; + +// Public: setHTTPSuccess changes the http_success setting +SWFUpload.prototype.setHTTPSuccess = function (http_status_codes) { + if (typeof http_status_codes === "string") { + http_status_codes = http_status_codes.replace(" ", "").split(","); + } + + this.settings.http_success = http_status_codes; + this.callFlash("SetHTTPSuccess", [http_status_codes]); +}; + +// Public: setHTTPSuccess changes the http_success setting +SWFUpload.prototype.setAssumeSuccessTimeout = function (timeout_seconds) { + this.settings.assume_success_timeout = timeout_seconds; + this.callFlash("SetAssumeSuccessTimeout", [timeout_seconds]); +}; + +// Public: setDebugEnabled changes the debug_enabled setting +SWFUpload.prototype.setDebugEnabled = function (debugEnabled) { + this.settings.debug_enabled = debugEnabled; + this.callFlash("SetDebugEnabled", [debugEnabled]); +}; + +// Public: setButtonImageURL loads a button image sprite +SWFUpload.prototype.setButtonImageURL = function (buttonImageURL) { + if (buttonImageURL == undefined) { + buttonImageURL = ""; + } + + this.settings.button_image_url = buttonImageURL; + this.callFlash("SetButtonImageURL", [buttonImageURL]); +}; + +// Public: setButtonDimensions resizes the Flash Movie and button +SWFUpload.prototype.setButtonDimensions = function (width, height) { + this.settings.button_width = width; + this.settings.button_height = height; + + var movie = this.getMovieElement(); + if (movie != undefined) { + movie.style.width = width + "px"; + movie.style.height = height + "px"; + } + + this.callFlash("SetButtonDimensions", [width, height]); +}; +// Public: setButtonText Changes the text overlaid on the button +SWFUpload.prototype.setButtonText = function (html) { + this.settings.button_text = html; + this.callFlash("SetButtonText", [html]); +}; +// Public: setButtonTextPadding changes the top and left padding of the text overlay +SWFUpload.prototype.setButtonTextPadding = function (left, top) { + this.settings.button_text_top_padding = top; + this.settings.button_text_left_padding = left; + this.callFlash("SetButtonTextPadding", [left, top]); +}; + +// Public: setButtonTextStyle changes the CSS used to style the HTML/Text overlaid on the button +SWFUpload.prototype.setButtonTextStyle = function (css) { + this.settings.button_text_style = css; + this.callFlash("SetButtonTextStyle", [css]); +}; +// Public: setButtonDisabled disables/enables the button +SWFUpload.prototype.setButtonDisabled = function (isDisabled) { + this.settings.button_disabled = isDisabled; + this.callFlash("SetButtonDisabled", [isDisabled]); +}; +// Public: setButtonAction sets the action that occurs when the button is clicked +SWFUpload.prototype.setButtonAction = function (buttonAction) { + this.settings.button_action = buttonAction; + this.callFlash("SetButtonAction", [buttonAction]); +}; + +// Public: setButtonCursor changes the mouse cursor displayed when hovering over the button +SWFUpload.prototype.setButtonCursor = function (cursor) { + this.settings.button_cursor = cursor; + this.callFlash("SetButtonCursor", [cursor]); +}; + +/* ******************************* + Flash Event Interfaces + These functions are used by Flash to trigger the various + events. + + All these functions a Private. + + Because the ExternalInterface library is buggy the event calls + are added to a queue and the queue then executed by a setTimeout. + This ensures that events are executed in a determinate order and that + the ExternalInterface bugs are avoided. +******************************* */ + +SWFUpload.prototype.queueEvent = function (handlerName, argumentArray) { + // Warning: Don't call this.debug inside here or you'll create an infinite loop + + if (argumentArray == undefined) { + argumentArray = []; + } else if (!(argumentArray instanceof Array)) { + argumentArray = [argumentArray]; + } + + var self = this; + if (typeof this.settings[handlerName] === "function") { + // Queue the event + this.eventQueue.push(function () { + this.settings[handlerName].apply(this, argumentArray); + }); + + // Execute the next queued event + setTimeout(function () { + self.executeNextEvent(); + }, 0); + + } else if (this.settings[handlerName] !== null) { + throw "Event handler " + handlerName + " is unknown or is not a function"; + } +}; + +// Private: Causes the next event in the queue to be executed. Since events are queued using a setTimeout +// we must queue them in order to garentee that they are executed in order. +SWFUpload.prototype.executeNextEvent = function () { + // Warning: Don't call this.debug inside here or you'll create an infinite loop + + var f = this.eventQueue ? this.eventQueue.shift() : null; + if (typeof(f) === "function") { + f.apply(this); + } +}; + +// Private: unescapeFileParams is part of a workaround for a flash bug where objects passed through ExternalInterface cannot have +// properties that contain characters that are not valid for JavaScript identifiers. To work around this +// the Flash Component escapes the parameter names and we must unescape again before passing them along. +SWFUpload.prototype.unescapeFilePostParams = function (file) { + var reg = /[$]([0-9a-f]{4})/i; + var unescapedPost = {}; + var uk; + + if (file != undefined) { + for (var k in file.post) { + if (file.post.hasOwnProperty(k)) { + uk = k; + var match; + while ((match = reg.exec(uk)) !== null) { + uk = uk.replace(match[0], String.fromCharCode(parseInt("0x" + match[1], 16))); + } + unescapedPost[uk] = file.post[k]; + } + } + + file.post = unescapedPost; + } + + return file; +}; + +// Private: Called by Flash to see if JS can call in to Flash (test if External Interface is working) +SWFUpload.prototype.testExternalInterface = function () { + try { + return this.callFlash("TestExternalInterface"); + } catch (ex) { + return false; + } +}; + +// Private: This event is called by Flash when it has finished loading. Don't modify this. +// Use the swfupload_loaded_handler event setting to execute custom code when SWFUpload has loaded. +SWFUpload.prototype.flashReady = function () { + // Check that the movie element is loaded correctly with its ExternalInterface methods defined + var movieElement = this.getMovieElement(); + + if (!movieElement) { + this.debug("Flash called back ready but the flash movie can't be found."); + return; + } + + this.cleanUp(movieElement); + + this.queueEvent("swfupload_loaded_handler"); +}; + +// Private: removes Flash added fuctions to the DOM node to prevent memory leaks in IE. +// This function is called by Flash each time the ExternalInterface functions are created. +SWFUpload.prototype.cleanUp = function (movieElement) { + // Pro-actively unhook all the Flash functions + try { + if (this.movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE + this.debug("Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)"); + for (var key in movieElement) { + try { + if (typeof(movieElement[key]) === "function") { + movieElement[key] = null; + } + } catch (ex) { + } + } + } + } catch (ex1) { + + } + + // Fix Flashes own cleanup code so if the SWFMovie was removed from the page + // it doesn't display errors. + window["__flash__removeCallback"] = function (instance, name) { + try { + if (instance) { + instance[name] = null; + } + } catch (flashEx) { + + } + }; + +}; + + +/* This is a chance to do something before the browse window opens */ +SWFUpload.prototype.fileDialogStart = function () { + this.queueEvent("file_dialog_start_handler"); +}; + + +/* Called when a file is successfully added to the queue. */ +SWFUpload.prototype.fileQueued = function (file) { + file = this.unescapeFilePostParams(file); + this.queueEvent("file_queued_handler", file); +}; + + +/* Handle errors that occur when an attempt to queue a file fails. */ +SWFUpload.prototype.fileQueueError = function (file, errorCode, message) { + file = this.unescapeFilePostParams(file); + this.queueEvent("file_queue_error_handler", [file, errorCode, message]); +}; + +/* Called after the file dialog has closed and the selected files have been queued. + You could call startUpload here if you want the queued files to begin uploading immediately. */ +SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued, numFilesInQueue) { + this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued, numFilesInQueue]); +}; + +SWFUpload.prototype.uploadStart = function (file) { + file = this.unescapeFilePostParams(file); + this.queueEvent("return_upload_start_handler", file); +}; + +SWFUpload.prototype.returnUploadStart = function (file) { + var returnValue; + if (typeof this.settings.upload_start_handler === "function") { + file = this.unescapeFilePostParams(file); + returnValue = this.settings.upload_start_handler.call(this, file); + } else if (this.settings.upload_start_handler != undefined) { + throw "upload_start_handler must be a function"; + } + + // Convert undefined to true so if nothing is returned from the upload_start_handler it is + // interpretted as 'true'. + if (returnValue === undefined) { + returnValue = true; + } + + returnValue = !!returnValue; + + this.callFlash("ReturnUploadStart", [returnValue]); +}; + + + +SWFUpload.prototype.uploadProgress = function (file, bytesComplete, bytesTotal) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_progress_handler", [file, bytesComplete, bytesTotal]); +}; + +SWFUpload.prototype.uploadError = function (file, errorCode, message) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_error_handler", [file, errorCode, message]); +}; + +SWFUpload.prototype.uploadSuccess = function (file, serverData, responseReceived) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_success_handler", [file, serverData, responseReceived]); +}; + +SWFUpload.prototype.uploadComplete = function (file) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_complete_handler", file); +}; + +/* Called by SWFUpload JavaScript and Flash functions when debug is enabled. By default it writes messages to the + internal debug console. You can override this event and have messages written where you want. */ +SWFUpload.prototype.debug = function (message) { + this.queueEvent("debug_handler", message); +}; + + +/* ********************************** + Debug Console + The debug console is a self contained, in page location + for debug message to be sent. The Debug Console adds + itself to the body if necessary. + + The console is automatically scrolled as messages appear. + + If you are using your own debug handler or when you deploy to production and + have debug disabled you can remove these functions to reduce the file size + and complexity. +********************************** */ + +// Private: debugMessage is the default debug_handler. If you want to print debug messages +// call the debug() function. When overriding the function your own function should +// check to see if the debug setting is true before outputting debug information. +SWFUpload.prototype.debugMessage = function (message) { + if (this.settings.debug) { + var exceptionMessage, exceptionValues = []; + + // Check for an exception object and print it nicely + if (typeof message === "object" && typeof message.name === "string" && typeof message.message === "string") { + for (var key in message) { + if (message.hasOwnProperty(key)) { + exceptionValues.push(key + ": " + message[key]); + } + } + exceptionMessage = exceptionValues.join("\n") || ""; + exceptionValues = exceptionMessage.split("\n"); + exceptionMessage = "EXCEPTION: " + exceptionValues.join("\nEXCEPTION: "); + SWFUpload.Console.writeLine(exceptionMessage); + } else { + SWFUpload.Console.writeLine(message); + } + } +}; + +SWFUpload.Console = {}; +SWFUpload.Console.writeLine = function (message) { + var console, documentForm; + + try { + console = document.getElementById("SWFUpload_Console"); + + if (!console) { + documentForm = document.createElement("form"); + document.getElementsByTagName("body")[0].appendChild(documentForm); + + console = document.createElement("textarea"); + console.id = "SWFUpload_Console"; + console.style.fontFamily = "monospace"; + console.setAttribute("wrap", "off"); + console.wrap = "off"; + console.style.overflow = "auto"; + console.style.width = "700px"; + console.style.height = "350px"; + console.style.margin = "5px"; + documentForm.appendChild(console); + } + + console.value += message + "\n"; + + console.scrollTop = console.scrollHeight - console.clientHeight; + } catch (ex) { + alert("Exception: " + ex.name + " Message: " + ex.message); + } +}; + +})(); + +(function() { +/* + Queue Plug-in + + Features: + *Adds a cancelQueue() method for cancelling the entire queue. + *All queued files are uploaded when startUpload() is called. + *If false is returned from uploadComplete then the queue upload is stopped. + If false is not returned (strict comparison) then the queue upload is continued. + *Adds a QueueComplete event that is fired when all the queued files have finished uploading. + Set the event handler with the queue_complete_handler setting. + + */ + +if (typeof(SWFUpload) === "function") { + SWFUpload.queue = {}; + + SWFUpload.prototype.initSettings = (function (oldInitSettings) { + return function () { + if (typeof(oldInitSettings) === "function") { + oldInitSettings.call(this); + } + + this.queueSettings = {}; + + this.queueSettings.queue_cancelled_flag = false; + this.queueSettings.queue_upload_count = 0; + + this.queueSettings.user_upload_complete_handler = this.settings.upload_complete_handler; + this.queueSettings.user_upload_start_handler = this.settings.upload_start_handler; + this.settings.upload_complete_handler = SWFUpload.queue.uploadCompleteHandler; + this.settings.upload_start_handler = SWFUpload.queue.uploadStartHandler; + + this.settings.queue_complete_handler = this.settings.queue_complete_handler || null; + }; + })(SWFUpload.prototype.initSettings); + + SWFUpload.prototype.startUpload = function (fileID) { + this.queueSettings.queue_cancelled_flag = false; + this.callFlash("StartUpload", [fileID]); + }; + + SWFUpload.prototype.cancelQueue = function () { + this.queueSettings.queue_cancelled_flag = true; + this.stopUpload(); + + var stats = this.getStats(); + while (stats.files_queued > 0) { + this.cancelUpload(); + stats = this.getStats(); + } + }; + + SWFUpload.queue.uploadStartHandler = function (file) { + var returnValue; + if (typeof(this.queueSettings.user_upload_start_handler) === "function") { + returnValue = this.queueSettings.user_upload_start_handler.call(this, file); + } + + // To prevent upload a real "FALSE" value must be returned, otherwise default to a real "TRUE" value. + returnValue = (returnValue === false) ? false : true; + + this.queueSettings.queue_cancelled_flag = !returnValue; + + return returnValue; + }; + + SWFUpload.queue.uploadCompleteHandler = function (file) { + var user_upload_complete_handler = this.queueSettings.user_upload_complete_handler; + var continueUpload; + + if (file.filestatus === SWFUpload.FILE_STATUS.COMPLETE) { + this.queueSettings.queue_upload_count++; + } + + if (typeof(user_upload_complete_handler) === "function") { + continueUpload = (user_upload_complete_handler.call(this, file) === false) ? false : true; + } else if (file.filestatus === SWFUpload.FILE_STATUS.QUEUED) { + // If the file was stopped and re-queued don't restart the upload + continueUpload = false; + } else { + continueUpload = true; + } + + if (continueUpload) { + var stats = this.getStats(); + if (stats.files_queued > 0 && this.queueSettings.queue_cancelled_flag === false) { + this.startUpload(); + } else if (this.queueSettings.queue_cancelled_flag === false) { + this.queueEvent("queue_complete_handler", [this.queueSettings.queue_upload_count]); + this.queueSettings.queue_upload_count = 0; + } else { + this.queueSettings.queue_cancelled_flag = false; + this.queueSettings.queue_upload_count = 0; + } + } + }; +} + +})(); diff --git a/php/kindeditor_demo/kindeditor/plugins/pagebreak/pagebreak.js b/php/kindeditor_demo/kindeditor/plugins/pagebreak/pagebreak.js new file mode 100755 index 0000000..3898e32 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/plugins/pagebreak/pagebreak.js @@ -0,0 +1,27 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('pagebreak', function(K) { + var self = this; + var name = 'pagebreak'; + var pagebreakHtml = K.undef(self.pagebreakHtml, '
        '); + + self.clickToolbar(name, function() { + var cmd = self.cmd, range = cmd.range; + self.focus(); + var tail = self.newlineTag == 'br' || K.WEBKIT ? '' : ''; + self.insertHtml(pagebreakHtml + tail); + if (tail !== '') { + var p = K('#__kindeditor_tail_tag__', self.edit.doc); + range.selectNodeContents(p[0]); + p.removeAttr('id'); + cmd.select(); + } + }); +}); diff --git a/php/kindeditor_demo/kindeditor/plugins/plainpaste/plainpaste.js b/php/kindeditor_demo/kindeditor/plugins/plainpaste/plainpaste.js new file mode 100755 index 0000000..1faec86 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/plugins/plainpaste/plainpaste.js @@ -0,0 +1,41 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('plainpaste', function(K) { + var self = this, name = 'plainpaste'; + self.clickToolbar(name, function() { + var lang = self.lang(name + '.'), + html = '
        ' + + '
        ' + lang.comment + '
        ' + + '' + + '
        ', + dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var html = textarea.val(); + html = K.escape(html); + html = html.replace(/ {2}/g, '  '); + if (self.newlineTag == 'p') { + html = html.replace(/^/, '

        ').replace(/$/, '

        ').replace(/\n/g, '

        '); + } else { + html = html.replace(/\n/g, '
        $&'); + } + self.insertHtml(html).hideDialog().focus(); + } + } + }), + textarea = K('textarea', dialog.div); + textarea[0].focus(); + }); +}); diff --git a/php/kindeditor_demo/kindeditor/plugins/preview/preview.js b/php/kindeditor_demo/kindeditor/plugins/preview/preview.js new file mode 100755 index 0000000..3bbb7b5 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/plugins/preview/preview.js @@ -0,0 +1,31 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('preview', function(K) { + var self = this, name = 'preview', undefined; + self.clickToolbar(name, function() { + var lang = self.lang(name + '.'), + html = '

        ' + + '' + + '
        ', + dialog = self.createDialog({ + name : name, + width : 750, + title : self.lang(name), + body : html + }), + iframe = K('iframe', dialog.div), + doc = K.iframeDoc(iframe); + doc.open(); + doc.write(self.fullHtml()); + doc.close(); + K(doc.body).css('background-color', '#FFF'); + iframe[0].contentWindow.focus(); + }); +}); diff --git a/php/kindeditor_demo/kindeditor/plugins/quickformat/quickformat.js b/php/kindeditor_demo/kindeditor/plugins/quickformat/quickformat.js new file mode 100755 index 0000000..a7af1e5 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/plugins/quickformat/quickformat.js @@ -0,0 +1,81 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('quickformat', function(K) { + var self = this, name = 'quickformat', + blockMap = K.toMap('blockquote,center,div,h1,h2,h3,h4,h5,h6,p'); + function getFirstChild(knode) { + var child = knode.first(); + while (child && child.first()) { + child = child.first(); + } + return child; + } + self.clickToolbar(name, function() { + self.focus(); + var doc = self.edit.doc, + range = self.cmd.range, + child = K(doc.body).first(), next, + nodeList = [], subList = [], + bookmark = range.createBookmark(true); + while(child) { + next = child.next(); + var firstChild = getFirstChild(child); + if (!firstChild || firstChild.name != 'img') { + if (blockMap[child.name]) { + child.html(child.html().replace(/^(\s| | )+/ig, '')); + child.css('text-indent', '2em'); + } else { + subList.push(child); + } + if (!next || (blockMap[next.name] || blockMap[child.name] && !blockMap[next.name])) { + if (subList.length > 0) { + nodeList.push(subList); + } + subList = []; + } + } + child = next; + } + K.each(nodeList, function(i, subList) { + var wrapper = K('

        ', doc); + subList[0].before(wrapper); + K.each(subList, function(i, knode) { + wrapper.append(knode); + }); + }); + range.moveToBookmark(bookmark); + self.addBookmark(); + }); +}); + +/** +-------------------------- +abcd
        +1234
        + +to + +

        + abcd
        + 1234
        +

        + +-------------------------- + +  abcd1233 +

        1234

        + +to + +

        abcd1233

        +

        1234

        + +-------------------------- +*/ \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/plugins/table/table.js b/php/kindeditor_demo/kindeditor/plugins/table/table.js new file mode 100755 index 0000000..d3f1232 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/plugins/table/table.js @@ -0,0 +1,712 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('table', function(K) { + var self = this, name = 'table', lang = self.lang(name + '.'), zeroborder = 'ke-zeroborder'; + // 设置颜色 + function _setColor(box, color) { + color = color.toUpperCase(); + box.css('background-color', color); + box.css('color', color === '#000000' ? '#FFFFFF' : '#000000'); + box.html(color); + } + // 初始化取色器 + var pickerList = []; + function _initColorPicker(dialogDiv, colorBox) { + colorBox.bind('click,mousedown', function(e){ + e.stopPropagation(); + }); + function removePicker() { + K.each(pickerList, function() { + this.remove(); + }); + pickerList = []; + K(document).unbind('click,mousedown', removePicker); + dialogDiv.unbind('click,mousedown', removePicker); + } + colorBox.click(function(e) { + removePicker(); + var box = K(this), + pos = box.pos(); + var picker = K.colorpicker({ + x : pos.x, + y : pos.y + box.height(), + z : 811214, + selectedColor : K(this).html(), + colors : self.colorTable, + noColor : self.lang('noColor'), + shadowMode : self.shadowMode, + click : function(color) { + _setColor(box, color); + removePicker(); + } + }); + pickerList.push(picker); + K(document).bind('click,mousedown', removePicker); + dialogDiv.bind('click,mousedown', removePicker); + }); + } + // 取得下一行cell的index + function _getCellIndex(table, row, cell) { + var rowSpanCount = 0; + for (var i = 0, len = row.cells.length; i < len; i++) { + if (row.cells[i] == cell) { + break; + } + rowSpanCount += row.cells[i].rowSpan - 1; + } + return cell.cellIndex - rowSpanCount; + } + self.plugin.table = { + //insert or modify table + prop : function(isInsert) { + var html = [ + '
        ', + //rows, cols + '
        ', + '', + lang.rows + '   ', + lang.cols + ' ', + '
        ', + //width, height + '
        ', + '', + lang.width + '   ', + '   ', + lang.height + '   ', + '', + '
        ', + //space, padding + '
        ', + '', + lang.padding + '   ', + lang.spacing + ' ', + '
        ', + //align + '
        ', + '', + '', + '
        ', + //border + '
        ', + '', + lang.borderWidth + '   ', + lang.borderColor + ' ', + '
        ', + //background color + '
        ', + '', + '', + '
        ', + '
        ' + ].join(''); + var bookmark = self.cmd.range.createBookmark(); + var dialog = self.createDialog({ + name : name, + width : 500, + title : self.lang(name), + body : html, + beforeRemove : function() { + colorBox.unbind(); + }, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var rows = rowsBox.val(), + cols = colsBox.val(), + width = widthBox.val(), + height = heightBox.val(), + widthType = widthTypeBox.val(), + heightType = heightTypeBox.val(), + padding = paddingBox.val(), + spacing = spacingBox.val(), + align = alignBox.val(), + border = borderBox.val(), + borderColor = K(colorBox[0]).html() || '', + bgColor = K(colorBox[1]).html() || ''; + if (rows == 0 || !/^\d+$/.test(rows)) { + alert(self.lang('invalidRows')); + rowsBox[0].focus(); + return; + } + if (cols == 0 || !/^\d+$/.test(cols)) { + alert(self.lang('invalidRows')); + colsBox[0].focus(); + return; + } + if (!/^\d*$/.test(width)) { + alert(self.lang('invalidWidth')); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + alert(self.lang('invalidHeight')); + heightBox[0].focus(); + return; + } + if (!/^\d*$/.test(padding)) { + alert(self.lang('invalidPadding')); + paddingBox[0].focus(); + return; + } + if (!/^\d*$/.test(spacing)) { + alert(self.lang('invalidSpacing')); + spacingBox[0].focus(); + return; + } + if (!/^\d*$/.test(border)) { + alert(self.lang('invalidBorder')); + borderBox[0].focus(); + return; + } + //modify table + if (table) { + if (width !== '') { + table.width(width + widthType); + } else { + table.css('width', ''); + } + if (table[0].width !== undefined) { + table.removeAttr('width'); + } + if (height !== '') { + table.height(height + heightType); + } else { + table.css('height', ''); + } + if (table[0].height !== undefined) { + table.removeAttr('height'); + } + table.css('background-color', bgColor); + if (table[0].bgColor !== undefined) { + table.removeAttr('bgColor'); + } + if (padding !== '') { + table[0].cellPadding = padding; + } else { + table.removeAttr('cellPadding'); + } + if (spacing !== '') { + table[0].cellSpacing = spacing; + } else { + table.removeAttr('cellSpacing'); + } + if (align !== '') { + table[0].align = align; + } else { + table.removeAttr('align'); + } + if (border !== '') { + table.attr('border', border); + } else { + table.removeAttr('border'); + } + if (border === '' || border === '0') { + table.addClass(zeroborder); + } else { + table.removeClass(zeroborder); + } + if (borderColor !== '') { + table.attr('borderColor', borderColor); + } else { + table.removeAttr('borderColor'); + } + self.hideDialog().focus(); + self.cmd.range.moveToBookmark(bookmark); + self.cmd.select(); + self.addBookmark(); + return; + } + //insert new table + var style = ''; + if (width !== '') { + style += 'width:' + width + widthType + ';'; + } + if (height !== '') { + style += 'height:' + height + heightType + ';'; + } + if (bgColor !== '') { + style += 'background-color:' + bgColor + ';'; + } + var html = '') + ''; + } + html += ''; + } + html += ''; + if (!K.IE) { + html += '
        '; + } + self.insertHtml(html); + self.select().hideDialog().focus(); + self.addBookmark(); + } + } + }), + div = dialog.div, + rowsBox = K('[name="rows"]', div).val(3), + colsBox = K('[name="cols"]', div).val(2), + widthBox = K('[name="width"]', div).val(100), + heightBox = K('[name="height"]', div), + widthTypeBox = K('[name="widthType"]', div), + heightTypeBox = K('[name="heightType"]', div), + paddingBox = K('[name="padding"]', div).val(2), + spacingBox = K('[name="spacing"]', div).val(0), + alignBox = K('[name="align"]', div), + borderBox = K('[name="border"]', div).val(1), + colorBox = K('.ke-input-color', div); + _initColorPicker(div, colorBox.eq(0)); + _initColorPicker(div, colorBox.eq(1)); + _setColor(colorBox.eq(0), '#000000'); + _setColor(colorBox.eq(1), ''); + // foucs and select + rowsBox[0].focus(); + rowsBox[0].select(); + var table; + if (isInsert) { + return; + } + //get selected table node + table = self.plugin.getSelectedTable(); + if (table) { + rowsBox.val(table[0].rows.length); + colsBox.val(table[0].rows.length > 0 ? table[0].rows[0].cells.length : 0); + rowsBox.attr('disabled', true); + colsBox.attr('disabled', true); + var match, + tableWidth = table[0].style.width || table[0].width, + tableHeight = table[0].style.height || table[0].height; + if (tableWidth !== undefined && (match = /^(\d+)((?:px|%)*)$/.exec(tableWidth))) { + widthBox.val(match[1]); + widthTypeBox.val(match[2]); + } else { + widthBox.val(''); + } + if (tableHeight !== undefined && (match = /^(\d+)((?:px|%)*)$/.exec(tableHeight))) { + heightBox.val(match[1]); + heightTypeBox.val(match[2]); + } + paddingBox.val(table[0].cellPadding || ''); + spacingBox.val(table[0].cellSpacing || ''); + alignBox.val(table[0].align || ''); + borderBox.val(table[0].border === undefined ? '' : table[0].border); + _setColor(colorBox.eq(0), K.toHex(table.attr('borderColor') || '')); + _setColor(colorBox.eq(1), K.toHex(table[0].style.backgroundColor || table[0].bgColor || '')); + widthBox[0].focus(); + widthBox[0].select(); + } + }, + //modify cell + cellprop : function() { + var html = [ + '
        ', + //width, height + '
        ', + '', + lang.width + '   ', + '   ', + lang.height + '   ', + '', + '
        ', + //align + '
        ', + '', + lang.textAlign + ' ', + lang.verticalAlign + ' ', + '
        ', + //border + '
        ', + '', + lang.borderWidth + '   ', + lang.borderColor + ' ', + '
        ', + //background color + '
        ', + '', + '', + '
        ', + '
        ' + ].join(''); + var bookmark = self.cmd.range.createBookmark(); + var dialog = self.createDialog({ + name : name, + width : 500, + title : self.lang('tablecell'), + body : html, + beforeRemove : function() { + colorBox.unbind(); + }, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var width = widthBox.val(), + height = heightBox.val(), + widthType = widthTypeBox.val(), + heightType = heightTypeBox.val(), + padding = paddingBox.val(), + spacing = spacingBox.val(), + textAlign = textAlignBox.val(), + verticalAlign = verticalAlignBox.val(), + border = borderBox.val(), + borderColor = K(colorBox[0]).html() || '', + bgColor = K(colorBox[1]).html() || ''; + if (!/^\d*$/.test(width)) { + alert(self.lang('invalidWidth')); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + alert(self.lang('invalidHeight')); + heightBox[0].focus(); + return; + } + if (!/^\d*$/.test(border)) { + alert(self.lang('invalidBorder')); + borderBox[0].focus(); + return; + } + cell.css({ + width : width !== '' ? (width + widthType) : '', + height : height !== '' ? (height + heightType) : '', + 'background-color' : bgColor, + 'text-align' : textAlign, + 'vertical-align' : verticalAlign, + 'border-width' : border, + 'border-style' : border !== '' ? 'solid' : '', + 'border-color' : borderColor + }); + self.hideDialog().focus(); + self.cmd.range.moveToBookmark(bookmark); + self.cmd.select(); + self.addBookmark(); + } + } + }), + div = dialog.div, + widthBox = K('[name="width"]', div).val(100), + heightBox = K('[name="height"]', div), + widthTypeBox = K('[name="widthType"]', div), + heightTypeBox = K('[name="heightType"]', div), + paddingBox = K('[name="padding"]', div).val(2), + spacingBox = K('[name="spacing"]', div).val(0), + textAlignBox = K('[name="textAlign"]', div), + verticalAlignBox = K('[name="verticalAlign"]', div), + borderBox = K('[name="border"]', div).val(1), + colorBox = K('.ke-input-color', div); + _initColorPicker(div, colorBox.eq(0)); + _initColorPicker(div, colorBox.eq(1)); + _setColor(colorBox.eq(0), '#000000'); + _setColor(colorBox.eq(1), ''); + // foucs and select + widthBox[0].focus(); + widthBox[0].select(); + // get selected cell + var cell = self.plugin.getSelectedCell(); + var match, + cellWidth = cell[0].style.width || cell[0].width || '', + cellHeight = cell[0].style.height || cell[0].height || ''; + if ((match = /^(\d+)((?:px|%)*)$/.exec(cellWidth))) { + widthBox.val(match[1]); + widthTypeBox.val(match[2]); + } else { + widthBox.val(''); + } + if ((match = /^(\d+)((?:px|%)*)$/.exec(cellHeight))) { + heightBox.val(match[1]); + heightTypeBox.val(match[2]); + } + textAlignBox.val(cell[0].style.textAlign || ''); + verticalAlignBox.val(cell[0].style.verticalAlign || ''); + var border = cell[0].style.borderWidth || ''; + if (border) { + border = parseInt(border); + } + borderBox.val(border); + _setColor(colorBox.eq(0), K.toHex(cell[0].style.borderColor || '')); + _setColor(colorBox.eq(1), K.toHex(cell[0].style.backgroundColor || '')); + widthBox[0].focus(); + widthBox[0].select(); + }, + insert : function() { + this.prop(true); + }, + 'delete' : function() { + var table = self.plugin.getSelectedTable(); + self.cmd.range.setStartBefore(table[0]).collapse(true); + self.cmd.select(); + table.remove(); + self.addBookmark(); + }, + colinsert : function(offset) { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + index = cell.cellIndex + offset; + // 取得第一行的index + index += table.rows[0].cells.length - row.cells.length; + + for (var i = 0, len = table.rows.length; i < len; i++) { + var newRow = table.rows[i], + newCell = newRow.insertCell(index); + newCell.innerHTML = K.IE ? '' : '
        '; + // 调整下一行的单元格index + index = _getCellIndex(table, newRow, newCell); + } + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + colinsertleft : function() { + this.colinsert(0); + }, + colinsertright : function() { + this.colinsert(1); + }, + rowinsert : function(offset) { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0]; + var rowIndex = row.rowIndex; + if (offset === 1) { + rowIndex = row.rowIndex + (cell.rowSpan - 1) + offset; + } + var newRow = table.insertRow(rowIndex); + + for (var i = 0, len = row.cells.length; i < len; i++) { + // 调整cell个数 + if (row.cells[i].rowSpan > 1) { + len -= row.cells[i].rowSpan - 1; + } + var newCell = newRow.insertCell(i); + // copy colspan + if (offset === 1 && row.cells[i].colSpan > 1) { + newCell.colSpan = row.cells[i].colSpan; + } + newCell.innerHTML = K.IE ? '' : '
        '; + } + // 调整rowspan + for (var j = rowIndex; j >= 0; j--) { + var cells = table.rows[j].cells; + if (cells.length > i) { + for (var k = cell.cellIndex; k >= 0; k--) { + if (cells[k].rowSpan > 1) { + cells[k].rowSpan += 1; + } + } + break; + } + } + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + rowinsertabove : function() { + this.rowinsert(0); + }, + rowinsertbelow : function() { + this.rowinsert(1); + }, + rowmerge : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + rowIndex = row.rowIndex, // 当前行的index + nextRowIndex = rowIndex + cell.rowSpan, // 下一行的index + nextRow = table.rows[nextRowIndex]; // 下一行 + // 最后一行不能合并 + if (table.rows.length <= nextRowIndex) { + return; + } + var cellIndex = cell.cellIndex; // 下一行单元格的index + if (nextRow.cells.length <= cellIndex) { + return; + } + var nextCell = nextRow.cells[cellIndex]; // 下一行单元格 + // 上下行的colspan不一致时不能合并 + if (cell.colSpan !== nextCell.colSpan) { + return; + } + cell.rowSpan += nextCell.rowSpan; + nextRow.deleteCell(cellIndex); + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + colmerge : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + rowIndex = row.rowIndex, // 当前行的index + cellIndex = cell.cellIndex, + nextCellIndex = cellIndex + 1; + // 最后一列不能合并 + if (row.cells.length <= nextCellIndex) { + return; + } + var nextCell = row.cells[nextCellIndex]; + // 左右列的rowspan不一致时不能合并 + if (cell.rowSpan !== nextCell.rowSpan) { + return; + } + cell.colSpan += nextCell.colSpan; + row.deleteCell(nextCellIndex); + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + rowsplit : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + rowIndex = row.rowIndex; + // 不是可分割单元格 + if (cell.rowSpan === 1) { + return; + } + var cellIndex = _getCellIndex(table, row, cell); + for (var i = 1, len = cell.rowSpan; i < len; i++) { + var newRow = table.rows[rowIndex + i], + newCell = newRow.insertCell(cellIndex); + if (cell.colSpan > 1) { + newCell.colSpan = cell.colSpan; + } + newCell.innerHTML = K.IE ? '' : '
        '; + // 调整下一行的单元格index + cellIndex = _getCellIndex(table, newRow, newCell); + } + K(cell).removeAttr('rowSpan'); + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + colsplit : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + cellIndex = cell.cellIndex; + // 不是可分割单元格 + if (cell.colSpan === 1) { + return; + } + for (var i = 1, len = cell.colSpan; i < len; i++) { + var newCell = row.insertCell(cellIndex + i); + if (cell.rowSpan > 1) { + newCell.rowSpan = cell.rowSpan; + } + newCell.innerHTML = K.IE ? '' : '
        '; + } + K(cell).removeAttr('colSpan'); + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + coldelete : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + index = cell.cellIndex; + for (var i = 0, len = table.rows.length; i < len; i++) { + var newRow = table.rows[i], + newCell = newRow.cells[index]; + if (newCell.colSpan > 1) { + newCell.colSpan -= 1; + if (newCell.colSpan === 1) { + K(newCell).removeAttr('colSpan'); + } + } else { + newRow.deleteCell(index); + } + // 跳过不需要删除的行 + if (newCell.rowSpan > 1) { + i += newCell.rowSpan - 1; + } + } + if (row.cells.length === 0) { + self.cmd.range.setStartBefore(table).collapse(true); + self.cmd.select(); + K(table).remove(); + } else { + self.cmd.selection(true); + } + self.addBookmark(); + }, + rowdelete : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + rowIndex = row.rowIndex; + // 从下到上删除 + for (var i = cell.rowSpan - 1; i >= 0; i--) { + table.deleteRow(rowIndex + i); + } + if (table.rows.length === 0) { + self.cmd.range.setStartBefore(table).collapse(true); + self.cmd.select(); + K(table).remove(); + } else { + self.cmd.selection(true); + } + self.addBookmark(); + } + }; + self.clickToolbar(name, self.plugin.table.prop); +}); diff --git a/php/kindeditor_demo/kindeditor/plugins/template/html/1.html b/php/kindeditor_demo/kindeditor/plugins/template/html/1.html new file mode 100755 index 0000000..034126b --- /dev/null +++ b/php/kindeditor_demo/kindeditor/plugins/template/html/1.html @@ -0,0 +1,14 @@ + + + + + + +

        + 在此处输入标题 +

        +

        + 在此处输入内容 +

        + + \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/plugins/template/html/2.html b/php/kindeditor_demo/kindeditor/plugins/template/html/2.html new file mode 100755 index 0000000..dc2584a --- /dev/null +++ b/php/kindeditor_demo/kindeditor/plugins/template/html/2.html @@ -0,0 +1,42 @@ + + + + + + +

        + 标题 +

        + + + + + + + + + + + + + + + +
        +

        标题1

        +
        +

        标题1

        +
        + 内容1 + + 内容2 +
        + 内容3 + + 内容4 +
        +

        + 表格说明 +

        + + \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/plugins/template/html/3.html b/php/kindeditor_demo/kindeditor/plugins/template/html/3.html new file mode 100755 index 0000000..873f0c6 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/plugins/template/html/3.html @@ -0,0 +1,36 @@ + + + + + + +

        + 在此处输入内容 +

        +
          +
        1. + 描述1 +
        2. +
        3. + 描述2 +
        4. +
        5. + 描述3 +
        6. +
        +

        + 在此处输入内容 +

        +
          +
        • + 描述1 +
        • +
        • + 描述2 +
        • +
        • + 描述3 +
        • +
        + + \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/plugins/template/template.js b/php/kindeditor_demo/kindeditor/plugins/template/template.js new file mode 100755 index 0000000..644882a --- /dev/null +++ b/php/kindeditor_demo/kindeditor/plugins/template/template.js @@ -0,0 +1,58 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('template', function(K) { + var self = this, name = 'template', lang = self.lang(name + '.'), + htmlPath = self.pluginsPath + name + '/html/'; + function getFilePath(fileName) { + return htmlPath + fileName + '?ver=' + encodeURIComponent(K.DEBUG ? K.TIME : K.VERSION); + } + self.clickToolbar(name, function() { + var lang = self.lang(name + '.'), + arr = ['
        ', + '
        ', + // left start + '
        ', + lang. selectTemplate + '
        ', + // right start + '
        ', + ' ', + '
        ', + '
        ', + '
        ', + '', + '
        '].join(''); + var dialog = self.createDialog({ + name : name, + width : 500, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var doc = K.iframeDoc(iframe); + self[checkbox[0].checked ? 'html' : 'insertHtml'](doc.body.innerHTML).hideDialog().focus(); + } + } + }); + var selectBox = K('select', dialog.div), + checkbox = K('[name="replaceFlag"]', dialog.div), + iframe = K('iframe', dialog.div); + checkbox[0].checked = true; + iframe.attr('src', getFilePath(selectBox.val())); + selectBox.change(function() { + iframe.attr('src', getFilePath(this.value)); + }); + }); +}); diff --git a/php/kindeditor_demo/kindeditor/plugins/wordpaste/wordpaste.js b/php/kindeditor_demo/kindeditor/plugins/wordpaste/wordpaste.js new file mode 100755 index 0000000..d3af21b --- /dev/null +++ b/php/kindeditor_demo/kindeditor/plugins/wordpaste/wordpaste.js @@ -0,0 +1,51 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('wordpaste', function(K) { + var self = this, name = 'wordpaste'; + self.clickToolbar(name, function() { + var lang = self.lang(name + '.'), + html = '
        ' + + '
        ' + lang.comment + '
        ' + + '' + + '
        ', + dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var str = doc.body.innerHTML; + str = K.clearMsWord(str, self.filterMode ? self.htmlTags : K.options.htmlTags); + self.insertHtml(str).hideDialog().focus(); + } + } + }), + div = dialog.div, + iframe = K('iframe', div), + doc = K.iframeDoc(iframe); + if (!K.IE) { + doc.designMode = 'on'; + } + doc.open(); + doc.write('WordPaste'); + doc.write(''); + if (!K.IE) { + doc.write('
        '); + } + doc.write(''); + doc.close(); + if (K.IE) { + doc.body.contentEditable = 'true'; + } + iframe[0].contentWindow.focus(); + }); +}); diff --git a/php/kindeditor_demo/kindeditor/src/ajax.js b/php/kindeditor_demo/kindeditor/src/ajax.js new file mode 100755 index 0000000..c81bfa3 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/src/ajax.js @@ -0,0 +1,72 @@ + +function _loadScript(url, fn) { + var head = document.getElementsByTagName('head')[0] || (_QUIRKS ? document.body : document.documentElement), + script = document.createElement('script'); + head.appendChild(script); + script.src = url; + script.charset = 'utf-8'; + script.onload = script.onreadystatechange = function() { + if (!this.readyState || this.readyState === 'loaded') { + if (fn) { + fn(); + } + script.onload = script.onreadystatechange = null; + head.removeChild(script); + } + }; +} + +// 移除URL里的GET参数 +function _chopQuery(url) { + var index = url.indexOf('?'); + return index > 0 ? url.substr(0, index) : url; +} + +function _loadStyle(url) { + var head = document.getElementsByTagName('head')[0] || (_QUIRKS ? document.body : document.documentElement), + link = document.createElement('link'), + absoluteUrl = _chopQuery(_formatUrl(url, 'absolute')); + var links = K('link[rel="stylesheet"]', head); + for (var i = 0, len = links.length; i < len; i++) { + if (_chopQuery(_formatUrl(links[i].href, 'absolute')) === absoluteUrl) { + return; + } + } + head.appendChild(link); + link.href = url; + link.rel = 'stylesheet'; +} + +function _ajax(url, fn, method, param, dataType) { + method = method || 'GET'; //POST or GET + dataType = dataType || 'json'; //json or html + var xhr = window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); + xhr.open(method, url, true); + xhr.onreadystatechange = function () { + if (xhr.readyState == 4 && xhr.status == 200) { + if (fn) { + var data = _trim(xhr.responseText); + if (dataType == 'json') { + data = _json(data); + } + fn(data); + } + } + }; + if (method == 'POST') { + var params = []; + _each(param, function(key, val) { + params.push(encodeURIComponent(key) + '=' + encodeURIComponent(val)); + }); + try { + xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + } catch (e) {} + xhr.send(params.join('&')); + } else { + xhr.send(null); + } +} + +K.loadScript = _loadScript; +K.loadStyle = _loadStyle; +K.ajax = _ajax; diff --git a/php/kindeditor_demo/kindeditor/src/cmd.js b/php/kindeditor_demo/kindeditor/src/cmd.js new file mode 100755 index 0000000..4e93057 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/src/cmd.js @@ -0,0 +1,884 @@ + +// original execCommand +function _nativeCommand(doc, key, val) { + try { + doc.execCommand(key, false, val); + } catch(e) {} +} +// original queryCommandValue +function _nativeCommandValue(doc, key) { + var val = ''; + try { + val = doc.queryCommandValue(key); + } catch (e) {} + if (typeof val !== 'string') { + val = ''; + } + return val; +} +// get current selection of a document +function _getSel(doc) { + var win = _getWin(doc); + return _IERANGE ? doc.selection : win.getSelection(); +} +// get range of current selection +function _getRng(doc) { + var sel = _getSel(doc), rng; + try { + if (sel.rangeCount > 0) { + rng = sel.getRangeAt(0); + } else { + rng = sel.createRange(); + } + } catch(e) {} + if (_IERANGE && (!rng || (!rng.item && rng.parentElement().ownerDocument !== doc))) { + return null; + } + return rng; +} +//将map的复合key转换成单一key +function _singleKeyMap(map) { + var newMap = {}, arr, v; + _each(map, function(key, val) { + arr = key.split(','); + for (var i = 0, len = arr.length; i < len; i++) { + v = arr[i]; + newMap[v] = val; + } + }); + return newMap; +} +//判断一个node是否有指定属性或CSS +function _hasAttrOrCss(knode, map) { + return _hasAttrOrCssByKey(knode, map, '*') || _hasAttrOrCssByKey(knode, map); +} +function _hasAttrOrCssByKey(knode, map, mapKey) { + mapKey = mapKey || knode.name; + if (knode.type !== 1) { + return false; + } + var newMap = _singleKeyMap(map); + if (!newMap[mapKey]) { + return false; + } + var arr = newMap[mapKey].split(','); + for (var i = 0, len = arr.length; i < len; i++) { + var key = arr[i]; + if (key === '*') { + return true; + } + var match = /^(\.?)([^=]+)(?:=([^=]*))?$/.exec(key); + var method = match[1] ? 'css' : 'attr'; + key = match[2]; + var val = match[3] || ''; + if (val === '' && knode[method](key) !== '') { + return true; + } + if (val !== '' && knode[method](key) === val) { + return true; + } + } + return false; +} +//删除一个node的属性和CSS +function _removeAttrOrCss(knode, map) { + if (knode.type != 1) { + return; + } + _removeAttrOrCssByKey(knode, map, '*'); + _removeAttrOrCssByKey(knode, map); +} +function _removeAttrOrCssByKey(knode, map, mapKey) { + mapKey = mapKey || knode.name; + if (knode.type !== 1) { + return; + } + var newMap = _singleKeyMap(map); + if (!newMap[mapKey]) { + return; + } + var arr = newMap[mapKey].split(','), allFlag = false; + for (var i = 0, len = arr.length; i < len; i++) { + var key = arr[i]; + if (key === '*') { + allFlag = true; + break; + } + var match = /^(\.?)([^=]+)(?:=([^=]*))?$/.exec(key); + key = match[2]; + if (match[1]) { + key = _toCamel(key); + if (knode[0].style[key]) { + knode[0].style[key] = ''; + } + } else { + knode.removeAttr(key); + } + } + if (allFlag) { + knode.remove(true); + } +} +//取得最里面的element +function _getInnerNode(knode) { + var inner = knode; + while (inner.first()) { + inner = inner.first(); + } + return inner; +} +//最里面的element为inline element时返回true +function _isEmptyNode(knode) { + if (knode.type != 1 || knode.isSingle()) { + return false; + } + return knode.html().replace(/<[^>]+>/g, '') === ''; +} +//merge two wrapper +//a : +//b : +//result : +function _mergeWrapper(a, b) { + a = a.clone(true); + var lastA = _getInnerNode(a), childA = a, merged = false; + while (b) { + while (childA) { + if (childA.name === b.name) { + _mergeAttrs(childA, b.attr(), b.css()); + merged = true; + } + childA = childA.first(); + } + if (!merged) { + lastA.append(b.clone(false)); + } + merged = false; + b = b.first(); + } + return a; +} +//wrap and merge a node +function _wrapNode(knode, wrapper) { + wrapper = wrapper.clone(true); + //node为text node时 + if (knode.type == 3) { + _getInnerNode(wrapper).append(knode.clone(false)); + knode.replaceWith(wrapper); + return wrapper; + } + //node为element时 + //取得node的wrapper + var nodeWrapper = knode, child; + while ((child = knode.first()) && child.children().length == 1) { + knode = child; + } + //将node的子节点纳入在一个documentFragment里 + child = knode.first(); + var frag = knode.doc.createDocumentFragment(); + while (child) { + frag.appendChild(child[0]); + child = child.next(); + } + wrapper = _mergeWrapper(nodeWrapper, wrapper); + if (frag.firstChild) { + _getInnerNode(wrapper).append(frag); + } + nodeWrapper.replaceWith(wrapper); + return wrapper; +} +//merge attributes and styles +function _mergeAttrs(knode, attrs, styles) { + _each(attrs, function(key, val) { + if (key !== 'style') { + knode.attr(key, val); + } + }); + _each(styles, function(key, val) { + knode.css(key, val); + }); +} +// 判断node是否在pre、style、script里 +function _inPreElement(knode) { + while (knode && knode.name != 'body') { + if (_PRE_TAG_MAP[knode.name] || knode.name == 'div' && knode.hasClass('ke-script')) { + return true; + } + knode = knode.parent(); + } + return false; +} +// create KCmd class +function KCmd(range) { + this.init(range); +} +_extend(KCmd, { + init : function(range) { + var self = this, doc = range.doc; + self.doc = doc; + self.win = _getWin(doc); + self.sel = _getSel(doc); + self.range = range; + }, + selection : function(forceReset) { + var self = this, doc = self.doc, rng = _getRng(doc); + self.sel = _getSel(doc); + if (rng) { + self.range = _range(rng); + if (K(self.range.startContainer).name == 'html') { + self.range.selectNodeContents(doc.body).collapse(false); + } + return self; + } + if (forceReset) { + self.range.selectNodeContents(doc.body).collapse(false); + } + return self; + }, + select : function(hasDummy) { + hasDummy = _undef(hasDummy, true); + var self = this, sel = self.sel, range = self.range.cloneRange().shrink(), + sc = range.startContainer, so = range.startOffset, + ec = range.endContainer, eo = range.endOffset, + doc = _getDoc(sc), win = self.win, rng, hasU200b = false; + // tag内部无内容时选中tag内部,[] + if (hasDummy && sc.nodeType == 1 && range.collapsed) { + if (_IERANGE) { + var dummy = K(' ', doc); + range.insertNode(dummy[0]); + rng = doc.body.createTextRange(); + try { + rng.moveToElementText(dummy[0]); + } catch(ex) {} + rng.collapse(false); + rng.select(); + dummy.remove(); + win.focus(); + return self; + } + if (_WEBKIT) { + var children = sc.childNodes; + if (K(sc).isInline() || so > 0 && K(children[so - 1]).isInline() || children[so] && K(children[so]).isInline()) { + range.insertNode(doc.createTextNode('\u200B')); + hasU200b = true; + } + } + } + //other case + if (_IERANGE) { + try { + rng = range.get(true); + rng.select(); + } catch(e) {} + } else { + if (hasU200b) { + range.collapse(false); + } + rng = range.get(true); + sel.removeAllRanges(); + sel.addRange(rng); + // Bugfix: https://github.com/kindsoft/kindeditor/issues/54 + if (doc !== document) { + var pos = K(rng.endContainer).pos(); + win.scrollTo(pos.x, pos.y); + } + } + win.focus(); + return self; + }, + wrap : function(val) { + var self = this, doc = self.doc, range = self.range, wrapper; + wrapper = K(val, doc); + // collapsed=true + if (range.collapsed) { + range.shrink(); + range.insertNode(wrapper[0]).selectNodeContents(wrapper[0]); + return self; + } + // block wrapper + if (wrapper.isBlock()) { + var copyWrapper = wrapper.clone(true), child = copyWrapper; + // find inner element + while (child.first()) { + child = child.first(); + } + child.append(range.extractContents()); + range.insertNode(copyWrapper[0]).selectNode(copyWrapper[0]); + return self; + } + // collapsed=false + range.enlarge(); + var bookmark = range.createBookmark(), ancestor = range.commonAncestor(), isStart = false; + K(ancestor).scan(function(node) { + if (!isStart && node == bookmark.start) { + isStart = true; + return; + } + if (isStart) { + if (node == bookmark.end) { + return false; + } + var knode = K(node); + if (_inPreElement(knode)) { + return; + } + if (knode.type == 3 && _trim(node.nodeValue).length > 0) { + // textNode为唯一的子节点时,重新设置node + var parent; + while ((parent = knode.parent()) && parent.isStyle() && parent.children().length == 1) { + knode = parent; + } + _wrapNode(knode, wrapper); + } + } + }); + range.moveToBookmark(bookmark); + return self; + }, + split : function(isStart, map) { + var range = this.range, doc = range.doc; + //get parent node + var tempRange = range.cloneRange().collapse(isStart); + var node = tempRange.startContainer, pos = tempRange.startOffset, + parent = node.nodeType == 3 ? node.parentNode : node, + needSplit = false, knode; + while (parent && parent.parentNode) { + knode = K(parent); + if (map) { + if (!knode.isStyle()) { + break; + } + if (!_hasAttrOrCss(knode, map)) { + break; + } + } else { + if (_NOSPLIT_TAG_MAP[knode.name]) { + break; + } + } + needSplit = true; + parent = parent.parentNode; + } + //split parent node + if (needSplit) { + var dummy = doc.createElement('span'); + range.cloneRange().collapse(!isStart).insertNode(dummy); + if (isStart) { + tempRange.setStartBefore(parent.firstChild).setEnd(node, pos); + } else { + tempRange.setStart(node, pos).setEndAfter(parent.lastChild); + } + var frag = tempRange.extractContents(), + first = frag.firstChild, last = frag.lastChild; + if (isStart) { + tempRange.insertNode(frag); + range.setStartAfter(last).setEndBefore(dummy); + } else { + parent.appendChild(frag); + range.setStartBefore(dummy).setEndBefore(first); + } + //调整endOffset + var dummyParent = dummy.parentNode; + if (dummyParent == range.endContainer) { + var prev = K(dummy).prev(), next = K(dummy).next(); + if (prev && next && prev.type == 3 && next.type == 3) { + //dummy元素的左右都是textNode,fg + range.setEnd(prev[0], prev[0].nodeValue.length); + } else if (!isStart) { + range.setEnd(range.endContainer, range.endOffset - 1); + } + } + dummyParent.removeChild(dummy); + } + return this; + }, + remove : function(map) { + var self = this, doc = self.doc, range = self.range; + range.enlarge(); + //

        [123456789]

        , remove strong + if (range.startOffset === 0) { + var ksc = K(range.startContainer), parent; + while ((parent = ksc.parent()) && parent.isStyle() && parent.children().length == 1) { + ksc = parent; + } + range.setStart(ksc[0], 0); + //

        [abcd

        , remove style + ksc = K(range.startContainer); + if (ksc.isBlock()) { + _removeAttrOrCss(ksc, map); + } + var kscp = ksc.parent(); + if (kscp && kscp.isBlock()) { + _removeAttrOrCss(kscp, map); + } + } + var sc, so; + // collapsed == true + if (range.collapsed) { + self.split(true, map); + // remove empty element + sc = range.startContainer; + so = range.startOffset; + if (so > 0) { + var sb = K(sc.childNodes[so - 1]); + if (sb && _isEmptyNode(sb)) { + sb.remove(); + range.setStart(sc, so - 1); + } + } + var sa = K(sc.childNodes[so]); + if (sa && _isEmptyNode(sa)) { + sa.remove(); + } + // | + if (_isEmptyNode(sc)) { + range.startBefore(sc); + sc.remove(); + } + range.collapse(true); + return self; + } + // split range + self.split(true, map); + self.split(false, map); + // insert dummy element + var startDummy = doc.createElement('span'), endDummy = doc.createElement('span'); + range.cloneRange().collapse(false).insertNode(endDummy); + range.cloneRange().collapse(true).insertNode(startDummy); + // select element + var nodeList = [], cmpStart = false; + K(range.commonAncestor()).scan(function(node) { + if (!cmpStart && node == startDummy) { + cmpStart = true; + return; + } + if (node == endDummy) { + return false; + } + if (cmpStart) { + nodeList.push(node); + } + }); + // remove dummy element + K(startDummy).remove(); + K(endDummy).remove(); + // remove empty element + sc = range.startContainer; + so = range.startOffset; + var ec = range.endContainer, eo = range.endOffset; + if (so > 0) { + var startBefore = K(sc.childNodes[so - 1]); + if (startBefore && _isEmptyNode(startBefore)) { + startBefore.remove(); + range.setStart(sc, so - 1); + if (sc == ec) { + range.setEnd(ec, eo - 1); + } + } + // abc[def]ghi,分割后HTML变成 + // abc[def]ghi + var startAfter = K(sc.childNodes[so]); + if (startAfter && _isEmptyNode(startAfter)) { + startAfter.remove(); + if (sc == ec) { + range.setEnd(ec, eo - 1); + } + } + } + var endAfter = K(ec.childNodes[range.endOffset]); + if (endAfter && _isEmptyNode(endAfter)) { + endAfter.remove(); + } + var bookmark = range.createBookmark(true); + // remove attributes or styles + _each(nodeList, function(i, node) { + _removeAttrOrCss(K(node), map); + }); + range.moveToBookmark(bookmark); + return self; + }, + commonNode : function(map) { + var range = this.range; + var ec = range.endContainer, eo = range.endOffset, + node = (ec.nodeType == 3 || eo === 0) ? ec : ec.childNodes[eo - 1]; + function find(node) { + var child = node, parent = node; + while (parent) { + if (_hasAttrOrCss(K(parent), map)) { + return K(parent); + } + parent = parent.parentNode; + } + while (child && (child = child.lastChild)) { + if (_hasAttrOrCss(K(child), map)) { + return K(child); + } + } + return null; + } + var cNode = find(node); + if (cNode) { + return cNode; + } + //123|4567 + //123|
        + if (node.nodeType == 1 || (ec.nodeType == 3 && eo === 0)) { + var prev = K(node).prev(); + if (prev) { + return find(prev); + } + } + return null; + }, + commonAncestor : function(tagName) { + var range = this.range, + sc = range.startContainer, so = range.startOffset, + ec = range.endContainer, eo = range.endOffset, + startNode = (sc.nodeType == 3 || so === 0) ? sc : sc.childNodes[so - 1], + endNode = (ec.nodeType == 3 || eo === 0) ? ec : ec.childNodes[eo - 1]; + function find(node) { + while (node) { + if (node.nodeType == 1) { + if (node.tagName.toLowerCase() === tagName) { + return node; + } + } + node = node.parentNode; + } + return null; + } + var start = find(startNode), end = find(endNode); + if (start && end && start === end) { + return K(start); + } + return null; + }, + // Reference: document.queryCommandState + // TODO + state : function(key) { + var self = this, doc = self.doc, bool = false; + try { + bool = doc.queryCommandState(key); + } catch (e) {} + return bool; + }, + // Reference: document.queryCommandValue + val : function(key) { + var self = this, doc = self.doc, range = self.range; + function lc(val) { + return val.toLowerCase(); + } + key = lc(key); + var val = '', knode; + if (key === 'fontfamily' || key === 'fontname') { + val = _nativeCommandValue(doc, 'fontname'); + val = val.replace(/['"]/g, ''); + return lc(val); + } + if (key === 'formatblock') { + val = _nativeCommandValue(doc, key); + if (val === '') { + knode = self.commonNode({'h1,h2,h3,h4,h5,h6,p,div,pre,address' : '*'}); + if (knode) { + val = knode.name; + } + } + if (val === 'Normal') { + val = 'p'; + } + return lc(val); + } + if (key === 'fontsize') { + knode = self.commonNode({'*' : '.font-size'}); + if (knode) { + val = knode.css('font-size'); + } + return lc(val); + } + if (key === 'forecolor') { + knode = self.commonNode({'*' : '.color'}); + if (knode) { + val = knode.css('color'); + } + val = _toHex(val); + if (val === '') { + val = 'default'; + } + return lc(val); + } + if (key === 'hilitecolor') { + knode = self.commonNode({'*' : '.background-color'}); + if (knode) { + val = knode.css('background-color'); + } + val = _toHex(val); + if (val === '') { + val = 'default'; + } + return lc(val); + } + return val; + }, + toggle : function(wrapper, map) { + var self = this; + if (self.commonNode(map)) { + self.remove(map); + } else { + self.wrap(wrapper); + } + return self.select(); + }, + bold : function() { + return this.toggle('', { + span : '.font-weight=bold', + strong : '*', + b : '*' + }); + }, + italic : function() { + return this.toggle('', { + span : '.font-style=italic', + em : '*', + i : '*' + }); + }, + underline : function() { + return this.toggle('', { + span : '.text-decoration=underline', + u : '*' + }); + }, + strikethrough : function() { + return this.toggle('', { + span : '.text-decoration=line-through', + s : '*' + }); + }, + forecolor : function(val) { + return this.wrap('').select(); + // return this.toggle('', { + // span : '.color=' + val, + // font : 'color' + // }); + }, + hilitecolor : function(val) { + return this.wrap('').select(); + // return this.toggle('', { + // span : '.background-color=' + val + // }); + }, + fontsize : function(val) { + return this.wrap('').select(); + // return this.toggle('', { + // span : '.font-size=' + val, + // font : 'size' + // }); + }, + fontname : function(val) { + return this.fontfamily(val); + }, + fontfamily : function(val) { + return this.wrap('').select(); + // return this.toggle('', { + // span : '.font-family=' + val, + // font : 'face' + // }); + }, + removeformat : function() { + var map = { + '*' : '.font-weight,.font-style,.text-decoration,.color,.background-color,.font-size,.font-family,.text-indent' + }, + tags = _STYLE_TAG_MAP; + _each(tags, function(key, val) { + map[key] = '*'; + }); + this.remove(map); + return this.select(); + }, + inserthtml : function(val, quickMode) { + var self = this, range = self.range; + if (val === '') { + return self; + } + //if (_inPreElement(K(range.startContainer))) { + // return self; + //} + // IE专用,优化性能 + function pasteHtml(range, val) { + val = '' + val; + var rng = range.get(); + if (rng.item) { + rng.item(0).outerHTML = val; + } else { + rng.pasteHTML(val); + } + var temp = range.doc.getElementById('__kindeditor_temp_tag__'); + temp.parentNode.removeChild(temp); + var newRange = _toRange(rng); + range.setEnd(newRange.endContainer, newRange.endOffset); + range.collapse(false); + self.select(false); + } + // 全浏览器兼容,在IE上速度慢 + function insertHtml(range, val) { + var doc = range.doc, + frag = doc.createDocumentFragment(); + K('@' + val, doc).each(function() { + frag.appendChild(this); + }); + range.deleteContents(); + range.insertNode(frag); + range.collapse(false); + self.select(false); + } + if (_IERANGE && quickMode) { + try { + pasteHtml(range, val); + } catch(e) { + insertHtml(range, val); + } + return self; + } + insertHtml(range, val); + return self; + }, + hr : function() { + return this.inserthtml('
        '); + }, + print : function() { + this.win.print(); + return this; + }, + insertimage : function(url, title, width, height, border, align) { + title = _undef(title, ''); + border = _undef(border, 0); + var html = ''; + return self.inserthtml(html); + } + if (range.isControl()) { + var node = K(range.startContainer.childNodes[range.startOffset]); + html += '>'; + node.after(K(html, doc)); + node.next().append(node); + range.selectNode(node[0]); + return self.select(); + } + function setAttr(node, url, type) { + K(node).attr('href', url).attr('data-ke-src', url); + if (type) { + K(node).attr('target', type); + } else { + K(node).removeAttr('target'); + } + } + // Bugfix: https://github.com/kindsoft/kindeditor/issues/117 + // [IE] 当两个A标签并排在一起中间没有别的内容,修改后面的链接地址时,前面的链接地址也被改掉。 + var sc = range.startContainer, so = range.startOffset, + ec = range.endContainer, eo = range.endOffset; + if (sc.nodeType == 1 && sc === ec && so + 1 === eo) { + var child = sc.childNodes[so]; + if (child.nodeName.toLowerCase() == 'a') { + setAttr(child, url, type); + return self; + } + } + _nativeCommand(doc, 'createlink', '__kindeditor_temp_url__'); + K('a[href="__kindeditor_temp_url__"]', doc).each(function() { + setAttr(this, url, type); + }); + return self; + }, + unlink : function() { + var self = this, doc = self.doc, range = self.range; + self.select(); + if (range.collapsed) { + var a = self.commonNode({ a : '*' }); + if (a) { + range.selectNode(a.get()); + self.select(); + } + _nativeCommand(doc, 'unlink', null); + if (_WEBKIT && K(range.startContainer).name === 'img') { + var parent = K(range.startContainer).parent(); + if (parent.name === 'a') { + parent.remove(true); + } + } + } else { + _nativeCommand(doc, 'unlink', null); + } + return self; + } +}); + +_each(('formatblock,selectall,justifyleft,justifycenter,justifyright,justifyfull,insertorderedlist,' + + 'insertunorderedlist,indent,outdent,subscript,superscript').split(','), function(i, name) { + KCmd.prototype[name] = function(val) { + var self = this; + self.select(); + _nativeCommand(self.doc, name, val); + // Bugfix: [IE] 先选中图片后居中,再左对齐,光标跳到顶部 + if (_IERANGE && _inArray(name, 'justifyleft,justifycenter,justifyright,justifyfull'.split(',')) >= 0) { + self.selection(); + } + // 在webkit和firefox上需要重新选取range,否则有时候会报错 + if (!_IERANGE || _inArray(name, 'formatblock,selectall,insertorderedlist,insertunorderedlist'.split(',')) >= 0) { + self.selection(); + } + return self; + }; +}); + +_each('cut,copy,paste'.split(','), function(i, name) { + KCmd.prototype[name] = function() { + var self = this; + if (!self.doc.queryCommandSupported(name)) { + throw 'not supported'; + } + self.select(); + _nativeCommand(self.doc, name, null); + return self; + }; +}); + +function _cmd(mixed) { + // mixed is a node + if (mixed.nodeName) { + var doc = _getDoc(mixed); + mixed = _range(doc).selectNodeContents(doc.body).collapse(false); + } + // mixed is a KRange + return new KCmd(mixed); +} + +K.CmdClass = KCmd; +K.cmd = _cmd; diff --git a/php/kindeditor_demo/kindeditor/src/colorpicker.js b/php/kindeditor_demo/kindeditor/src/colorpicker.js new file mode 100755 index 0000000..25ef259 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/src/colorpicker.js @@ -0,0 +1,79 @@ + +// create KColorPicker class +function KColorPicker(options) { + this.init(options); +} +_extend(KColorPicker, KWidget, { + init : function(options) { + var self = this; + options.z = options.z || 811213; + KColorPicker.parent.init.call(self, options); + var colors = options.colors || [ + ['#E53333', '#E56600', '#FF9900', '#64451D', '#DFC5A4', '#FFE500'], + ['#009900', '#006600', '#99BB00', '#B8D100', '#60D978', '#00D5FF'], + ['#337FE5', '#003399', '#4C33E5', '#9933E5', '#CC33E5', '#EE33EE'], + ['#FFFFFF', '#CCCCCC', '#999999', '#666666', '#333333', '#000000'] + ]; + self.selectedColor = (options.selectedColor || '').toLowerCase(); + self._cells = []; + self.div.addClass('ke-colorpicker').bind('click,mousedown', function(e){ + e.stopPropagation(); + }).attr('unselectable', 'on'); + var table = self.doc.createElement('table'); + self.div.append(table); + table.className = 'ke-colorpicker-table'; + table.cellPadding = 0; + table.cellSpacing = 0; + table.border = 0; + var row = table.insertRow(0), cell = row.insertCell(0); + cell.colSpan = colors[0].length; + self._addAttr(cell, '', 'ke-colorpicker-cell-top'); + for (var i = 0; i < colors.length; i++) { + row = table.insertRow(i + 1); + for (var j = 0; j < colors[i].length; j++) { + cell = row.insertCell(j); + self._addAttr(cell, colors[i][j], 'ke-colorpicker-cell'); + } + } + }, + _addAttr : function(cell, color, cls) { + var self = this; + cell = K(cell).addClass(cls); + if (self.selectedColor === color.toLowerCase()) { + cell.addClass('ke-colorpicker-cell-selected'); + } + cell.attr('title', color || self.options.noColor); + cell.mouseover(function(e) { + K(this).addClass('ke-colorpicker-cell-on'); + }); + cell.mouseout(function(e) { + K(this).removeClass('ke-colorpicker-cell-on'); + }); + cell.click(function(e) { + e.stop(); + self.options.click.call(K(this), color); + }); + if (color) { + cell.append(K('
        ').css('background-color', color)); + } else { + cell.html(self.options.noColor); + } + K(cell).attr('unselectable', 'on'); + self._cells.push(cell); + }, + remove : function() { + var self = this; + _each(self._cells, function() { + this.unbind(); + }); + KColorPicker.parent.remove.call(self); + return self; + } +}); + +function _colorpicker(options) { + return new KColorPicker(options); +} + +K.ColorPickerClass = KColorPicker; +K.colorpicker = _colorpicker; diff --git a/php/kindeditor_demo/kindeditor/src/config.js b/php/kindeditor_demo/kindeditor/src/config.js new file mode 100755 index 0000000..c584652 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/src/config.js @@ -0,0 +1,97 @@ + +function _getBasePath() { + var els = document.getElementsByTagName('script'), src; + for (var i = 0, len = els.length; i < len; i++) { + src = els[i].src || ''; + if (/kindeditor[\w\-\.]*\.js/.test(src)) { + return src.substring(0, src.lastIndexOf('/') + 1); + } + } + return ''; +} + +K.basePath = _getBasePath(); + +K.options = { + designMode : true, + fullscreenMode : false, + filterMode : true, + wellFormatMode : true, + shadowMode : true, + loadStyleMode : true, + basePath : K.basePath, + themesPath : K.basePath + 'themes/', + langPath : K.basePath + 'lang/', + pluginsPath : K.basePath + 'plugins/', + themeType : 'default', // default, simple + langType : 'zh-CN', + urlType : '', // "", relative, absolute, domain + newlineTag : 'p', // p, br + resizeType : 2, // 0, 1, 2 + syncType : 'form', // "", form + pasteType : 2, // 0:none, 1:text, 2:HTML + dialogAlignType : 'page', // page, editor + useContextmenu : true, + fullscreenShortcut : false, + bodyClass : 'ke-content', + indentChar : '\t', // \t, " " + cssPath : '', //String or Array + cssData : '', + minWidth : 650, + minHeight : 100, + minChangeSize : 50, + zIndex : 811213, + items : [ + 'source', '|', 'undo', 'redo', '|', 'preview', 'print', 'template', 'code', 'cut', 'copy', 'paste', + 'plainpaste', 'wordpaste', '|', 'justifyleft', 'justifycenter', 'justifyright', + 'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'subscript', + 'superscript', 'clearhtml', 'quickformat', 'selectall', '|', 'fullscreen', '/', + 'formatblock', 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold', + 'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', '|', 'image', 'multiimage', + 'flash', 'media', 'insertfile', 'table', 'hr', 'emoticons', 'baidumap', 'pagebreak', + 'anchor', 'link', 'unlink', '|', 'about' + ], + noDisableItems : ['source', 'fullscreen'], + colorTable : [ + ['#E53333', '#E56600', '#FF9900', '#64451D', '#DFC5A4', '#FFE500'], + ['#009900', '#006600', '#99BB00', '#B8D100', '#60D978', '#00D5FF'], + ['#337FE5', '#003399', '#4C33E5', '#9933E5', '#CC33E5', '#EE33EE'], + ['#FFFFFF', '#CCCCCC', '#999999', '#666666', '#333333', '#000000'] + ], + fontSizeTable : ['9px', '10px', '12px', '14px', '16px', '18px', '24px', '32px'], + htmlTags : { + font : ['id', 'class', 'color', 'size', 'face', '.background-color'], + span : [ + 'id', 'class', '.color', '.background-color', '.font-size', '.font-family', '.background', + '.font-weight', '.font-style', '.text-decoration', '.vertical-align', '.line-height' + ], + div : [ + 'id', 'class', 'align', '.border', '.margin', '.padding', '.text-align', '.color', + '.background-color', '.font-size', '.font-family', '.font-weight', '.background', + '.font-style', '.text-decoration', '.vertical-align', '.margin-left' + ], + table: [ + 'id', 'class', 'border', 'cellspacing', 'cellpadding', 'width', 'height', 'align', 'bordercolor', + '.padding', '.margin', '.border', 'bgcolor', '.text-align', '.color', '.background-color', + '.font-size', '.font-family', '.font-weight', '.font-style', '.text-decoration', '.background', + '.width', '.height', '.border-collapse' + ], + 'td,th': [ + 'id', 'class', 'align', 'valign', 'width', 'height', 'colspan', 'rowspan', 'bgcolor', + '.text-align', '.color', '.background-color', '.font-size', '.font-family', '.font-weight', + '.font-style', '.text-decoration', '.vertical-align', '.background', '.border' + ], + a : ['id', 'class', 'href', 'target', 'name'], + embed : ['id', 'class', 'src', 'width', 'height', 'type', 'loop', 'autostart', 'quality', '.width', '.height', 'align', 'allowscriptaccess', 'wmode'], + img : ['id', 'class', 'src', 'width', 'height', 'border', 'alt', 'title', 'align', '.width', '.height', '.border'], + 'p,ol,ul,li,blockquote,h1,h2,h3,h4,h5,h6' : [ + 'id', 'class', 'align', '.text-align', '.color', '.background-color', '.font-size', '.font-family', '.background', + '.font-weight', '.font-style', '.text-decoration', '.vertical-align', '.text-indent', '.margin-left' + ], + pre : ['id', 'class'], + hr : ['id', 'class', '.page-break-after'], + 'br,tbody,tr,strong,b,sub,sup,em,i,u,strike,s,del' : ['id', 'class'], + iframe : ['id', 'class', 'src', 'frameborder', 'width', 'height', '.width', '.height'] + }, + layout : '
        ' +}; diff --git a/php/kindeditor_demo/kindeditor/src/core.js b/php/kindeditor_demo/kindeditor/src/core.js new file mode 100755 index 0000000..d1c0687 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/src/core.js @@ -0,0 +1,231 @@ + +/**/ var undefined; + +if (!window.console) { + window.console = {}; +} +if (!console.log) { + console.log = function () {}; +} + +var _VERSION = '${VERSION}', + _ua = navigator.userAgent.toLowerCase(), + _IE = _ua.indexOf('msie') > -1 && _ua.indexOf('opera') == -1, + _NEWIE = _ua.indexOf('msie') == -1 && _ua.indexOf('trident') > -1, + _GECKO = _ua.indexOf('gecko') > -1 && _ua.indexOf('khtml') == -1, + _WEBKIT = _ua.indexOf('applewebkit') > -1, + _OPERA = _ua.indexOf('opera') > -1, + _MOBILE = _ua.indexOf('mobile') > -1, + _IOS = /ipad|iphone|ipod/.test(_ua), + _QUIRKS = document.compatMode != 'CSS1Compat', + _IERANGE = !window.getSelection, + _matches = /(?:msie|firefox|webkit|opera)[\/:\s](\d+)/.exec(_ua), + _V = _matches ? _matches[1] : '0', + _TIME = new Date().getTime(); + +function _isArray(val) { + if (!val) { + return false; + } + return Object.prototype.toString.call(val) === '[object Array]'; +} + +function _isFunction(val) { + if (!val) { + return false; + } + return Object.prototype.toString.call(val) === '[object Function]'; +} + +function _inArray(val, arr) { + for (var i = 0, len = arr.length; i < len; i++) { + if (val === arr[i]) { + return i; + } + } + return -1; +} + +function _each(obj, fn) { + if (_isArray(obj)) { + for (var i = 0, len = obj.length; i < len; i++) { + if (fn.call(obj[i], i, obj[i]) === false) { + break; + } + } + } else { + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + if (fn.call(obj[key], key, obj[key]) === false) { + break; + } + } + } + } +} + +function _trim(str) { + // Forgive various special whitespaces, e.g.  (\xa0). + return str.replace(/(?:^[ \t\n\r]+)|(?:[ \t\n\r]+$)/g, ''); +} + +function _inString(val, str, delimiter) { + delimiter = delimiter === undefined ? ',' : delimiter; + return (delimiter + str + delimiter).indexOf(delimiter + val + delimiter) >= 0; +} + +function _addUnit(val, unit) { + unit = unit || 'px'; + return val && /^-?\d+(?:\.\d+)?$/.test(val) ? val + unit : val; +} + +function _removeUnit(val) { + var match; + return val && (match = /(\d+)/.exec(val)) ? parseInt(match[1], 10) : 0; +} + +function _escape(val) { + return val.replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); +} + +function _unescape(val) { + return val.replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/&/g, '&'); +} + +function _toCamel(str) { + var arr = str.split('-'); + str = ''; + _each(arr, function(key, val) { + str += (key > 0) ? val.charAt(0).toUpperCase() + val.substr(1) : val; + }); + return str; +} + +function _toHex(val) { + function hex(d) { + var s = parseInt(d, 10).toString(16).toUpperCase(); + return s.length > 1 ? s : '0' + s; + } + return val.replace(/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/ig, + function($0, $1, $2, $3) { + return '#' + hex($1) + hex($2) + hex($3); + } + ); +} + +function _toMap(val, delimiter) { + delimiter = delimiter === undefined ? ',' : delimiter; + var map = {}, arr = _isArray(val) ? val : val.split(delimiter), match; + _each(arr, function(key, val) { + if ((match = /^(\d+)\.\.(\d+)$/.exec(val))) { + for (var i = parseInt(match[1], 10); i <= parseInt(match[2], 10); i++) { + map[i.toString()] = true; + } + } else { + map[val] = true; + } + }); + return map; +} + +function _toArray(obj, offset) { + return Array.prototype.slice.call(obj, offset || 0); +} + +function _undef(val, defaultVal) { + return val === undefined ? defaultVal : val; +} + +function _invalidUrl(url) { + return !url || /[<>"]/.test(url); +} + +function _addParam(url, param) { + return url.indexOf('?') >= 0 ? url + '&' + param : url + '?' + param; +} + +function _extend(child, parent, proto) { + if (!proto) { + proto = parent; + parent = null; + } + var childProto; + if (parent) { + var fn = function () {}; + fn.prototype = parent.prototype; + childProto = new fn(); + _each(proto, function(key, val) { + childProto[key] = val; + }); + } else { + childProto = proto; + } + childProto.constructor = child; + child.prototype = childProto; + child.parent = parent ? parent.prototype : null; +} + +//From http://www.json.org/json2.js +function _json(text) { + var match; + if ((match = /\{[\s\S]*\}|\[[\s\S]*\]/.exec(text))) { + text = match[0]; + } + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + if (/^[\],:{}\s]*$/. + test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'). + replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'). + replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + return eval('(' + text + ')'); + } + throw 'JSON parse error'; +} + +var _round = Math.round; + +var K = { + DEBUG : false, + VERSION : _VERSION, + IE : _IE, + GECKO : _GECKO, + WEBKIT : _WEBKIT, + OPERA : _OPERA, + V : _V, + TIME : _TIME, + each : _each, + isArray : _isArray, + isFunction : _isFunction, + inArray : _inArray, + inString : _inString, + trim : _trim, + addUnit : _addUnit, + removeUnit : _removeUnit, + escape : _escape, + unescape : _unescape, + toCamel : _toCamel, + toHex : _toHex, + toMap : _toMap, + toArray : _toArray, + undef : _undef, + invalidUrl : _invalidUrl, + addParam : _addParam, + extend : _extend, + json : _json +}; + +var _INLINE_TAG_MAP = _toMap('a,abbr,acronym,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,img,input,ins,kbd,label,map,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'), + _BLOCK_TAG_MAP = _toMap('address,applet,blockquote,body,center,dd,dir,div,dl,dt,fieldset,form,frameset,h1,h2,h3,h4,h5,h6,head,hr,html,iframe,ins,isindex,li,map,menu,meta,noframes,noscript,object,ol,p,pre,script,style,table,tbody,td,tfoot,th,thead,title,tr,ul'), + _SINGLE_TAG_MAP = _toMap('area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed'), + _STYLE_TAG_MAP = _toMap('b,basefont,big,del,em,font,i,s,small,span,strike,strong,sub,sup,u'), + _CONTROL_TAG_MAP = _toMap('img,table,input,textarea,button'), + _PRE_TAG_MAP = _toMap('pre,style,script'), + _NOSPLIT_TAG_MAP = _toMap('html,head,body,td,tr,table,ol,ul,li'), + _AUTOCLOSE_TAG_MAP = _toMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'), + _FILL_ATTR_MAP = _toMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'), + _VALUE_TAG_MAP = _toMap('input,button,textarea,select'); diff --git a/php/kindeditor_demo/kindeditor/src/dialog.js b/php/kindeditor_demo/kindeditor/src/dialog.js new file mode 100755 index 0000000..8d89d91 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/src/dialog.js @@ -0,0 +1,142 @@ + +function _createButton(arg) { + arg = arg || {}; + var name = arg.name || '', + span = K(''), + btn = K(''); + if (arg.click) { + btn.click(arg.click); + } + span.append(btn); + return span; +} + +// create KToolbar class +function KDialog(options) { + this.init(options); +} +_extend(KDialog, KWidget, { + init : function(options) { + var self = this; + var shadowMode = _undef(options.shadowMode, true); + options.z = options.z || 811213; + options.shadowMode = false; + options.autoScroll = _undef(options.autoScroll, true); + KDialog.parent.init.call(self, options); + var title = options.title, + body = K(options.body, self.doc), + previewBtn = options.previewBtn, + yesBtn = options.yesBtn, + noBtn = options.noBtn, + closeBtn = options.closeBtn, + showMask = _undef(options.showMask, true); + + self.div.addClass('ke-dialog').bind('click,mousedown', function(e){ + e.stopPropagation(); + }); + var contentDiv = K('
        ').appendTo(self.div); + if (_IE && _V < 7) { + self.iframeMask = K('').appendTo(self.div); + } else if (shadowMode) { + K('
        ').appendTo(self.div); + } + var headerDiv = K('
        '); + contentDiv.append(headerDiv); + headerDiv.html(title); + self.closeIcon = K('').click(closeBtn.click); + headerDiv.append(self.closeIcon); + self.draggable({ + clickEl : headerDiv, + beforeDrag : options.beforeDrag + }); + var bodyDiv = K('
        '); + contentDiv.append(bodyDiv); + bodyDiv.append(body); + var footerDiv = K(''); + if (previewBtn || yesBtn || noBtn) { + contentDiv.append(footerDiv); + } + _each([ + { btn : previewBtn, name : 'preview' }, + { btn : yesBtn, name : 'yes' }, + { btn : noBtn, name : 'no' } + ], function() { + if (this.btn) { + var button = _createButton(this.btn); + button.addClass('ke-dialog-' + this.name); + footerDiv.append(button); + } + }); + if (self.height) { + bodyDiv.height(_removeUnit(self.height) - headerDiv.height() - footerDiv.height()); + } + self.div.width(self.div.width()); + self.div.height(self.div.height()); + self.mask = null; + if (showMask) { + var docEl = _docElement(self.doc), + docWidth = Math.max(docEl.scrollWidth, docEl.clientWidth), + docHeight = Math.max(docEl.scrollHeight, docEl.clientHeight); + self.mask = _widget({ + x : 0, + y : 0, + z : self.z - 1, + cls : 'ke-dialog-mask', + width : docWidth, + height : docHeight + }); + } + self.autoPos(self.div.width(), self.div.height()); + self.footerDiv = footerDiv; + self.bodyDiv = bodyDiv; + self.headerDiv = headerDiv; + self.isLoading = false; + }, + setMaskIndex : function(z) { + var self = this; + self.mask.div.css('z-index', z); + }, + showLoading : function(msg) { + msg = _undef(msg, ''); + var self = this, body = self.bodyDiv; + self.loading = K('
        ' + msg + '
        ') + .width(body.width()).height(body.height()) + .css('top', self.headerDiv.height() + 'px'); + body.css('visibility', 'hidden').after(self.loading); + self.isLoading = true; + return self; + }, + hideLoading : function() { + this.loading && this.loading.remove(); + this.bodyDiv.css('visibility', 'visible'); + this.isLoading = false; + return this; + }, + remove : function() { + var self = this; + if (self.options.beforeRemove) { + self.options.beforeRemove.call(self); + } + self.mask && self.mask.remove(); + self.iframeMask && self.iframeMask.remove(); + self.closeIcon.unbind(); + K('input', self.div).unbind(); + K('button', self.div).unbind(); + self.footerDiv.unbind(); + self.bodyDiv.unbind(); + self.headerDiv.unbind(); + K('iframe', self.div).each(function() { + //this.src = 'javascript:false'; + K(this).remove(); + }); + KDialog.parent.remove.call(self); + return self; + } +}); + +function _dialog(options) { + return new KDialog(options); +} + +K.DialogClass = KDialog; +K.dialog = _dialog; diff --git a/php/kindeditor_demo/kindeditor/src/edit.js b/php/kindeditor_demo/kindeditor/src/edit.js new file mode 100755 index 0000000..d04a5cb --- /dev/null +++ b/php/kindeditor_demo/kindeditor/src/edit.js @@ -0,0 +1,371 @@ + +function _iframeDoc(iframe) { + iframe = _get(iframe); + return iframe.contentDocument || iframe.contentWindow.document; +} + +var html, _direction = ''; +if ((html = document.getElementsByTagName('html'))) { + _direction = html[0].dir; +} + +function _getInitHtml(themesPath, bodyClass, cssPath, cssData) { + var arr = [ + (_direction === '' ? '' : ''), + '', + '' + ]; + if (!_isArray(cssPath)) { + cssPath = [cssPath]; + } + _each(cssPath, function(i, path) { + if (path) { + arr.push(''); + } + }); + if (cssData) { + arr.push(''); + } + arr.push(''); + return arr.join('\n'); +} + +function _elementVal(knode, val) { + if (knode.hasVal()) { + if (val === undefined) { + var html = knode.val(); + // 去除内容为空的p标签 + // https://github.com/kindsoft/kindeditor/pull/52 + html = html.replace(/(<(?:p|p\s[^>]*)>) *(<\/p>)/ig, ''); + return html; + } + return knode.val(val); + } + return knode.html(val); +} + +// create KEdit class +function KEdit(options) { + this.init(options); +} +_extend(KEdit, KWidget, { + init : function(options) { + var self = this; + KEdit.parent.init.call(self, options); + + self.srcElement = K(options.srcElement); + self.div.addClass('ke-edit'); + self.designMode = _undef(options.designMode, true); + self.beforeGetHtml = options.beforeGetHtml; + self.beforeSetHtml = options.beforeSetHtml; + self.afterSetHtml = options.afterSetHtml; + + var themesPath = _undef(options.themesPath, ''), + bodyClass = options.bodyClass, + cssPath = options.cssPath, + cssData = options.cssData, + isDocumentDomain = location.protocol != 'res:' && location.host.replace(/:\d+/, '') !== document.domain, + srcScript = ('document.open();' + + (isDocumentDomain ? 'document.domain="' + document.domain + '";' : '') + + 'document.close();'), + iframeSrc = _IE ? ' src="javascript:void(function(){' + encodeURIComponent(srcScript) + '}())"' : ''; + self.iframe = K('').css('width', '100%'); + self.textarea = K('').css('width', '100%'); + self.tabIndex = isNaN(parseInt(options.tabIndex, 10)) ? self.srcElement.attr('tabindex') : parseInt(options.tabIndex, 10); + self.iframe.attr('tabindex', self.tabIndex); + self.textarea.attr('tabindex', self.tabIndex); + + if (self.width) { + self.setWidth(self.width); + } + if (self.height) { + self.setHeight(self.height); + } + if (self.designMode) { + self.textarea.hide(); + } else { + self.iframe.hide(); + } + function ready() { + var doc = _iframeDoc(self.iframe); + doc.open(); + if (isDocumentDomain) { + doc.domain = document.domain; + } + doc.write(_getInitHtml(themesPath, bodyClass, cssPath, cssData)); + doc.close(); + self.win = self.iframe[0].contentWindow; + self.doc = doc; + var cmd = _cmd(doc); + // add events + self.afterChange(function(e) { + cmd.selection(); + }); + // [WEBKIT] select an image after click the image + if (_WEBKIT) { + K(doc).click(function(e) { + if (K(e.target).name === 'img') { + cmd.selection(true); + cmd.range.selectNode(e.target); + cmd.select(); + } + }); + } + if (_IE) { + // Fix bug: https://github.com/kindsoft/kindeditor/issues/53 + self._mousedownHandler = function() { + var newRange = cmd.range.cloneRange(); + newRange.shrink(); + if (newRange.isControl()) { + self.blur(); + } + }; + K(document).mousedown(self._mousedownHandler); + // [IE] bug: clear iframe when press backspase key + K(doc).keydown(function(e) { + if (e.which == 8) { + cmd.selection(); + var rng = cmd.range; + if (rng.isControl()) { + rng.collapse(true); + K(rng.startContainer.childNodes[rng.startOffset]).remove(); + e.preventDefault(); + } + } + }); + } + self.cmd = cmd; + self.html(_elementVal(self.srcElement)); + if (_IE) { + doc.body.disabled = true; + doc.body.contentEditable = true; + doc.body.removeAttribute('disabled'); + } else { + doc.designMode = 'on'; + } + if (options.afterCreate) { + options.afterCreate.call(self); + } + } + if (isDocumentDomain) { + self.iframe.bind('load', function(e) { + self.iframe.unbind('load'); + if (_IE) { + ready(); + } else { + setTimeout(ready, 0); + } + }); + } + self.div.append(self.iframe); + self.div.append(self.textarea); + self.srcElement.hide(); + !isDocumentDomain && ready(); + }, + setWidth : function(val) { + var self = this; + val = _addUnit(val); + self.width = val; + self.div.css('width', val); + return self; + }, + setHeight : function(val) { + var self = this; + val = _addUnit(val); + self.height = val; + self.div.css('height', val); + self.iframe.css('height', val); + // 校正IE6和IE7的textarea高度 + if ((_IE && _V < 8) || _QUIRKS) { + val = _addUnit(_removeUnit(val) - 2); + } + self.textarea.css('height', val); + return self; + }, + remove : function() { + var self = this, doc = self.doc; + // remove events + K(doc.body).unbind(); + K(doc).unbind(); + K(self.win).unbind(); + if (self._mousedownHandler) { + K(document).unbind('mousedown', self._mousedownHandler); + } + // remove elements + _elementVal(self.srcElement, self.html()); + self.srcElement.show(); + // doc.write(''); + self.iframe.unbind(); + self.textarea.unbind(); + KEdit.parent.remove.call(self); + }, + html : function(val, isFull) { + var self = this, doc = self.doc; + // design mode + if (self.designMode) { + var body = doc.body; + // get + if (val === undefined) { + if (isFull) { + val = '' + body.parentNode.innerHTML + ''; + } else { + val = body.innerHTML; + } + if (self.beforeGetHtml) { + val = self.beforeGetHtml(val); + } + // bugfix: Firefox自动生成一个br标签 + if (_GECKO && val == '
        ') { + val = ''; + } + return val; + } + // set + if (self.beforeSetHtml) { + val = self.beforeSetHtml(val); + } + // IE9 Bugfix: https://github.com/kindsoft/kindeditor/issues/62 + if (_IE && _V >= 9) { + val = val.replace(/(<.*?checked=")checked(".*>)/ig, '$1$2'); + } + K(body).html(val); + if (self.afterSetHtml) { + self.afterSetHtml(); + } + return self; + } + // source mode + if (val === undefined) { + return self.textarea.val(); + } + self.textarea.val(val); + return self; + }, + design : function(bool) { + var self = this, val; + if (bool === undefined ? !self.designMode : bool) { + if (!self.designMode) { + val = self.html(); + + self.designMode = true; + self.textarea.hide(); + + self.html(val); + + // cache + var iframe = self.iframe; + var height = _removeUnit(self.height); + + iframe.height(height - 2); + iframe.show(); + + // safari iframe scrollbar hack + setTimeout(function() { + iframe.height(height); + }, 0); + } + } else { + if (self.designMode) { + val = self.html(); + self.designMode = false; + self.html(val); + self.iframe.hide(); + self.textarea.show(); + } + } + return self.focus(); + }, + focus : function() { + var self = this; + self.designMode ? self.win.focus() : self.textarea[0].focus(); + return self; + }, + blur : function() { + var self = this; + if (_IE) { + var input = K('', self.div); + self.div.append(input); + input[0].focus(); + input.remove(); + } else { + self.designMode ? self.win.blur() : self.textarea[0].blur(); + } + return self; + }, + afterChange : function(fn) { + var self = this, doc = self.doc, body = doc.body; + K(doc).keyup(function(e) { + if (!e.ctrlKey && !e.altKey && _CHANGE_KEY_MAP[e.which]) { + fn(e); + } + }); + K(doc).mouseup(fn).contextmenu(fn); + K(self.win).blur(fn); + function timeoutHandler(e) { + setTimeout(function() { + fn(e); + }, 1); + } + K(body).bind('paste', timeoutHandler); + K(body).bind('cut', timeoutHandler); + return self; + } +}); + +function _edit(options) { + return new KEdit(options); +} + +K.EditClass = KEdit; +K.edit = _edit; +K.iframeDoc = _iframeDoc; diff --git a/php/kindeditor_demo/kindeditor/src/event.js b/php/kindeditor_demo/kindeditor/src/event.js new file mode 100755 index 0000000..facbc79 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/src/event.js @@ -0,0 +1,389 @@ + +var _useCapture = false; + +/** +DOM_VK_BACK_SPACE : 8 +DOM_VK_TAB : 9 +DOM_VK_RETURN : 13 +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_DELETE : 46 +DOM_VK_0 ~ DOM_VK_9 : 48 ~ 57 +DOM_VK_SEMICOLON : 59 (;:) +DOM_VK_EQUALS : 61 (=+) (+) +DOM_VK_A ~ DOM_VK_Z : 65 ~ 90 +DOM_VK_MULTIPLY : 106 (*) +DOM_VK_SUBTRACT : 109 (-_) (-) +DOM_VK_DECIMAL : 110 (.) +DOM_VK_DIVIDE : 111 (/) +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 ('") +*/ +// 输入文字的键值 +var _INPUT_KEY_MAP = _toMap('8,9,13,32,46,48..57,59,61,65..90,106,109..111,188,190..192,219..222'); +// 移动光标的键值 +var _CURSORMOVE_KEY_MAP = _toMap('33..40'); +// 输入文字或移动光标的键值 +var _CHANGE_KEY_MAP = {}; +_each(_INPUT_KEY_MAP, function(key, val) { + _CHANGE_KEY_MAP[key] = val; +}); +_each(_CURSORMOVE_KEY_MAP, function(key, val) { + _CHANGE_KEY_MAP[key] = val; +}); + +// add native event +function _bindEvent(el, type, fn) { + if (el.addEventListener){ + el.addEventListener(type, fn, _useCapture); + } else if (el.attachEvent){ + el.attachEvent('on' + type, fn); + } +} +// remove native event +function _unbindEvent(el, type, fn) { + if (el.removeEventListener){ + el.removeEventListener(type, fn, _useCapture); + } else if (el.detachEvent){ + el.detachEvent('on' + type, fn); + } +} + +var _EVENT_PROPS = ('altKey,attrChange,attrName,bubbles,button,cancelable,charCode,clientX,clientY,ctrlKey,currentTarget,' + + 'data,detail,eventPhase,fromElement,handler,keyCode,metaKey,newValue,offsetX,offsetY,originalTarget,pageX,' + + 'pageY,prevValue,relatedNode,relatedTarget,screenX,screenY,shiftKey,srcElement,target,toElement,view,wheelDelta,which').split(','); + +// create KEvent class +function KEvent(el, event) { + this.init(el, event); +} +_extend(KEvent, { + init : function(el, event) { + var self = this, doc = el.ownerDocument || el.document || el; + self.event = event; + _each(_EVENT_PROPS, function(key, val) { + self[val] = event[val]; + }); + if (!self.target) { + self.target = self.srcElement || doc; + } + if (self.target.nodeType === 3) { + self.target = self.target.parentNode; + } + if (!self.relatedTarget && self.fromElement) { + self.relatedTarget = self.fromElement === self.target ? self.toElement : self.fromElement; + } + if (self.pageX == null && self.clientX != null) { + var d = doc.documentElement, body = doc.body; + self.pageX = self.clientX + (d && d.scrollLeft || body && body.scrollLeft || 0) - (d && d.clientLeft || body && body.clientLeft || 0); + self.pageY = self.clientY + (d && d.scrollTop || body && body.scrollTop || 0) - (d && d.clientTop || body && body.clientTop || 0); + } + if (!self.which && ((self.charCode || self.charCode === 0) ? self.charCode : self.keyCode)) { + self.which = self.charCode || self.keyCode; + } + if (!self.metaKey && self.ctrlKey) { + self.metaKey = self.ctrlKey; + } + if (!self.which && self.button !== undefined) { + self.which = (self.button & 1 ? 1 : (self.button & 2 ? 3 : (self.button & 4 ? 2 : 0))); + } + /** + DOM_VK_SEMICOLON : 59 (;:) + - IE,WEBKIT: 186 + - GECKO,OPERA : 59 + DOM_VK_EQUALS : 61 (=+) + - IE,WEBKIT : 187 + - GECKO : 107 + - OPERA : 61 + DOM_VK_NUMPAD0 ~ DOM_VK_NUMPAD9 : 96 ~ 105 + - IE、WEBKIT,GECKO : 96 ~ 105 + - OPERA : 48 ~ 57 + DOM_VK_MULTIPLY : 106 (*) + - IE、WEBKIT,GECKO : 106 + - OPERA : 42 + DOM_VK_ADD : 107 (+) + - IE、WEBKIT,GECKO : 107 + - OPERA : 43 + DOM_VK_SUBTRACT : 109 (-_) (-) + - IE,WEBKIT : 189, 109 + - GECKO : 109, 109 + - OPERA : 109, 45 + DOM_VK_DECIMAL : 110 (.) + - IE、WEBKIT,GECKO : 110 + - OPERA : 78 + DOM_VK_DIVIDE : 111 (/) + - IE、WEBKIT,GECKO : 111 + - OPERA : 47 + + Reference: + https://developer.mozilla.org/en/DOM/Event/UIEvent/KeyEvent + http://msdn.microsoft.com/en-us/library/ms536940(v=VS.85).aspx + */ + switch (self.which) { + case 186 : + self.which = 59; + break; + case 187 : + case 107 : + case 43 : + self.which = 61; + break; + case 189 : + case 45 : + self.which = 109; + break; + case 42 : + self.which = 106; + break; + case 47 : + self.which = 111; + break; + case 78 : + self.which = 110; + break; + } + if (self.which >= 96 && self.which <= 105) { + self.which -= 48; + } + }, + preventDefault : function() { + var ev = this.event; + if (ev.preventDefault) { + ev.preventDefault(); + } else { + ev.returnValue = false; + } + }, + stopPropagation : function() { + var ev = this.event; + if (ev.stopPropagation) { + ev.stopPropagation(); + } else { + ev.cancelBubble = true; + } + }, + stop : function() { + this.preventDefault(); + this.stopPropagation(); + } +}); + +var _eventExpendo = 'kindeditor_' + _TIME, _eventId = 0, _eventData = {}; + +function _getId(el) { + return el[_eventExpendo] || null; +} + +function _setId(el) { + el[_eventExpendo] = ++_eventId; + return _eventId; +} + +function _removeId(el) { + try { + delete el[_eventExpendo]; + } catch(e) { + if (el.removeAttribute) { + el.removeAttribute(_eventExpendo); + } + } +} + +function _bind(el, type, fn) { + if (type.indexOf(',') >= 0) { + _each(type.split(','), function() { + _bind(el, this, fn); + }); + return; + } + var id = _getId(el); + if (!id) { + id = _setId(el); + } + if (_eventData[id] === undefined) { + _eventData[id] = {}; + } + var events = _eventData[id][type]; + if (events && events.length > 0) { + _unbindEvent(el, type, events[0]); + } else { + _eventData[id][type] = []; + _eventData[id].el = el; + } + events = _eventData[id][type]; + if (events.length === 0) { + events[0] = function(e) { + var kevent = e ? new KEvent(el, e) : undefined; + _each(events, function(i, event) { + if (i > 0 && event) { + event.call(el, kevent); + } + }); + }; + } + if (_inArray(fn, events) < 0) { + events.push(fn); + } + _bindEvent(el, type, events[0]); +} + +function _unbind(el, type, fn) { + if (type && type.indexOf(',') >= 0) { + _each(type.split(','), function() { + _unbind(el, this, fn); + }); + return; + } + var id = _getId(el); + if (!id) { + return; + } + if (type === undefined) { + if (id in _eventData) { + _each(_eventData[id], function(key, events) { + if (key != 'el' && events.length > 0) { + _unbindEvent(el, key, events[0]); + } + }); + delete _eventData[id]; + _removeId(el); + } + return; + } + if (!_eventData[id]) { + return; + } + var events = _eventData[id][type]; + if (events && events.length > 0) { + if (fn === undefined) { + _unbindEvent(el, type, events[0]); + delete _eventData[id][type]; + } else { + _each(events, function(i, event) { + if (i > 0 && event === fn) { + events.splice(i, 1); + } + }); + if (events.length == 1) { + _unbindEvent(el, type, events[0]); + delete _eventData[id][type]; + } + } + var count = 0; + _each(_eventData[id], function() { + count++; + }); + if (count < 2) { + delete _eventData[id]; + _removeId(el); + } + } +} + +function _fire(el, type) { + if (type.indexOf(',') >= 0) { + _each(type.split(','), function() { + _fire(el, this); + }); + return; + } + var id = _getId(el); + if (!id) { + return; + } + var events = _eventData[id][type]; + if (_eventData[id] && events && events.length > 0) { + events[0](); + } +} + +function _ctrl(el, key, fn) { + var self = this; + key = /^\d{2,}$/.test(key) ? key : key.toUpperCase().charCodeAt(0); + _bind(el, 'keydown', function(e) { + if (e.ctrlKey && e.which == key && !e.shiftKey && !e.altKey) { + fn.call(el); + e.stop(); + } + }); +} + +var _readyFinished = false; + +function _ready(fn) { + if (_readyFinished) { + fn(KindEditor); + return; + } + var loaded = false; + function readyFunc() { + if (!loaded) { + loaded = true; + fn(KindEditor); + _readyFinished = true; + } + } + function ieReadyFunc() { + if (!loaded) { + try { + document.documentElement.doScroll('left'); + } catch(e) { + setTimeout(ieReadyFunc, 100); + return; + } + readyFunc(); + } + } + function ieReadyStateFunc() { + if (document.readyState === 'complete') { + readyFunc(); + } + } + if (document.addEventListener) { + _bind(document, 'DOMContentLoaded', readyFunc); + } else if (document.attachEvent) { + _bind(document, 'readystatechange', ieReadyStateFunc); + // 在跨域的frame里调用会报错 + var toplevel = false; + try { + toplevel = window.frameElement == null; + } catch(e) {} + if (document.documentElement.doScroll && toplevel) { + ieReadyFunc(); + } + } + _bind(window, 'load', readyFunc); +} + +/** + Note: + 发现绑定dbclick事件后移除element会有内存泄漏,以下代码也不起作用。 + Reference: + http://isaacschlueter.com/2006/10/msie-memory-leaks/ + http://msdn.microsoft.com/en-us/library/bb250448.aspx +*/ +if (window.attachEvent) { + window.attachEvent('onunload', function() { + _each(_eventData, function(key, events) { + if (events.el) { + _unbind(events.el); + } + }); + }); +} + +K.ctrl = _ctrl; +K.ready = _ready; diff --git a/php/kindeditor_demo/kindeditor/src/footer.js b/php/kindeditor_demo/kindeditor/src/footer.js new file mode 100755 index 0000000..a1e329f --- /dev/null +++ b/php/kindeditor_demo/kindeditor/src/footer.js @@ -0,0 +1,2 @@ + +})(window); diff --git a/php/kindeditor_demo/kindeditor/src/header.js b/php/kindeditor_demo/kindeditor/src/header.js new file mode 100755 index 0000000..d0ca4be --- /dev/null +++ b/php/kindeditor_demo/kindeditor/src/header.js @@ -0,0 +1,15 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-${THISYEAR} kindsoft.net +* +* @author Roddy +* @website http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +* @version ${VERSION} +*******************************************************************************/ + +(function (window, undefined) { + + if (window.KindEditor) { + return; + } diff --git a/php/kindeditor_demo/kindeditor/src/html.js b/php/kindeditor_demo/kindeditor/src/html.js new file mode 100755 index 0000000..2e07bcd --- /dev/null +++ b/php/kindeditor_demo/kindeditor/src/html.js @@ -0,0 +1,428 @@ +function _getCssList(css) { + var list = {}, + reg = /\s*([\w\-]+)\s*:([^;]*)(;|$)/g, + match; + while ((match = reg.exec(css))) { + var key = _trim(match[1].toLowerCase()), + val = _trim(_toHex(match[2])); + list[key] = val; + } + return list; +} + +function _getAttrList(tag) { + var list = {}, + reg = /\s+(?:([\w\-:]+)|(?:([\w\-:]+)=([^\s"'<>]+))|(?:([\w\-:"]+)="([^"]*)")|(?:([\w\-:"]+)='([^']*)'))(?=(?:\s|\/|>)+)/g, + match; + while ((match = reg.exec(tag))) { + var key = (match[1] || match[2] || match[4] || match[6]).toLowerCase(), + val = (match[2] ? match[3] : (match[4] ? match[5] : match[7])) || ''; + list[key] = val; + } + return list; +} + +function _addClassToTag(tag, className) { + if (/\s+class\s*=/.test(tag)) { + tag = tag.replace(/(\s+class=["']?)([^"']*)(["']?[\s>])/, function($0, $1, $2, $3) { + if ((' ' + $2 + ' ').indexOf(' ' + className + ' ') < 0) { + return $2 === '' ? $1 + className + $3 : $1 + $2 + ' ' + className + $3; + } else { + return $0; + } + }); + } else { + tag = tag.substr(0, tag.length - 1) + ' class="' + className + '">'; + } + return tag; +} + +function _formatCss(css) { + var str = ''; + _each(_getCssList(css), function(key, val) { + str += key + ':' + val + ';'; + }); + return str; +} + +function _formatUrl(url, mode, host, pathname) { + mode = _undef(mode, '').toLowerCase(); + // 移除连续斜线,比如,http://localhost/upload/file/201205//maincus.swf + // base64 data 除外 + if (url.substr(0, 5) != 'data:') { + url = url.replace(/([^:])\/\//g, '$1/'); + } + if (_inArray(mode, ['absolute', 'relative', 'domain']) < 0) { + return url; + } + host = host || location.protocol + '//' + location.host; + if (pathname === undefined) { + var m = location.pathname.match(/^(\/.*)\//); + pathname = m ? m[1] : ''; + } + var match; + if ((match = /^(\w+:\/\/[^\/]*)/.exec(url))) { + if (match[1] !== host) { + return url; + } + } else if (/^\w+:/.test(url)) { + return url; + } + function getRealPath(path) { + var parts = path.split('/'), paths = []; + for (var i = 0, len = parts.length; i < len; i++) { + var part = parts[i]; + if (part == '..') { + if (paths.length > 0) { + paths.pop(); + } + } else if (part !== '' && part != '.') { + paths.push(part); + } + } + return '/' + paths.join('/'); + } + if (/^\//.test(url)) { + url = host + getRealPath(url.substr(1)); + } else if (!/^\w+:\/\//.test(url)) { + url = host + getRealPath(pathname + '/' + url); + } + function getRelativePath(path, depth) { + if (url.substr(0, path.length) === path) { + var arr = []; + for (var i = 0; i < depth; i++) { + arr.push('..'); + } + var prefix = '.'; + if (arr.length > 0) { + prefix += '/' + arr.join('/'); + } + if (pathname == '/') { + prefix += '/'; + } + return prefix + url.substr(path.length); + } else { + if ((match = /^(.*)\//.exec(path))) { + return getRelativePath(match[1], ++depth); + } + } + } + if (mode === 'relative') { + url = getRelativePath(host + pathname, 0).substr(2); + } else if (mode === 'absolute') { + if (url.substr(0, host.length) === host) { + url = url.substr(host.length); + } + } + return url; +} + +function _formatHtml(html, htmlTags, urlType, wellFormatted, indentChar) { + // null or undefined: object == null + if (html == null) { + html = ''; + } + urlType = urlType || ''; + wellFormatted = _undef(wellFormatted, false); + indentChar = _undef(indentChar, '\t'); + var fontSizeList = 'xx-small,x-small,small,medium,large,x-large,xx-large'.split(','); + // 将pre里的br转换成\n + html = html.replace(/(<(?:pre|pre\s[^>]*)>)([\s\S]*?)(<\/pre>)/ig, function($0, $1, $2, $3) { + return $1 + $2.replace(/<(?:br|br\s[^>]*)>/ig, '\n') + $3; + }); + //

        to

        + html = html.replace(/<(?:br|br\s[^>]*)\s*\/?>\s*<\/p>/ig, '

        '); + //

        to


        + html = html.replace(/(<(?:p|p\s[^>]*)>)\s*(<\/p>)/ig, '$1
        $2'); + // empty char + html = html.replace(/\u200B/g, ''); + // © + html = html.replace(/\u00A9/g, '©'); + // ® + html = html.replace(/\u00AE/g, '®'); + // Bugfix: + // https://github.com/kindsoft/kindeditor/issues/147 + html = html.replace(/\u2003/g, ' '); + html = html.replace(/\u3000/g, ' '); + // Bugfix: + // https://github.com/kindsoft/kindeditor/issues/116 + // https://github.com/kindsoft/kindeditor/issues/145 + html = html.replace(/<[^>]+/g, function($0) { + return $0.replace(/\s+/g, ' '); + }); + + var htmlTagMap = {}; + if (htmlTags) { + // 展开htmlTags里的key + _each(htmlTags, function(key, val) { + var arr = key.split(','); + for (var i = 0, len = arr.length; i < len; i++) { + htmlTagMap[arr[i]] = _toMap(val); + } + }); + // 删除script和style里的内容 + if (!htmlTagMap.script) { + html = html.replace(/(<(?:script|script\s[^>]*)>)([\s\S]*?)(<\/script>)/ig, ''); + } + if (!htmlTagMap.style) { + html = html.replace(/(<(?:style|style\s[^>]*)>)([\s\S]*?)(<\/style>)/ig, ''); + } + } + var re = /(\s*)<(\/)?([\w\-:]+)((?:\s+|(?:\s+[\w\-:]+)|(?:\s+[\w\-:]+=[^\s"'<>]+)|(?:\s+[\w\-:"]+="[^"]*")|(?:\s+[\w\-:"]+='[^']*'))*)(\/)?>(\s*)/g; + var tagStack = []; + html = html.replace(re, function($0, $1, $2, $3, $4, $5, $6) { + var full = $0, + startNewline = $1 || '', + startSlash = $2 || '', + tagName = $3.toLowerCase(), + attr = $4 || '', + endSlash = $5 ? ' ' + $5 : '', + endNewline = $6 || ''; + // 不在名单里的过滤掉 + if (htmlTags && !htmlTagMap[tagName]) { + return ''; + } + // 无闭合标签的自动添加斜线 + if (endSlash === '' && _SINGLE_TAG_MAP[tagName]) { + endSlash = ' /'; + } + // inline tag时自动将多个空白转换成一个空格 + if (_INLINE_TAG_MAP[tagName]) { + if (startNewline) { + startNewline = ' '; + } + if (endNewline) { + endNewline = ' '; + } + } + // pre,style,script tag的格式化 + if (_PRE_TAG_MAP[tagName]) { + if (startSlash) { + endNewline = '\n'; + } else { + startNewline = '\n'; + } + } + // br tag + if (wellFormatted && tagName == 'br') { + endNewline = '\n'; + } + // block tag的格式化 + if (_BLOCK_TAG_MAP[tagName] && !_PRE_TAG_MAP[tagName]) { + if (wellFormatted) { + if (startSlash && tagStack.length > 0 && tagStack[tagStack.length - 1] === tagName) { + tagStack.pop(); + } else { + tagStack.push(tagName); + } + startNewline = '\n'; + endNewline = '\n'; + for (var i = 0, len = startSlash ? tagStack.length : tagStack.length - 1; i < len; i++) { + startNewline += indentChar; + if (!startSlash) { + endNewline += indentChar; + } + } + if (endSlash) { + tagStack.pop(); + } else if (!startSlash) { + endNewline += indentChar; + } + } else { + startNewline = endNewline = ''; + } + } + if (attr !== '') { + var attrMap = _getAttrList(full); + // 将font tag转换成span tag + if (tagName === 'font') { + var fontStyleMap = {}, fontStyle = ''; + _each(attrMap, function(key, val) { + if (key === 'color') { + fontStyleMap.color = val; + delete attrMap[key]; + } + if (key === 'size') { + fontStyleMap['font-size'] = fontSizeList[parseInt(val, 10) - 1] || ''; + delete attrMap[key]; + } + if (key === 'face') { + fontStyleMap['font-family'] = val; + delete attrMap[key]; + } + if (key === 'style') { + fontStyle = val; + } + }); + if (fontStyle && !/;$/.test(fontStyle)) { + fontStyle += ';'; + } + _each(fontStyleMap, function(key, val) { + if (val === '') { + return; + } + if (/\s/.test(val)) { + val = "'" + val + "'"; + } + fontStyle += key + ':' + val + ';'; + }); + attrMap.style = fontStyle; + } + // 处理attribute和style + _each(attrMap, function(key, val) { + // 补全单独属性 + if (_FILL_ATTR_MAP[key]) { + attrMap[key] = key; + } + // 处理URL + if (_inArray(key, ['src', 'href']) >= 0) { + attrMap[key] = _formatUrl(val, urlType); + } + // 过滤属性 + if (htmlTags && key !== 'style' && !htmlTagMap[tagName]['*'] && !htmlTagMap[tagName][key] || + tagName === 'body' && key === 'contenteditable' || + /^kindeditor_\d+$/.test(key)) { + delete attrMap[key]; + } + if (key === 'style' && val !== '') { + var styleMap = _getCssList(val); + _each(styleMap, function(k, v) { + // 过滤样式 + if (htmlTags && !htmlTagMap[tagName].style && !htmlTagMap[tagName]['.' + k]) { + delete styleMap[k]; + } + }); + var style = ''; + _each(styleMap, function(k, v) { + style += k + ':' + v + ';'; + }); + attrMap.style = style; + } + }); + attr = ''; + _each(attrMap, function(key, val) { + if (key === 'style' && val === '') { + return; + } + val = val.replace(/"/g, '"'); + attr += ' ' + key + '="' + val + '"'; + }); + } + if (tagName === 'font') { + tagName = 'span'; + } + return startNewline + '<' + startSlash + tagName + attr + endSlash + '>' + endNewline; + }); + // 将pre里的\n转换成 临时标签 + \n,防止被替换 + html = html.replace(/(<(?:pre|pre\s[^>]*)>)([\s\S]*?)(<\/pre>)/ig, function($0, $1, $2, $3) { + return $1 + $2.replace(/\n/g, '\n') + $3; + }); + html = html.replace(/\n\s*\n/g, '\n'); + // 删除临时标签 + html = html.replace(/\n/g, '\n'); + return _trim(html); +} +// 清理MS Word专用标签 +function _clearMsWord(html, htmlTags) { + html = html.replace(//ig, '') + .replace(//ig, '') + .replace(/]*>[\s\S]*?<\/style>/ig, '') + .replace(/]*>[\s\S]*?<\/script>/ig, '') + .replace(/]+>[\s\S]*?<\/w:[^>]+>/ig, '') + .replace(/]+>[\s\S]*?<\/o:[^>]+>/ig, '') + .replace(/[\s\S]*?<\/xml>/ig, '') + .replace(/<(?:table|td)[^>]*>/ig, function(full) { + return full.replace(/border-bottom:([#\w\s]+)/ig, 'border:$1'); + }); + return _formatHtml(html, htmlTags); +} +// 根据URL判断 media type +function _mediaType(src) { + if (/\.(rm|rmvb)(\?|$)/i.test(src)) { + return 'audio/x-pn-realaudio-plugin'; + } + if (/\.(swf|flv)(\?|$)/i.test(src)) { + return 'application/x-shockwave-flash'; + } + return 'video/x-ms-asf-plugin'; +} +// 根据 media type取得className +function _mediaClass(type) { + if (/realaudio/i.test(type)) { + return 'ke-rm'; + } + if (/flash/i.test(type)) { + return 'ke-flash'; + } + return 'ke-media'; +} + +function _mediaAttrs(srcTag) { + return _getAttrList(unescape(srcTag)); +} + +function _mediaEmbed(attrs) { + var html = ' 0) { + style += 'width:' + width + 'px;'; + } + if (/\D/.test(height)) { + style += 'height:' + height + ';'; + } else if (height > 0) { + style += 'height:' + height + 'px;'; + } + var html = ''; + return html; +} + +// Simple JavaScript Templating +// John Resig - http://ejohn.org/ - MIT Licensed +// http://ejohn.org/blog/javascript-micro-templating/ +function _tmpl(str, data) { + // Figure out if we're getting a template, or if we need to + // load the template - and be sure to cache the result. + var fn = new Function("obj", + "var p=[],print=function(){p.push.apply(p,arguments);};" + + // Introduce the data as local variables using with(){} + "with(obj){p.push('" + + // Convert the template into pure JavaScript + str.replace(/[\r\t\n]/g, " ") + .split("<%").join("\t") + .replace(/((^|%>)[^\t]*)'/g, "$1\r") + .replace(/\t=(.*?)%>/g, "',$1,'") + .split("\t").join("');") + .split("%>").join("p.push('") + .split("\r").join("\\'") + "');}return p.join('');"); + // Provide some basic currying to the user + return data ? fn(data) : fn; +} + +K.formatUrl = _formatUrl; +K.formatHtml = _formatHtml; +K.getCssList = _getCssList; +K.getAttrList = _getAttrList; +K.mediaType = _mediaType; +K.mediaAttrs = _mediaAttrs; +K.mediaEmbed = _mediaEmbed; +K.mediaImg = _mediaImg; +K.clearMsWord = _clearMsWord; +K.tmpl = _tmpl; diff --git a/php/kindeditor_demo/kindeditor/src/main.js b/php/kindeditor_demo/kindeditor/src/main.js new file mode 100755 index 0000000..b6b0fd3 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/src/main.js @@ -0,0 +1,1623 @@ + +var _plugins = {}; + +function _plugin(name, fn) { + if (name === undefined) { + return _plugins; + } + if (!fn) { + return _plugins[name]; + } + _plugins[name] = fn; +} + +var _language = {}; + +function _parseLangKey(key) { + var match, ns = 'core'; + if ((match = /^(\w+)\.(\w+)$/.exec(key))) { + ns = match[1]; + key = match[2]; + } + return { ns : ns, key : key }; +} +/** + @example + K.lang('about'); //get core.about + K.lang('about.version'); // get about.version + K.lang('about.').version; // get about.version + K.lang('about', 'en'); //get English core.about + K.lang({ + core.about : '关于', + about.version : '4.0' + }, 'zh-CN'); //add language +*/ +function _lang(mixed, langType) { + langType = langType === undefined ? K.options.langType : langType; + if (typeof mixed === 'string') { + if (!_language[langType]) { + return 'no language'; + } + var pos = mixed.length - 1; + if (mixed.substr(pos) === '.') { + return _language[langType][mixed.substr(0, pos)]; + } + var obj = _parseLangKey(mixed); + return _language[langType][obj.ns][obj.key]; + } + _each(mixed, function(key, val) { + var obj = _parseLangKey(key); + if (!_language[langType]) { + _language[langType] = {}; + } + if (!_language[langType][obj.ns]) { + _language[langType][obj.ns] = {}; + } + _language[langType][obj.ns][obj.key] = val; + }); +} + +// 当前range为图片时返回KNode,否则返回undefined +function _getImageFromRange(range, fn) { + if (range.collapsed) { + return; + } + range = range.cloneRange().up(); + var sc = range.startContainer, so = range.startOffset; + if (!_WEBKIT && !range.isControl()) { + return; + } + var img = K(sc.childNodes[so]); + if (!img || img.name != 'img') { + return; + } + if (fn(img)) { + return img; + } +} + +function _bindContextmenuEvent() { + var self = this, doc = self.edit.doc; + K(doc).contextmenu(function(e) { + if (self.menu) { + self.hideMenu(); + } + if (!self.useContextmenu) { + e.preventDefault(); + return; + } + if (self._contextmenus.length === 0) { + return; + } + var maxWidth = 0, items = []; + _each(self._contextmenus, function() { + if (this.title == '-') { + items.push(this); + return; + } + if (this.cond && this.cond()) { + items.push(this); + if (this.width && this.width > maxWidth) { + maxWidth = this.width; + } + } + }); + while (items.length > 0 && items[0].title == '-') { + items.shift(); + } + while (items.length > 0 && items[items.length - 1].title == '-') { + items.pop(); + } + var prevItem = null; + _each(items, function(i) { + if (this.title == '-' && prevItem.title == '-') { + delete items[i]; + } + prevItem = this; + }); + if (items.length > 0) { + e.preventDefault(); + var pos = K(self.edit.iframe).pos(), + menu = _menu({ + x : pos.x + e.clientX, + y : pos.y + e.clientY, + width : maxWidth, + css : { visibility: 'hidden' }, + shadowMode : self.shadowMode + }); + _each(items, function() { + if (this.title) { + menu.addItem(this); + } + }); + // 下拉菜单超过可视区域时调整菜单位置 + var docEl = _docElement(menu.doc), + menuHeight = menu.div.height(); + if (e.clientY + menuHeight >= docEl.clientHeight - 100) { + menu.pos(menu.x, _removeUnit(menu.y) - menuHeight); + } + menu.div.css('visibility', 'visible'); + self.menu = menu; + } + }); +} + +function _bindNewlineEvent() { + var self = this, doc = self.edit.doc, newlineTag = self.newlineTag; + if (_IE && newlineTag !== 'br') { + return; + } + if (_GECKO && _V < 3 && newlineTag !== 'p') { + return; + } + if (_OPERA && _V < 9) { + return; + } + var brSkipTagMap = _toMap('h1,h2,h3,h4,h5,h6,pre,li'), + pSkipTagMap = _toMap('p,h1,h2,h3,h4,h5,h6,pre,li,blockquote'); + // 取得range的block标签名 + function getAncestorTagName(range) { + var ancestor = K(range.commonAncestor()); + while (ancestor) { + if (ancestor.type == 1 && !ancestor.isStyle()) { + break; + } + ancestor = ancestor.parent(); + } + return ancestor.name; + } + K(doc).keydown(function(e) { + if (e.which != 13 || e.shiftKey || e.ctrlKey || e.altKey) { + return; + } + self.cmd.selection(); + var tagName = getAncestorTagName(self.cmd.range); + if (tagName == 'marquee' || tagName == 'select') { + return; + } + // br + if (newlineTag === 'br' && !brSkipTagMap[tagName]) { + e.preventDefault(); + self.insertHtml('
        ' + (_IE && _V < 9 ? '' : '\u200B')); + return; + } + // p + if (!pSkipTagMap[tagName]) { + _nativeCommand(doc, 'formatblock', '

        '); + } + }); + K(doc).keyup(function(e) { + if (e.which != 13 || e.shiftKey || e.ctrlKey || e.altKey) { + return; + } + if (newlineTag == 'br') { + return; + } + if (_GECKO) { + var root = self.cmd.commonAncestor('p'); + var a = self.cmd.commonAncestor('a'); + if (a && a.text() == '') { + a.remove(true); + self.cmd.range.selectNodeContents(root[0]).collapse(true); + self.cmd.select(); + } + return; + } + self.cmd.selection(); + var tagName = getAncestorTagName(self.cmd.range); + if (tagName == 'marquee' || tagName == 'select') { + return; + } + if (!pSkipTagMap[tagName]) { + _nativeCommand(doc, 'formatblock', '

        '); + } + // [WEBKIT] 将DIV改成P + var div = self.cmd.commonAncestor('div'); + if (div) { + var p = K('

        '), + child = div[0].firstChild; + while (child) { + var next = child.nextSibling; + p.append(child); + child = next; + } + div.before(p); + div.remove(); + self.cmd.range.selectNodeContents(p[0]); + self.cmd.select(); + } + }); +} + +function _bindTabEvent() { + var self = this, doc = self.edit.doc; + K(doc).keydown(function(e) { + if (e.which == 9) { + e.preventDefault(); + if (self.afterTab) { + self.afterTab.call(self, e); + return; + } + var cmd = self.cmd, range = cmd.range; + range.shrink(); + // Bugfix #271: 回车,按下tab键,光标在下一行显示 + if (range.collapsed && range.startContainer.nodeType == 1) { + range.insertNode(K('@ ', doc)[0]); + cmd.select(); + } + self.insertHtml('    '); + } + }); +} + +function _bindFocusEvent() { + var self = this; + K(self.edit.textarea[0], self.edit.win).focus(function(e) { + if (self.afterFocus) { + self.afterFocus.call(self, e); + } + }).blur(function(e) { + if (self.afterBlur) { + self.afterBlur.call(self, e); + } + }); +} + +function _removeBookmarkTag(html) { + return _trim(html.replace(/]*id="?__kindeditor_bookmark_\w+_\d+__"?[^>]*><\/span>/ig, '')); +} + +function _removeTempTag(html) { + return html.replace(/]+class="?__kindeditor_paste__"?[^>]*>[\s\S]*?<\/div>/ig, ''); +} + +function _addBookmarkToStack(stack, bookmark) { + if (stack.length === 0) { + stack.push(bookmark); + return; + } + var prev = stack[stack.length - 1]; + if (_removeBookmarkTag(bookmark.html) !== _removeBookmarkTag(prev.html)) { + stack.push(bookmark); + } +} + +// undo: _undoToRedo.call(this, undoStack, redoStack); +// redo: _undoToRedo.call(this, redoStack, undoStack); +function _undoToRedo(fromStack, toStack) { + var self = this, edit = self.edit, + body = edit.doc.body, + range, bookmark; + if (fromStack.length === 0) { + return self; + } + if (edit.designMode) { + range = self.cmd.range; + bookmark = range.createBookmark(true); + bookmark.html = body.innerHTML; + } else { + bookmark = { + html : body.innerHTML + }; + } + _addBookmarkToStack(toStack, bookmark); + var prev = fromStack.pop(); + if (_removeBookmarkTag(bookmark.html) === _removeBookmarkTag(prev.html) && fromStack.length > 0) { + prev = fromStack.pop(); + } + if (edit.designMode) { + edit.html(prev.html); + if (prev.start) { + range.moveToBookmark(prev); + self.select(); + } + } else { + K(body).html(_removeBookmarkTag(prev.html)); + } + return self; +} + +function KEditor(options) { + var self = this; + // save original options + self.options = {}; + function setOption(key, val) { + if (KEditor.prototype[key] === undefined) { + self[key] = val; + } + self.options[key] = val; + } + // set options from param + _each(options, function(key, val) { + setOption(key, options[key]); + }); + // set options from default setting + _each(K.options, function(key, val) { + if (self[key] === undefined) { + setOption(key, val); + } + }); + var se = K(self.srcElement || ' +
        +
        +
        +
        + + + + + + diff --git a/php/kindeditor_demo/kindeditor/test/edit.js b/php/kindeditor_demo/kindeditor/test/edit.js new file mode 100755 index 0000000..284dce2 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/edit.js @@ -0,0 +1,52 @@ + +var edit = null; + +var cmds = { + bold : '', + italic : '', + underline : '', + strikethrough : '', + forecolor : '#FF0000', + hilitecolor : '#DDDDDD', + fontsize : '32px', + fontfamily : 'Arial Black', + removeformat : '', + selectall : '' +}; + +K.each(cmds, function(key, val) { + var a = K('' + key + '').bind('click', (function(key, val) { + return function(e) { + edit.cmd[key](val); + e.stop(); + }; + })(key, val)); + K('#cmdArea').append(a); + K('#cmdArea').append(document.createTextNode(' ')); +}); + +edit = K.edit({ + src : 'div#edit', + srcElement : 'body textarea', + width : '700px', + height : '200px', + designMode : true, + bodyClass : 'ke-content', + cssData : 'body {font-size:12px;margin:0;}' +}); + +K('#design').bind('click', function(e) { + if (edit) { + edit.design(true); + } +}); +K('#source').bind('click', function(e) { + if (edit) { + edit.design(false); + } +}); +K('#toggle').bind('click', function(e) { + if (edit) { + edit.design(); + } +}); \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/test/editor.html b/php/kindeditor_demo/kindeditor/test/editor.html new file mode 100755 index 0000000..4315374 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/editor.html @@ -0,0 +1,59 @@ + + + + + KindEditor Unittest + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

        KindEditor Unittest

        +

        KindEditor Unittest

        +

        +
          +
          +
          + +
          + +
          + + + + diff --git a/php/kindeditor_demo/kindeditor/test/editor.js b/php/kindeditor_demo/kindeditor/test/editor.js new file mode 100755 index 0000000..f5176b8 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/editor.js @@ -0,0 +1,140 @@ +module("editor"); + +KindEditor.ready(function (K) { + + var editor = K.create('#content1', { + basePath : '../', + filterMode : false, + wellFormatMode : false + }); + + var editor2 = K.create('#content2', { + basePath : '../', + filterMode : false, + wellFormatMode : false + }); + + test("K.instances", function() { + ok(editor == K.instances[0]); + ok(editor2 == K.instances[1]); + }); + + test("editor.html", function() { + editor.html(undefined); + equals(editor.html(), ''); + + editor.html(null); + equals(editor.html(), ''); + + editor.html('

          abc

          '); + equals(editor.html(), '

          abc

          '); + + editor.html('
          abc
          '); + equals(editor.html(), '
          abc
          '); + + editor.html(''); + equals(editor.html(), ''); + + editor.html('
          abc
          '); + equals(editor.html(), '
          abc
          '); + + editor.html('

          abc

          '); + equals(editor.html(), '

          abc

          '); + + editor.html('
          '); + equals(editor.html(), '
          '); + + editor.html('test'); + equals(editor.html(), 'test'); + + editor.html('test'); + equals(editor.html(), 'test'); + + editor.html(''); + equals(editor.html(), ''); + + editor.html(''); + equals(editor.html(), ''); + + editor.html('test'); + equals(editor.html(), 'test'); + + editor.html(''); + equals(editor.html(), ''); + + editor.html(''); + equals(editor.html(), ''); + + editor.html(''); + equals(editor.html(), ''); + + editor.html(''); + equals(editor.html(), ''); + + }); + + test("editor.text", function() { + editor.html('

          abc

          '); + equals(editor.text(), 'abc'); + editor.html('
          abc
          '); + equals(editor.text(), 'abc'); + editor.text('

          '); + equals(editor.text(), '<p class="a"></p>'); + editor.text(''); + equals(editor.text(), ''); + }); + + test("editor.insertHtml", function() { + editor.html('

          abc

          '); + var h3 = K('#test-h3', editor.edit.doc); + editor.cmd.range.selectNodeContents(h3[0]); + editor.cmd.select(); + editor.insertHtml('abc'); + equals(editor.html(), '

          abc

          '); + editor.html(''); + }); + + test("editor.selectedHtml", function() { + editor.html('abc'); + var span = K('#test', editor.edit.doc); + editor.cmd.range.setStart(span.first()[0], 0).setEnd(span.first()[0], 2); + editor.cmd.select(); + equals(editor.selectedHtml().replace(/<.+?>/g, ''), 'ab'); + editor.html(''); + }); + + test("editor.appendHtml", function() { + editor.html(''); + editor.appendHtml('

          abc

          '); + equals(editor.html(), '

          abc

          '); + editor.appendHtml('
          abc
          '); + equals(editor.html(), '

          abc

          abc
          '); + editor.html(''); + editor.appendHtml('abc'); + equals(editor.html(), 'abc'); + }); + + test("editor.isEmpty", function() { + editor.html('

          abc

          '); + ok(editor.isEmpty() === false); + editor.html('

          '); + ok(editor.isEmpty() === true); + editor.html(''); + ok(editor.isEmpty() === false); + editor.html(''); + }); + + test("editor.count", function() { + editor.html('

          abc

          '); + ok(editor.count('html') === 12); + ok(editor.count('text') === 3); + editor.html('

          '); + ok(editor.count('html') === 9); + ok(editor.count('text') === 0); + editor.html(''); + ok(editor.count('html') === 14); + ok(editor.count('text') === 1); + editor.html(''); + }); + +}); diff --git a/php/kindeditor_demo/kindeditor/test/event.html b/php/kindeditor_demo/kindeditor/test/event.html new file mode 100755 index 0000000..4e39d28 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/event.html @@ -0,0 +1,61 @@ + + + + + KindEditor Event Test + + + + + + + + + + + + + +

          KindEditor Event Test

          +

          +
            +
            + outer event: + inner event: + event method: +
            + +
            + + + + diff --git a/php/kindeditor_demo/kindeditor/test/event.js b/php/kindeditor_demo/kindeditor/test/event.js new file mode 100755 index 0000000..9c208dd --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/event.js @@ -0,0 +1,153 @@ +module('event'); + +test('bind/unbind/fire', function() { + var result = ''; + function click1(e) { + result += 'click1'; + } + //bind + K(document).click(click1); + result = ''; + K(document).click(); + equals(result, 'click1'); + //unbind + K(document).unbind('click', click1); + result = ''; + K(document).click(); + equals(result, ''); + function click2(e) { + K(this).html('click2'); + } + K('#test-data-01').click(click2); + K('#test-data-01').click(); + equals(K('#test-data-01').html(), 'click2'); +}); + +test('unbind(el, type, fn)', function() { + var result = ''; + function click1(e) { + result += 'click1'; + } + function click2(e) { + result += 'click2'; + } + function mousedown1(e) { + result += 'mousedown1'; + } + K(document).click(click1); + K(document).click(click2); + K(document).mousedown(mousedown1); + result = ''; + K(document).click(); + equals(result, 'click1click2'); + result = ''; + K(document).mousedown(); + equals(result, 'mousedown1'); + K(document).unbind('click', click1); + result = ''; + K(document).click(); + equals(result, 'click2'); + K(document).unbind('click', click2); + result = ''; + K(document).click(); + equals(result, ''); + K(document).unbind('mousedown', mousedown1); + result = ''; + K(document).mousedown(); + equals(result, ''); +}); + +test('unbind(el, type)', function() { + var result = ''; + function click1(e) { + result += 'click1'; + } + function click2(e) { + result += 'click2'; + } + function mousedown1(e) { + result += 'mousedown1'; + } + K(document).click(click1); + K(document).click(click2); + K(document).mousedown(mousedown1); + //unbind click + K(document).unbind('click'); + result = ''; + K(document).click(); + equals(result, ''); + //unbind mousedown + K(document).unbind('mousedown'); + result = ''; + K(document).mousedown(); + equals(result, ''); +}); + +test('unbind(el)', function() { + var result = ''; + function click1(e) { + result += 'click1'; + console.log('check'); + } + function click2(e) { + result += 'click2'; + console.log('check'); + } + function mousedown1(e) { + result += 'mousedown1'; + console.log('check'); + } + K(document).click(click1); + K(document).click(click2); + K(document).mousedown(mousedown1); + //unbind + K(document).unbind(); + result = ''; + K(document).click(); + equals(result, ''); + result = ''; + K(document).mousedown(); + equals(result, ''); +}); + +(function () { + var outerEvent = K('#outerEvent'), + innerEvent = K('#innerEvent'), + eventMethod = K('#eventMethod'), + outerDiv = K('#outerDiv'), + innerDiv = K('#innerDiv'); + outerEvent.change(function(e) { + outerDiv.unbind(); + if (outerEvent.val() === 'none') return; + outerDiv.bind(outerEvent.val(), function(e) { + console.log('outer: ' + outerEvent.val()); + if (eventMethod.val() === 'none') return; + e[eventMethod.val()](); + }); + }); + innerEvent.change(function(e) { + innerDiv.unbind(); + if (innerEvent.val() === 'none') return; + innerDiv.bind(innerEvent.val(), function(e) { + console.log('inner: ' + innerEvent.val()); + if (eventMethod.val() === 'none') return; + e[eventMethod.val()](); + }); + }); +})(); + +K.ready(function() { + console.log('ready1'); +}); +K.ready(function() { + console.log('ready2'); +}); +K.ready(function() { + console.log('ready3'); +}); +K.ready(function() { + console.log('ready4'); +}); +K.ready(function() { + console.log('ready5'); +}); \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/test/frame.html b/php/kindeditor_demo/kindeditor/test/frame.html new file mode 100755 index 0000000..f0c2f31 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/frame.html @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/test/hidden.html b/php/kindeditor_demo/kindeditor/test/hidden.html new file mode 100755 index 0000000..a46a144 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/hidden.html @@ -0,0 +1,48 @@ + + + + + + KindEditor Test + + +

            KindEditor Test

            + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/php/kindeditor_demo/kindeditor/test/html.html b/php/kindeditor_demo/kindeditor/test/html.html new file mode 100755 index 0000000..cbb957a --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/html.html @@ -0,0 +1,48 @@ + + + + + KindEditor Unittest + + + + + + + + + + + +

            KindEditor Unittest

            +

            +
              + +
              + + + + + + + + + +
              test
              +
              123
              test
              123
              +
              +
              test
              +
              test
              +
              test
              +
              test
              +
              ddd
              +
              ddd
              +
              ddd
              +
              ddd
              +
              ©
              +
              + + + + + diff --git a/php/kindeditor_demo/kindeditor/test/html.js b/php/kindeditor_demo/kindeditor/test/html.js new file mode 100755 index 0000000..778adc5 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/html.js @@ -0,0 +1,91 @@ +module('html'); + +test("formatUrl", function() { + equals(K.formatUrl(K.query("#test01").value, "absolute", 'http://localhost', '/ke/test'), '/ke/images/xxx.gif'); + equals(K.formatUrl(K.query("#test01").value, "relative", 'http://localhost', '/ke/test'), '../images/xxx.gif'); + equals(K.formatUrl(K.query("#test01").value, "domain", 'http://localhost', '/ke/test'), 'http://localhost/ke/images/xxx.gif'); + equals(K.formatUrl(K.query("#test01").value), '../images/xxx.gif'); + + equals(K.formatUrl(K.query("#test02").value, "absolute", 'http://localhost:8080', '/ke/test'), '/images/xxx.gif'); + equals(K.formatUrl(K.query("#test02").value, "relative", 'http://localhost:8080', '/ke/test'), '../../images/xxx.gif'); + equals(K.formatUrl(K.query("#test02").value, "domain", 'http://localhost:8080', '/ke/test'), 'http://localhost:8080/images/xxx.gif'); + equals(K.formatUrl(K.query("#test02").value), './../../images/xxx.gif'); + + equals(K.formatUrl(K.query("#test03").value, "absolute", 'http://localhost', '/ke/test'), '/ke/images/xxx.gif'); + equals(K.formatUrl(K.query("#test03").value, "relative", 'http://localhost', '/ke/test'), '../images/xxx.gif'); + equals(K.formatUrl(K.query("#test03").value, "domain", 'http://localhost', '/ke/test'), 'http://localhost/ke/images/xxx.gif'); + equals(K.formatUrl(K.query("#test03").value), '/ke/images/xxx.gif'); + + equals(K.formatUrl(K.query("#test04").value, "absolute", 'http://localhost', '/ke/test'), '/ke/images/xxx.gif'); + equals(K.formatUrl(K.query("#test04").value, "relative", 'http://localhost', '/ke/images'), 'xxx.gif'); + equals(K.formatUrl(K.query("#test04").value, "domain", 'http://localhost', '/ke'), 'http://localhost/ke/images/xxx.gif'); + equals(K.formatUrl(K.query("#test04").value), 'http://localhost/ke/images/xxx.gif'); + + equals(K.formatUrl(K.query("#test05").value, "absolute", 'http://localhost', '/ke'), 'http://www.163.com/images/xxx.gif'); + equals(K.formatUrl(K.query("#test05").value, "relative", 'http://localhost', '/ke'), 'http://www.163.com/images/xxx.gif'); + equals(K.formatUrl(K.query("#test05").value, "domain", 'http://localhost', '/ke'), 'http://www.163.com/images/xxx.gif'); + equals(K.formatUrl(K.query("#test05").value), 'http://www.163.com/images/xxx.gif'); + + equals(K.formatUrl(K.query("#test06").value, "absolute", 'http://kindsoft.net', '/'), '/kindeditor/plugins/emoticons/etc_01.gif'); + equals(K.formatUrl(K.query("#test06").value, "relative", 'http://kindsoft.net', '/'), 'kindeditor/plugins/emoticons/etc_01.gif'); + equals(K.formatUrl(K.query("#test06").value, "domain", 'http://kindsoft.net', '/'), 'http://kindsoft.net/kindeditor/plugins/emoticons/etc_01.gif'); + equals(K.formatUrl(K.query("#test06").value), 'http://kindsoft.net/kindeditor/plugins/emoticons/etc_01.gif'); + + equals(K.formatUrl(K.query("#test07").value, "absolute", 'http://kindsoft.net', '/'), 'mailto:test@test.com'); + equals(K.formatUrl(K.query("#test07").value, "relative", 'http://kindsoft.net', '/'), 'mailto:test@test.com'); + equals(K.formatUrl(K.query("#test07").value, "domain", 'http://kindsoft.net', '/'), 'mailto:test@test.com'); + equals(K.formatUrl(K.query("#test07").value), 'mailto:test@test.com'); + + equals(K.formatUrl('http://static.domain.com/img//123.png'), 'http://static.domain.com/img/123.png'); + + equals(K.formatUrl('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='); +}); + +test("formatHtml", function() { + equals(K.formatHtml(K.query("#test11").innerHTML).toLowerCase(), 'test'); + equals(K.formatHtml(K.query("#test11").innerHTML, {span:[".color"]}).toLowerCase(), 'test'); + equals(K.formatHtml(K.query("#test11").innerHTML, {span:[".font-size", "class"]}), 'test'); + equals(K.formatHtml(K.query("#test11").innerHTML, {div:[".font-size", "class"]}), 'test'); + equals(K.formatHtml(K.query("#test11").innerHTML, {span:["style"]}).toLowerCase(), 'test'); + equals(K.formatHtml(K.query("#test11").innerHTML, {span:[]}), 'test'); + + equals(K.formatHtml(K.query("#test12").innerHTML).toLowerCase(), '123
              test
              123'); + equals(K.formatHtml(K.query("#test12").innerHTML, {span:[".color"]}), '123test123'); + equals(K.formatHtml(K.query("#test12").innerHTML, {div:[".font-size", "class"]}), '123
              test
              123'); + equals(K.formatHtml(K.query("#test12").innerHTML, {div:[".color"]}).toLowerCase(), '123
              test
              123'); + equals(K.formatHtml(K.query("#test12").innerHTML, {div:[".color", ".font-weight"]}).toLowerCase(), '123
              test
              123'); + + equals(K.formatHtml(K.query("#test13").innerHTML), ' '); + equals(K.formatHtml(K.query("#test13").innerHTML, {input:["type", "value"]}), ' checkbox'); + equals(K.formatHtml(K.query("#test13").innerHTML, {input:["checked"],label:[]}), ' '); + equals(K.formatHtml(K.query("#test13").innerHTML, {}), 'checkbox'); + + equals(K.formatHtml(K.query("#test14").innerHTML, null, "relative"), ' test'); + + equals(K.formatHtml(K.query("#test16").innerHTML), 'test'); + equals(K.formatHtml(K.query("#test17").innerHTML), 'test'); + + equals(K.formatHtml(K.query("#test18").innerHTML), 'ddd'); + equals(K.formatHtml(K.query("#test19").innerHTML), 'ddd'); + equals(K.formatHtml(K.query("#test20").innerHTML).toLowerCase(), 'ddd'); + equals(K.formatHtml(K.query("#test21").innerHTML), 'ddd'); + + equals(K.formatHtml(K.query("#test22").innerHTML, {}), '©'); + + equals(K.formatHtml('123', {a:['href']}), '123'); + equals(K.formatHtml('123', {a:['*']}), '123'); + + equals(K.formatHtml('

              '), '


              '); + equals(K.formatHtml('

              \t\n
              \n

              '), '


              '); + +}); + + +test("getAttrList/getCssList", function() { + var tag = ''; + var attrList = K.getAttrList(tag); + equals(attrList.href, '#'); + equals(attrList.onclick, 'javascript:if(1<2)alert(1);'); + var cssList = K.getCssList(attrList.style); + equals(cssList['font-family'], '\'Arial Black\''); +}); \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/test/index.html b/php/kindeditor_demo/kindeditor/test/index.html new file mode 100755 index 0000000..e8cb8ac --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/index.html @@ -0,0 +1,11 @@ + + + + + KindEditor Test + + + + + + \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/test/leak.html b/php/kindeditor_demo/kindeditor/test/leak.html new file mode 100755 index 0000000..c95f3ba --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/leak.html @@ -0,0 +1,39 @@ + + + + + KindEditor Memory Leak Test + + + + + + + + + + + + + 刷新 + 返回上一步 + + + diff --git a/php/kindeditor_demo/kindeditor/test/main.html b/php/kindeditor_demo/kindeditor/test/main.html new file mode 100755 index 0000000..eea92a1 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/main.html @@ -0,0 +1,369 @@ + + + + + KindEditor Main Test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

              KindEditor Main Test

              + + + + + +
              + + diff --git a/php/kindeditor_demo/kindeditor/test/menu.html b/php/kindeditor_demo/kindeditor/test/menu.html new file mode 100755 index 0000000..95e5196 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/menu.html @@ -0,0 +1,33 @@ + + + + + KindEditor Menu Test + + + + + + + + + + + + + + + + + + + + + +

              KindEditor Menu Test

              + + + + + + diff --git a/php/kindeditor_demo/kindeditor/test/menu.js b/php/kindeditor_demo/kindeditor/test/menu.js new file mode 100755 index 0000000..f8d1de4 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/menu.js @@ -0,0 +1,72 @@ + +var menu = null; +K('#menu').bind('click', function(e) { + if (menu) { + menu.remove(); + menu = null; + } else { + var menuPos = K('#menu').pos(); + menu = K.menu({ + width : 200, + x : menuPos.x, + y : menuPos.y + K('#menu').height(), + z : 19811212, + centerLineMode : false + }); + K.each('9px,10px,12px,14px,16px,18px,24px,32px'.split(','), function(i, val) { + menu.addItem({ + title : '' + val + '', + click : function() { + alert(val); + }, + height : parseInt(val, 10) + 12, + checked : val === '12px' + }); + }); + } +}); + +var contextmenu = null; +K('#contextmenu').bind('click', function(e) { + if (contextmenu) { + contextmenu.remove(); + contextmenu = null; + } else { + var contextmenuPos = K('#contextmenu').pos(); + contextmenu = K.menu({ + width : 200, + x : contextmenuPos.x, + y : contextmenuPos.y + K('#contextmenu').height(), + z : 19811213 + }); + K.each('image,flash,media,-,bold,cut,copy,paste,-,selectall'.split(','), function(i, val) { + contextmenu.addItem({ + title : val, + click : function() { + alert(val); + }, + iconClass : 'ke-icon-' + val + }); + }); + } +}); + +var colorpicker = null; +K('#colorpicker').bind('click', function(e) { + if (colorpicker) { + colorpicker.remove(); + colorpicker = null; + } else { + var colorpickerPos = K('#colorpicker').pos(); + colorpicker = K.colorpicker({ + x : colorpickerPos.x, + y : colorpickerPos.y + K('#colorpicker').height(), + z : 19811214, + selectedColor : 'default', + noColor : '无颜色', + click : function(color) { + alert(color); + } + }); + } +}); \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/test/navi.html b/php/kindeditor_demo/kindeditor/test/navi.html new file mode 100755 index 0000000..c2e24cb --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/navi.html @@ -0,0 +1,36 @@ + + + + + KindEditor Test + + + + + + + \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/test/node.html b/php/kindeditor_demo/kindeditor/test/node.html new file mode 100755 index 0000000..9ae86eb --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/node.html @@ -0,0 +1,62 @@ + + + + + KindEditor Unittest + + + + + + + + + + + + + + + + +

              KindEditor Unittest

              +

              +
                + + +
                +

                +abcdefghijkxyz
                +0123456789
                +

                +
                div area
                +
                div area 2
                + +
                + + + + + + + + + + diff --git a/php/kindeditor_demo/kindeditor/test/node.js b/php/kindeditor_demo/kindeditor/test/node.js new file mode 100755 index 0000000..de7ec94 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/node.js @@ -0,0 +1,206 @@ +module('node'); + +test('K(html)', function(){ + var node = K('
                abc

                '); + equals(node.name, 'div'); + equals(node.length, 3); + equals(node.attr('class'), 'abc'); + equals(node.css('font-size'), '12px'); + equals(K('@p > strong').get().nodeValue, 'p > strong'); + equals(K('@1 2 ').get().nodeValue, '1 2 '); +}); + +test('K(selector)', function(){ + var node = K('p > strong'); + equals(node.name, 'strong'); + equals(node.get(1).nodeName.toLowerCase(), 'strong'); + equals(node.get(2).nodeName.toLowerCase(), 'strong'); + equals(node.length, 3); +}); + +test('K(node)', function(){ + var node = K(document.createTextNode('abc'), document.createElement('div')); + equals(node.name, '#text'); + equals(node.get(1).nodeName.toLowerCase(), 'div'); + equals(node.length, 2); +}); + +test('get', function() { + var div = K('div'); + ok(div.get(0) === div[0]); +}); + +test('eq', function() { + var div = K('div'); + ok(div.eq(0)[0] === div[0]); +}); + +test('attr/removeAttr', function() { + equals(K('#test-data-01').attr('src', 'aaa').attr('src'), 'aaa'); + equals(K('#test-data-02').attr('src', 'aaa').removeAttr('src').attr('src'), ''); + equals(K('#test-data-01').attr('id'), 'test-data-01'); + equals(K('#test-data-01').attr('class'), 'test-class'); + equals(K('#test-data-01 p img').attr('src'), './data/logo_180_30.gif'); + equals(K('#test-data-03 p span').attr('style'), 'color:red;'); + equals(K('#test-data-01 p img').attr('border'), '0'); + equals(K('#test-data-01').attr('class'), 'test-class'); + equals(K('
                ').attr('class', 'aaa').attr('class'), 'aaa'); + equals(K('
                ').removeAttr('class').attr('class'), ''); + equals(K('
                ').attr('style'), 'color:red;'); +}); + +test("hasClass/addClass/removeClass", function() { + var knode = K('
                '); + var div = knode.get(); + knode.addClass('aaa'); + ok(knode.hasClass('aaa')); + equals(div.className, 'aaa'); + knode.addClass('aaa'); + equals(div.className, 'aaa'); + knode.addClass('bbb'); + ok(knode.hasClass('bbb')); + equals(div.className, 'aaa bbb'); + knode.addClass('ccc'); + ok(knode.hasClass('ccc')); + equals(div.className, 'aaa bbb ccc'); + knode.removeClass('aaa'); + ok(!knode.hasClass('aaa')); + equals(div.className, 'bbb ccc'); + knode.removeClass('bbb'); + ok(!knode.hasClass('bbb')); + equals(div.className, 'ccc'); + knode.removeClass('ccc'); + ok(!knode.hasClass('ccc')); + equals(div.className, ''); + equals(K('
                ').addClass('aaa').removeClass('aaa').addClass('bbb').get().className, 'bbb'); +}); + +test("contains",function(){ + ok(K('#test-data-01 p').contains(K('#test-data-01 p')) === false); + ok(K('#test-data-01').contains(K('#test-data-01 p')) === true); + ok(K('#test-data-01 strong').contains(K('#test-data-01 strong').first()) === true); + ok(K(document).contains(K('#test-data-01 strong')) === true); + ok(K(document).contains(document) === false); + ok(K(document).contains(document.body)); + ok(K('#test-data-01 strong').first().contains(K('#test-data-01 strong')) === false); +}); + +test("val",function(){ + equals(K('').val(), "aa"); + equals(K('
                ').val(), "aa"); + equals(K('').val("bb").val(), "bb"); + equals(K('
                ').val("").val(), ""); + equals(K('').val('abc').val(), 'abc'); +}); + +test("css",function(){ + var node = K('
                '); + equals(node.css('width','300px').css('width'), '300px'); + equals(node.css('border','1px solid #ccc').css('border'),node.css('border')); + node = K('#test-data-01'); + equals(node.css('width'), '300px'); +}); + +test("width/height",function(){ + equals(K('#test-data-01').width(), 300); + ok(K('#test-data-01').height() > 110); +}); + +test("append",function(){ + var node = K('

                ').append('@abc'); + equals(node.html(), 'abc'); + equals(K(node[1]).html(), 'abc'); +}); + +test("before",function(){ + var parent = K('

                '); + K(document.body).append(parent); + K('.abc', parent).before('def'); + var children = parent.children(); + equals(children.length, 4); + equals(K(children[0]).name, 'span'); + equals(K(children[1]).name, 'div'); + equals(K(children[2]).name, 'span'); + equals(K(children[3]).name, 'p'); + parent.remove(); +}); + +test("after",function(){ + var parent = K('

                '); + K(document.body).append(parent); + K('.abc', parent).after('def'); + var children = parent.children(); + equals(children.length, 4); + equals(K(children[0]).name, 'div'); + equals(K(children[1]).name, 'span'); + equals(K(children[2]).name, 'p'); + equals(K(children[3]).name, 'span'); + parent.remove(); +}); + +test("replaceWith",function(){ + var node = K('
                ').replaceWith('

                '); + equals(node.length, 1); + equals(node.name, 'p'); +}); + +test("remove",function(){ + var node = K('

                123

                ').addClass('abc').html('test'); + node.remove(); + equals(node.length, 0); + // Test preserve child nodes. + var node = K('

                123456789

                '); + K('p', node).remove(true); + equals(node.html(), '123456789'); +}); + +test("html",function(){ + var node = K('
                xxx
                '); + K(document.body).append(node); + equals(node.html(), 'xxx'); + equals(node.html('bbb').html(), 'bbb'); + equals(K('').html('abc').html(), 'abc'); + equals(node.html('


                ').html(), '


                '); + equals(node.html('').html(), ''); + node.remove(); +}); + +test("outer",function(){ + var node = K('
                xxx
                '); + equals(node.outer(), '
                xxx
                '); + equals(node.addClass('aaa').outer(), '
                xxx
                '); +}); + +test("chidren",function(){ + var node = K('
                abc123
                '); + equals(node.children().length, 2); + equals(node.children().name, 'span'); + equals(K('
                ').children().length, 0); +}); + +test('show/hide',function(){ + var node = K('
                '); + equals(node.show().outer(), '
                '); + equals(node.hide().outer(), '
                '); + equals(node.show().outer(), '
                '); + + node = K('
                '); + equals(node.show().outer(), '
                '); + equals(node.hide().outer(), '
                '); + equals(node.show().outer(), '
                '); + + node = K('
                '); + equals(node.show().outer(), '
                '); + equals(node.hide().outer(), '
                '); + equals(node.show().outer(), '
                '); +}); + +test("data", function(){ + K(document).data('abc', '123'); + K('body').data('abc', '1234'); + K('body div').data('abc', '12345'); + + equals(K(document).data('abc'), '123'); + equals(K('body').data('abc'), '1234'); + equals(K('body div').data('abc'), '12345'); +}); diff --git a/php/kindeditor_demo/kindeditor/test/quirkmode.html b/php/kindeditor_demo/kindeditor/test/quirkmode.html new file mode 100755 index 0000000..3d7bc82 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/quirkmode.html @@ -0,0 +1,25 @@ + + + + + KindEditor Test + + +

                KindEditor Test

                +
                + +
                + + + + +
                + + diff --git a/php/kindeditor_demo/kindeditor/test/range.html b/php/kindeditor_demo/kindeditor/test/range.html new file mode 100755 index 0000000..abbef04 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/range.html @@ -0,0 +1,52 @@ + + + + + KindEditor Unittest + + + + + + + + + + + + + +

                KindEditor Unittest

                +

                +
                  + + + + + + + + + + + diff --git a/php/kindeditor_demo/kindeditor/test/range.js b/php/kindeditor_demo/kindeditor/test/range.js new file mode 100755 index 0000000..3197aca --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/range.js @@ -0,0 +1,812 @@ +module('range'); + +test('range', function() { + var p = K.query('#test-data-01 p'); + var strong = K.query('#test-data-01 strong'); + + var range, nativeRange; + range = K.range(document); + ok(range.startContainer === document); + ok(range.startOffset === 0); + ok(range.endContainer === document); + ok(range.endOffset === 0); + ok(range.collapsed === true); + ok(range.commonAncestor() === document); + + range = K.range(document); + range.selectNodeContents(strong); + nativeRange = range.get(); + var newRange = K.range(nativeRange); + same(range.toString(), newRange.toString()); +}); + +test('range.setStart', function() { + expect(6); + + var p = K.query('#test-data-01 p'); + var strong = K.query('#test-data-01 strong'); + + var range = K.range(document); + range.setStart(strong.previousSibling, 3); + + ok(range.startContainer === strong.previousSibling); + ok(range.startOffset === 3); + ok(range.endContainer === strong.previousSibling); + ok(range.endOffset === 3); + ok(range.collapsed === true); + ok(range.commonAncestor() === strong.previousSibling); +}); + +test('range.setEnd', function() { + expect(6); + + var p = K.query('#test-data-01 p'); + var strong = K.query('#test-data-01 strong'); + + var range = K.range(document); + range.setStart(strong.previousSibling, 3); + range.setEnd(p, 4); + + ok(range.startContainer === strong.previousSibling); + ok(range.startOffset === 3); + ok(range.endContainer === p); + ok(range.endOffset === 4); + ok(range.collapsed === false); + ok(range.commonAncestor() === p); +}); + +test('range.setStartBefore', function() { + expect(6); + + var p = K.query('#test-data-01 p'); + var strong = K.query('#test-data-01 strong'); + + var range = K.range(document); + range.setStartBefore(strong); + + ok(range.startContainer === p); + ok(range.startOffset === 1); + ok(range.endContainer === p); + ok(range.endOffset === 1); + ok(range.collapsed === true); + ok(range.commonAncestor() === p); +}); + +test('range.setStartAfter', function() { + expect(6); + + var p = K.query('#test-data-01 p'); + var strong = K.query('#test-data-01 strong'); + + var range = K.range(document); + range.setStartAfter(strong); + + ok(range.startContainer === p); + ok(range.startOffset === 2); + ok(range.endContainer === p); + ok(range.endOffset === 2); + ok(range.collapsed === true); + ok(range.commonAncestor() === p); +}); + +test('range.setEndBefore', function() { + expect(6); + + var p = K.query('#test-data-01 p'); + var strong = K.query('#test-data-01 strong'); + + var range = K.range(document); + range.setEndBefore(strong); + ok(range.startContainer === p); + ok(range.startOffset === 1); + ok(range.endContainer === p); + ok(range.endOffset === 1); + ok(range.collapsed === true); + ok(range.commonAncestor() === p); +}); + +test('range.setEndAfter', function() { + expect(6); + + var p = K.query('#test-data-01 p'); + var strong = K.query('#test-data-01 strong'); + + var range = K.range(document); + range.setStartAfter(strong); + range.setEndAfter(strong); + + ok(range.startContainer === p); + ok(range.startOffset === 2); + ok(range.endContainer === p); + ok(range.endOffset === 2); + ok(range.collapsed === true); + ok(range.commonAncestor() === p); +}); + +test('range.selectNode', function() { + expect(6); + + var p = K.query('#test-data-01 p'); + var strong = K.query('#test-data-01 strong'); + + var range = K.range(document); + range.selectNode(strong); + ok(range.startContainer === p); + ok(range.startOffset === 1); + ok(range.endContainer === p); + ok(range.endOffset === 2); + ok(range.collapsed === false); + ok(range.commonAncestor() === p); +}); + +test('range.selectNodeContents', function() { + var range, strong, img, p; + //1 + strong = K.query('#test-data-01 strong'); + range = K.range(document); + range.selectNodeContents(strong); + ok(range.startContainer === strong); + ok(range.startOffset === 0); + ok(range.endContainer === strong); + ok(range.endOffset === 1); + ok(range.collapsed === false); + ok(range.commonAncestor() === strong); + //2 + img = K.query('#test-data-01 img'); + range = K.range(document); + range.selectNodeContents(img); + ok(range.startContainer === img.parentNode); + ok(range.startOffset === 3); + ok(range.endContainer === img.parentNode); + ok(range.endOffset === 4); + ok(range.collapsed === false); + ok(range.commonAncestor() === img.parentNode); + //3 + strong = K.query('#test-data-02 strong'); + range = K.range(document); + range.selectNodeContents(strong); + ok(range.startContainer === strong); + ok(range.startOffset === 0); + ok(range.endContainer === strong); + ok(range.endOffset === 0); + ok(range.collapsed === true); + ok(range.commonAncestor() === strong); + //4 + p = K.query('#test-data-02 p'); + range = K.range(document); + range.selectNodeContents(p); + ok(range.startContainer === p); + ok(range.endContainer === p); + ok(range.startOffset === 0); + ok(range.endOffset === 7); + ok(range.collapsed === false); + ok(range.commonAncestor() === p); +}); + +test('range.collapse', function() { + var p = K.query('#test-data-01 p'); + var strong = K.query('#test-data-01 strong'); + var range; + range = K.range(document); + range.setStart(p.childNodes[2], 0); + range.setEnd(p.childNodes[4], 2); + range.collapse(true); + ok(range.startContainer === range.endContainer); + ok(range.startOffset === range.endOffset); + ok(range.collapsed === true); + range = K.range(document); + range.setStart(p.childNodes[2], 0); + range.setEnd(p.childNodes[4], 2); + range.collapse(false); + ok(range.startContainer === range.endContainer); + ok(range.startOffset === range.endOffset); + ok(range.collapsed === true); +}); + +test('range.compareBoundaryPoints', function() { + var p = K.query('#test-data-01 p'); + var strong = K.query('#test-data-01 strong'); + var cmp, rangeA, rangeB; + //1 + rangeA = K.range(document); + rangeB = K.range(document); + rangeA.setStart(p.childNodes[0], 0); + rangeA.setEnd(p.childNodes[0], 2); + rangeB.setStart(p.childNodes[4], 0); + rangeB.setEnd(p.childNodes[4], 2); + cmp = rangeA.compareBoundaryPoints(K.START_TO_START, rangeB); + ok(cmp === -1); + cmp = rangeA.compareBoundaryPoints(K.START_TO_END, rangeB); + ok(cmp === -1); + cmp = rangeA.compareBoundaryPoints(K.END_TO_END, rangeB); + ok(cmp === -1); + cmp = rangeA.compareBoundaryPoints(K.END_TO_START, rangeB); + ok(cmp === -1); + //2 + rangeA = K.range(document); + rangeB = K.range(document); + rangeA.setStart(p.childNodes[0], 0); + rangeA.setEnd(p.childNodes[4], 3); + rangeB.setStart(p.childNodes[4], 0); + rangeB.setEnd(p.childNodes[4], 2); + cmp = rangeA.compareBoundaryPoints(K.START_TO_START, rangeB); + ok(cmp === -1); + cmp = rangeA.compareBoundaryPoints(K.START_TO_END, rangeB); + ok(cmp === 1); + cmp = rangeA.compareBoundaryPoints(K.END_TO_END, rangeB); + ok(cmp === 1); + cmp = rangeA.compareBoundaryPoints(K.END_TO_START, rangeB); + ok(cmp === -1); + //3 + rangeA = K.range(document); + rangeB = K.range(document); + rangeA.setStart(p.childNodes[0], 0); + rangeA.setEnd(p.childNodes[2], 3); + rangeB.setStart(p.childNodes[2], 0); + rangeB.setEnd(p.childNodes[4], 2); + cmp = rangeA.compareBoundaryPoints(K.START_TO_START, rangeB); + ok(cmp === -1); + cmp = rangeA.compareBoundaryPoints(K.START_TO_END, rangeB); + ok(cmp === 1); + cmp = rangeA.compareBoundaryPoints(K.END_TO_END, rangeB); + ok(cmp === -1); + cmp = rangeA.compareBoundaryPoints(K.END_TO_START, rangeB); + ok(cmp === -1); + //4 + rangeA = K.range(document); + rangeB = K.range(document); + rangeA.selectNode(strong); + rangeB.selectNode(p); + cmp = rangeA.compareBoundaryPoints(K.START_TO_START, rangeB); + ok(cmp === 1); + cmp = rangeA.compareBoundaryPoints(K.START_TO_END, rangeB); + ok(cmp === 1); + cmp = rangeA.compareBoundaryPoints(K.END_TO_END, rangeB); + ok(cmp === -1); + cmp = rangeA.compareBoundaryPoints(K.END_TO_START, rangeB); + ok(cmp === -1); + //5 + rangeA = K.range(document); + rangeB = K.range(document); + rangeA.setStart(p.childNodes[0], 0); + rangeA.setEnd(p.childNodes[0], 2); + rangeB.setStart(p.childNodes[0], 0); + rangeB.setEnd(p.childNodes[0], 2); + cmp = rangeA.compareBoundaryPoints(K.START_TO_START, rangeB); + ok(cmp === 0); + cmp = rangeA.compareBoundaryPoints(K.START_TO_END, rangeB); + ok(cmp === 1); + cmp = rangeA.compareBoundaryPoints(K.END_TO_END, rangeB); + ok(cmp === 0); + cmp = rangeA.compareBoundaryPoints(K.END_TO_START, rangeB); + ok(cmp === -1); + //6 + rangeA = K.range(document); + rangeB = K.range(document); + rangeA.selectNode(strong); + rangeB.selectNode(strong.firstChild); + cmp = rangeA.compareBoundaryPoints(K.START_TO_START, rangeB); + ok(cmp === -1); + cmp = rangeA.compareBoundaryPoints(K.START_TO_END, rangeB); + ok(cmp === 1); + cmp = rangeA.compareBoundaryPoints(K.END_TO_END, rangeB); + ok(cmp === 1); + cmp = rangeA.compareBoundaryPoints(K.END_TO_START, rangeB); + ok(cmp === -1); + //7 + rangeA = K.range(document); + rangeB = K.range(document); + rangeA.selectNode(strong.firstChild); + rangeB.setStart(strong.firstChild, 0); + rangeB.setEnd(strong.firstChild, 2); + cmp = rangeA.compareBoundaryPoints(K.START_TO_START, rangeB); + ok(cmp === -1); + cmp = rangeA.compareBoundaryPoints(K.START_TO_END, rangeB); + ok(cmp === 1); + cmp = rangeA.compareBoundaryPoints(K.END_TO_END, rangeB); + ok(cmp === 1); + cmp = rangeA.compareBoundaryPoints(K.END_TO_START, rangeB); + ok(cmp === -1); + //8 + rangeA = K.range(document); + rangeB = K.range(document); + rangeA.selectNode(p.childNodes[3]); + rangeB.selectNode(strong.firstChild); + rangeB.setEnd(strong.nextSibling, 4); + cmp = rangeA.compareBoundaryPoints(K.START_TO_START, rangeB); + ok(cmp === 1); + cmp = rangeA.compareBoundaryPoints(K.START_TO_END, rangeB); + ok(cmp === 1); + cmp = rangeA.compareBoundaryPoints(K.END_TO_END, rangeB); + ok(cmp === 1); + cmp = rangeA.compareBoundaryPoints(K.END_TO_START, rangeB); + ok(cmp === 1); + //9 + rangeA = K.range(document); + rangeB = K.range(document); + rangeA.selectNode(strong.previousSibling); + rangeB.setStart(p, 1); + rangeB.setEnd(strong.firstChild, 3); + cmp = rangeA.compareBoundaryPoints(K.START_TO_START, rangeB); + ok(cmp === -1); + cmp = rangeA.compareBoundaryPoints(K.START_TO_END, rangeB); + ok(cmp === 0); + cmp = rangeA.compareBoundaryPoints(K.END_TO_END, rangeB); + ok(cmp === -1); + cmp = rangeA.compareBoundaryPoints(K.END_TO_START, rangeB); + ok(cmp === -1); + //10 + rangeA = K.range(document); + rangeB = K.range(document); + rangeA.selectNode(strong.previousSibling); + rangeB.selectNode(strong.firstChild); + rangeB.setEnd(strong.nextSibling, 4); + cmp = rangeA.compareBoundaryPoints(K.START_TO_START, rangeB); + ok(cmp === -1); + cmp = rangeA.compareBoundaryPoints(K.START_TO_END, rangeB); + ok(cmp === -1); + cmp = rangeA.compareBoundaryPoints(K.END_TO_END, rangeB); + ok(cmp === -1); + cmp = rangeA.compareBoundaryPoints(K.END_TO_START, rangeB); + ok(cmp === -1); + //10 + rangeA = K.range(document); + rangeB = K.range(document); + rangeA.setStart(strong.previousSibling, 4); + rangeB.setStart(strong.firstChild, 0); + cmp = rangeA.compareBoundaryPoints(K.START_TO_END, rangeB); + ok(cmp === -1); +}); + +test('range.cloneRange', function() { + expect(6); + var p = K.query('#test-data-01 p'); + var strong = K.query('#test-data-01 strong'); + + var range = K.range(document); + range.setStart(p.childNodes[2], 0); + range.setEnd(p.childNodes[4], 2); + var cloneRange = range.cloneRange(); + ok(range.startContainer === cloneRange.startContainer); + ok(range.startOffset === cloneRange.startOffset); + ok(range.endContainer === cloneRange.endContainer); + ok(range.endOffset === cloneRange.endOffset); + ok(range.collapsed === cloneRange.collapsed); + ok(range.commonAncestor() === cloneRange.commonAncestor()); +}); + +test('range.toString', function() { + var p = K.query('#test-data-01 p'); + var strong = K.query('#test-data-01 strong'); + var range; + //1 + range = K.range(document); + range.selectNode(strong); + same(range.toString(), 'efg'); + //2 + range = K.range(document); + range.selectNode(strong); + range.setStart(strong.firstChild, 1); + same(range.toString(), 'fg'); + //3 + range = K.range(document); + range.setStart(strong.firstChild, 1); + range.setEnd(strong.firstChild, 2); + same(range.toString(), 'f'); + //4 + range = K.range(document); + range.setStart(p.childNodes[0], 0); + range.setEnd(p.childNodes[4], 2); + same(range.toString(), 'abcdefghijkxy'); + //5 + range = K.range(document); + range.setStart(p.childNodes[4], 1); + range.setEnd(p.childNodes[4], 2); + same(range.toString(), 'y'); + //6 + range = K.range(document); + range.selectNode(p); + same(range.toString(), 'abcdefghijkxyz0123456789'); + //7 + range = K.range(document); + range.selectNode(strong.firstChild); + same(range.toString(), 'efg'); + //8 + range = K.range(document); + range.selectNode(strong); + same(range.toString(), 'efg'); + //9 + range = K.range(document); + same(range.toString(), ''); + //10 + range = K.range(document); + range.selectNode(document.body); + ok(range.toString().length > 100); +}); + +test('range.cloneContents', function() { + var p = K.query('#test-data-01 p'); + var strong = K.query('#test-data-01 strong'); + var range, frag; + //1 + range = K.range(document); + range.selectNode(strong); + frag = range.cloneContents(); + same(K(frag).outer().toLowerCase(), 'efg'); + ok(!range.collapsed); + //2 + range = K.range(document); + range.setStart(strong.firstChild, 1); + range.setEnd(strong.firstChild, 2); + frag = range.cloneContents(); + same(K(frag).outer().toLowerCase(), 'f'); + //3 + range = K.range(document); + range.setStart(strong.firstChild, 0); + range.setEnd(strong.firstChild, 3); + frag = range.cloneContents(); + same(K(frag).outer().toLowerCase(), 'efg'); + //4 + range = K.range(document); + range.setStart(strong.firstChild, 1); + range.setEnd(strong.nextSibling, 1); + frag = range.cloneContents(); + same(K(frag).outer().toLowerCase(), 'fgh'); + //5 + range = K.range(document); + range.setStart(strong.firstChild, 1); + range.setEnd(strong.nextSibling, 0); + frag = range.cloneContents(); + same(K(frag).outer().toLowerCase(), 'fg'); + //6 + range = K.range(document); + range.setStart(p, 0); + range.setEnd(p, 4); + frag = range.cloneContents(); + ok(K(frag).children().length === 4); + //7 + range = K.range(document); + range.selectNode(strong.firstChild); + range.setEnd(strong.nextSibling, 4); + frag = range.cloneContents(); + same(K(frag).outer().toLowerCase(), 'efghijk'); + //8 + range = K.range(document); + range.setStart(strong.nextSibling, 4); + range.setEnd(p, 4); + frag = range.cloneContents(); + ok(K(frag).children().length === 1); + same(K(frag).first().name, 'img'); +}); + +test('range.extractContents', function() { + var p = K.query('#test-data-01 p'), + cloneP, strong, range, frag, div; + //1 + cloneP = p.cloneNode(true); + document.body.appendChild(cloneP); + strong = K.query('strong', cloneP); + range = K.range(document); + range.selectNode(strong); + frag = range.extractContents(); + same(K(frag).outer().toLowerCase(), 'efg'); + ok(range.collapsed); + document.body.removeChild(cloneP); + //2 + cloneP = p.cloneNode(true); + document.body.appendChild(cloneP); + strong = K.query('strong', cloneP); + range = K.range(document); + range.setStart(strong.firstChild, 1); + range.setEnd(strong.firstChild, 2); + frag = range.extractContents(); + same(K(frag).outer().toLowerCase(), 'f'); + document.body.removeChild(cloneP); + //3 + cloneP = p.cloneNode(true); + document.body.appendChild(cloneP); + strong = K.query('strong', cloneP); + range = K.range(document); + range.setStart(strong.firstChild, 0); + range.setEnd(strong.firstChild, 3); + frag = range.extractContents(); + same(K(frag).outer().toLowerCase(), 'efg'); + document.body.removeChild(cloneP); + //4 + cloneP = p.cloneNode(true); + document.body.appendChild(cloneP); + strong = K.query('strong', cloneP); + range = K.range(document); + range.setStart(strong.firstChild, 1); + range.setEnd(strong.nextSibling, 1); + frag = range.extractContents(); + same(K(frag).outer().toLowerCase(), 'fgh'); + document.body.removeChild(cloneP); + //5 + cloneP = p.cloneNode(true); + document.body.appendChild(cloneP); + strong = K.query('strong', cloneP); + range = K.range(document); + range.setStart(strong.firstChild, 1); + range.setEnd(strong.nextSibling, 0); + frag = range.extractContents(); + same(K(frag).outer().toLowerCase(), 'fg'); + document.body.removeChild(cloneP); + //6 + cloneP = p.cloneNode(true); + document.body.appendChild(cloneP); + strong = K.query('strong', cloneP); + range = K.range(document); + range.setStart(cloneP, 0); + range.setEnd(cloneP, 4); + frag = range.extractContents(); + ok(K(frag).children().length === 4); + document.body.removeChild(cloneP); + //7 + cloneP = p.cloneNode(true); + document.body.appendChild(cloneP); + strong = K.query('strong', cloneP); + range = K.range(document); + range.selectNode(strong.firstChild); + range.setEnd(strong.nextSibling, 4); + frag = range.extractContents(); + same(K(frag).outer().toLowerCase(), 'efghijk'); + document.body.removeChild(cloneP); + //8 + cloneP = p.cloneNode(true); + document.body.appendChild(cloneP); + strong = K.query('strong', cloneP); + range = K.range(document); + range.setStart(cloneP, 3); + range.setEnd(cloneP, 4); + frag = range.extractContents(); + ok(K(frag).children().length === 1); + same(K(frag).first().name, 'img'); + document.body.removeChild(cloneP); + //9 + cloneP = p.cloneNode(true); + document.body.appendChild(cloneP); + strong = K.query('strong', cloneP); + range = K.range(document); + range.setStart(cloneP, 1); + range.setEnd(strong.firstChild, 3); + frag = range.extractContents(); + same(K(frag).outer().toLowerCase(), 'efg'); + document.body.removeChild(cloneP); + //10 + cloneP = p.cloneNode(true); + document.body.appendChild(cloneP); + strong = K.query('strong', cloneP); + range = K.range(document); + range.setStart(cloneP, 0); + range.setEnd(strong.firstChild, 1); + frag = range.extractContents(); + same(K(frag).outer(), 'abcde'); + document.body.removeChild(cloneP); + //11 + div = K('
                  efg
                  '); + document.body.appendChild(div[0]); + range = K.range(document); + range.setStart(div[0], 1); + range.setEnd(div.last().first()[0], 1); + frag = range.extractContents(); + same(div.outer().toLowerCase(), '
                  eg
                  '); + same(K(frag).outer().toLowerCase(), 'f'); + document.body.removeChild(div[0]); + //12 + div = K('
                  abcdefghijk
                  '); + document.body.appendChild(div[0]); + range = K.range(document); + range.setStart(div[0], 2); + range.setEnd(div.children()[2], 1); + frag = range.extractContents(); + same(div.outer().toLowerCase(), '
                  abcdhijk
                  '); + same(K(frag).outer().toLowerCase(), 'efg'); + document.body.removeChild(div[0]); + //13 + div = K('
                  abcdefghijk
                  '); + document.body.appendChild(div[0]); + range = K.range(document); + range.setStart(div.children().eq(2).first()[0], 1); + range.setEnd(div[0], 4); + frag = range.extractContents(); + same(div.outer().toLowerCase(), '
                  abcdefg
                  '); + same(K(frag).outer().toLowerCase(), 'hijk'); + document.body.removeChild(div[0]); + //14 + div = K('
                  \nabcd\n
                  '); + document.body.appendChild(div[0]); + range = K.range(document); + range.setStart(div.first().next()[0], 1); + range.setEnd(div[0], 3); + frag = range.extractContents(); + same(div.html().toLowerCase(), 'abcd'); + same(K(frag).outer().toLowerCase(), ''); + document.body.removeChild(div[0]); +}); + +test('range.deleteContents', function() { + var p = K.query('#test-data-01 p'), + cloneP, strong, range, frag; + //1 + cloneP = p.cloneNode(true); + document.body.appendChild(cloneP); + strong = K.query('strong', cloneP); + range = K.range(document); + range.selectNode(strong); + frag = range.deleteContents(); + ok(range.collapsed); + ok(frag === range); + document.body.removeChild(cloneP); +}); + +test('range.insertNode', function() { + var p = K.query('#test-data-01 p'), + cloneP, strong, range, frag; + //1 + cloneP = p.cloneNode(true); + document.body.appendChild(cloneP); + strong = K.query('strong', cloneP); + range = K.range(document); + range.selectNode(strong); + range.insertNode(K('abc').get()); + same(range.toString(), 'abcefg'); + document.body.removeChild(cloneP); + //2 + cloneP = p.cloneNode(true); + document.body.appendChild(cloneP); + strong = K.query('strong', cloneP); + range = K.range(document); + range.selectNode(strong.firstChild); + range.insertNode(K('123').get()); + same(range.toString(), '123efg'); + document.body.removeChild(cloneP); + //3 + cloneP = p.cloneNode(true); + document.body.appendChild(cloneP); + strong = K.query('strong', cloneP); + range = K.range(document); + range.setStart(strong.firstChild, 0); + range.setEnd(strong.firstChild, 3); + range.insertNode(K('123').get()); + same(range.toString(), '123efg'); + document.body.removeChild(cloneP); + //4 + cloneP = p.cloneNode(true); + document.body.appendChild(cloneP); + strong = K.query('strong', cloneP); + range = K.range(document); + range.setStart(strong.firstChild, 1); + range.setEnd(strong.firstChild, 2); + range.insertNode(K('123').get()); + same(range.toString(), '123f'); + document.body.removeChild(cloneP); + //5 + cloneP = p.cloneNode(true); + document.body.appendChild(cloneP); + strong = K.query('strong', cloneP); + var frag = document.createDocumentFragment(); + frag.appendChild(K('1').get()); + frag.appendChild(K('2').get()); + range = K.range(document); + range.selectNode(strong); + range.insertNode(frag); + same(range.toString(), '12efg'); + document.body.removeChild(cloneP); +}); + +test('range.surroundContents', function() { + var p = K.query('#test-data-01 p'), + cloneP, strong, range; + //1 + cloneP = p.cloneNode(true); + document.body.appendChild(cloneP); + strong = K.query('strong', cloneP); + range = K.range(document); + range.selectNode(strong); + range.surroundContents(K('').get()); + same(range.html(), 'efg'); + document.body.removeChild(cloneP); + //2 + cloneP = p.cloneNode(true); + document.body.appendChild(cloneP); + strong = K.query('strong', cloneP); + range = K.range(document); + range.selectNode(strong.firstChild); + range.surroundContents(K('').get()); + same(range.html(), 'efg'); + document.body.removeChild(cloneP); + //3 + cloneP = p.cloneNode(true); + document.body.appendChild(cloneP); + strong = K.query('strong', cloneP); + range = K.range(document); + range.setStart(strong.firstChild, 1); + range.setEnd(strong.firstChild, 2); + range.surroundContents(K('').get()); + same(range.html(), 'f'); + document.body.removeChild(cloneP); + //4 + cloneP = p.cloneNode(true); + document.body.appendChild(cloneP); + strong = K.query('strong', cloneP); + range = K.range(document); + range.setStart(strong.firstChild, 0); + range.setEnd(strong.firstChild, 3); + range.surroundContents(K('').get()); + same(range.html(), 'efg'); + document.body.removeChild(cloneP); + //5 + cloneP = p.cloneNode(true); + document.body.appendChild(cloneP); + strong = K.query('strong', cloneP); + range = K.range(document); + range.setStart(strong.firstChild, 1); + range.setEnd(cloneP, 3); + range.surroundContents(K('').get()); + same(range.html(), 'fghijk'); + document.body.removeChild(cloneP); +}); + +test('range.enlarge', function() { + var div = K('
                  '); + K(document.body.firstChild).before(div); + //1 + div.html('123abcdef'); + range = K.range(document); + range.setStart(div.first().first().first()[0], 0); + range.setEnd(div.first().first().next()[0], 3); + range.enlarge(); + same(range.html(), '123abc'); + div.html(''); +}); + +test('range.shrink', function() { + var div = K('
                  '); + K(document.body.firstChild).before(div); + //1 + div.html('

                  123abc

                  '); + range = K.range(document); + range.setStart(div[0], 0); + range.setEnd(div[0], 1); + range.shrink(); + same(range.html(), '123abc'); + div.html(''); +}); + +test('range.moveToBookmark', function() { + var div = K('
                  '); + K(document.body.firstChild).before(div); + //1 + div.html('

                  123456789

                  '); + range = K.range(document); + range.setStart(div.first().first()[0], 3); + range.setEnd(div.first().first().next()[0], 1); + var bookmark = range.createBookmark(); + range.moveToBookmark(bookmark); + same(range.html(), '45678'); + div.html(''); + //2 + div.html('

                  123456789

                  '); + range = K.range(document); + range.setStart(div.first()[0], 1); + range.setEnd(div.first().last()[0], 0); + var bookmark = range.createBookmark(true); + range.moveToBookmark(bookmark); + same(range.html(), '5678'); + div.html(''); +}); + +test('range.get', function() { + var div = K('
                  '); + K(document.body.firstChild).before(div); + //1 + div.html('0123456789
                  123
                  '); + range = K.range(document); + range.setStart(div.first()[0], 7); + range.setEnd(div.first()[0], 8); // "7" + var nativeRange = range.get(); + newRange = K.range(nativeRange); + equals(range.html(), newRange.html()); + div.html(''); +}); \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/test/remote.html b/php/kindeditor_demo/kindeditor/test/remote.html new file mode 100755 index 0000000..d0c1638 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/remote.html @@ -0,0 +1,19 @@ + + + + + KindEditor Test + + + + +

                  KindEditor Test

                  + + + diff --git a/php/kindeditor_demo/kindeditor/test/selector.html b/php/kindeditor_demo/kindeditor/test/selector.html new file mode 100755 index 0000000..3815de9 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/selector.html @@ -0,0 +1,56 @@ + + + + + KindEditor Unittest + + + + + + + + + + + + +

                  KindEditor Unittest

                  +

                  +
                    + + + + + + + + + + + diff --git a/php/kindeditor_demo/kindeditor/test/selector.js b/php/kindeditor_demo/kindeditor/test/selector.js new file mode 100755 index 0000000..e396e57 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/selector.js @@ -0,0 +1,55 @@ +module('selector'); + +test('query', function() { + var div = K.query('#test-data-01'); + var strong = K.query('#test-data-01 strong'); + + ok(K.query('p', div) === jQuery('p', div).get(0)); + ok(K.query('strong', strong) === null); + ok(K.query('strong', div) === jQuery('strong', div).get(0)); + ok(K.query('img[border]', div) === jQuery('img[border]', div).get(0)); + ok(K.query('img[alt]', div) === null); + ok(K.query('img[border="0"]', div) === jQuery('img[border="0"]', div).get(0)); + ok(K.query('img[border="1"]', div) === null); + ok(typeof K.query('img[src="\\.\\/data\\/logo_180_30\\.gif"]') === 'object'); // note: jquery has a bug + ok(K.query('.test-class') === jQuery('.test-class').get(0)); + ok(K.query('.test-class', document.body) === jQuery('.test-class').get(0)); + ok(K.query('[class="test-class"]') === jQuery('[class="test-class"]').get(0)); + ok(K.query('[id="test-data-01"]') === jQuery('[id="test-data-01"]').get(0)); + ok(K.query('img.test-class') === null); + ok(K.query('img#test-data-01') === null); + ok(K.query('div#escaped-id\\:\\.') === jQuery('div#escaped-id\\:\\.').get(0)); + ok(K.query('input[name="escaped-name\\:\\."]') === jQuery('input[name="escaped-name\\:\\."]').get(0)); + ok(K.query('input[name="escaped-name\\:\\."]', div) === jQuery('input[name="escaped-name\\:\\."]').get(0)); + ok(K.query('img[border="0"]', div) === jQuery('img[border="0"]', div).get(0)); + ok(K.query('img[border]', div) === jQuery('img[border]', div).get(0)); + ok(K.query('.test-class') === jQuery('.test-class').get(0)); + ok(K.query('img #test-data-01') === null); + ok(K.query('body #test-data-01') === jQuery('body #test-data-01').get(0)); + + ok(K.query('div#test-data-01 strong') === jQuery('div#test-data-01 strong').get(0)); + ok(K.query('div#test-data-01 p strong') === jQuery('div#test-data-01 p strong').get(0)); + ok(K.query('div#test-data-01 > p > strong') === jQuery('div#test-data-01 > p > strong').get(0)); + ok(K.query('div#test-data-01>p>strong') === jQuery('div#test-data-01>p>strong').get(0)); + ok(K.query('div#test-data-01 > p > img[border="0"]') === jQuery('div#test-data-01 > p > img[border="0"]').get(0)); + ok(K.query('div#test-data-01 > strong', document, false) === null); +}); + +test('queryAll', function() { + var div = K.query('#test-data-01'); + var strong = K.query('#test-data-01 strong'); + + ok(K.queryAll('*').length === jQuery('*').length); + ok(K.queryAll('div').length === jQuery('div').length); + ok(K.queryAll('.test-class').length === jQuery('.test-class').length); + ok(K.queryAll('*', div).length === jQuery('*', div).length); + ok(K.queryAll('[border]', div).length === jQuery('[border]', div).length); + ok(K.queryAll('[border="0"]', div).length === jQuery('[border="0"]', div).length); + ok(K.queryAll('[border="1"]', div).length === jQuery('[border="1"]', div).length); + ok(K.queryAll('div', div).length === jQuery('div', div).length); + ok(K.queryAll('p *', div).length === jQuery('p *', div).length); + ok(K.queryAll('strong', div).length === jQuery('strong', div).length); + ok(K.queryAll('strong', strong).length === jQuery('strong', strong).length); + ok(K.queryAll('div p').length === jQuery('div p').length); + ok(K.queryAll('div,.test-class').length === jQuery('div,test-class').length); +}); diff --git a/php/kindeditor_demo/kindeditor/test/tabs.html b/php/kindeditor_demo/kindeditor/test/tabs.html new file mode 100755 index 0000000..60455df --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/tabs.html @@ -0,0 +1,49 @@ + + + + + KindEditor Tabs Test + + + + + + + + + + + + + + + + +

                    KindEditor Tabs Test

                    +
                    +
                    内容1
                    +
                    内容2
                    +
                    内容3
                    + + + diff --git a/php/kindeditor_demo/kindeditor/test/toolbar.html b/php/kindeditor_demo/kindeditor/test/toolbar.html new file mode 100755 index 0000000..0383b9b --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/toolbar.html @@ -0,0 +1,34 @@ + + + + + KindEditor Toolbar Test + + + + + + + + + + + + + + + + + +

                    KindEditor Toolbar Test

                    +
                    +
                    +
                    + + + + + + + + diff --git a/php/kindeditor_demo/kindeditor/test/toolbar.js b/php/kindeditor_demo/kindeditor/test/toolbar.js new file mode 100755 index 0000000..829e9b7 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/toolbar.js @@ -0,0 +1,60 @@ + +var items = [ + 'source', '|', 'fullscreen', 'undo', 'redo', 'print', 'cut', 'copy', 'paste', + 'plainpaste', 'wordpaste', '|', 'justifyleft', 'justifycenter', 'justifyright', + 'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'subscript', + 'superscript', '|', 'selectall', '/', + 'formatblock', 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold', + 'italic', 'underline', 'strikethrough', 'removeformat', '|', 'image', + 'flash', 'media', 'table', 'hr', 'emoticons', 'link', 'unlink', '|', 'about' +]; +var list = []; +K.each(items, function(i, name) { + if (name == '|') { + list.push(''); + } else if (name == '/') { + list.push('
                    '); + } else { + list.push(''); + list.push(''); + } +}); + +var toolbar = K.toolbar({ + src : 'div#toolbar', + width : '100%', + html : list.join(''), + click : function(e, name) { + alert(name); + } +}); + +K('#enable').bind('click', function(e) { + if (toolbar) { + toolbar.disableAll(false); + } +}); + +K('#disable').bind('click', function(e) { + if (toolbar) { + toolbar.disableAll(true); + } +}); + +K('#toggle').bind('click', function(e) { + if (toolbar) { + toolbar.disableAll(); + } +}); + +K('#select').bind('click', function(e) { + if (toolbar) { + toolbar.select('bold'); + } +}); + +K('#unselect').bind('click', function(e) { + if (toolbar) { + toolbar.unselect('bold'); + } +}); diff --git a/php/kindeditor_demo/kindeditor/test/total.html b/php/kindeditor_demo/kindeditor/test/total.html new file mode 100755 index 0000000..b79daeb --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/total.html @@ -0,0 +1,58 @@ + + + + + + KindEditor Test + + +

                    KindEditor Test

                    +
                    + +
                    + +
                    + +
                    + +
                    + +
                    + + + + + + + + + + +
                    + + diff --git a/php/kindeditor_demo/kindeditor/test/webdriver/KindEditorDriver.php b/php/kindeditor_demo/kindeditor/test/webdriver/KindEditorDriver.php new file mode 100755 index 0000000..557d84c --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/webdriver/KindEditorDriver.php @@ -0,0 +1,151 @@ +webDriver = new WebDriver($serverUrl); + $this->session = $this->webDriver->session($browser); + if ($url !== '') { + $this->open($url); + } + } + + public function open($url) { + if (strpos($url, 'http://') !== 0) { + $url = $this->baseUrl . $url; + } + $this->session->open($url); + return $this; + } + + public function selector($selector, $index = 0) { + $endTime = time() + $this->timeout; + while (true) { + try { + if ($index > 0) { + $elements = $this->session->elements('css selector', $selector); + $this->element = $elements[$index]; + } else { + $this->element = $this->session->element('css selector', $selector); + } + return $this; + } catch (NoSuchElementWebDriverError $e) { + } + sleep(1); + if (time() > $endTime) { + break; + } + } + throw new TimeOutWebDriverError('The element could not be found', ''); + } + + public function value($val) { + $this->element->value(array('value' => strSplitUnicode($val))); + return $this; + } + + public function keys($val) { + $this->session->keys(array('value' => strSplitUnicode($val))); + return $this; + } + + public function click() { + $this->element->click(''); + return $this; + } + + public function mouseover() { + $this->session->moveto(array('element' => $this->element->getID())); + return $this; + } + + public function script($script) { + return $this->session->execute(array( + 'script' => $script, + 'args' => array(), + )); + } + + public function clickToolbar($name) { + $this->session->frame(array('id' => null)); + return $this->selector('.ke-icon-' . $name)->click(); + } + + // get or set editor content + public function html($val = null) { + $this->session->frame(array('id' => null)); + if ($val === null) { + return preg_replace('/[\r\n\t]/', '', $this->script("return editor.html();")); + } + $this->script("editor.html('$val');"); + return $this; + } + + // input editor content + public function input($val) { + $id = 'ke-edit-iframe'; + $this->script("KindEditor('.ke-edit-iframe').eq(0).attr('id', '$id');"); + $this->selector("#$id"); + $this->session->frame(array('id' => $id)); + $this->keys($val); + return $this; + } + + // drag element + public function drag($x, $y) { + //$id = 'document-body'; + //$this->script("KindEditor('body').attr('id', '$id');"); + + $this->mouseover(); + $this->session->buttondown(""); + $this->session->moveto(array( + //'element' => $id, + 'xoffset' => $x, + 'yoffset' => $y, + )); + $this->session->buttonup(""); + return $this; + } + + public function close() { + $this->session->close(); + return $this; + } + +} + +function strSplitUnicode($str, $l = 1) { + if ($l > 0) { + $ret = array(); + $len = mb_strlen($str, "UTF-8"); + for ($i = 0; $i < $len; $i += $l) { + $ret[] = mb_substr($str, $i, $l, "UTF-8"); + } + return $ret; + } + return preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY); +} + +function equals($a, $b) { + if ($a === $b) { + echo "[OK] \"$a\"\n"; + } else { + echo "[FAILED]\n"; + echo "Expected: \"$b\"\n"; + echo "Result: \"$a\"\n"; + } +} diff --git a/php/kindeditor_demo/kindeditor/test/webdriver/all-chrome.bat b/php/kindeditor_demo/kindeditor/test/webdriver/all-chrome.bat new file mode 100755 index 0000000..81febc4 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/webdriver/all-chrome.bat @@ -0,0 +1,2 @@ +php all.php --browser=chrome +pause \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/test/webdriver/all-firefox.bat b/php/kindeditor_demo/kindeditor/test/webdriver/all-firefox.bat new file mode 100755 index 0000000..12e4e22 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/webdriver/all-firefox.bat @@ -0,0 +1,2 @@ +php all.php --browser=firefox +pause \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/test/webdriver/all-ie.bat b/php/kindeditor_demo/kindeditor/test/webdriver/all-ie.bat new file mode 100755 index 0000000..ada464b --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/webdriver/all-ie.bat @@ -0,0 +1,2 @@ +php all.php --browser="internet explorer" +pause \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/test/webdriver/all.php b/php/kindeditor_demo/kindeditor/test/webdriver/all.php new file mode 100755 index 0000000..c702a18 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/webdriver/all.php @@ -0,0 +1,27 @@ +session('firefox'); + +* See also [wiki page for launching different browsers](https://github.com/facebook/php-webdriver/wiki/Launching-Browsers). + +## SIMPLE EXAMPLES + +### Note that all of these match the Protocol exactly +* Move to a specific spot on the screen + + // POST /session/:sessionId/moveto + $session->moveto(array('xoffset' => 3, 'yoffset' => 300)); + +* Get the current url + + // GET /session/:sessionId/url + $session->url(); + +* Change focus to another frame + + // POST /session/:sessionId/frame + $session->frame(array('id' => 'some_frame_id')); + +* Get a list of window handles for all open windows + + // GET /session/:sessionId/window_handles + $session->window_handles(); + +* Accept the currently displayed alert dialog + + // POST /session/:sessionId/accept_alert + $session->accept_alert(); + +* Change asynchronous script timeout + + // POST /session/:sessionId/timeouts/async_script + $session->timeouts()->async_script(array('ms' => 2000)); + +* Doubleclick an element on a touch screen + + // POST session/:sessionId/touch/doubleclick + $session->touch()->doubleclick(array('element' => $element->getID()) + +* Check if two elements are equal + + // GET /session/:sessionId/element/:id/equals/:other + $element->equals($other_element->getID())) + +* Get value of a css property on element + + // GET /session/:sessionId/element/:id/css/:propertyName + $element->css($property_name) + +## 'GET', 'POST', or 'DELETE' to the same command examples + +### When you can do multiple http methods for the same command, call the command directly for the 'GET', and prepend the http method for the 'POST' or 'DELETE'. + +* Set landscape orientation with 'POST' + + // POST /session/:sessionId/orientation + $session->postOrientation(array('orientation' => 'LANDSCAPE')); + +* Get landscape orientation with normal 'GET' + + // GET /session/:sessionId/orientation + $session->orientation(); + +* Set size of window that has $window_handle with 'POST' + + // If excluded, $window_handle defaults to 'current' + // POST /session/:sessionId/window/:windowHandle/size + $session + ->window($window_handle) + ->postSize(array('width' => 10, 'height' => 10)); + +* Get current window size with 'GET' + + // GET /session/:sessionId/window/:windowHandle/size + $session->window()->size(); + +## Some unavoidable exceptions to direct protocol translation. + +* Opening pages + + // POST /session/:sessionId/url + $session->open('http://www.facebook.com'); + +* Dealing with the session + + // DELETE /session/:sessionId + $session->close(); + + // GET /session/:sessionId + $session->capabilities(); + +* To find elements + + // POST /session/:sessionId/element + $element = $session->element($using, $value); + + // POST /session/:sessionId/elements + $session->elements($using, $value); + + // POST /session/:sessionId/element/:id/element + $element->element($using, $value); + + // POST /session/:sessionId/element/:id/elements + $element->elements($using, $value); + +* To get the active element + + // POST /session/:sessionId/element/active + $session->activeElement(); + +* To manipulate cookies + + // GET /session/:sessionId/cookie + $session->getAllCookies(); + + // POST /session/:sessionId/cookie + $session->setCookie($cookie_json); + + // DELETE /session/:sessionId/cookie + $session->deleteAllCookies() + + // DELETE /session/:sessionId/cookie/:name + $session->deleteCookie($name) + +* To manipulate windows + + // POST /session/:sessionId/window + $session->focusWindow($window_handle); + + // DELETE /session/:sessionId/window + $session->deleteWindow(); + +### See also [wiki page of examples](https://github.com/facebook/php-webdriver/wiki/Example-command-reference). \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriver.php b/php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriver.php new file mode 100755 index 0000000..a2dbbc2 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriver.php @@ -0,0 +1,49 @@ + 'GET', + ); + } + + public function session( + $browser = 'firefox', + $additional_capabilities = array()) { + + $desired_capabilities = array_merge( + $additional_capabilities, + array('browserName' => $browser)); + + $results = $this->curl( + 'POST', + '/session', + array('desiredCapabilities' => $desired_capabilities), + array(CURLOPT_FOLLOWLOCATION => true)); + + return new WebDriverSession($results['info']['url']); + } + + public function sessions() { + $result = $this->curl('GET', '/sessions'); + $sessions = array(); + foreach ($result['value'] as $session) { + $sessions[] = new WebDriverSession( + $this->url . '/session/' . $session['id']); + } + return $sessions; + } +} diff --git a/php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriverBase.php b/php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriverBase.php new file mode 100755 index 0000000..6d17fc5 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriverBase.php @@ -0,0 +1,236 @@ +url = $url; + } + public function __toString() { + return $this->url; + } + + public function getURL() { + return $this->url; + } + + /** + * Curl request to webdriver server. + * + * $http_method 'GET', 'POST', or 'DELETE' + * $command If not defined in methods() this function will throw. + * $params If an array(), they will be posted as JSON parameters + * If a number or string, "/$params" is appended to url + * $extra_opts key=>value pairs of curl options to pass to curl_setopt() + */ + protected function curl( + $http_method, + $command, + $params = null, + $extra_opts = array()) { + + if ($params && is_array($params) && $http_method !== 'POST') { + throw new Exception(sprintf( + 'The http method called for %s is %s but it has to be POST' . + ' if you want to pass the JSON params %s', + $command, + $http_method, + json_encode($params))); + } + + $url = sprintf('%s%s', $this->url, $command); + if ($params && (is_int($params) || is_string($params))) { + $url .= '/' . $params; + } + + $curl = curl_init($url); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt( + $curl, + CURLOPT_HTTPHEADER, + array( + 'Content-Type: application/json;charset=UTF-8', + 'Accept: application/json')); + + if ($http_method === 'POST') { + curl_setopt($curl, CURLOPT_POST, true); + if ($params && is_array($params)) { + curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($params)); + } + } else if ($http_method == 'DELETE') { + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE'); + } + + foreach ($extra_opts as $option => $value) { + curl_setopt($curl, $option, $value); + } + + $raw_results = trim(WebDriverEnvironment::CurlExec($curl)); + $info = curl_getinfo($curl); + + if ($error = curl_error($curl)) { + $msg = sprintf( + 'Curl error thrown for http %s to %s', + $http_method, + $url); + if ($params && is_array($params)) { + $msg .= sprintf(' with params: %s', json_encode($params)); + } + throw new WebDriverCurlException($msg . "\n\n" . $error); + } + curl_close($curl); + + $results = json_decode($raw_results, true); + + $value = null; + if (is_array($results) && array_key_exists('value', $results)) { + $value = $results['value']; + } + + $message = null; + if (is_array($value) && array_key_exists('message', $value)) { + $message = $value['message']; + } + + self::throwException($results['status'], $message, $results); + + return array('value' => $value, 'info' => $info); + } + + public function __call($name, $arguments) { + if (count($arguments) > 1) { + throw new Exception( + 'Commands should have at most only one parameter,' . + ' which should be the JSON Parameter object'); + } + + if (preg_match('/^(get|post|delete)/', $name, $matches)) { + $http_method = strtoupper($matches[0]); + $webdriver_command = strtolower(substr($name, strlen($http_method))); + $default_http_method = $this->getHTTPMethod($webdriver_command); + if ($http_method === $default_http_method) { + throw new Exception(sprintf( + '%s is the default http method for %s. Please just call %s().', + $http_method, + $webdriver_command, + $webdriver_command)); + } + $methods = $this->methods(); + if (!in_array($http_method, $methods[$webdriver_command])) { + throw new Exception(sprintf( + '%s is not an available http method for the command %s.', + $http_method, + $webdriver_command)); + } + } else { + $webdriver_command = $name; + $http_method = $this->getHTTPMethod($webdriver_command); + } + + $results = $this->curl( + $http_method, + '/' . $webdriver_command, + array_shift($arguments)); + + return $results['value']; + } + + private function getHTTPMethod($webdriver_command) { + if (!array_key_exists($webdriver_command, $this->methods())) { + throw new Exception(sprintf( + '%s is not a valid webdriver command.', + $webdriver_command)); + } + + $methods = $this->methods(); + $http_methods = (array) $methods[$webdriver_command]; + return array_shift($http_methods); + } +} diff --git a/php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriverContainer.php b/php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriverContainer.php new file mode 100755 index 0000000..9787ae7 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriverContainer.php @@ -0,0 +1,60 @@ +curl( + 'POST', + '/element', + array( + 'using' => $using, + 'value' => $value)); + } catch (NoSuchElementWebDriverError $e) { + throw new NoSuchElementWebDriverError( + sprintf( + 'Element not found with %s, %s', + $using, + $value) . "\n\n" . $e->getMessage(), + $e->getResults()); + } + + return $this->webDriverElement($results['value']); + } + + public function elements($using, $value) { + $results = $this->curl( + 'POST', + '/elements', + array( + 'using' => $using, + 'value' => $value + )); + + return array_filter(array_map( + array($this, 'webDriverElement'), $results['value'])); + } + + protected function webDriverElement($value) { + return array_key_exists('ELEMENT', (array) $value) ? + new WebDriverElement( + $this->getElementPath($value['ELEMENT']), // url + $value['ELEMENT']) : // id + null; + } + + + abstract protected function getElementPath($element_id); +} diff --git a/php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriverElement.php b/php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriverElement.php new file mode 100755 index 0000000..2b806e4 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriverElement.php @@ -0,0 +1,50 @@ + 'POST', + 'submit' => 'POST', + 'text' => 'GET', + 'value' => 'POST', + 'name' => 'GET', + 'clear' => 'POST', + 'selected' => 'GET', + 'enabled' => 'GET', + 'attribute' => 'GET', + 'equals' => 'GET', + 'displayed' => 'GET', + 'location' => 'GET', + 'location_in_view' => 'GET', + 'size' => 'GET', + 'css' => 'GET', + ); + } + + private $id; + public function __construct($url, $id) { + $this->id = $id; + parent::__construct($url); + } + + public function getID() { + return $this->id; + } + + protected function getElementPath($element_id) { + return preg_replace(sprintf('/%s$/', $this->id), $element_id, $this->url); + } +} diff --git a/php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriverEnvironment.php b/php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriverEnvironment.php new file mode 100755 index 0000000..71d393b --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriverEnvironment.php @@ -0,0 +1,25 @@ +results = $results; + } + + public function getResults() { + return $this->results; + } +} + +class IndexOutOfBoundsWebDriverError extends WebDriverException {} // 1 +class NoCollectionWebDriverError extends WebDriverException {} // 2 +class NoStringWebDriverError extends WebDriverException {} // 3 +class NoStringLengthWebDriverError extends WebDriverException {} // 4 +class NoStringWrapperWebDriverError extends WebDriverException {} // 5 +class NoSuchDriverWebDriverError extends WebDriverException {} // 6 +class NoSuchElementWebDriverError extends WebDriverException {} // 7 +class NoSuchFrameWebDriverError extends WebDriverException {} // 8 +class UnknownCommandWebDriverError extends WebDriverException {} // 9 +class ObsoleteElementWebDriverError extends WebDriverException {} // 10 +class ElementNotDisplayedWebDriverError extends WebDriverException {} // 11 +class InvalidElementStateWebDriverError extends WebDriverException {} // 12 +class UnhandledWebDriverError extends WebDriverException {} // 13 +class ExpectedWebDriverError extends WebDriverException {} // 14 +class ElementNotSelectableWebDriverError extends WebDriverException {} // 15 +class NoSuchDocumentWebDriverError extends WebDriverException {} // 16 +class UnexpectedJavascriptWebDriverError extends WebDriverException {} // 17 +class NoScriptResultWebDriverError extends WebDriverException {} // 18 +class XPathLookupWebDriverError extends WebDriverException {} // 19 +class NoSuchCollectionWebDriverError extends WebDriverException {} // 20 +class TimeOutWebDriverError extends WebDriverException {} // 21 +class NullPointerWebDriverError extends WebDriverException {} // 22 +class NoSuchWindowWebDriverError extends WebDriverException {} // 23 +class InvalidCookieDomainWebDriverError extends WebDriverException {} // 24 +class UnableToSetCookieWebDriverError extends WebDriverException {} // 25 +class UnexpectedAlertOpenWebDriverError extends WebDriverException {} // 26 +class NoAlertOpenWebDriverError extends WebDriverException {} // 27 +class ScriptTimeoutWebDriverError extends WebDriverException {} // 28 +class InvalidElementCoordinatesWebDriverError extends WebDriverException {}// 29 +class IMENotAvailableWebDriverError extends WebDriverException {} // 30 +class IMEEngineActivationFailedWebDriverError extends WebDriverException {}// 31 +class InvalidSelectorWebDriverError extends WebDriverException {} // 32 diff --git a/php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriverSession.php b/php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriverSession.php new file mode 100755 index 0000000..5679b78 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriverSession.php @@ -0,0 +1,148 @@ + 'GET', // for POST, use open($url) + 'forward' => 'POST', + 'back' => 'POST', + 'refresh' => 'POST', + 'execute' => 'POST', + 'execute_async' => 'POST', + 'screenshot' => 'GET', + 'window_handle' => 'GET', + 'window_handles' => 'GET', + 'frame' => 'POST', + 'source' => 'GET', + 'title' => 'GET', + 'keys' => 'POST', + 'orientation' => array('GET', 'POST'), + 'alert_text' => array('GET', 'POST'), + 'accept_alert' => 'POST', + 'dismiss_alert' => 'POST', + 'moveto' => 'POST', + 'click' => 'POST', + 'buttondown' => 'POST', + 'buttonup' => 'POST', + 'doubleclick' => 'POST', + ); + } + + // /session/:sessionId/url (POST) + public function open($url) { + $this->curl('POST', '/url', array('url' => $url)); + return $this; + } + + // /session/:sessionId (GET) + public function capabilities() { + $result = $this->curl('GET', ''); + return $result['value']; + } + + // /session/:sessionId (DELETE) + public function close() { + $result = $this->curl('DELETE', ''); + return $result['value']; + } + + // /session/:sessionId/cookie (GET) + public function getAllCookies() { + $result = $this->curl('GET', '/cookie'); + return $result['value']; + } + + // /session/:sessionId/cookie (POST) + public function setCookie($cookie_json) { + $this->curl('POST', '/cookie', array('cookie' => $cookie_json)); + return $this; + } + + // /session/:sessionId/cookie (DELETE) + public function deleteAllCookies() { + $this->curl('DELETE', '/cookie'); + return $this; + } + + // /session/:sessionId/cookie/:name (DELETE) + public function deleteCookie($cookie_name) { + $this->curl('DELETE', '/cookie/' . $cookie_name); + return $this; + } + + public function timeouts() { + $item = new WebDriverSimpleItem($this->url . '/timeouts'); + return $item->setMethods(array( + 'async_script' => 'POST', + 'implicit_wait' => 'POST', + )); + } + + public function ime() { + $item = new WebDriverSimpleItem($this->url . '/ime'); + return $item->setMethods(array( + 'available_engines' => 'GET', + 'active_engine' => 'GET', + 'activated' => 'GET', + 'deactivate' => 'POST', + 'activate' => 'POST', + )); + } + + // /session/:sessionId/window (DELETE) + public function deleteWindow() { + $this->curl('DELETE', '/window'); + return $this; + } + + // /session/:sessionId/window (POST) + public function focusWindow($name) { + $this->curl('POST', '/window', array('name' => $name)); + return $this; + } + + public function window($window_handle = 'current') { + $item = new WebDriverSimpleItem($this->url . '/window/' . $window_handle); + return $item->setMethods(array( + 'size' => array('GET', 'POST'), + 'position' => array('GET', 'POST'), + )); + } + + // /session/:sessionId/element/active (POST) + public function activeElement() { + $results = $this->curl('POST', '/element/active'); + return $this->webDriverElement($results['value']); + } + + public function touch() { + $item = new WebDriverSimpleItem($this->url . '/touch'); + return $item->setMethods(array( + 'click' => 'POST', + 'down' => 'POST', + 'up' => 'POST', + 'move' => 'POST', + 'scroll' => 'POST', + 'doubleclick' => 'POST', + 'longclick' => 'POST', + 'flick' => 'POST', + )); + } + + protected function getElementPath($element_id) { + return sprintf('%s/element/%s', $this->url, $element_id); + } +} diff --git a/php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriverSimpleItem.php b/php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriverSimpleItem.php new file mode 100755 index 0000000..f675c45 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/WebDriverSimpleItem.php @@ -0,0 +1,26 @@ +_methods; + } + + public function setMethods($methods) { + $this->_methods = $methods; + return $this; + } +} diff --git a/php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/__init__.php b/php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/__init__.php new file mode 100755 index 0000000..d2d4aa9 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/webdriver/php-webdriver/__init__.php @@ -0,0 +1,23 @@ +html(''); +// bold +$driver->clickToolbar('bold'); +$driver->input('abc'); +equals($driver->html(), 'abc'); +// fontsize +$driver->clickToolbar('fontsize'); +$driver->selector('.ke-menu-item', 6)->mouseover()->click(); +$driver->input('abc'); +equals($driver->html(), 'abcabc'); +// removeformat +$driver->clickToolbar('removeformat'); +$driver->input('123'); +equals($driver->html(), 'abcabc123'); + +$driver->close(); diff --git a/php/kindeditor_demo/kindeditor/test/webdriver/test-dialog.php b/php/kindeditor_demo/kindeditor/test/webdriver/test-dialog.php new file mode 100755 index 0000000..5912d14 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/webdriver/test-dialog.php @@ -0,0 +1,17 @@ +script("return KindEditor('.ke-dialog').css('top')")); +$prevLeft = intval($driver->script("return KindEditor('.ke-dialog').css('left')")); +$driver->selector('.ke-dialog-header')->drag(100, 200); +equals(intval($driver->script("return KindEditor('.ke-dialog').css('top')")), $prevTop + 200); +equals(intval($driver->script("return KindEditor('.ke-dialog').css('left')")), $prevLeft + 100); + +// close dialog +$driver->selector('.ke-dialog-icon-close')->click(); + +$driver->close(); diff --git a/php/kindeditor_demo/kindeditor/test/webdriver/test-unittest.php b/php/kindeditor_demo/kindeditor/test/webdriver/test-unittest.php new file mode 100755 index 0000000..08982bf --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/webdriver/test-unittest.php @@ -0,0 +1,23 @@ +open($file); + equals($driver->selector('.failed')->element->text(), '0'); +} + +$driver->close(); diff --git a/php/kindeditor_demo/kindeditor/test/widget.html b/php/kindeditor_demo/kindeditor/test/widget.html new file mode 100755 index 0000000..6896ef3 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/test/widget.html @@ -0,0 +1,64 @@ + + + + + KindEditor Widget Test + + + + + + + + + + + + + + + + + +

                    KindEditor Widget Test

                    + + +
                    +
                    + + + + diff --git a/php/kindeditor_demo/kindeditor/themes/common/anchor.gif b/php/kindeditor_demo/kindeditor/themes/common/anchor.gif new file mode 100755 index 0000000000000000000000000000000000000000..61145ea78138f12df43b666409bcc4b8e3231a60 GIT binary patch literal 371 zcmZ?wbhEHb6krfwxN6QYDW2i~>#Uh+4FA{5|NoTr{}#jK1cv|r8K$Q&OaU@(FieVN zn48I*>dcU0&(ImhkmAVj|0cu#%M2+_4F5kfq&hJ~TQO9G2;_J&L|HM+%VPe&MQ&C) z)BiVF|KBtGUnBJY9mD^(IUOMk|2NBZhcf(sRXQn=;s4jN|DPBp#xP8bXXprI=#FCe zf19B@45+gB{|AQI=^Wh=4F5Ms{Qp)u1*rHM&^`YdZ~(=hEQ|~c<_tO@d61tN*d`p9 zUBIEi)aIe0aDYcB+&yV9KvzU~I(C$-u_p#Ky|bWX>%jt!B=|&dL_YB{V~Gw$?l$E`JVT wW>zLW4P_lBR%X%3<`U-X1)1cSnFM$4@f6r##-+BwLW0RJL(*8l(j literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/themes/common/blank.gif b/php/kindeditor_demo/kindeditor/themes/common/blank.gif new file mode 100755 index 0000000000000000000000000000000000000000..5bfd67a2d6f72ac3a55cbfcea5866e841d22f5d9 GIT binary patch literal 43 mcmZ?wbhEHbWMp7uXkdT>#h)yUAf^t80Ld^gF}W}@SOWlZ0R#L1 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/themes/common/flash.gif b/php/kindeditor_demo/kindeditor/themes/common/flash.gif new file mode 100755 index 0000000000000000000000000000000000000000..2cb12b28429f8c2e5294a177e14dfda6f533e6fc GIT binary patch literal 1089 zcmV-H1it%6Nk%w1VITk?0OkMy03afP|W&d}4=YJZZjyvFwT_~zc`k)Er>%FkqZjiIl;5K(o%zrQM3b^te9 zd4`jDi=FT9?{#&eq?= z&Da1aLZ`OBD`bS6tF=*bg7@$DY?G-hUVMa=piygoaD&NUadR3gv@04*cpk2HtAZvUIW`(NU|>7P#~?T>bqX|Nt1v+(S;PTf64}~3U<`K* zQ47$GNYff1*Ai|w>^DYkFnuK@BVh*%D~w4xavESj>TdAhksv{a02d;V89-(NkSuI; z@L1#^M-~tO-3&CsF~bdc0~it*00hhu2Mr1pabN>S0CfZnW|*lULdY2te1viHB@CVg z1qgY7;qQyaf-`3(IU!=e3^X@bV92&33(G+gUc?FW@&?kR8L&(l;AaAlsoK7*fT3iN z0U~q%z!>FW1nj{GBFO03AO)K?31H&ra3iS90S#U0+HDYFh8`v}B6JudMca-!L3sT^ zB4-6QuXZzBP@(6_l|57_pkSd5ND(Cl1R*iu`HMTd2E>>~fPf1Z)vU7t(V(D)Y}#Lv z-%h%q%M}DvqCe@fy0r!+#{ZCzBP6+ZHyZ7Ti2>ch3OeWm$Y^af)1M-T0sfWn#*7#Q z57J1*z<<5vB_D7g$Pfy|HD3m001!hA6j%`4eA$42M_Yq1qe%EK|&)k zXh97SJe+Zc4BqwW9T;;c;l(B#Xc2{!1+=56qF~s7#h|Om(1QYaXaIyvU>PAn5irQv z%OD}Npnx28(D6@68rYBn78UUL=^z+{(1R8VC{e2eSZKkAtFJC1!w^jb+eRKz^lI#< HfdBwIq8;my literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/themes/common/loading.gif b/php/kindeditor_demo/kindeditor/themes/common/loading.gif new file mode 100755 index 0000000000000000000000000000000000000000..c69e937232b24ea30f01c68bbd2ebc798dcecfcb GIT binary patch literal 2608 zcmdVcdr(tX9tZGC9yiG~=H_*Q-0%n(kWqP*D#hw{AQu8;1%gl-Hrf&{2?48KX;hHy z3Ze*zEz4t3XdUFyLbNPUYlA`|B}P=N1fqtL1*}S;87#|-W9v<#G;ul(e%d3)N(^9c$d2Dz{7}?ErjNd;{EMKkCsk21~b9Gvg zDo<7L=3Z5HNbVlZUcm1eg#o#CZCJU`3IYHwM->zCd?uYrF3vKFeM}v?f+%s?E>ly|3W25ry9#NNbTx-}0ON58dTrs^ix{_1O0Wh~SVSBlH)Ajn zPn^Gbjz}PCtN@#keR&hK&Dhl-b$kZ8^S)x#dh0{7X=X%CCJk7P1PSO>T&S8I4{#Lg zb5#)o=;!ZP*1nM{cI4@(x7o27*SA()NHmrn67aN@Pmi~(i_SnrjYnwh36aG%!@i0d zqbvfa44f|?OG4ntP|nbjhEl1)Yp6ZN@yjy zy4==QmLy%t;ps3R?~f2KfTTI|2?q8dFd6^z5GF+Xa&Y)sjG)hxit80pPcOP zJ z*LW{SyGHD%hUotV+W%I}fBLAIx!8|7#}$;clKQ+{&FjDqGQ2ZNx(lYM3*%~}ILnao zM`aui55~ZFJlu^!5rdA9Q_7H68H_;##u{x(Yn-vSfIRCb^Nqsg zGRS!Egm>h+o<}LeV4&CLReo9FrDjDvs}8?JwC)#Qs|ie=r?~xUh)&*d`Fx>FG}%X# zNdtDHBKhLPC0wpooFDAQKL%*6T|ULH$=wX!NhcasgD3d;-d$I6yRK3yN+E~C1335_iLOt+*9uvSZ`>*KA}vm}08wRq=>5l|t*Na&jR z-C1&C`nkEk#sB|@yyt-#fXngP04My zm7u$Q%EJbHp`>~`5W&L{W!6`y&}LMS;jfUpgO~7TLVMRZ9IC)IZp0A${`yp0{&wco z#1nx@XMkhqeK%7?RE7JdLr1^nwFfaJ0Q&Lv?WNJ%9}VSJsNY2+UYs2%EU0J~ayFXv zi*?7KCXQHkD)O6!0Q%4N+HTODHxJ{kQSuQX$l-rSwkwh(zMkdfzxyGwl@yHC)C4p< z&n2%8#M?)Q@mgHL1ot8`SFdSEj9ye|jHy+U8#@HoUExG=@AVkRAe_qYm4EpzK6L*& zh`)26?V#f4#_h^P9G^%>h2-H3)$QP zQovu6J9qDvsxqweDdNNa!Lb?L4_UF{tLX_nN7r0U_vF14YKcGR-*Gl} zx3oG)bzf|65dBxD-;2ZCp??K;+TuQ9onnK?==5hzbkb^r_g>z4#D8mcv8(+XdoszA zCx-qhdgxMNMotj}SiL_6V(tLcsK7(M(r(%u<}QrVfOvyK6_;~NOTlPGfX@M7S5YQF z&*$(ylJMHJt^_aQeu{C6NaTE$G3HNN@_SnN8YcaKn%`)F@~L1x+ah7-gEJPpc6w%3 zyX}r+Qk$4RHZzfH){e~F*qJ{d*L8a6n4;U?+{de0-t)mal#TVxe)3F}^UBh+zd T)6_**#cgp_+?JL9(ew3BlNF>u literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/themes/common/media.gif b/php/kindeditor_demo/kindeditor/themes/common/media.gif new file mode 100755 index 0000000000000000000000000000000000000000..e1c0e30afb2587f6d4ed4f8bd90bd4f865a98aa6 GIT binary patch literal 1036 zcmV+n1oQhxNk%w1VITk?0OkMy0A@37!Q*M$LcQvWmF_2mBqn_S(Z}jxMfqHi`g}=qph8>ajebfv(>`m;o;&^Lc|^(|NrX%akkXw-P74|0GZ6czP`)p_nDcQGnvdD zc0~XGnV{C}vBAMgeD0s2|`x$DghH8$$U7>xK#;fx3!ne0y#NE=_*_PMt z_y>GB^Uu$Ge1HG_;FiYa=8%l{_V#|d-OC&c_xDxA;Ovc%k|v_lc$J`Bwb{dadH?@r z@x;Xc|NqR)%}29%<|$If5zj<+@0oSRV;#1JEGEmvzHHo zK^dCR=H%o1@9)CL*8l%AwbJdn)bQZ%_W*P=|NlRu%(O41eiycq}AUsoyi)CnB1Zg8JKLBrW4U~m-5(Hdm1!Wys z4Ipt4096R0e^4V_5gm0MWn~S&2w8n^EmxFg1QETHV3Fir9=USl7#n1P3KbeR3g1gYqk`oMXDUdJ zg6G5<1`H+;N>ZXUoIFKRM`?WK43#rR-li^s2Z;d#4Ac+;Q@Vtg4^vcISU~)S9(%L( zWLR^X0f|Bt4oEkWMfidX7Ld;_BBsr40~!n&k?v(lk}OlwTaZ0F{ggZ!u-tZFNROBM zUII+Xg1(6R|5=FP02TxqAjBatc!2^6bG#4?e-QFV2OWA$Py>NjJb?%pb1?XT9|=uC zM+hX6s0SDm@Nvh5H9Uui3Ue%xR$D%Rv0V{DxbVaieAG~bZi-m(VE{u6@xoO;2%!dP z87{~m1CMu*K}ix#5P6jfD)^wrmPuopT&2f}B#@w_3l8kC!dHw;kpcxC zFu_3*$Ei6%4`Fx^L<(@mDTM+`1d)IeE3BYI0zoLDfE0n!l0^toq+n?ZQiPBNEu1nE G2mm`UjPBh4 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/themes/common/rm.gif b/php/kindeditor_demo/kindeditor/themes/common/rm.gif new file mode 100755 index 0000000000000000000000000000000000000000..d013d551de909a5588a7d81be96aba60089a846b GIT binary patch literal 989 zcmV<310wuKNk%w1VITk?0OkMy0!fO7(d!x1vrw+q9#)Y6nas=J??8L1wang{j*6Pl=&;@Hf}+8--sXvYcn4dU zBZIas|JI-=;-JdPm1R7 z_XtOZ$=c^+!QzqB>;;U(l*HkTz1wT0#bS`RMUul|e~QY(!2kdMA^8La6aaq!EC2ui z03ZM$000O7fPaF6goTEOh>41ei!?V?RW~$@i!&HvFmVtNaWG;SGn9o&UUMfHRWmd+ zGgTNTb6!fKe>V^(Kr~9MGrhVrKqnA4lvV%^Sy?yB%+1LT09K1P0DE**6clA;Of@x3 z+u0O!djQ0UN@EigKM1Af(LLXatAr11&%Z_h6`n=>lNV z^yR^)?+hs*-k51&=*gSwS6oPNys-?J0@t4$no{7-ofRFn=RGLr!Ik$@5FIFD9txBn z7M?WOueJ%1BS+j(!~uzL0pNXFXt9P6FFe80K`&@QMu1!_ase4+D7eNCYj9!J0d{nt zMFeDAKuH55?C?V!b#MU{14O9s!ww@fAW8`zEI@_;P6WUJ16{~Y*f4+wG9-Cp2n1B1!4Q40z(OBGXixzGA!td9AaI}%LI{5N@g@pz LtZAnrfdBwIov+u= literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/themes/default/background.png b/php/kindeditor_demo/kindeditor/themes/default/background.png new file mode 100755 index 0000000000000000000000000000000000000000..e59bd6890d1633243d5de27c09f06ede17392a56 GIT binary patch literal 1410 zcmah}eM}o=7(dp37Lr9L{^LyM<(Ttp?e+S(o>Uw?U`@EDmS#31WL(<=E^r@SuWKP@ z(dniHO{R%vZpI~x(HL-!#Tlb4n8>y+Q3xbdN7AtJQNGGb3#G{T@O>F&{vrCydw0+K z-1GZA&-=d5U7OQUxu_;gVf)pGA_V>G0;QmxR9)l01+@n;B^-745S>%Xc z^s=a(XBt=+%lKQ~xWkqpi0T06_9z~@iu8%RhJi7fFfRc%f|QhoCC1mpDyWxj-~=m{ z`nd-~IlmQq-AHR`$;LKvM_XmKy4B(KwKn-IeysErv?NRd0iIPDG|V>(0WxgGHg!p0 zLpP40n;}Y*6?<5ehjyYiQD#x2Mz8j12?8~lG=#xuG7*PRotDtyS};s%!ay2Lq|S_P z0R!1&e?94w8<=^h_YK0oAbNqY!nqS&?ri%t=fb>PcuGFfQ}b7 z88l7Wg@D2cKGsfIF`%L0I6rCAYAFL{)*C9cWdu=fJZ#evhYc2enbBg?=?$hlmlAzJ zo)wfl*Z+uX*pUmHftNsLij}#OtiM7Qd31BpB)4-d#EyDfT>s9s=yv4dpcot;?LUq> z?*jb;&F#holkL`L1<>y@XzX|NXMO}9#bsxeyL@9~V|{&nZEbCJbroC>09GLW0$5&N z&gF7TOH0}8;^HE_78VvVnM@jDA)U_5L!?rvbSgD}A0jmekxVA%W@nSLo0x%^o}Nxl zPftxv%}hch5{aoqVq#)qe0+QojIpta(b4gEd~9SS7K;rJ4-XCw4h#(R_xJbp^HVPwulK{YU}fi0@61c^#fqcz)Z-n`c3o)RzyH0B+8b9-j;0y?H*;6;vGX76X$J-3^%+v@1*$C2)v zWJ~4vmp6~UdEi=OmqTp({0C15P90N6@0zg&b#&#qkAm&NbbF+{J-B``(sCm9``RQ4U+ DMaDx) literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/themes/default/default.css b/php/kindeditor_demo/kindeditor/themes/default/default.css new file mode 100755 index 0000000..3f72660 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/themes/default/default.css @@ -0,0 +1,1147 @@ +/* common */ +.ke-inline-block { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; +} +.ke-clearfix { + zoom: 1; +} +.ke-clearfix:after { + content: "."; + display: block; + clear: both; + font-size: 0; + height: 0; + line-height: 0; + visibility: hidden; +} +.ke-shadow { + box-shadow: 1px 1px 3px #A0A0A0; + -moz-box-shadow: 1px 1px 3px #A0A0A0; + -webkit-box-shadow: 1px 1px 3px #A0A0A0; + filter: progid:DXImageTransform.Microsoft.Shadow(color='#A0A0A0', Direction=135, Strength=3); + background-color: #F0F0EE; +} +.ke-menu a, +.ke-menu a:hover, +.ke-dialog a, +.ke-dialog a:hover { + color: #337FE5; + text-decoration: none; +} +/* icons */ +.ke-icon-source { + background-position: 0px 0px; + width: 16px; + height: 16px; +} +.ke-icon-preview { + background-position: 0px -16px; + width: 16px; + height: 16px; +} +.ke-icon-print { + background-position: 0px -32px; + width: 16px; + height: 16px; +} +.ke-icon-undo { + background-position: 0px -48px; + width: 16px; + height: 16px; +} +.ke-icon-redo { + background-position: 0px -64px; + width: 16px; + height: 16px; +} +.ke-icon-cut { + background-position: 0px -80px; + width: 16px; + height: 16px; +} +.ke-icon-copy { + background-position: 0px -96px; + width: 16px; + height: 16px; +} +.ke-icon-paste { + background-position: 0px -112px; + width: 16px; + height: 16px; +} +.ke-icon-selectall { + background-position: 0px -128px; + width: 16px; + height: 16px; +} +.ke-icon-justifyleft { + background-position: 0px -144px; + width: 16px; + height: 16px; +} +.ke-icon-justifycenter { + background-position: 0px -160px; + width: 16px; + height: 16px; +} +.ke-icon-justifyright { + background-position: 0px -176px; + width: 16px; + height: 16px; +} +.ke-icon-justifyfull { + background-position: 0px -192px; + width: 16px; + height: 16px; +} +.ke-icon-insertorderedlist { + background-position: 0px -208px; + width: 16px; + height: 16px; +} +.ke-icon-insertunorderedlist { + background-position: 0px -224px; + width: 16px; + height: 16px; +} +.ke-icon-indent { + background-position: 0px -240px; + width: 16px; + height: 16px; +} +.ke-icon-outdent { + background-position: 0px -256px; + width: 16px; + height: 16px; +} +.ke-icon-subscript { + background-position: 0px -272px; + width: 16px; + height: 16px; +} +.ke-icon-superscript { + background-position: 0px -288px; + width: 16px; + height: 16px; +} +.ke-icon-date { + background-position: 0px -304px; + width: 25px; + height: 16px; +} +.ke-icon-time { + background-position: 0px -320px; + width: 25px; + height: 16px; +} +.ke-icon-formatblock { + background-position: 0px -336px; + width: 25px; + height: 16px; +} +.ke-icon-fontname { + background-position: 0px -352px; + width: 21px; + height: 16px; +} +.ke-icon-fontsize { + background-position: 0px -368px; + width: 23px; + height: 16px; +} +.ke-icon-forecolor { + background-position: 0px -384px; + width: 20px; + height: 16px; +} +.ke-icon-hilitecolor { + background-position: 0px -400px; + width: 23px; + height: 16px; +} +.ke-icon-bold { + background-position: 0px -416px; + width: 16px; + height: 16px; +} +.ke-icon-italic { + background-position: 0px -432px; + width: 16px; + height: 16px; +} +.ke-icon-underline { + background-position: 0px -448px; + width: 16px; + height: 16px; +} +.ke-icon-strikethrough { + background-position: 0px -464px; + width: 16px; + height: 16px; +} +.ke-icon-removeformat { + background-position: 0px -480px; + width: 16px; + height: 16px; +} +.ke-icon-image { + background-position: 0px -496px; + width: 16px; + height: 16px; +} +.ke-icon-flash { + background-position: 0px -512px; + width: 16px; + height: 16px; +} +.ke-icon-media { + background-position: 0px -528px; + width: 16px; + height: 16px; +} +.ke-icon-div { + background-position: 0px -544px; + width: 16px; + height: 16px; +} +.ke-icon-formula { + background-position: 0px -576px; + width: 16px; + height: 16px; +} +.ke-icon-hr { + background-position: 0px -592px; + width: 16px; + height: 16px; +} +.ke-icon-emoticons { + background-position: 0px -608px; + width: 16px; + height: 16px; +} +.ke-icon-link { + background-position: 0px -624px; + width: 16px; + height: 16px; +} +.ke-icon-unlink { + background-position: 0px -640px; + width: 16px; + height: 16px; +} +.ke-icon-fullscreen { + background-position: 0px -656px; + width: 16px; + height: 16px; +} +.ke-icon-about { + background-position: 0px -672px; + width: 16px; + height: 16px; +} +.ke-icon-plainpaste { + background-position: 0px -704px; + width: 16px; + height: 16px; +} +.ke-icon-wordpaste { + background-position: 0px -720px; + width: 16px; + height: 16px; +} +.ke-icon-table { + background-position: 0px -784px; + width: 16px; + height: 16px; +} +.ke-icon-tablemenu { + background-position: 0px -768px; + width: 16px; + height: 16px; +} +.ke-icon-tableinsert { + background-position: 0px -784px; + width: 16px; + height: 16px; +} +.ke-icon-tabledelete { + background-position: 0px -800px; + width: 16px; + height: 16px; +} +.ke-icon-tablecolinsertleft { + background-position: 0px -816px; + width: 16px; + height: 16px; +} +.ke-icon-tablecolinsertright { + background-position: 0px -832px; + width: 16px; + height: 16px; +} +.ke-icon-tablerowinsertabove { + background-position: 0px -848px; + width: 16px; + height: 16px; +} +.ke-icon-tablerowinsertbelow { + background-position: 0px -864px; + width: 16px; + height: 16px; +} +.ke-icon-tablecoldelete { + background-position: 0px -880px; + width: 16px; + height: 16px; +} +.ke-icon-tablerowdelete { + background-position: 0px -896px; + width: 16px; + height: 16px; +} +.ke-icon-tablecellprop { + background-position: 0px -912px; + width: 16px; + height: 16px; +} +.ke-icon-tableprop { + background-position: 0px -928px; + width: 16px; + height: 16px; +} +.ke-icon-checked { + background-position: 0px -944px; + width: 16px; + height: 16px; +} +.ke-icon-code { + background-position: 0px -960px; + width: 16px; + height: 16px; +} +.ke-icon-map { + background-position: 0px -976px; + width: 16px; + height: 16px; +} +.ke-icon-baidumap { + background-position: 0px -976px; + width: 16px; + height: 16px; +} +.ke-icon-lineheight { + background-position: 0px -992px; + width: 16px; + height: 16px; +} +.ke-icon-clearhtml { + background-position: 0px -1008px; + width: 16px; + height: 16px; +} +.ke-icon-pagebreak { + background-position: 0px -1024px; + width: 16px; + height: 16px; +} +.ke-icon-insertfile { + background-position: 0px -1040px; + width: 16px; + height: 16px; +} +.ke-icon-quickformat { + background-position: 0px -1056px; + width: 16px; + height: 16px; +} +.ke-icon-template { + background-position: 0px -1072px; + width: 16px; + height: 16px; +} +.ke-icon-tablecellsplit { + background-position: 0px -1088px; + width: 16px; + height: 16px; +} +.ke-icon-tablerowmerge { + background-position: 0px -1104px; + width: 16px; + height: 16px; +} +.ke-icon-tablerowsplit { + background-position: 0px -1120px; + width: 16px; + height: 16px; +} +.ke-icon-tablecolmerge { + background-position: 0px -1136px; + width: 16px; + height: 16px; +} +.ke-icon-tablecolsplit { + background-position: 0px -1152px; + width: 16px; + height: 16px; +} +.ke-icon-anchor { + background-position: 0px -1168px; + width: 16px; + height: 16px; +} +.ke-icon-search { + background-position: 0px -1184px; + width: 16px; + height: 16px; +} +.ke-icon-new { + background-position: 0px -1200px; + width: 16px; + height: 16px; +} +.ke-icon-specialchar { + background-position: 0px -1216px; + width: 16px; + height: 16px; +} +.ke-icon-multiimage { + background-position: 0px -1232px; + width: 16px; + height: 16px; +} +/* container */ +.ke-container { + display: block; + border: 1px solid #CCCCCC; + background-color: #FFF; + overflow: hidden; + margin: 0; + padding: 0; +} +/* toolbar */ +.ke-toolbar { + border-bottom: 1px solid #CCC; + background-color: #F0F0EE; + padding: 2px 5px; + text-align: left; + overflow: hidden; + zoom: 1; +} +.ke-toolbar-icon { + background-repeat: no-repeat; + font-size: 0; + line-height: 0; + overflow: hidden; + display: block; +} +.ke-toolbar-icon-url { + background-image: url(default.png); +} +.ke-toolbar .ke-outline { + border: 1px solid #F0F0EE; + margin: 1px; + padding: 1px 2px; + font-size: 0; + line-height: 0; + overflow: hidden; + cursor: pointer; + display: block; + float: left; +} +.ke-toolbar .ke-on { + border: 1px solid #5690D2; +} +.ke-toolbar .ke-selected { + border: 1px solid #5690D2; + background-color: #E9EFF6; +} +.ke-toolbar .ke-disabled { + cursor: default; +} +.ke-toolbar .ke-separator { + height: 16px; + margin: 2px 3px; + border-left: 1px solid #A0A0A0; + border-right: 1px solid #FFFFFF; + border-top:0; + border-bottom:0; + width: 0; + font-size: 0; + line-height: 0; + overflow: hidden; + display: block; + float: left; +} +.ke-toolbar .ke-hr { + overflow: hidden; + height: 1px; + clear: both; +} +/* edit */ +.ke-edit { + padding: 0; +} +.ke-edit-iframe, +.ke-edit-textarea { + border: 0; + margin: 0; + padding: 0; + overflow: auto; +} +.ke-edit-textarea { + font: 12px/1.5 "Consolas", "Monaco", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace; + color: #000; + overflow: auto; + resize: none; +} +.ke-edit-textarea:focus { + outline: none; +} +/* statusbar */ +.ke-statusbar { + position: relative; + background-color: #F0F0EE; + border-top: 1px solid #CCCCCC; + font-size: 0; + line-height: 0; + *height: 12px; + overflow: hidden; + text-align: center; + cursor: s-resize; +} +.ke-statusbar-center-icon { + background-position: -0px -754px; + width: 15px; + height: 11px; + background-image: url(default.png); +} +.ke-statusbar-right-icon { + position: absolute; + right: 0; + bottom: 0; + cursor: se-resize; + background-position: -5px -741px; + width: 11px; + height: 11px; + background-image: url(default.png); +} +/* menu */ +.ke-menu { + border: 1px solid #A0A0A0; + background-color: #F1F1F1; + color: #222222; + padding: 2px; + font-family: "sans serif",tahoma,verdana,helvetica; + font-size: 12px; + text-align: left; + overflow: hidden; +} +.ke-menu-item { + border: 1px solid #F1F1F1; + background-color: #F1F1F1; + color: #222222; + height: 24px; + overflow: hidden; + cursor: pointer; +} +.ke-menu-item-on { + border: 1px solid #5690D2; + background-color: #E9EFF6; +} +.ke-menu-item-left { + width: 27px; + text-align: center; + overflow: hidden; +} +.ke-menu-item-center { + width: 0; + height: 24px; + border-left: 1px solid #E3E3E3; + border-right: 1px solid #FFFFFF; + border-top: 0; + border-bottom: 0; +} +.ke-menu-item-center-on { + border-left: 1px solid #E9EFF6; + border-right: 1px solid #E9EFF6; +} +.ke-menu-item-right { + border: 0; + padding: 0 0 0 5px; + line-height: 24px; + text-align: left; + overflow: hidden; +} +.ke-menu-separator { + margin: 2px 0; + height: 0; + overflow: hidden; + border-top: 1px solid #CCCCCC; + border-bottom: 1px solid #FFFFFF; + border-left: 0; + border-right: 0; +} +/* colorpicker */ +.ke-colorpicker { + border: 1px solid #A0A0A0; + background-color: #F1F1F1; + color: #222222; + padding: 2px; +} +.ke-colorpicker-table { + border:0; + margin:0; + padding:0; + border-collapse: separate; +} +.ke-colorpicker-cell { + font-size: 0; + line-height: 0; + border: 1px solid #F0F0EE; + cursor: pointer; + margin:3px; + padding:0; +} +.ke-colorpicker-cell-top { + font-family: "sans serif",tahoma,verdana,helvetica; + font-size: 12px; + line-height: 24px; + border: 1px solid #F0F0EE; + cursor: pointer; + margin:0; + padding:0; + text-align: center; +} +.ke-colorpicker-cell-on { + border: 1px solid #5690D2; +} +.ke-colorpicker-cell-selected { + border: 1px solid #2446AB; +} +.ke-colorpicker-cell-color { + width: 14px; + height: 14px; + margin: 3px; + padding: 0; + border: 0; +} +/* dialog */ +.ke-dialog { + position: absolute; + margin: 0; + padding: 0; +} +.ke-dialog .ke-header { + width: 100%; + margin-bottom: 10px; +} +.ke-dialog .ke-header .ke-left { + float: left; +} +.ke-dialog .ke-header .ke-right { + float: right; +} +.ke-dialog .ke-header label { + margin-right: 0; + cursor: pointer; + font-weight: normal; + display: inline; + vertical-align: top; +} +.ke-dialog-content { + background-color: #FFF; + width: 100%; + height: 100%; + color: #333; + border: 1px solid #A0A0A0; +} +.ke-dialog-shadow { + position: absolute; + z-index: -1; + top: 0; + left: 0; + width: 100%; + height: 100%; + box-shadow: 3px 3px 7px #999; + -moz-box-shadow: 3px 3px 7px #999; + -webkit-box-shadow: 3px 3px 7px #999; + filter: progid:DXImageTransform.Microsoft.Blur(PixelRadius='3', MakeShadow='true', ShadowOpacity='0.4'); + background-color: #F0F0EE; +} +.ke-dialog-header { + border:0; + margin:0; + padding: 0 10px; + background: url(background.png) repeat scroll 0 0 #F0F0EE; + border-bottom: 1px solid #CFCFCF; + height: 24px; + font: 12px/24px "sans serif",tahoma,verdana,helvetica; + text-align: left; + color: #222; + cursor: move; +} +.ke-dialog-icon-close { + display: block; + background: url(default.png) no-repeat scroll 0px -688px; + width: 16px; + height: 16px; + position: absolute; + right: 6px; + top: 6px; + cursor: pointer; +} +.ke-dialog-body { + font: 12px/1.5 "sans serif",tahoma,verdana,helvetica; + text-align: left; + overflow: hidden; + width: 100%; +} +.ke-dialog-body textarea { + display: block; + overflow: auto; + padding: 0; + resize: none; +} +.ke-dialog-body textarea:focus, +.ke-dialog-body input:focus, +.ke-dialog-body select:focus { + outline: none; +} +.ke-dialog-body label { + margin-right: 10px; + cursor: pointer; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; +} +.ke-dialog-body img { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; +} +.ke-dialog-body select { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; + width: auto; +} +.ke-dialog-body .ke-textarea { + display: block; + width: 408px; + height: 260px; + font-family: "sans serif",tahoma,verdana,helvetica; + font-size: 12px; + border-color: #848484 #E0E0E0 #E0E0E0 #848484; + border-style: solid; + border-width: 1px; +} +.ke-dialog-body .ke-form { + margin: 0; + padding: 0; +} +.ke-dialog-loading { + position: absolute; + top: 0; + left: 1px; + z-index: 1; + text-align: center; +} +.ke-dialog-loading-content { + background: url("../common/loading.gif") no-repeat; + color: #666; + font-size: 14px; + font-weight: bold; + height: 31px; + line-height: 31px; + padding-left: 36px; +} +.ke-dialog-row { + margin-bottom: 10px; +} +.ke-dialog-footer { + font: 12px/1 "sans serif",tahoma,verdana,helvetica; + text-align: right; + padding:0 0 5px 0; + background-color: #FFF; + width: 100%; +} +.ke-dialog-preview, +.ke-dialog-yes { + margin: 5px; +} +.ke-dialog-no { + margin: 5px 10px 5px 5px; +} +.ke-dialog-mask { + background-color:#FFF; + filter:alpha(opacity=50); + opacity:0.5; +} +.ke-button-common { + background: url(background.png) no-repeat; + cursor: pointer; + height: 23px; + line-height: 23px; + overflow: visible; + display: inline-block; + vertical-align: top; + cursor: pointer; +} +.ke-button-outer { + background-position: 0 -25px; + padding: 0; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; +} +.ke-button { + background-position: right -25px; + padding: 0 14px 0 12px; + margin: 0 0 0 2px; + font-family: "sans serif",tahoma,verdana,helvetica; + border: 0 none; + color: #333; + font-size: 12px; + text-decoration: none; +} +/* inputbox */ +.ke-input-text { + background-color:#FFFFFF; + font-family: "sans serif",tahoma,verdana,helvetica; + font-size: 12px; + line-height: 17px; + height: 17px; + padding: 2px 4px; + border-color: #848484 #E0E0E0 #E0E0E0 #848484; + border-style: solid; + border-width: 1px; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; +} +.ke-input-number { + width: 50px; +} +.ke-input-color { + border: 1px solid #A0A0A0; + background-color: #FFFFFF; + font-size: 12px; + width: 60px; + height: 20px; + line-height: 20px; + padding-left: 5px; + overflow: hidden; + cursor: pointer; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; +} +.ke-upload-button { + position: relative; +} +.ke-upload-area { + position: relative; + overflow: hidden; + margin: 0; + padding: 0; + *height: 25px; +} +.ke-upload-area .ke-upload-file { + position: absolute; + font-size: 60px; + top: 0; + right: 0; + padding: 0; + margin: 0; + z-index: 811212; + border: 0 none; + opacity: 0; + filter: alpha(opacity=0); +} +/* tabs */ +.ke-tabs { + font: 12px/1 "sans serif",tahoma,verdana,helvetica; + border-bottom:1px solid #A0A0A0; + padding-left:5px; + margin-bottom:20px; +} +.ke-tabs-ul { + list-style-image:none; + list-style-position:outside; + list-style-type:none; + margin:0; + padding:0; +} +.ke-tabs-li { + position: relative; + border: 1px solid #A0A0A0; + background-color: #F0F0EE; + margin: 0 2px -1px 0; + padding: 0 20px; + float: left; + line-height: 25px; + text-align: center; + color: #555555; + cursor: pointer; +} +.ke-tabs-li-selected { + background-color: #FFF; + border-bottom: 1px solid #FFF; + color: #000; + cursor: default; +} +.ke-tabs-li-on { + background-color: #FFF; + color: #000; +} +/* progressbar */ +.ke-progressbar { + position: relative; + margin: 0; + padding: 0; +} +.ke-progressbar-bar { + border: 1px solid #6FA5DB; + width: 80px; + height: 5px; + margin: 10px 10px 0 10px; + padding: 0; +} +.ke-progressbar-bar-inner { + width: 0; + height: 5px; + background-color: #6FA5DB; + overflow: hidden; + margin: 0; + padding: 0; +} +.ke-progressbar-percent { + position: absolute; + top: 0; + left: 40%; + display: none; +} +/* swfupload */ +.ke-swfupload-top { + position: relative; + margin-bottom: 10px; + _width: 608px; +} +.ke-swfupload-button { + height: 23px; + line-height: 23px; +} +.ke-swfupload-desc { + padding: 0 10px; + height: 23px; + line-height: 23px; +} +.ke-swfupload-startupload { + position: absolute; + top: 0; + right: 0; +} +.ke-swfupload-body { + overflow: scroll; + background-color:#FFFFFF; + border-color: #848484 #E0E0E0 #E0E0E0 #848484; + border-style: solid; + border-width: 1px; + width: auto; + height: 370px; + padding: 5px; +} +.ke-swfupload-body .ke-item { + width: 100px; + margin: 5px; +} +.ke-swfupload-body .ke-photo { + position: relative; + border: 1px solid #DDDDDD; + background-color:#FFFFFF; + padding: 10px; +} +.ke-swfupload-body .ke-delete { + display: block; + background: url(default.png) no-repeat scroll 0px -688px; + width: 16px; + height: 16px; + position: absolute; + right: 0; + top: 0; + cursor: pointer; +} +.ke-swfupload-body .ke-status { + position: absolute; + left: 0; + bottom: 5px; + width: 100px; + height: 17px; +} +.ke-swfupload-body .ke-message { + width: 100px; + text-align: center; + overflow: hidden; + height:17px; +} +.ke-swfupload-body .ke-error { + color: red; +} +.ke-swfupload-body .ke-name { + width: 100px; + text-align: center; + overflow: hidden; + height:16px; +} +.ke-swfupload-body .ke-on { + border: 1px solid #5690D2; + background-color: #E9EFF6; +} + +/* emoticons */ +.ke-plugin-emoticons { + position: relative; +} +.ke-plugin-emoticons .ke-preview { + position: absolute; + text-align: center; + margin: 2px; + padding: 10px; + top: 0; + border: 1px solid #A0A0A0; + background-color: #FFFFFF; + display: none; +} +.ke-plugin-emoticons .ke-preview-img { + border:0; + margin:0; + padding:0; +} +.ke-plugin-emoticons .ke-table { + border:0; + margin:0; + padding:0; + border-collapse:separate; +} +.ke-plugin-emoticons .ke-cell { + margin:0; + padding:1px; + border:1px solid #F0F0EE; + cursor:pointer; +} +.ke-plugin-emoticons .ke-on { + border: 1px solid #5690D2; + background-color: #E9EFF6; +} +.ke-plugin-emoticons .ke-img { + display:block; + background-repeat:no-repeat; + overflow:hidden; + margin:2px; + width:24px; + height:24px; + margin: 0; + padding: 0; + border: 0; +} +.ke-plugin-emoticons .ke-page { + text-align: right; + margin: 5px; + padding: 0; + border: 0; + font: 12px/1 "sans serif",tahoma,verdana,helvetica; + color: #333; + text-decoration: none; +} +.ke-plugin-plainpaste-textarea, +.ke-plugin-wordpaste-iframe { + display: block; + width: 408px; + height: 260px; + font-family: "sans serif",tahoma,verdana,helvetica; + font-size: 12px; + border-color: #848484 #E0E0E0 #E0E0E0 #848484; + border-style: solid; + border-width: 1px; +} +/* filemanager */ +.ke-plugin-filemanager-header { + width: 100%; + margin-bottom: 10px; +} +.ke-plugin-filemanager-header .ke-left { + float: left; +} +.ke-plugin-filemanager-header .ke-right { + float: right; +} +.ke-plugin-filemanager-body { + overflow: scroll; + background-color:#FFFFFF; + border-color: #848484 #E0E0E0 #E0E0E0 #848484; + border-style: solid; + border-width: 1px; + width: auto; + height: 370px; + padding: 5px; +} +.ke-plugin-filemanager-body .ke-item { + width: 100px; + margin: 5px; +} +.ke-plugin-filemanager-body .ke-photo { + border: 1px solid #DDDDDD; + background-color:#FFFFFF; + padding: 10px; +} +.ke-plugin-filemanager-body .ke-name { + width: 100px; + text-align: center; + overflow: hidden; + height:16px; +} +.ke-plugin-filemanager-body .ke-on { + border: 1px solid #5690D2; + background-color: #E9EFF6; +} +.ke-plugin-filemanager-body .ke-table { + width: 95%; + border: 0; + margin: 0; + padding: 0; + border-collapse: separate; +} +.ke-plugin-filemanager-body .ke-table .ke-cell { + margin: 0; + padding: 0; + border: 0; +} +.ke-plugin-filemanager-body .ke-table .ke-name { + width: 55%; + text-align: left; +} +.ke-plugin-filemanager-body .ke-table .ke-size { + width: 15%; + text-align: left; +} +.ke-plugin-filemanager-body .ke-table .ke-datetime { + width: 30%; + text-align: center; +} + diff --git a/php/kindeditor_demo/kindeditor/themes/default/default.png b/php/kindeditor_demo/kindeditor/themes/default/default.png new file mode 100755 index 0000000000000000000000000000000000000000..cc9e72d2bdf9a67ae587dba81b94bfc2d1edc827 GIT binary patch literal 8299 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/themes/qq/editor.gif b/php/kindeditor_demo/kindeditor/themes/qq/editor.gif new file mode 100755 index 0000000000000000000000000000000000000000..b256841f3088117a98b969499784042bab41aeca GIT binary patch literal 1449 zcmV;a1y=e;Nk%w1VL$>90M$PLQia8GoX|62nLBW?f~M5g+~Q1v!`Ir}#@Fmee!?zP zh+U1zmb2M1O>e8g;1W5WgsIkUn$Ip`%2$fVXMn^#bhsNcP%c~9LU_GjdBU~IL&`rMETD?m}ueX??hjiOzpp!m?j@drmO88u=IIcuapktQofL6Om9 zlnpU3=)x$aWkr|!ZjLRGtHu(6ln;RftGGxJA%N`& zB3!hPVK$<~K3mqbjTQ**Wh4;j?t!p}uD+aU3*p3)vL@2CO@zgW@33^N#Dz#wk2xug@*QIr;sbl%D3g@yevA{5qO(~K1eoM}ioR&X#O0XO)7 zC>}k1iN$(*CgI+kSUe&`4IOx}g9rC5+2j>lWz-reRe*J%2q`SIzyw-Cq+p#->}Q4# zF}^iMr9Y_9g9^Z^K!X7^1nVmeT%t%#6@roYClqeYl;aaH$uuS}8eNzxIp6R)VWWYR zQ|WoS0bydH7?X}U^)0D=w|T#%%iqME>NYuB9`8x$>wa8RoXF$6%Ydp?LATGHbA zgs*#?s|T{yMQ10C)X~ZW1B4l-Fd9ganG+En>$q9DlM2PI5qYfe0|!A?Q2+)+((phA z2T(9Cy%~)vg?|DJ!LvY8oU&@a2f`vNN+Cy~1s7}h0+)0hWBbIj%qqK#)e#@;#5mlE zV@}s153=!Ol48N~9_(Qu015=H@PGmZ+|16LV>f|q(o0P6!UCwYus~S`I3RezUZ%57 z7JpRs+u;ZkwF~2oSUjubjZ6FlG<~8G$s}!DL~*S;P0PgR6Wdy`=}{=4z+)>k5W)dT zLf%Bn=%v%f#0a?OuKNhJL+FG<6UZREE3X7DdlGu0SN9MABrrh2wOCf3(R2Ag z1jrcz4&fr|GN2ohS30~+PHIoc9OaS_0{~d-2c)yx0d;aK4zBMF69nDZ&}Anikgy3S zNTCW>s6s&~@EkAPN9PRl!5Yc|V;EEe>TJlv9@5YvNOQ@_kmti98u5rnh#?ZO69fP| DK<${p literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/themes/qq/qq.css b/php/kindeditor_demo/kindeditor/themes/qq/qq.css new file mode 100755 index 0000000..75aac1e --- /dev/null +++ b/php/kindeditor_demo/kindeditor/themes/qq/qq.css @@ -0,0 +1,163 @@ +/* container */ +.ke-container-qq { + display: block; + border: 1px solid #c3c3c3; + background-color: #FFF; + overflow: hidden; + margin: 0; + padding: 0; +} +/* toolbar */ +.ke-container-qq .ke-toolbar { + border-bottom: 1px solid #c3c3c3; + background-color: #FFFFFF; + padding: 2px 5px; + text-align: left; + overflow: hidden; + zoom: 1; +} +.ke-toolbar-icon-url { + background-image: url(editor.gif); + width:18px; + *xwidth:20px; + height:18px; + *xheight:20px; +} +.ke-icon-checked{ + background-image: url(../default/default.png); + width:16px; + height:16px; +} +.ke-container-qq .ke-icon-bold{ + background-position: 4px 1px; +} +.ke-container-qq .ke-icon-italic{ + background-position: -27px 1px; +} +.ke-container-qq .ke-icon-italic{ + background-position: -28px 1px; +} +.ke-container-qq .ke-icon-underline{ + background-position: -60px 1px; +} +.ke-container-qq .ke-icon-fontname{ + background-position: -95px 1px; +} +.ke-container-qq .ke-icon-fontsize{ + background-position: -128px 1px; +} +.ke-container-qq .ke-icon-forecolor{ + background-position: -159px 1px; +} +.ke-container-qq .ke-icon-hilitecolor{ + background-position: -190px 1px; +} +.ke-container-qq .ke-icon-plug-align{ + background-position: -223px 1px; +} +/*这是2016年添加的img图标 ----start*/ +.ke-container-qq .ke-icon-image{ + background-image: url(../default/default.png); + background-position: 0px -496px; + width: 16px; + height: 16px; +} +.ke-container-qq .ke-icon-multiimage{ + background-image: url(../default/default.png); + background-position: 0px -1232px; + width: 16px; + height: 16px; +} +.ke-container-qq .ke-icon-baidumap{ + background-image: url(../default/default.png); + background-position: 0px -976px; + width: 16px; + height: 16px; +} +/*这是2016年添加的img图标 ----end*/ +.plug-align-justifyleft{ + background-position: -350px 1px; +} +.plug-align-justifycenter{ + background-position: -382px 1px; +} +.plug-align-justifyright{ + background-position: -414px 1px; +} +.plug-order-insertorderedlist{ + background-position: -446px 1px; +} +.plug-order-insertunorderedlist{ + background-position: -477px 1px; +} +.plug-indent-indent{ + background-position: -513px 1px; +} +.plug-indent-outdent{ + background-position: -545px 1px; +} +.ke-container-qq .ke-icon-plug-order{ + background-position: -255px 1px; +} +.ke-container-qq .ke-icon-plug-indent{ + background-position: -287px 1px; +} +.ke-container-qq .ke-icon-link{ + background-position: -319px 1px; +} + +.ke-container-qq .ke-toolbar .ke-outline { + cursor: default; + padding:0px; + border:1px solid #fff; +} +.ke-container-qq .ke-toolbar .ke-on { + border-left:1px solid white; + border-top:1px solid white; + border-right:1px solid gray; + border-bottom:1px solid gray; + background-color: #FFFFFF; +} +.ke-container-qq .ke-toolbar .ke-selected { + border-left:1px solid gray; + border-top:1px solid gray; + border-right:1px solid white; + border-bottom:1px solid white; + background-color: #FFFFFF; +} +.ke-container-qq .ke-toolbar .ke-disabled { + cursor: default; +} + +.ke-colorpicker-qq{ + background:#fff; +} +/* statusbar */ +.ke-container-qq .ke-statusbar { + display:none; +} +/* menu */ +.ke-menu-qq { + border:1px solid #a6a6a6; + position:absolute; + background:#fff; + -moz-box-shadow:2px 2px 4px #DDDDDD; + z-index:999; + left:-400px; + top:-386px; + right:218px; + width:130px; +} +.ke-menu-qq .ke-menu-item { + padding:0px; + background:#fff; +} +.ke-menu-qq .ke-menu-item-on { + border:1px solid #000080;background:#FFEEC2;color:#036; +} +.ke-menu-qq .ke-toolbar .ke-selected { + border:1px solid #9a9afb; +} +.ke-menu-qq .ke-menu-item-left{ + width:auto; +} diff --git a/php/kindeditor_demo/kindeditor/themes/simple/simple.css b/php/kindeditor_demo/kindeditor/themes/simple/simple.css new file mode 100755 index 0000000..4c76cf9 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/themes/simple/simple.css @@ -0,0 +1,100 @@ +/* container */ +.ke-container-simple { + display: block; + border: 1px solid #CCC; + background-color: #FFF; + overflow: hidden; +} +/* toolbar */ +.ke-container-simple .ke-toolbar { + border-bottom: 1px solid #CCC; + background-color: #FFF; + padding: 2px 5px; + overflow: hidden; +} +.ke-container-simple .ke-toolbar .ke-outline { + border: 1px solid #FFF; + background-color: transparent; + margin: 1px; + padding: 1px 2px; + font-size: 0; + line-height: 0; + overflow: hidden; + cursor: pointer; +} +.ke-container-simple .ke-toolbar .ke-on { + border: 1px solid #5690D2; +} +.ke-container-simple .ke-toolbar .ke-selected { + border: 1px solid #5690D2; + background-color: #E9EFF6; +} +.ke-container-simple .ke-toolbar .ke-disabled { + cursor: default; +} +/* statusbar */ +.ke-container-simple .ke-statusbar { + position: relative; + background-color: #FFF; + border-top: 1px solid #CCCCCC; + font-size: 0; + line-height: 0; + *height: 12px; + overflow: hidden; + text-align: center; + cursor: s-resize; +} +/* menu */ +.ke-menu-simple { + border: 1px solid #A0A0A0; + background-color: #FFF; + color: #222222; + padding: 2px; + font-family: "sans serif",tahoma,verdana,helvetica; + font-size: 12px; + text-align: left; + overflow: hidden; +} +.ke-menu-simple .ke-menu-item { + border: 1px solid #FFF; + background-color: #FFF; + color: #222222; + height: 24px; + overflow: hidden; + cursor: pointer; +} +.ke-menu-simple .ke-menu-item-on { + border: 1px solid #5690D2; + background-color: #FFF; +} +/* colorpicker */ +.ke-colorpicker-simple { + border: 1px solid #A0A0A0; + background-color: #FEFEFE; + color: #222222; + padding: 2px; +} +.ke-colorpicker-simple .ke-colorpicker-cell { + font-size: 0; + line-height: 0; + border: 1px solid #FEFEFE; + cursor: pointer; + margin:3px; + padding:0; +} +.ke-colorpicker-simple .ke-colorpicker-cell-top { + font-family: "sans serif",tahoma,verdana,helvetica; + font-size: 12px; + line-height: 24px; + border: 1px solid #FEFEFE; + cursor: pointer; + margin:0; + padding:0; + text-align: center; +} +.ke-colorpicker-simple .ke-colorpicker-cell-on { + border: 1px solid #5690D2; +} +.ke-colorpicker-simple .ke-colorpicker-cell-selected { + border: 1px solid #2446AB; +}
                  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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/search.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/search.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/search.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/search.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/shadow.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/shadow.gif new file mode 100755 index 0000000000000000000000000000000000000000..af7f537e391f08327e417c7be6323c917d5d3788 GIT binary patch literal 4364 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 mNRx4)$-Se2KGVRJG=-nEko^8U73WMVE8{ literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/shadow2.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/shadow2.gif new file mode 100755 index 0000000000000000000000000000000000000000..099cbf35d455e13d49010e736c40bab22c3d1a23 GIT binary patch literal 3093 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/shadowAlpha.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/shadowAlpha.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/sprite.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/sprite.png new file mode 100755 index 0000000000000000000000000000000000000000..33d2c4d4649ec35b7771213977d7c83180907ccd GIT binary patch literal 40027 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabHoverMid.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabHoverMid.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabHoverRight.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabHoverRight.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabMenuCheckbox.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabMenuCheckbox.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabMenuPin.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabMenuPin.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabMenuRadio.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabMenuRadio.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabMenuTarget.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabMenuTarget.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabMenuTargetHover.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabMenuTargetHover.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabRight.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tabRight.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/textEditorBorders.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/textEditorBorders.gif new file mode 100755 index 0000000000000000000000000000000000000000..0ee5497874cec4a5599e562dd7c00b8c57bc5a44 GIT binary patch literal 117 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 L`)q75=;;3dF|oR- literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/textEditorCorners.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/textEditorCorners.png new file mode 100755 index 0000000000000000000000000000000000000000..a0f839dc598edd80d093e1cf954134a916db5af0 GIT binary patch literal 3960 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 literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/titlebarMid.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/titlebarMid.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tree_close.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tree_close.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tree_open.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/tree_open.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/up.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/up.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/warningIcon.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/warningIcon.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/warningIcon.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/chrome-extension/skin/xp/warningIcon.png new file mode 100755 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 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}"}; + } + + 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; + + // 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 + 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; + } + } + } + + // 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) + return ob + ""; + + 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, ""); + + if (elt.offsetLeft) + coords.x += elt.offsetLeft + parseInt(style.borderLeftWidth); + if (elt.offsetTop) + coords.y += elt.offsetTop + parseInt(style.borderTopWidth); + + if (p) + { + if (p.nodeType == 1) + addOffset(p, coords, view); + } + else + { + var otherView = isIE ? elt.ownerDocument.parentWindow : elt.ownerDocument.defaultView; + if (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; + + return toString.call(object) === "[object Function]" || + this.isIE && typeof object != "string" && reFunction.test(""+object); +}; + + +// ************************************************************************************************ +// 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 = this.getXHRObject(); + }, + + 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); + +/* See license.txt for terms of usage */ + +FBL.ns( /** @scope ns-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; +}; + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +FBL.ns( /** @scope ns-firebug */ function() { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +// Globals + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Internals + +var modules = []; +var panelTypes = []; +var panelTypeMap = {}; +var reps = []; + +var parentPanelMap = {}; + + +// ************************************************************************************************ +// Firebug + +/** + * @namespace describe Firebug + * @exports window.Firebug as Firebug + */ +window.Firebug = FBL.Firebug = +{ + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + version: "Firebug Lite 1.3.2", + revision: "$Revision: 9760 $", + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + 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; + + // Document must be cached before chrome initialization + cacheDocument(); + + if (Firebug.Inspector) + Firebug.Inspector.create(); + + if (FBL.processAllStyleSheets) + processAllStyleSheets(Firebug.browser.document); + + FirebugChrome.initialize(); + + dispatch(modules, "initialize", []); + + if (Env.onLoad) + { + var onLoad = Env.onLoad; + delete Env.onLoad; + + setTimeout(onLoad, 200); + } + }, + + shutdown: function() + { + if (Firebug.Inspector) + Firebug.Inspector.destroy(); + + dispatch(modules, "shutdown", []); + + var chromeMap = FirebugChrome.chromeMap; + + for (var name in chromeMap) + { + if (chromeMap.hasOwnProperty(name)) + { + chromeMap[name].destroy(); + } + } + + 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; + + this.savePrefs(); + }, + + setPrefs: function(prefs) + { + for (var name in prefs) + { + if (prefs.hasOwnProperty(name)) + Firebug[name] = prefs[name]; + } + + this.savePrefs(); + }, + + restorePrefs: function() + { + var Options = Env.Options; + + for (var name in Options) + { + Firebug[name] = Options[name]; + } + }, + + loadPrefs: function(prefs) + { + this.restorePrefs(); + + prefs = prefs || eval("(" + readCookie("FirebugLite") + ")"); + + for (var name in prefs) + { + if (prefs.hasOwnProperty(name)) + Firebug[name] = prefs[name]; + } + }, + + savePrefs: function() + { + var json = ['{'], jl = 0; + var Options = Env.Options; + + for (var name in Options) + { + if (Options.hasOwnProperty(name)) + { + var value = Firebug[name]; + + json[++jl] = '"'; + json[++jl] = name; + + var type = typeof value; + if (type == "boolean" || type == "number") + { + json[++jl] = '":'; + json[++jl] = value; + json[++jl] = ','; + } + else + { + json[++jl] = '":"'; + json[++jl] = value; + json[++jl] = '",'; + } + } + } + + json.length = jl--; + json[++jl] = '}'; + + createCookie("FirebugLite", json.join("")); + }, + + erasePrefs: function() + { + removeCookie("FirebugLite"); + } +}; + +Firebug.restorePrefs(); + +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; + Firebug.InfoTip.initializeBrowser(Firebug.chrome); + }, + + shutdown: function() + { + if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.Panel.shutdown", this.name); + + /// TODO: xxxpedro infoTip Hack + 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.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"; + } +}); + +// ************************************************************************************************ + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +FBL.ns( /** @scope ns-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) + FirebugChrome.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 width || el.scrollHeight > height)) + { + width = el.scrollWidth; + height = el.scrollHeight; + } + + return {width: width, height: height}; + }, + + getWindowScrollPosition: function() + { + var top=0, left=0, el; + + if(typeof this.window.pageYOffset == "number") + { + top = this.window.pageYOffset; + left = this.window.pageXOffset; + } + else if((el=this.document.body) && (el.scrollTop || el.scrollLeft)) + { + top = el.scrollTop; + left = el.scrollLeft; + } + else if((el=this.document.documentElement) && (el.scrollTop || el.scrollLeft)) + { + top = el.scrollTop; + left = el.scrollLeft; + } + + return {top:top, left:left}; + }, + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Element Methods + + getElementFromPoint: function(x, y) + { + if (shouldFixElementFromPoint) + { + var scroll = this.getWindowScrollPosition(); + return this.document.elementFromPoint(x + scroll.left, y + scroll.top); + } + else + return this.document.elementFromPoint(x, y); + }, + + getElementPosition: function(el) + { + var left = 0 + var top = 0; + + do + { + left += el.offsetLeft; + top += el.offsetTop; + } + while (el = el.offsetParent); + + return {left:left, top:top}; + }, + + getElementBox: function(el) + { + var result = {}; + + if (el.getBoundingClientRect) + { + var rect = el.getBoundingClientRect(); + + // fix IE problem with offset when not in fullscreen mode + var offset = isIE ? this.document.body.clientTop || this.document.documentElement.clientTop: 0; + + var scroll = this.getWindowScrollPosition(); + + result.top = Math.round(rect.top - offset + scroll.top); + result.left = Math.round(rect.left - offset + scroll.left); + result.height = Math.round(rect.bottom - rect.top); + result.width = Math.round(rect.right - rect.left); + } + else + { + var position = this.getElementPosition(el); + + result.top = position.top; + result.left = position.left; + result.height = el.offsetHeight; + result.width = el.offsetWidth; + } + + return result; + }, + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Measurement Methods + + getMeasurement: function(el, name) + { + var result = {value: 0, unit: "px"}; + + var cssValue = this.getStyle(el, name); + + if (!cssValue) return result; + if (cssValue.toLowerCase() == "auto") return result; + + var reMeasure = /(\d+\.?\d*)(.*)/; + var m = cssValue.match(reMeasure); + + if (m) + { + result.value = m[1]-0; + result.unit = m[2].toLowerCase(); + } + + return result; + }, + + getMeasurementInPixels: function(el, name) + { + if (!el) return null; + + var m = this.getMeasurement(el, name); + var value = m.value; + var unit = m.unit; + + if (unit == "px") + return value; + + else if (unit == "pt") + return this.pointsToPixels(name, value); + + if (unit == "em") + return this.emToPixels(el, value); + + else if (unit == "%") + return this.percentToPixels(el, value); + }, + + getMeasurementBox1: function(el, name) + { + var sufixes = ["Top", "Left", "Bottom", "Right"]; + var result = []; + + for(var i=0, sufix; sufix=sufixes[i]; i++) + result[i] = Math.round(this.getMeasurementInPixels(el, name + sufix)); + + return {top:result[0], left:result[1], bottom:result[2], right:result[3]}; + }, + + getMeasurementBox: function(el, name) + { + var result = []; + var sufixes = name == "border" ? + ["TopWidth", "LeftWidth", "BottomWidth", "RightWidth"] : + ["Top", "Left", "Bottom", "Right"]; + + if (isIE) + { + var propName, cssValue; + var autoMargin = null; + + for(var i=0, sufix; sufix=sufixes[i]; i++) + { + propName = name + sufix; + + cssValue = el.currentStyle[propName] || el.style[propName]; + + if (cssValue == "auto") + { + if (!autoMargin) + autoMargin = this.getCSSAutoMarginBox(el); + + result[i] = autoMargin[sufix.toLowerCase()]; + } + else + result[i] = this.getMeasurementInPixels(el, propName); + + } + + } + else + { + for(var i=0, sufix; sufix=sufixes[i]; i++) + result[i] = this.getMeasurementInPixels(el, name + sufix); + } + + return {top:result[0], left:result[1], bottom:result[2], right:result[3]}; + }, + + getCSSAutoMarginBox: function(el) + { + if (isIE && " meta title input script link a ".indexOf(" "+el.nodeName.toLowerCase()+" ") != -1) + return {top:0, left:0, bottom:0, right:0}; + /**/ + + if (isIE && " h1 h2 h3 h4 h5 h6 h7 ul p ".indexOf(" "+el.nodeName.toLowerCase()+" ") == -1) + return {top:0, left:0, bottom:0, right:0}; + /**/ + + var offsetTop = 0; + if (false && isIEStantandMode) + { + var scrollSize = Firebug.browser.getWindowScrollSize(); + offsetTop = scrollSize.height; + } + + var box = this.document.createElement("div"); + //box.style.cssText = "margin:0; padding:1px; border: 0; position:static; overflow:hidden; visibility: hidden;"; + box.style.cssText = "margin:0; padding:1px; border: 0; visibility: hidden;"; + + var clone = el.cloneNode(false); + var text = this.document.createTextNode(" "); + clone.appendChild(text); + + box.appendChild(clone); + + this.document.body.appendChild(box); + + var marginTop = clone.offsetTop - box.offsetTop - 1; + var marginBottom = box.offsetHeight - clone.offsetHeight - 2 - marginTop; + + var marginLeft = clone.offsetLeft - box.offsetLeft - 1; + var marginRight = box.offsetWidth - clone.offsetWidth - 2 - marginLeft; + + this.document.body.removeChild(box); + + return {top:marginTop+offsetTop, left:marginLeft, bottom:marginBottom-offsetTop, right:marginRight}; + }, + + getFontSizeInPixels: function(el) + { + var size = this.getMeasurement(el, "fontSize"); + + if (size.unit == "px") return size.value; + + // get font size, the dirty way + var computeDirtyFontSize = function(el, calibration) + { + var div = this.document.createElement("div"); + var divStyle = offscreenStyle; + + if (calibration) + divStyle += " font-size:"+calibration+"px;"; + + div.style.cssText = divStyle; + div.innerHTML = "A"; + el.appendChild(div); + + var value = div.offsetHeight; + el.removeChild(div); + return value; + } + + /* + var calibrationBase = 200; + var calibrationValue = computeDirtyFontSize(el, calibrationBase); + var rate = calibrationBase / calibrationValue; + /**/ + + // the "dirty technique" fails in some environments, so we're using a static value + // based in some tests. + var rate = 200 / 225; + + var value = computeDirtyFontSize(el); + + return value * rate; + }, + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Unit Funtions + + pointsToPixels: function(name, value, returnFloat) + { + var axis = /Top$|Bottom$/.test(name) ? "y" : "x"; + + var result = value * pixelsPerInch[axis] / 72; + + return returnFloat ? result : Math.round(result); + }, + + emToPixels: function(el, value) + { + if (!el) return null; + + var fontSize = this.getFontSizeInPixels(el); + + return Math.round(value * fontSize); + }, + + exToPixels: function(el, value) + { + if (!el) return null; + + // get ex value, the dirty way + var div = this.document.createElement("div"); + div.style.cssText = offscreenStyle + "width:"+value + "ex;"; + + el.appendChild(div); + var value = div.offsetWidth; + el.removeChild(div); + + return value; + }, + + percentToPixels: function(el, value) + { + if (!el) return null; + + // get % value, the dirty way + var div = this.document.createElement("div"); + div.style.cssText = offscreenStyle + "width:"+value + "%;"; + + el.appendChild(div); + var value = div.offsetWidth; + el.removeChild(div); + + return value; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getStyle: isIE ? function(el, name) + { + return el.currentStyle[name] || el.style[name] || undefined; + } + : function(el, name) + { + return this.document.defaultView.getComputedStyle(el,null)[name] + || el.style[name] || undefined; + } + +}; + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +FBL.ns( /**@scope ns-chrome*/ function() { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +// Globals + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Window Options + +var WindowDefaultOptions = + { + type: "frame", + id: "FirebugUI", + height: 250 + }, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Instantiated objects + + commandLine, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Interface Elements Cache + + fbTop, + fbContent, + fbContentStyle, + fbBottom, + fbBtnInspect, + + fbToolbar, + + fbPanelBox1, + fbPanelBox1Style, + fbPanelBox2, + fbPanelBox2Style, + fbPanelBar2Box, + fbPanelBar2BoxStyle, + + fbHSplitter, + fbVSplitter, + fbVSplitterStyle, + + fbPanel1, + fbPanel1Style, + fbPanel2, + fbPanel2Style, + + fbConsole, + fbConsoleStyle, + fbHTML, + + fbCommandLine, + fbLargeCommandLine, + fbLargeCommandButtons, + +//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Cached size values + + topHeight, + topPartialHeight, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + chromeRedrawSkipRate = isIE ? 75 : isOpera ? 80 : 75, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + lastSelectedPanelName, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + focusCommandLineState = 0, + lastFocusedPanelName, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + lastHSplitterMouseMove = 0, + onHSplitterMouseMoveBuffer = null, + onHSplitterMouseMoveTimer = null, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + lastVSplitterMouseMove = 0; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + +// ************************************************************************************************ +// FirebugChrome + +/**@namespace*/ +FBL.FirebugChrome = +{ + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + isOpen: false, + height: 250, + sidePanelWidth: 350, + + selectedPanelName: "Console", + selectedHTMLElementId: null, + + chromeMap: {}, + + htmlSelectionStack: [], + consoleMessageQueue: [], + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + create: function() + { + if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("FirebugChrome.create", "creating chrome window"); + + createChromeWindow(); + }, + + initialize: function() + { + if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("FirebugChrome.initialize", "initializing chrome window"); + + if (Env.chrome.type == "frame" || Env.chrome.type == "div") + ChromeMini.create(Env.chrome); + + var chrome = Firebug.chrome = new Chrome(Env.chrome); + FirebugChrome.chromeMap[chrome.type] = chrome; + + addGlobalEvent("keydown", onGlobalKeyDown); + + if (Env.Options.enablePersistent && chrome.type == "popup") + { + // TODO: xxxpedro persist - revise chrome synchronization when in persistent mode + var frame = FirebugChrome.chromeMap.frame; + if (frame) + frame.close(); + + //chrome.reattach(frame, chrome); + //TODO: xxxpedro persist synchronize? + chrome.initialize(); + } + }, + + clone: function(FBChrome) + { + for (var name in FBChrome) + { + var prop = FBChrome[name]; + if (FBChrome.hasOwnProperty(name) && !isFunction(prop)) + { + this[name] = prop; + } + } + } +}; + + + +// ************************************************************************************************ +// Chrome Window Creation + +var createChromeWindow = function(options) +{ + options = extend(WindowDefaultOptions, options || {}); + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Locals + + var chrome = {}, + + context = options.context || Env.browser, + + type = chrome.type = Env.Options.enablePersistent ? + "popup" : + options.type, + + isChromeFrame = type == "frame", + + useLocalSkin = Env.useLocalSkin, + + url = useLocalSkin ? + Env.Location.skin : + "about:blank", + + // document.body not available in XML+XSL documents in Firefox + body = context.document.getElementsByTagName("body")[0], + + formatNode = function(node) + { + if (!Env.isDebugMode) + { + node.firebugIgnore = true; + } + + node.style.border = "0"; + node.style.visibility = "hidden"; + node.style.zIndex = "2147483647"; // MAX z-index = 2147483647 + node.style.position = noFixedPosition ? "absolute" : "fixed"; + node.style.width = "100%"; // "102%"; IE auto margin bug + node.style.left = "0"; + node.style.bottom = noFixedPosition ? "-1px" : "0"; + node.style.height = options.height + "px"; + + // avoid flickering during chrome rendering + if (isFirefox) + node.style.display = "none"; + }, + + createChromeDiv = function() + { + //Firebug.Console.warn("Firebug Lite GUI is working in 'windowless mode'. It may behave slower and receive interferences from the page in which it is installed."); + + var node = chrome.node = createGlobalElement("div"), + style = createGlobalElement("style"), + + css = FirebugChrome.Skin.CSS + /* + .replace(/;/g, " !important;") + .replace(/!important\s!important/g, "!important") + .replace(/display\s*:\s*(\w+)\s*!important;/g, "display:$1;")*/, + + // reset some styles to minimize interference from the main page's style + rules = ".fbBody *{margin:0;padding:0;font-size:11px;line-height:13px;color:inherit;}" + + // load the chrome styles + css + + // adjust some remaining styles + ".fbBody #fbHSplitter{position:absolute !important;} .fbBody #fbHTML span{line-height:14px;} .fbBody .lineNo div{line-height:inherit !important;}"; + /* + if (isIE) + { + // IE7 CSS bug (FbChrome table bigger than its parent div) + rules += ".fbBody table.fbChrome{position: static !important;}"; + }/**/ + + style.type = "text/css"; + + if (style.styleSheet) + style.styleSheet.cssText = rules; + else + style.appendChild(context.document.createTextNode(rules)); + + document.getElementsByTagName("head")[0].appendChild(style); + + node.className = "fbBody"; + node.style.overflow = "hidden"; + node.innerHTML = getChromeDivTemplate(); + + if (isIE) + { + // IE7 CSS bug (FbChrome table bigger than its parent div) + setTimeout(function(){ + node.firstChild.style.height = "1px"; + node.firstChild.style.position = "static"; + },0); + /**/ + } + + formatNode(node); + + body.appendChild(node); + + chrome.window = window; + chrome.document = document; + onChromeLoad(chrome); + }; + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + try + { + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // create the Chrome as a "div" (windowless mode) + if (type == "div") + { + createChromeDiv(); + return; + } + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // cretate the Chrome as an "iframe" + else if (isChromeFrame) + { + // Create the Chrome Frame + var node = chrome.node = createGlobalElement("iframe"); + node.setAttribute("src", url); + node.setAttribute("frameBorder", "0"); + + formatNode(node); + + body.appendChild(node); + + // must set the id after appending to the document, otherwise will cause an + // strange error in IE, making the iframe load the page in which the bookmarklet + // was created (like getfirebug.com), before loading the injected UI HTML, + // generating an "Access Denied" error. + node.id = options.id; + } + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // create the Chrome as a "popup" + else + { + var height = FirebugChrome.height || options.height, + + options = [ + "true,top=", + Math.max(screen.availHeight - height - 61 /* Google Chrome bug */, 0), + ",left=0,height=", + height, + ",width=", + screen.availWidth-10, // Opera opens popup in a new tab if it's too big! + ",resizable" + ].join(""), + + node = chrome.node = context.window.open( + url, + "popup", + options + ); + + if (node) + { + try + { + node.focus(); + } + catch(E) + { + alert("Firebug Error: Firebug popup was blocked."); + return; + } + } + else + { + alert("Firebug Error: Firebug popup was blocked."); + return; + } + } + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Inject the interface HTML if it is not using the local skin + + if (!useLocalSkin) + { + var tpl = getChromeTemplate(!isChromeFrame), + doc = isChromeFrame ? node.contentWindow.document : node.document; + + doc.write(tpl); + doc.close(); + } + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Wait the Window to be loaded + + var win, + + waitDelay = useLocalSkin ? isChromeFrame ? 200 : 300 : 100, + + waitForWindow = function() + { + if ( // Frame loaded... OR + isChromeFrame && (win=node.contentWindow) && + node.contentWindow.document.getElementById("fbCommandLine") || + + // Popup loaded + !isChromeFrame && (win=node.window) && node.document && + node.document.getElementById("fbCommandLine") ) + { + chrome.window = win.window; + chrome.document = win.document; + + // Prevent getting the wrong chrome height in FF when opening a popup + setTimeout(function(){ + onChromeLoad(chrome); + },0); + } + else + setTimeout(waitForWindow, waitDelay); + }; + + waitForWindow(); + } + catch(e) + { + var msg = e.message || e; + + if (/access/i.test(msg)) + { + // Firebug Lite could not create a window for its Graphical User Interface due to + // a access restriction. This happens in some pages, when loading via bookmarklet. + // In such cases, the only way is to load the GUI in a "windowless mode". + + if (isChromeFrame) + body.removeChild(node); + else if(type == "popup") + node.close(); + + // Load the GUI in a "windowless mode" + createChromeDiv(); + } + else + { + alert("Firebug Error: Firebug GUI could not be created."); + } + } +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var onChromeLoad = function onChromeLoad(chrome) +{ + Env.chrome = chrome; + + if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Chrome onChromeLoad", "chrome window loaded"); + + if (Env.Options.enablePersistent) + { + // TODO: xxxpedro persist - make better chrome synchronization when in persistent mode + Env.FirebugChrome = FirebugChrome; + + chrome.window.Firebug = chrome.window.Firebug || {}; + chrome.window.Firebug.SharedEnv = Env; + + if (Env.isDevelopmentMode) + { + Env.browser.window.FBDev.loadChromeApplication(chrome); + } + else + { + var doc = chrome.document; + var script = doc.createElement("script"); + script.src = Env.Location.app + "#remote,persist"; + doc.getElementsByTagName("head")[0].appendChild(script); + } + } + else + { + if (chrome.type == "frame" || chrome.type == "div") + { + // initialize the chrome application + setTimeout(function(){ + FBL.Firebug.initialize(); + },0); + } + else if (chrome.type == "popup") + { + var oldChrome = FirebugChrome.chromeMap.frame; + + var newChrome = new Chrome(chrome); + + // TODO: xxxpedro sync detach reattach attach + dispatch(newChrome.panelMap, "detach", [oldChrome, newChrome]); + + if (oldChrome) + oldChrome.close(); + + newChrome.reattach(oldChrome, newChrome); + } + } +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var getChromeDivTemplate = function() +{ + return FirebugChrome.Skin.HTML; +}; + +var getChromeTemplate = function(isPopup) +{ + var tpl = FirebugChrome.Skin; + var r = [], i = -1; + + r[++i] = ''; + r[++i] = ''; + r[++i] = Firebug.version; + + /* + r[++i] = ''; + /**/ + + r[++i] = ''; + /**/ + + r[++i] = ''; + r[++i] = tpl.HTML; + r[++i] = ''; + + return r.join(""); +}; + + +// ************************************************************************************************ +// Chrome Class + +/**@class*/ +var Chrome = function Chrome(chrome) +{ + var type = chrome.type; + var Base = type == "frame" || type == "div" ? ChromeFrameBase : ChromePopupBase; + + append(this, Base); // inherit from base class (ChromeFrameBase or ChromePopupBase) + append(this, chrome); // inherit chrome window properties + append(this, new Context(chrome.window)); // inherit from Context class + + FirebugChrome.chromeMap[type] = this; + Firebug.chrome = this; + Env.chrome = chrome.window; + + this.commandLineVisible = false; + this.sidePanelVisible = false; + + this.create(); + + return this; +}; + +// ************************************************************************************************ +// ChromeBase + +/** + * @namespace + * @extends FBL.Controller + * @extends FBL.PanelBar + **/ +var ChromeBase = {}; +append(ChromeBase, Controller); +append(ChromeBase, PanelBar); +append(ChromeBase, +/**@extend ns-chrome-ChromeBase*/ +{ + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // inherited properties + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // inherited from createChrome function + + node: null, + type: null, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // inherited from Context.prototype + + document: null, + window: null, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // value properties + + sidePanelVisible: false, + commandLineVisible: false, + largeCommandLineVisible: false, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // object properties + + inspectButton: null, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + create: function() + { + PanelBar.create.call(this); + + if (Firebug.Inspector) + this.inspectButton = new Button({ + type: "toggle", + element: $("fbChrome_btInspect"), + owner: Firebug.Inspector, + + onPress: Firebug.Inspector.startInspecting, + onUnpress: Firebug.Inspector.stopInspecting + }); + }, + + destroy: function() + { + if(Firebug.Inspector) + this.inspectButton.destroy(); + + PanelBar.destroy.call(this); + + this.shutdown(); + }, + + testMenu: function() + { + var firebugMenu = new Menu( + { + id: "fbFirebugMenu", + + items: + [ + { + label: "Open Firebug", + type: "shortcut", + key: isFirefox ? "Shift+F12" : "F12", + checked: true, + command: "toggleChrome" + }, + { + label: "Open Firebug in New Window", + type: "shortcut", + key: isFirefox ? "Ctrl+Shift+F12" : "Ctrl+F12", + command: "openPopup" + }, + { + label: "Inspect Element", + type: "shortcut", + key: "Ctrl+Shift+C", + command: "toggleInspect" + }, + { + label: "Command Line", + type: "shortcut", + key: "Ctrl+Shift+L", + command: "focusCommandLine" + }, + "-", + { + label: "Options", + type: "group", + child: "fbFirebugOptionsMenu" + }, + "-", + { + label: "Firebug Lite Website...", + command: "visitWebsite" + }, + { + label: "Discussion Group...", + command: "visitDiscussionGroup" + }, + { + label: "Issue Tracker...", + command: "visitIssueTracker" + } + ], + + onHide: function() + { + iconButton.restore(); + }, + + toggleChrome: function() + { + Firebug.chrome.toggle(); + }, + + openPopup: function() + { + Firebug.chrome.toggle(true, true); + }, + + toggleInspect: function() + { + Firebug.Inspector.toggleInspect(); + }, + + focusCommandLine: function() + { + Firebug.chrome.focusCommandLine(); + }, + + visitWebsite: function() + { + this.visit("http://getfirebug.com/lite.html"); + }, + + visitDiscussionGroup: function() + { + this.visit("http://groups.google.com/group/firebug"); + }, + + visitIssueTracker: function() + { + this.visit("http://code.google.com/p/fbug/issues/list"); + }, + + visit: function(url) + { + window.open(url); + } + + }); + + /**@private*/ + var firebugOptionsMenu = + { + id: "fbFirebugOptionsMenu", + + getItems: function() + { + var cookiesDisabled = !Firebug.saveCookies; + + return [ + { + label: "Save Options in Cookies", + type: "checkbox", + value: "saveCookies", + checked: Firebug.saveCookies, + command: "saveOptions" + }, + "-", + { + label: "Start Opened", + type: "checkbox", + value: "startOpened", + checked: Firebug.startOpened, + disabled: cookiesDisabled + }, + { + label: "Start in New Window", + type: "checkbox", + value: "startInNewWindow", + checked: Firebug.startInNewWindow, + disabled: cookiesDisabled + }, + { + label: "Show Icon When Hidden", + type: "checkbox", + value: "showIconWhenHidden", + checked: Firebug.showIconWhenHidden, + disabled: cookiesDisabled + }, + { + label: "Override Console Object", + type: "checkbox", + value: "overrideConsole", + checked: Firebug.overrideConsole, + disabled: cookiesDisabled + }, + { + label: "Ignore Firebug Elements", + type: "checkbox", + value: "ignoreFirebugElements", + checked: Firebug.ignoreFirebugElements, + disabled: cookiesDisabled + }, + { + label: "Disable When Firebug Active", + type: "checkbox", + value: "disableWhenFirebugActive", + checked: Firebug.disableWhenFirebugActive, + disabled: cookiesDisabled + }, + { + label: "Disable XHR Listener", + type: "checkbox", + value: "disableXHRListener", + checked: Firebug.disableXHRListener, + disabled: cookiesDisabled + }, + { + label: "Enable Trace Mode", + type: "checkbox", + value: "enableTrace", + checked: Firebug.enableTrace, + disabled: cookiesDisabled + }, + { + label: "Enable Persistent Mode (experimental)", + type: "checkbox", + value: "enablePersistent", + checked: Firebug.enablePersistent, + disabled: cookiesDisabled + }, + "-", + { + label: "Reset All Firebug Options", + command: "restorePrefs", + disabled: cookiesDisabled + } + ]; + }, + + onCheck: function(target, value, checked) + { + Firebug.setPref(value, checked); + }, + + saveOptions: function(target) + { + var saveEnabled = target.getAttribute("checked"); + + if (!saveEnabled) this.restorePrefs(); + + this.updateMenu(target); + + return false; + }, + + restorePrefs: function(target) + { + Firebug.restorePrefs(); + + if(Firebug.saveCookies) + Firebug.savePrefs(); + else + Firebug.erasePrefs(); + + if (target) + this.updateMenu(target); + + return false; + }, + + updateMenu: function(target) + { + var options = getElementsByClass(target.parentNode, "fbMenuOption"); + + var firstOption = options[0]; + var enabled = Firebug.saveCookies; + if (enabled) + Menu.check(firstOption); + else + Menu.uncheck(firstOption); + + if (enabled) + Menu.check(options[0]); + else + Menu.uncheck(options[0]); + + for (var i = 1, length = options.length; i < length; i++) + { + var option = options[i]; + + var value = option.getAttribute("value"); + var pref = Firebug[value]; + + if (pref) + Menu.check(option); + else + Menu.uncheck(option); + + if (enabled) + Menu.enable(option); + else + Menu.disable(option); + } + } + }; + + Menu.register(firebugOptionsMenu); + + var menu = firebugMenu; + + var testMenuClick = function(event) + { + //console.log("testMenuClick"); + cancelEvent(event, true); + + var target = event.target || event.srcElement; + + if (menu.isVisible) + menu.hide(); + else + { + var offsetLeft = isIE6 ? 1 : -4, // IE6 problem with fixed position + + chrome = Firebug.chrome, + + box = chrome.getElementBox(target), + + offset = chrome.type == "div" ? + chrome.getElementPosition(chrome.node) : + {top: 0, left: 0}; + + menu.show( + box.left + offsetLeft - offset.left, + box.top + box.height -5 - offset.top + ); + } + + return false; + }; + + var iconButton = new IconButton({ + type: "toggle", + element: $("fbFirebugButton"), + + onClick: testMenuClick + }); + + iconButton.initialize(); + + //addEvent($("fbToolbarIcon"), "click", testMenuClick); + }, + + initialize: function() + { + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + if (Env.bookmarkletOutdated) + Firebug.Console.logFormatted([ + "A new bookmarklet version is available. " + + "Please visit http://getfirebug.com/firebuglite#Install and update it." + ], Firebug.context, "warn"); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + if (Firebug.Console) + Firebug.Console.flush(); + + if (Firebug.Trace) + FBTrace.flush(Firebug.Trace); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.chrome.initialize", "initializing chrome application"); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // initialize inherited classes + Controller.initialize.call(this); + PanelBar.initialize.call(this); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // create the interface elements cache + + fbTop = $("fbTop"); + fbContent = $("fbContent"); + fbContentStyle = fbContent.style; + fbBottom = $("fbBottom"); + fbBtnInspect = $("fbBtnInspect"); + + fbToolbar = $("fbToolbar"); + + fbPanelBox1 = $("fbPanelBox1"); + fbPanelBox1Style = fbPanelBox1.style; + fbPanelBox2 = $("fbPanelBox2"); + fbPanelBox2Style = fbPanelBox2.style; + fbPanelBar2Box = $("fbPanelBar2Box"); + fbPanelBar2BoxStyle = fbPanelBar2Box.style; + + fbHSplitter = $("fbHSplitter"); + fbVSplitter = $("fbVSplitter"); + fbVSplitterStyle = fbVSplitter.style; + + fbPanel1 = $("fbPanel1"); + fbPanel1Style = fbPanel1.style; + fbPanel2 = $("fbPanel2"); + fbPanel2Style = fbPanel2.style; + + fbConsole = $("fbConsole"); + fbConsoleStyle = fbConsole.style; + fbHTML = $("fbHTML"); + + fbCommandLine = $("fbCommandLine"); + fbLargeCommandLine = $("fbLargeCommandLine"); + fbLargeCommandButtons = $("fbLargeCommandButtons"); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // static values cache + topHeight = fbTop.offsetHeight; + topPartialHeight = fbToolbar.offsetHeight; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + disableTextSelection($("fbToolbar")); + disableTextSelection($("fbPanelBarBox")); + disableTextSelection($("fbPanelBar1")); + disableTextSelection($("fbPanelBar2")); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Add the "javascript:void(0)" href attributes used to make the hover effect in IE6 + if (isIE6 && Firebug.Selector) + { + // TODO: xxxpedro change to getElementsByClass + var as = $$(".fbHover"); + for (var i=0, a; a=as[i]; i++) + { + a.setAttribute("href", "javascript:void(0)"); + } + } + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // initialize all panels + /* + var panelMap = Firebug.panelTypes; + for (var i=0, p; p=panelMap[i]; i++) + { + if (!p.parentPanel) + { + this.addPanel(p.prototype.name); + } + } + /**/ + + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + + if(Firebug.Inspector) + this.inspectButton.initialize(); + + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + + this.addController( + [$("fbLargeCommandLineIcon"), "click", this.showLargeCommandLine] + ); + + // ************************************************************************************************ + + // Select the first registered panel + // TODO: BUG IE7 + var self = this; + setTimeout(function(){ + self.selectPanel(FirebugChrome.selectedPanelName); + + if (FirebugChrome.selectedPanelName == "Console" && Firebug.CommandLine) + Firebug.chrome.focusCommandLine(); + },0); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + //this.draw(); + + + + + + + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + var onPanelMouseDown = function onPanelMouseDown(event) + { + //console.log("onPanelMouseDown", event.target || event.srcElement, event); + + var target = event.target || event.srcElement; + + if (FBL.isLeftClick(event)) + { + var editable = FBL.getAncestorByClass(target, "editable"); + + // if an editable element has been clicked then start editing + if (editable) + { + Firebug.Editor.startEditing(editable); + FBL.cancelEvent(event); + } + // if any other element has been clicked then stop editing + else + { + if (!hasClass(target, "textEditorInner")) + Firebug.Editor.stopEditing(); + } + } + else if (FBL.isMiddleClick(event) && Firebug.getRepNode(target)) + { + // Prevent auto-scroll when middle-clicking a rep object + FBL.cancelEvent(event); + } + }; + + Firebug.getElementPanel = function(element) + { + var panelNode = getAncestorByClass(element, "fbPanel"); + var id = panelNode.id.substr(2); + + var panel = Firebug.chrome.panelMap[id]; + + if (!panel) + { + if (Firebug.chrome.selectedPanel.sidePanelBar) + panel = Firebug.chrome.selectedPanel.sidePanelBar.panelMap[id]; + } + + return panel; + }; + + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + // TODO: xxxpedro port to Firebug + + // Improved window key code event listener. Only one "keydown" event will be attached + // to the window, and the onKeyCodeListen() function will delegate which listeners + // should be called according to the event.keyCode fired. + var onKeyCodeListenersMap = []; + var onKeyCodeListen = function(event) + { + for (var keyCode in onKeyCodeListenersMap) + { + var listeners = onKeyCodeListenersMap[keyCode]; + + for (var i = 0, listener; listener = listeners[i]; i++) + { + var filter = listener.filter || FBL.noKeyModifiers; + + if (event.keyCode == keyCode && (!filter || filter(event))) + { + listener.listener(); + FBL.cancelEvent(event, true); + return false; + } + } + } + }; + + addEvent(Firebug.chrome.document, "keydown", onKeyCodeListen); + + /** + * @name keyCodeListen + * @memberOf FBL.FirebugChrome + */ + Firebug.chrome.keyCodeListen = function(key, filter, listener, capture) + { + var keyCode = KeyEvent["DOM_VK_"+key]; + + if (!onKeyCodeListenersMap[keyCode]) + onKeyCodeListenersMap[keyCode] = []; + + onKeyCodeListenersMap[keyCode].push({ + filter: filter, + listener: listener + }); + + return keyCode; + }; + + /** + * @name keyIgnore + * @memberOf FBL.FirebugChrome + */ + Firebug.chrome.keyIgnore = function(keyCode) + { + onKeyCodeListenersMap[keyCode] = null; + delete onKeyCodeListenersMap[keyCode]; + }; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + /**/ + // move to shutdown + //removeEvent(Firebug.chrome.document, "keydown", listener[0]); + + + /* + Firebug.chrome.keyCodeListen = function(key, filter, listener, capture) + { + if (!filter) + filter = FBL.noKeyModifiers; + + var keyCode = KeyEvent["DOM_VK_"+key]; + + var fn = function fn(event) + { + if (event.keyCode == keyCode && (!filter || filter(event))) + { + listener(); + FBL.cancelEvent(event, true); + return false; + } + } + + addEvent(Firebug.chrome.document, "keydown", fn); + + return [fn, capture]; + }; + + Firebug.chrome.keyIgnore = function(listener) + { + removeEvent(Firebug.chrome.document, "keydown", listener[0]); + }; + /**/ + + + this.addController( + [fbPanel1, "mousedown", onPanelMouseDown], + [fbPanel2, "mousedown", onPanelMouseDown] + ); +/**/ + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + + // menus can be used without domplate + if (FBL.domplate) + this.testMenu(); + /**/ + + //test XHR + /* + setTimeout(function(){ + + FBL.Ajax.request({url: "../content/firebug/boot.js"}); + FBL.Ajax.request({url: "../content/firebug/boot.js.invalid"}); + + },1000); + /**/ + }, + + shutdown: function() + { + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + + if(Firebug.Inspector) + this.inspectButton.shutdown(); + + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + // remove disableTextSelection event handlers + restoreTextSelection($("fbToolbar")); + restoreTextSelection($("fbPanelBarBox")); + restoreTextSelection($("fbPanelBar1")); + restoreTextSelection($("fbPanelBar2")); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // shutdown inherited classes + Controller.shutdown.call(this); + PanelBar.shutdown.call(this); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Remove the interface elements cache (this must happen after calling + // the shutdown method of all dependent components to avoid errors) + + fbTop = null; + fbContent = null; + fbContentStyle = null; + fbBottom = null; + fbBtnInspect = null; + + fbToolbar = null; + + fbPanelBox1 = null; + fbPanelBox1Style = null; + fbPanelBox2 = null; + fbPanelBox2Style = null; + fbPanelBar2Box = null; + fbPanelBar2BoxStyle = null; + + fbHSplitter = null; + fbVSplitter = null; + fbVSplitterStyle = null; + + fbPanel1 = null; + fbPanel1Style = null; + fbPanel2 = null; + + fbConsole = null; + fbConsoleStyle = null; + fbHTML = null; + + fbCommandLine = null; + fbLargeCommandLine = null; + fbLargeCommandButtons = null; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // static values cache + + topHeight = null; + topPartialHeight = null; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + toggle: function(forceOpen, popup) + { + if(popup) + { + this.detach(); + } + else + { + if (isOpera && Firebug.chrome.type == "popup" && Firebug.chrome.node.closed) + { + var frame = FirebugChrome.chromeMap.frame; + frame.reattach(); + + FirebugChrome.chromeMap.popup = null; + + frame.open(); + + return; + } + + // If the context is a popup, ignores the toggle process + if (Firebug.chrome.type == "popup") return; + + var shouldOpen = forceOpen || !FirebugChrome.isOpen; + + if(shouldOpen) + this.open(); + else + this.close(); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + detach: function() + { + if(!FirebugChrome.chromeMap.popup) + { + createChromeWindow({type: "popup"}); + } + }, + + reattach: function(oldChrome, newChrome) + { + Firebug.browser.window.Firebug = Firebug; + + // chrome synchronization + var newPanelMap = newChrome.panelMap; + var oldPanelMap = oldChrome.panelMap; + + var panel; + for(var name in newPanelMap) + { + // TODO: xxxpedro innerHTML + panel = newPanelMap[name]; + if (panel.options.innerHTMLSync) + panel.panelNode.innerHTML = oldPanelMap[name].panelNode.innerHTML; + } + + Firebug.chrome = newChrome; + + // TODO: xxxpedro sync detach reattach attach + //dispatch(Firebug.chrome.panelMap, "detach", [oldChrome, newChrome]); + + if (newChrome.type == "popup") + { + newChrome.initialize(); + //dispatch(Firebug.modules, "initialize", []); + } + else + { + // TODO: xxxpedro only needed in persistent + // should use FirebugChrome.clone, but popup FBChrome + // isn't acessible + FirebugChrome.selectedPanelName = oldChrome.selectedPanel.name; + } + + dispatch(newPanelMap, "reattach", [oldChrome, newChrome]); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + draw: function() + { + var size = this.getSize(); + + // Height related values + var commandLineHeight = Firebug.chrome.commandLineVisible ? fbCommandLine.offsetHeight : 0, + + y = Math.max(size.height /* chrome height */, topHeight), + + heightValue = Math.max(y - topHeight - commandLineHeight /* fixed height */, 0), + + height = heightValue + "px", + + // Width related values + sideWidthValue = Firebug.chrome.sidePanelVisible ? FirebugChrome.sidePanelWidth : 0, + + width = Math.max(size.width /* chrome width */ - sideWidthValue, 0) + "px"; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Height related rendering + fbPanelBox1Style.height = height; + fbPanel1Style.height = height; + + if (isIE || isOpera) + { + // Fix IE and Opera problems with auto resizing the verticall splitter + fbVSplitterStyle.height = Math.max(y - topPartialHeight - commandLineHeight, 0) + "px"; + } + //xxxpedro FF2 only? + /* + else if (isFirefox) + { + // Fix Firefox problem with table rows with 100% height (fit height) + fbContentStyle.maxHeight = Math.max(y - fixedHeight, 0)+ "px"; + }/**/ + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Width related rendering + fbPanelBox1Style.width = width; + fbPanel1Style.width = width; + + // SidePanel rendering + if (Firebug.chrome.sidePanelVisible) + { + sideWidthValue = Math.max(sideWidthValue - 6, 0); + + var sideWidth = sideWidthValue + "px"; + + fbPanelBox2Style.width = sideWidth; + + fbVSplitterStyle.right = sideWidth; + + if (Firebug.chrome.largeCommandLineVisible) + { + fbLargeCommandLine = $("fbLargeCommandLine"); + + fbLargeCommandLine.style.height = heightValue - 4 + "px"; + fbLargeCommandLine.style.width = sideWidthValue - 2 + "px"; + + fbLargeCommandButtons = $("fbLargeCommandButtons"); + fbLargeCommandButtons.style.width = sideWidth; + } + else + { + fbPanel2Style.height = height; + fbPanel2Style.width = sideWidth; + + fbPanelBar2BoxStyle.width = sideWidth; + } + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getSize: function() + { + return this.type == "div" ? + { + height: this.node.offsetHeight, + width: this.node.offsetWidth + } + : + this.getWindowSize(); + }, + + resize: function() + { + var self = this; + + // avoid partial resize when maximizing window + setTimeout(function(){ + self.draw(); + + if (noFixedPosition && (self.type == "frame" || self.type == "div")) + self.fixIEPosition(); + }, 0); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + layout: function(panel) + { + if (FBTrace.DBG_CHROME) FBTrace.sysout("Chrome.layout", ""); + + var options = panel.options; + + changeCommandLineVisibility(options.hasCommandLine); + changeSidePanelVisibility(panel.hasSidePanel); + + Firebug.chrome.draw(); + }, + + showLargeCommandLine: function(hideToggleIcon) + { + var chrome = Firebug.chrome; + + if (!chrome.largeCommandLineVisible) + { + chrome.largeCommandLineVisible = true; + + if (chrome.selectedPanel.options.hasCommandLine) + { + if (Firebug.CommandLine) + Firebug.CommandLine.blur(); + + changeCommandLineVisibility(false); + } + + changeSidePanelVisibility(true); + + fbLargeCommandLine.style.display = "block"; + fbLargeCommandButtons.style.display = "block"; + + fbPanel2Style.display = "none"; + fbPanelBar2BoxStyle.display = "none"; + + chrome.draw(); + + fbLargeCommandLine.focus(); + + if (Firebug.CommandLine) + Firebug.CommandLine.setMultiLine(true); + } + }, + + hideLargeCommandLine: function() + { + if (Firebug.chrome.largeCommandLineVisible) + { + Firebug.chrome.largeCommandLineVisible = false; + + if (Firebug.CommandLine) + Firebug.CommandLine.setMultiLine(false); + + fbLargeCommandLine.blur(); + + fbPanel2Style.display = "block"; + fbPanelBar2BoxStyle.display = "block"; + + fbLargeCommandLine.style.display = "none"; + fbLargeCommandButtons.style.display = "none"; + + changeSidePanelVisibility(false); + + if (Firebug.chrome.selectedPanel.options.hasCommandLine) + changeCommandLineVisibility(true); + + Firebug.chrome.draw(); + + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + focusCommandLine: function() + { + var selectedPanelName = this.selectedPanel.name, panelToSelect; + + if (focusCommandLineState == 0 || selectedPanelName != "Console") + { + focusCommandLineState = 0; + lastFocusedPanelName = selectedPanelName; + + panelToSelect = "Console"; + } + if (focusCommandLineState == 1) + { + panelToSelect = lastFocusedPanelName; + } + + this.selectPanel(panelToSelect); + + try + { + if (Firebug.CommandLine) + { + if (panelToSelect == "Console") + Firebug.CommandLine.focus(); + else + Firebug.CommandLine.blur(); + } + } + catch(e) + { + //TODO: xxxpedro trace error + } + + focusCommandLineState = ++focusCommandLineState % 2; + } + +}); + +// ************************************************************************************************ +// ChromeFrameBase + +/** + * @namespace + * @extends ns-chrome-ChromeBase + */ +var ChromeFrameBase = extend(ChromeBase, +/**@extend ns-chrome-ChromeFrameBase*/ +{ + create: function() + { + ChromeBase.create.call(this); + + // restore display for the anti-flicker trick + if (isFirefox) + this.node.style.display = "block"; + + if (Env.Options.startInNewWindow) + { + this.close(); + this.toggle(true, true); + return; + } + + if (Env.Options.startOpened) + this.open(); + else + this.close(); + }, + + destroy: function() + { + removeGlobalEvent("keydown", onGlobalKeyDown); + + ChromeBase.destroy.call(this); + + this.document = null; + delete this.document; + + this.window = null; + delete this.window; + + this.node.parentNode.removeChild(this.node); + this.node = null; + delete this.node; + }, + + initialize: function() + { + //FBTrace.sysout("Frame", "initialize();") + ChromeBase.initialize.call(this); + + this.addController( + [Firebug.browser.window, "resize", this.resize], + [$("fbWindow_btClose"), "click", this.close], + [$("fbWindow_btDetach"), "click", this.detach], + [$("fbWindow_btDeactivate"), "click", this.deactivate] + ); + + if (!Env.Options.enablePersistent) + this.addController([Firebug.browser.window, "unload", Firebug.shutdown]); + + if (noFixedPosition) + { + this.addController( + [Firebug.browser.window, "scroll", this.fixIEPosition] + ); + } + + fbVSplitter.onmousedown = onVSplitterMouseDown; + fbHSplitter.onmousedown = onHSplitterMouseDown; + + this.isInitialized = true; + }, + + shutdown: function() + { + fbVSplitter.onmousedown = null; + fbHSplitter.onmousedown = null; + + ChromeBase.shutdown.apply(this); + + this.isInitialized = false; + }, + + reattach: function() + { + var frame = FirebugChrome.chromeMap.frame; + + ChromeBase.reattach(FirebugChrome.chromeMap.popup, this); + }, + + open: function() + { + if (!FirebugChrome.isOpen) + { + FirebugChrome.isOpen = true; + + if (Env.isChromeExtension) + localStorage.setItem("Firebug", "1,1"); + + var node = this.node; + + node.style.visibility = "hidden"; // Avoid flickering + + if (Firebug.showIconWhenHidden) + { + if (ChromeMini.isInitialized) + { + ChromeMini.shutdown(); + } + + } + else + node.style.display = "block"; + + var main = $("fbChrome"); + + // IE6 throws an error when setting this property! why? + //main.style.display = "table"; + main.style.display = ""; + + var self = this; + setTimeout(function(){ + node.style.visibility = "visible"; + + //dispatch(Firebug.modules, "initialize", []); + self.initialize(); + + if (noFixedPosition) + self.fixIEPosition(); + + self.draw(); + + }, 10); + } + }, + + close: function() + { + if (FirebugChrome.isOpen || !this.isInitialized) + { + if (this.isInitialized) + { + //dispatch(Firebug.modules, "shutdown", []); + this.shutdown(); + } + + FirebugChrome.isOpen = false; + + if (Env.isChromeExtension) + localStorage.setItem("Firebug", "1,0"); + + var node = this.node; + + if (Firebug.showIconWhenHidden) + { + node.style.visibility = "hidden"; // Avoid flickering + + // TODO: xxxpedro - persist IE fixed? + var main = $("fbChrome", FirebugChrome.chromeMap.frame.document); + main.style.display = "none"; + + ChromeMini.initialize(); + + node.style.visibility = "visible"; + } + else + node.style.display = "none"; + } + }, + + deactivate: function() + { + // if it is running as a Chrome extension, dispatch a message to the extension signaling + // that Firebug should be deactivated for the current tab + if (Env.isChromeExtension) + { + localStorage.removeItem("Firebug"); + Firebug.GoogleChrome.dispatch("FB_deactivate"); + + // xxxpedro problem here regarding Chrome extension. We can't deactivate the whole + // app, otherwise it won't be able to be reactivated without reloading the page. + // but we need to stop listening global keys, otherwise the key activation won't work. + Firebug.chrome.close(); + } + else + { + Firebug.shutdown(); + } + }, + + fixIEPosition: function() + { + // fix IE problem with offset when not in fullscreen mode + var doc = this.document; + var offset = isIE ? doc.body.clientTop || doc.documentElement.clientTop: 0; + + var size = Firebug.browser.getWindowSize(); + var scroll = Firebug.browser.getWindowScrollPosition(); + var maxHeight = size.height; + var height = this.node.offsetHeight; + + var bodyStyle = doc.body.currentStyle; + + this.node.style.top = maxHeight - height + scroll.top + "px"; + + if ((this.type == "frame" || this.type == "div") && + (bodyStyle.marginLeft || bodyStyle.marginRight)) + { + this.node.style.width = size.width + "px"; + } + + if (fbVSplitterStyle) + fbVSplitterStyle.right = FirebugChrome.sidePanelWidth + "px"; + + this.draw(); + } + +}); + + +// ************************************************************************************************ +// ChromeMini + +/** + * @namespace + * @extends FBL.Controller + */ +var ChromeMini = extend(Controller, +/**@extend ns-chrome-ChromeMini*/ +{ + create: function(chrome) + { + append(this, chrome); + this.type = "mini"; + }, + + initialize: function() + { + Controller.initialize.apply(this); + + var doc = FirebugChrome.chromeMap.frame.document; + + var mini = $("fbMiniChrome", doc); + mini.style.display = "block"; + + var miniIcon = $("fbMiniIcon", doc); + var width = miniIcon.offsetWidth + 10; + miniIcon.title = "Open " + Firebug.version; + + var errors = $("fbMiniErrors", doc); + if (errors.offsetWidth) + width += errors.offsetWidth + 10; + + var node = this.node; + node.style.height = "27px"; + node.style.width = width + "px"; + node.style.left = ""; + node.style.right = 0; + + if (this.node.nodeName.toLowerCase() == "iframe") + { + node.setAttribute("allowTransparency", "true"); + this.document.body.style.backgroundColor = "transparent"; + } + else + node.style.background = "transparent"; + + if (noFixedPosition) + this.fixIEPosition(); + + this.addController( + [$("fbMiniIcon", doc), "click", onMiniIconClick] + ); + + if (noFixedPosition) + { + this.addController( + [Firebug.browser.window, "scroll", this.fixIEPosition] + ); + } + + this.isInitialized = true; + }, + + shutdown: function() + { + var node = this.node; + node.style.height = FirebugChrome.height + "px"; + node.style.width = "100%"; + node.style.left = 0; + node.style.right = ""; + + if (this.node.nodeName.toLowerCase() == "iframe") + { + node.setAttribute("allowTransparency", "false"); + this.document.body.style.backgroundColor = "#fff"; + } + else + node.style.background = "#fff"; + + if (noFixedPosition) + this.fixIEPosition(); + + var doc = FirebugChrome.chromeMap.frame.document; + + var mini = $("fbMiniChrome", doc); + mini.style.display = "none"; + + Controller.shutdown.apply(this); + + this.isInitialized = false; + }, + + draw: function() + { + + }, + + fixIEPosition: ChromeFrameBase.fixIEPosition + +}); + + +// ************************************************************************************************ +// ChromePopupBase + +/** + * @namespace + * @extends ns-chrome-ChromeBase + */ +var ChromePopupBase = extend(ChromeBase, +/**@extend ns-chrome-ChromePopupBase*/ +{ + + initialize: function() + { + setClass(this.document.body, "FirebugPopup"); + + ChromeBase.initialize.call(this); + + this.addController( + [Firebug.chrome.window, "resize", this.resize], + [Firebug.chrome.window, "unload", this.destroy] + ); + + if (Env.Options.enablePersistent) + { + this.persist = bind(this.persist, this); + addEvent(Firebug.browser.window, "unload", this.persist); + } + else + this.addController( + [Firebug.browser.window, "unload", this.close] + ); + + fbVSplitter.onmousedown = onVSplitterMouseDown; + }, + + destroy: function() + { + // TODO: xxxpedro sync detach reattach attach + var frame = FirebugChrome.chromeMap.frame; + + if(frame) + { + dispatch(frame.panelMap, "detach", [this, frame]); + + frame.reattach(this, frame); + } + + if (Env.Options.enablePersistent) + { + removeEvent(Firebug.browser.window, "unload", this.persist); + } + + ChromeBase.destroy.apply(this); + + FirebugChrome.chromeMap.popup = null; + + this.node.close(); + }, + + persist: function() + { + persistTimeStart = new Date().getTime(); + + removeEvent(Firebug.browser.window, "unload", this.persist); + + Firebug.Inspector.destroy(); + Firebug.browser.window.FirebugOldBrowser = true; + + var persistTimeStart = new Date().getTime(); + + var waitMainWindow = function() + { + var doc, head; + + try + { + if (window.opener && !window.opener.FirebugOldBrowser && (doc = window.opener.document)/* && + doc.documentElement && (head = doc.documentElement.firstChild)*/) + { + + try + { + // exposes the FBL to the global namespace when in debug mode + if (Env.isDebugMode) + { + window.FBL = FBL; + } + + window.Firebug = Firebug; + window.opener.Firebug = Firebug; + + Env.browser = window.opener; + Firebug.browser = Firebug.context = new Context(Env.browser); + + registerConsole(); + + // the delay time should be calculated right after registering the + // console, once right after the console registration, call log messages + // will be properly handled + var persistDelay = new Date().getTime() - persistTimeStart; + + var chrome = Firebug.chrome; + addEvent(Firebug.browser.window, "unload", chrome.persist); + + FBL.cacheDocument(); + Firebug.Inspector.create(); + + var htmlPanel = chrome.getPanel("HTML"); + htmlPanel.createUI(); + + Firebug.Console.logFormatted( + ["Firebug could not capture console calls during " + + persistDelay + "ms"], + Firebug.context, + "info" + ); + } + catch(pE) + { + alert("persist error: " + (pE.message || pE)); + } + + } + else + { + window.setTimeout(waitMainWindow, 0); + } + + } catch (E) { + window.close(); + } + }; + + waitMainWindow(); + }, + + close: function() + { + this.destroy(); + } + +}); + + +//************************************************************************************************ +// UI helpers + +var changeCommandLineVisibility = function changeCommandLineVisibility(visibility) +{ + var last = Firebug.chrome.commandLineVisible; + var visible = Firebug.chrome.commandLineVisible = + typeof visibility == "boolean" ? visibility : !Firebug.chrome.commandLineVisible; + + if (visible != last) + { + if (visible) + { + fbBottom.className = ""; + + if (Firebug.CommandLine) + Firebug.CommandLine.activate(); + } + else + { + if (Firebug.CommandLine) + Firebug.CommandLine.deactivate(); + + fbBottom.className = "hide"; + } + } +}; + +var changeSidePanelVisibility = function changeSidePanelVisibility(visibility) +{ + var last = Firebug.chrome.sidePanelVisible; + Firebug.chrome.sidePanelVisible = + typeof visibility == "boolean" ? visibility : !Firebug.chrome.sidePanelVisible; + + if (Firebug.chrome.sidePanelVisible != last) + { + fbPanelBox2.className = Firebug.chrome.sidePanelVisible ? "" : "hide"; + fbPanelBar2Box.className = Firebug.chrome.sidePanelVisible ? "" : "hide"; + } +}; + + +// ************************************************************************************************ +// F12 Handler + +var onGlobalKeyDown = function onGlobalKeyDown(event) +{ + var keyCode = event.keyCode; + var shiftKey = event.shiftKey; + var ctrlKey = event.ctrlKey; + + if (keyCode == 123 /* F12 */ && (!isFirefox && !shiftKey || shiftKey && isFirefox)) + { + Firebug.chrome.toggle(false, ctrlKey); + cancelEvent(event, true); + + // TODO: xxxpedro replace with a better solution. we're doing this + // to allow reactivating with the F12 key after being deactivated + if (Env.isChromeExtension) + { + Firebug.GoogleChrome.dispatch("FB_enableIcon"); + } + } + else if (keyCode == 67 /* C */ && ctrlKey && shiftKey) + { + Firebug.Inspector.toggleInspect(); + cancelEvent(event, true); + } + else if (keyCode == 76 /* L */ && ctrlKey && shiftKey) + { + Firebug.chrome.focusCommandLine(); + cancelEvent(event, true); + } +}; + +var onMiniIconClick = function onMiniIconClick(event) +{ + Firebug.chrome.toggle(false, event.ctrlKey); + cancelEvent(event, true); +}; + + +// ************************************************************************************************ +// Horizontal Splitter Handling + +var onHSplitterMouseDown = function onHSplitterMouseDown(event) +{ + addGlobalEvent("mousemove", onHSplitterMouseMove); + addGlobalEvent("mouseup", onHSplitterMouseUp); + + if (isIE) + addEvent(Firebug.browser.document.documentElement, "mouseleave", onHSplitterMouseUp); + + fbHSplitter.className = "fbOnMovingHSplitter"; + + return false; +}; + +var onHSplitterMouseMove = function onHSplitterMouseMove(event) +{ + cancelEvent(event, true); + + var clientY = event.clientY; + var win = isIE + ? event.srcElement.ownerDocument.parentWindow + : event.target.ownerDocument && event.target.ownerDocument.defaultView; + + if (!win) + return; + + if (win != win.parent) + { + var frameElement = win.frameElement; + if (frameElement) + { + var framePos = Firebug.browser.getElementPosition(frameElement).top; + clientY += framePos; + + if (frameElement.style.position != "fixed") + clientY -= Firebug.browser.getWindowScrollPosition().top; + } + } + + if (isOpera && isQuiksMode && win.frameElement.id == "FirebugUI") + { + clientY = Firebug.browser.getWindowSize().height - win.frameElement.offsetHeight + clientY; + } + /* + console.log( + typeof win.FBL != "undefined" ? "no-Chrome" : "Chrome", + //win.frameElement.id, + event.target, + clientY + );/**/ + + onHSplitterMouseMoveBuffer = clientY; // buffer + + if (new Date().getTime() - lastHSplitterMouseMove > chromeRedrawSkipRate) // frame skipping + { + lastHSplitterMouseMove = new Date().getTime(); + handleHSplitterMouseMove(); + } + else + if (!onHSplitterMouseMoveTimer) + onHSplitterMouseMoveTimer = setTimeout(handleHSplitterMouseMove, chromeRedrawSkipRate); + + // improving the resizing performance by canceling the mouse event. + // canceling events will prevent the page to receive such events, which would imply + // in more processing being expended. + cancelEvent(event, true); + return false; +}; + +var handleHSplitterMouseMove = function() +{ + if (onHSplitterMouseMoveTimer) + { + clearTimeout(onHSplitterMouseMoveTimer); + onHSplitterMouseMoveTimer = null; + } + + var clientY = onHSplitterMouseMoveBuffer; + + var windowSize = Firebug.browser.getWindowSize(); + var scrollSize = Firebug.browser.getWindowScrollSize(); + + // compute chrome fixed size (top bar and command line) + var commandLineHeight = Firebug.chrome.commandLineVisible ? fbCommandLine.offsetHeight : 0; + var fixedHeight = topHeight + commandLineHeight; + var chromeNode = Firebug.chrome.node; + + var scrollbarSize = !isIE && (scrollSize.width > windowSize.width) ? 17 : 0; + + //var height = !isOpera ? chromeNode.offsetTop + chromeNode.clientHeight : windowSize.height; + var height = windowSize.height; + + // compute the min and max size of the chrome + var chromeHeight = Math.max(height - clientY + 5 - scrollbarSize, fixedHeight); + chromeHeight = Math.min(chromeHeight, windowSize.height - scrollbarSize); + + FirebugChrome.height = chromeHeight; + chromeNode.style.height = chromeHeight + "px"; + + if (noFixedPosition) + Firebug.chrome.fixIEPosition(); + + Firebug.chrome.draw(); +}; + +var onHSplitterMouseUp = function onHSplitterMouseUp(event) +{ + removeGlobalEvent("mousemove", onHSplitterMouseMove); + removeGlobalEvent("mouseup", onHSplitterMouseUp); + + if (isIE) + removeEvent(Firebug.browser.document.documentElement, "mouseleave", onHSplitterMouseUp); + + fbHSplitter.className = ""; + + Firebug.chrome.draw(); + + // avoid text selection in IE when returning to the document + // after the mouse leaves the document during the resizing + return false; +}; + + +// ************************************************************************************************ +// Vertical Splitter Handling + +var onVSplitterMouseDown = function onVSplitterMouseDown(event) +{ + addGlobalEvent("mousemove", onVSplitterMouseMove); + addGlobalEvent("mouseup", onVSplitterMouseUp); + + return false; +}; + +var onVSplitterMouseMove = function onVSplitterMouseMove(event) +{ + if (new Date().getTime() - lastVSplitterMouseMove > chromeRedrawSkipRate) // frame skipping + { + var target = event.target || event.srcElement; + if (target && target.ownerDocument) // avoid error when cursor reaches out of the chrome + { + var clientX = event.clientX; + var win = document.all + ? event.srcElement.ownerDocument.parentWindow + : event.target.ownerDocument.defaultView; + + if (win != win.parent) + clientX += win.frameElement ? win.frameElement.offsetLeft : 0; + + var size = Firebug.chrome.getSize(); + var x = Math.max(size.width - clientX + 3, 6); + + FirebugChrome.sidePanelWidth = x; + Firebug.chrome.draw(); + } + + lastVSplitterMouseMove = new Date().getTime(); + } + + cancelEvent(event, true); + return false; +}; + +var onVSplitterMouseUp = function onVSplitterMouseUp(event) +{ + removeGlobalEvent("mousemove", onVSplitterMouseMove); + removeGlobalEvent("mouseup", onVSplitterMouseUp); + + Firebug.chrome.draw(); +}; + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +Firebug.Lite = +{ +}; + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + + +Firebug.Lite.Browser = function(window) +{ + this.contentWindow = window; + this.contentDocument = window.document; + this.currentURI = + { + spec: window.location.href + }; +}; + +Firebug.Lite.Browser.prototype = +{ + toString: function() + { + return "Firebug.Lite.Browser"; + } +}; + + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +Firebug.Lite.Cache = +{ + ID: "firebug" + new Date().getTime() +}; + +// ************************************************************************************************ + +/** + * TODO: if a cached element is cloned, the expando property will be cloned too in IE + * which will result in a bug. Firebug Lite will think the new cloned node is the old + * one. + * + * TODO: Investigate a possibility of cache validation, to be customized by each + * kind of cache. For ElementCache it should validate if the element still is + * inserted at the DOM. + */ +var cacheUID = 0; +var createCache = function() +{ + var map = {}; + var 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 = element[CID]; + + if (!id) + { + id = ++cacheUID; + element[CID] = id; + } + + if (!map.hasOwnProperty(id)) + { + map[id] = element; + } + + return id; + }, + + unset: function(element) + { + var id = element[CID]; + + if (supportsDeleteExpando) + { + delete element[CID]; + } + else if (element.removeAttribute) + { + element.removeAttribute(CID); + } + + delete map[id]; + + }, + + key: function(element) + { + return element[CID]; + }, + + has: function(element) + { + return map.hasOwnProperty(element[CID]); + }, + + clear: function() + { + for (var id in map) + { + var element = map[id]; + cacheAPI.unset(element); + } + } + }; + + 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(); + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + + +Firebug.Lite.Proxy = +{ + // jsonp callbacks + _callbacks: {}, + + /** + * Load a resource, either locally (directly) or externally (via proxy) using + * synchronous XHR calls. Loading external resources requires the proxy plugin to + * be installed and configured (see /plugin/proxy/proxy.php). + */ + load: function(url) + { + var resourceDomain = getDomain(url); + var isLocalResource = + // empty domain means local URL + !resourceDomain || + // same domain means local too + resourceDomain == Firebug.context.window.location.host; // TODO: xxxpedro context + + return isLocalResource ? fetchResource(url) : fetchProxyResource(url); + }, + + /** + * Load a resource using JSONP technique. + */ + loadJSONP: function(url, callback) + { + var script = createGlobalElement("script"), + doc = Firebug.context.document, + + uid = "" + new Date().getTime(), + callbackName = "callback=Firebug.Lite.Proxy._callbacks." + uid, + + jsonpURL = url.indexOf("?") != -1 ? + url + "&" + callbackName : + url + "?" + callbackName; + + Firebug.Lite.Proxy._callbacks[uid] = function(data) + { + if (callback) + callback(data); + + script.parentNode.removeChild(script); + delete Firebug.Lite.Proxy._callbacks[uid]; + }; + + script.src = jsonpURL; + + if (doc.documentElement) + doc.documentElement.appendChild(script); + }, + + /** + * Load a resource using YQL (not reliable). + */ + YQL: function(url, callback) + { + var yql = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22" + + encodeURIComponent(url) + "%22&format=xml"; + + this.loadJSONP(yql, function(data) + { + var source = data.results[0]; + + // clean up YQL bogus elements + var match = /\s+

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

                  "; + + // Safari can't handle uppercase or unicode characters when + // in quirks mode. + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function(query, context, extra, seed){ + context = context || document; + + // Only use querySelectorAll on non-XML documents + // (ID selectors don't work in non-HTML documents) + if ( !seed && context.nodeType === 9 && !isXML(context) ) { + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(e){} + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; + } + + div = null; // release memory in IE +})(); + +if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){ + var div = document.createElement("div"); + div.innerHTML = "
                  "; + + // Opera can't find a second classname (in 9.6) + if ( div.getElementsByClassName("e").length === 0 ) + return; + + // Safari caches class attributes, doesn't catch changes (in 3.2) + div.lastChild.className = "e"; + + if ( div.getElementsByClassName("e").length === 1 ) + return; + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS = function(match, context, isXML) { + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { + return context.getElementsByClassName(match[1]); + } + }; + + div = null; // release memory in IE +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + var sibDir = dir == "previousSibling" && !isXML; + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + if ( elem ) { + if ( sibDir && elem.nodeType === 1 ){ + elem.sizcache = doneName; + elem.sizset = i; + } + elem = elem[dir]; + var match = false; + + while ( elem ) { + if ( elem.sizcache === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem.sizcache = doneName; + elem.sizset = i; + } + + if ( elem.nodeName === cur ) { + match = elem; + break; + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + var sibDir = dir == "previousSibling" && !isXML; + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + if ( elem ) { + if ( sibDir && elem.nodeType === 1 ) { + elem.sizcache = doneName; + elem.sizset = i; + } + elem = elem[dir]; + var match = false; + + while ( elem ) { + if ( elem.sizcache === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem.sizcache = doneName; + elem.sizset = i; + } + if ( typeof cur !== "string" ) { + if ( elem === cur ) { + match = true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match = elem; + break; + } + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +var contains = document.compareDocumentPosition ? function(a, b){ + return a.compareDocumentPosition(b) & 16; +} : function(a, b){ + return a !== b && (a.contains ? a.contains(b) : true); +}; + +var isXML = function(elem){ + return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" || + !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML"; +}; + +var posProcess = function(selector, context){ + var tmpSet = [], later = "", match, + root = context.nodeType ? [context] : context; + + // Position selectors must be done after the filter + // And so must :not(positional) so we move all PSEUDOs to the end + while ( (match = Expr.match.PSEUDO.exec( selector )) ) { + later += match[0]; + selector = selector.replace( Expr.match.PSEUDO, "" ); + } + + selector = Expr.relative[selector] ? selector + "*" : selector; + + for ( var i = 0, l = root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE + +Firebug.Selector = Sizzle; + +/**#@-*/ + +// ************************************************************************************************ +}}); + +// Problems in IE +// FIXED - eval return +// FIXED - addEventListener problem in IE +// FIXED doc.createRange? +// +// class reserved word +// test all honza examples in IE6 and IE7 + + +/* See license.txt for terms of usage */ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +function DomplateTag(tagName) +{ + this.tagName = tagName; +} + +function DomplateEmbed() +{ +} + +function DomplateLoop() +{ +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +( /** @scope ns-domplate */ function() { + +var womb = null; + +var domplate = FBL.domplate = function() +{ + var lastSubject; + for (var i = 0; i < arguments.length; ++i) + lastSubject = lastSubject ? copyObject(lastSubject, arguments[i]) : arguments[i]; + + for (var name in lastSubject) + { + var val = lastSubject[name]; + if (isTag(val)) + val.tag.subject = lastSubject; + } + + return lastSubject; +}; + +domplate.context = function(context, fn) +{ + var lastContext = domplate.lastContext; + domplate.topContext = context; + fn.apply(context); + domplate.topContext = lastContext; +}; + +FBL.TAG = function() +{ + var embed = new DomplateEmbed(); + return embed.merge(arguments); +}; + +FBL.FOR = function() +{ + var loop = new DomplateLoop(); + return loop.merge(arguments); +}; + +DomplateTag.prototype = +{ + merge: function(args, oldTag) + { + if (oldTag) + this.tagName = oldTag.tagName; + + this.context = oldTag ? oldTag.context : null; + this.subject = oldTag ? oldTag.subject : null; + this.attrs = oldTag ? copyObject(oldTag.attrs) : {}; + this.classes = oldTag ? copyObject(oldTag.classes) : {}; + this.props = oldTag ? copyObject(oldTag.props) : null; + this.listeners = oldTag ? copyArray(oldTag.listeners) : null; + this.children = oldTag ? copyArray(oldTag.children) : []; + this.vars = oldTag ? copyArray(oldTag.vars) : []; + + var attrs = args.length ? args[0] : null; + var hasAttrs = typeof(attrs) == "object" && !isTag(attrs); + + this.children = []; + + if (domplate.topContext) + this.context = domplate.topContext; + + if (args.length) + parseChildren(args, hasAttrs ? 1 : 0, this.vars, this.children); + + if (hasAttrs) + this.parseAttrs(attrs); + + return creator(this, DomplateTag); + }, + + parseAttrs: function(args) + { + for (var name in args) + { + var val = parseValue(args[name]); + readPartNames(val, this.vars); + + if (name.indexOf("on") == 0) + { + var eventName = name.substr(2); + if (!this.listeners) + this.listeners = []; + this.listeners.push(eventName, val); + } + else if (name.indexOf("_") == 0) + { + var propName = name.substr(1); + if (!this.props) + this.props = {}; + this.props[propName] = val; + } + else if (name.indexOf("$") == 0) + { + var className = name.substr(1); + if (!this.classes) + this.classes = {}; + this.classes[className] = val; + } + else + { + if (name == "class" && this.attrs.hasOwnProperty(name) ) + this.attrs[name] += " " + val; + else + this.attrs[name] = val; + } + } + }, + + compile: function() + { + if (this.renderMarkup) + return; + + this.compileMarkup(); + this.compileDOM(); + + //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate renderMarkup: ", this.renderMarkup); + //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate renderDOM:", this.renderDOM); + //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate domArgs:", this.domArgs); + }, + + compileMarkup: function() + { + this.markupArgs = []; + var topBlock = [], topOuts = [], blocks = [], info = {args: this.markupArgs, argIndex: 0}; + + this.generateMarkup(topBlock, topOuts, blocks, info); + this.addCode(topBlock, topOuts, blocks); + + var fnBlock = ['r=(function (__code__, __context__, __in__, __out__']; + for (var i = 0; i < info.argIndex; ++i) + fnBlock.push(', s', i); + fnBlock.push(') {'); + + if (this.subject) + fnBlock.push('with (this) {'); + if (this.context) + fnBlock.push('with (__context__) {'); + fnBlock.push('with (__in__) {'); + + fnBlock.push.apply(fnBlock, blocks); + + if (this.subject) + fnBlock.push('}'); + if (this.context) + fnBlock.push('}'); + + fnBlock.push('}})'); + + function __link__(tag, code, outputs, args) + { + if (!tag || !tag.tag) + return; + + tag.tag.compile(); + + var tagOutputs = []; + var markupArgs = [code, tag.tag.context, args, tagOutputs]; + markupArgs.push.apply(markupArgs, tag.tag.markupArgs); + tag.tag.renderMarkup.apply(tag.tag.subject, markupArgs); + + outputs.push(tag); + outputs.push(tagOutputs); + } + + function __escape__(value) + { + function replaceChars(ch) + { + switch (ch) + { + case "<": + return "<"; + case ">": + return ">"; + case "&": + return "&"; + case "'": + return "'"; + case '"': + return """; + } + return "?"; + }; + return String(value).replace(/[<>&"']/g, replaceChars); + } + + function __loop__(iter, outputs, fn) + { + var iterOuts = []; + outputs.push(iterOuts); + + if (iter instanceof Array) + iter = new ArrayIterator(iter); + + try + { + while (1) + { + var value = iter.next(); + var itemOuts = [0,0]; + iterOuts.push(itemOuts); + fn.apply(this, [value, itemOuts]); + } + } + catch (exc) + { + if (exc != StopIteration) + throw exc; + } + } + + var js = fnBlock.join(""); + var r = null; + eval(js); + this.renderMarkup = r; + }, + + getVarNames: function(args) + { + if (this.vars) + args.push.apply(args, this.vars); + + for (var i = 0; i < this.children.length; ++i) + { + var child = this.children[i]; + if (isTag(child)) + child.tag.getVarNames(args); + else if (child instanceof Parts) + { + for (var i = 0; i < child.parts.length; ++i) + { + if (child.parts[i] instanceof Variable) + { + var name = child.parts[i].name; + var names = name.split("."); + args.push(names[0]); + } + } + } + } + }, + + generateMarkup: function(topBlock, topOuts, blocks, info) + { + topBlock.push(',"<', this.tagName, '"'); + + for (var name in this.attrs) + { + if (name != "class") + { + var val = this.attrs[name]; + topBlock.push(', " ', name, '=\\""'); + addParts(val, ',', topBlock, info, true); + topBlock.push(', "\\""'); + } + } + + if (this.listeners) + { + for (var i = 0; i < this.listeners.length; i += 2) + readPartNames(this.listeners[i+1], topOuts); + } + + if (this.props) + { + for (var name in this.props) + readPartNames(this.props[name], topOuts); + } + + if ( this.attrs.hasOwnProperty("class") || this.classes) + { + topBlock.push(', " class=\\""'); + if (this.attrs.hasOwnProperty("class")) + addParts(this.attrs["class"], ',', topBlock, info, true); + topBlock.push(', " "'); + for (var name in this.classes) + { + topBlock.push(', ('); + addParts(this.classes[name], '', topBlock, info); + topBlock.push(' ? "', name, '" + " " : "")'); + } + topBlock.push(', "\\""'); + } + topBlock.push(',">"'); + + this.generateChildMarkup(topBlock, topOuts, blocks, info); + topBlock.push(',""'); + }, + + generateChildMarkup: function(topBlock, topOuts, blocks, info) + { + for (var i = 0; i < this.children.length; ++i) + { + var child = this.children[i]; + if (isTag(child)) + child.tag.generateMarkup(topBlock, topOuts, blocks, info); + else + addParts(child, ',', topBlock, info, true); + } + }, + + addCode: function(topBlock, topOuts, blocks) + { + if (topBlock.length) + blocks.push('__code__.push(""', topBlock.join(""), ');'); + if (topOuts.length) + blocks.push('__out__.push(', topOuts.join(","), ');'); + topBlock.splice(0, topBlock.length); + topOuts.splice(0, topOuts.length); + }, + + addLocals: function(blocks) + { + var varNames = []; + this.getVarNames(varNames); + + var map = {}; + for (var i = 0; i < varNames.length; ++i) + { + var name = varNames[i]; + if ( map.hasOwnProperty(name) ) + continue; + + map[name] = 1; + var names = name.split("."); + blocks.push('var ', names[0] + ' = ' + '__in__.' + names[0] + ';'); + } + }, + + compileDOM: function() + { + var path = []; + var blocks = []; + this.domArgs = []; + path.embedIndex = 0; + path.loopIndex = 0; + path.staticIndex = 0; + path.renderIndex = 0; + var nodeCount = this.generateDOM(path, blocks, this.domArgs); + + var fnBlock = ['r=(function (root, context, o']; + + for (var i = 0; i < path.staticIndex; ++i) + fnBlock.push(', ', 's'+i); + + for (var i = 0; i < path.renderIndex; ++i) + fnBlock.push(', ', 'd'+i); + + fnBlock.push(') {'); + for (var i = 0; i < path.loopIndex; ++i) + fnBlock.push('var l', i, ' = 0;'); + for (var i = 0; i < path.embedIndex; ++i) + fnBlock.push('var e', i, ' = 0;'); + + if (this.subject) + fnBlock.push('with (this) {'); + if (this.context) + fnBlock.push('with (context) {'); + + fnBlock.push(blocks.join("")); + + if (this.subject) + fnBlock.push('}'); + if (this.context) + fnBlock.push('}'); + + fnBlock.push('return ', nodeCount, ';'); + fnBlock.push('})'); + + function __bind__(object, fn) + { + return function(event) { return fn.apply(object, [event]); }; + } + + function __link__(node, tag, args) + { + if (!tag || !tag.tag) + return; + + tag.tag.compile(); + + var domArgs = [node, tag.tag.context, 0]; + domArgs.push.apply(domArgs, tag.tag.domArgs); + domArgs.push.apply(domArgs, args); + //if (FBTrace.DBG_DOM) FBTrace.dumpProperties("domplate__link__ domArgs:", domArgs); + return tag.tag.renderDOM.apply(tag.tag.subject, domArgs); + } + + var self = this; + function __loop__(iter, fn) + { + var nodeCount = 0; + for (var i = 0; i < iter.length; ++i) + { + iter[i][0] = i; + iter[i][1] = nodeCount; + nodeCount += fn.apply(this, iter[i]); + //if (FBTrace.DBG_DOM) FBTrace.sysout("nodeCount", nodeCount); + } + return nodeCount; + } + + function __path__(parent, offset) + { + //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate __path__ offset: "+ offset+"\n"); + var root = parent; + + for (var i = 2; i < arguments.length; ++i) + { + var index = arguments[i]; + if (i == 3) + index += offset; + + if (index == -1) + parent = parent.parentNode; + else + parent = parent.childNodes[index]; + } + + //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate: "+arguments[2]+", root: "+ root+", parent: "+ parent+"\n"); + return parent; + } + + var js = fnBlock.join(""); + //if (FBTrace.DBG_DOM) FBTrace.sysout(js.replace(/(\;|\{)/g, "$1\n")); + var r = null; + eval(js); + this.renderDOM = r; + }, + + generateDOM: function(path, blocks, args) + { + if (this.listeners || this.props) + this.generateNodePath(path, blocks); + + if (this.listeners) + { + for (var i = 0; i < this.listeners.length; i += 2) + { + var val = this.listeners[i+1]; + var arg = generateArg(val, path, args); + //blocks.push('node.addEventListener("', this.listeners[i], '", __bind__(this, ', arg, '), false);'); + blocks.push('addEvent(node, "', this.listeners[i], '", __bind__(this, ', arg, '), false);'); + } + } + + if (this.props) + { + for (var name in this.props) + { + var val = this.props[name]; + var arg = generateArg(val, path, args); + blocks.push('node.', name, ' = ', arg, ';'); + } + } + + this.generateChildDOM(path, blocks, args); + return 1; + }, + + generateNodePath: function(path, blocks) + { + blocks.push("var node = __path__(root, o"); + for (var i = 0; i < path.length; ++i) + blocks.push(",", path[i]); + blocks.push(");"); + }, + + generateChildDOM: function(path, blocks, args) + { + path.push(0); + for (var i = 0; i < this.children.length; ++i) + { + var child = this.children[i]; + if (isTag(child)) + path[path.length-1] += '+' + child.tag.generateDOM(path, blocks, args); + else + path[path.length-1] += '+1'; + } + path.pop(); + } +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +DomplateEmbed.prototype = copyObject(DomplateTag.prototype, +{ + merge: function(args, oldTag) + { + this.value = oldTag ? oldTag.value : parseValue(args[0]); + this.attrs = oldTag ? oldTag.attrs : {}; + this.vars = oldTag ? copyArray(oldTag.vars) : []; + + var attrs = args[1]; + for (var name in attrs) + { + var val = parseValue(attrs[name]); + this.attrs[name] = val; + readPartNames(val, this.vars); + } + + return creator(this, DomplateEmbed); + }, + + getVarNames: function(names) + { + if (this.value instanceof Parts) + names.push(this.value.parts[0].name); + + if (this.vars) + names.push.apply(names, this.vars); + }, + + generateMarkup: function(topBlock, topOuts, blocks, info) + { + this.addCode(topBlock, topOuts, blocks); + + blocks.push('__link__('); + addParts(this.value, '', blocks, info); + blocks.push(', __code__, __out__, {'); + + var lastName = null; + for (var name in this.attrs) + { + if (lastName) + blocks.push(','); + lastName = name; + + var val = this.attrs[name]; + blocks.push('"', name, '":'); + addParts(val, '', blocks, info); + } + + blocks.push('});'); + //this.generateChildMarkup(topBlock, topOuts, blocks, info); + }, + + generateDOM: function(path, blocks, args) + { + var embedName = 'e'+path.embedIndex++; + + this.generateNodePath(path, blocks); + + var valueName = 'd' + path.renderIndex++; + var argsName = 'd' + path.renderIndex++; + blocks.push(embedName + ' = __link__(node, ', valueName, ', ', argsName, ');'); + + return embedName; + } +}); + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +DomplateLoop.prototype = copyObject(DomplateTag.prototype, +{ + merge: function(args, oldTag) + { + this.varName = oldTag ? oldTag.varName : args[0]; + this.iter = oldTag ? oldTag.iter : parseValue(args[1]); + this.vars = []; + + this.children = oldTag ? copyArray(oldTag.children) : []; + + var offset = Math.min(args.length, 2); + parseChildren(args, offset, this.vars, this.children); + + return creator(this, DomplateLoop); + }, + + getVarNames: function(names) + { + if (this.iter instanceof Parts) + names.push(this.iter.parts[0].name); + + DomplateTag.prototype.getVarNames.apply(this, [names]); + }, + + generateMarkup: function(topBlock, topOuts, blocks, info) + { + this.addCode(topBlock, topOuts, blocks); + + var iterName; + if (this.iter instanceof Parts) + { + var part = this.iter.parts[0]; + iterName = part.name; + + if (part.format) + { + for (var i = 0; i < part.format.length; ++i) + iterName = part.format[i] + "(" + iterName + ")"; + } + } + else + iterName = this.iter; + + blocks.push('__loop__.apply(this, [', iterName, ', __out__, function(', this.varName, ', __out__) {'); + this.generateChildMarkup(topBlock, topOuts, blocks, info); + this.addCode(topBlock, topOuts, blocks); + blocks.push('}]);'); + }, + + generateDOM: function(path, blocks, args) + { + var iterName = 'd'+path.renderIndex++; + var counterName = 'i'+path.loopIndex; + var loopName = 'l'+path.loopIndex++; + + if (!path.length) + path.push(-1, 0); + + var preIndex = path.renderIndex; + path.renderIndex = 0; + + var nodeCount = 0; + + var subBlocks = []; + var basePath = path[path.length-1]; + for (var i = 0; i < this.children.length; ++i) + { + path[path.length-1] = basePath+'+'+loopName+'+'+nodeCount; + + var child = this.children[i]; + if (isTag(child)) + nodeCount += '+' + child.tag.generateDOM(path, subBlocks, args); + else + nodeCount += '+1'; + } + + path[path.length-1] = basePath+'+'+loopName; + + blocks.push(loopName,' = __loop__.apply(this, [', iterName, ', function(', counterName,',',loopName); + for (var i = 0; i < path.renderIndex; ++i) + blocks.push(',d'+i); + blocks.push(') {'); + blocks.push(subBlocks.join("")); + blocks.push('return ', nodeCount, ';'); + blocks.push('}]);'); + + path.renderIndex = preIndex; + + return loopName; + } +}); + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +function Variable(name, format) +{ + this.name = name; + this.format = format; +} + +function Parts(parts) +{ + this.parts = parts; +} + +// ************************************************************************************************ + +function parseParts(str) +{ + var re = /\$([_A-Za-z][_A-Za-z0-9.|]*)/g; + var index = 0; + var parts = []; + + var m; + while (m = re.exec(str)) + { + var pre = str.substr(index, (re.lastIndex-m[0].length)-index); + if (pre) + parts.push(pre); + + var expr = m[1].split("|"); + parts.push(new Variable(expr[0], expr.slice(1))); + index = re.lastIndex; + } + + if (!index) + return str; + + var post = str.substr(index); + if (post) + parts.push(post); + + return new Parts(parts); +} + +function parseValue(val) +{ + return typeof(val) == 'string' ? parseParts(val) : val; +} + +function parseChildren(args, offset, vars, children) +{ + for (var i = offset; i < args.length; ++i) + { + var val = parseValue(args[i]); + children.push(val); + readPartNames(val, vars); + } +} + +function readPartNames(val, vars) +{ + if (val instanceof Parts) + { + for (var i = 0; i < val.parts.length; ++i) + { + var part = val.parts[i]; + if (part instanceof Variable) + vars.push(part.name); + } + } +} + +function generateArg(val, path, args) +{ + if (val instanceof Parts) + { + var vals = []; + for (var i = 0; i < val.parts.length; ++i) + { + var part = val.parts[i]; + if (part instanceof Variable) + { + var varName = 'd'+path.renderIndex++; + if (part.format) + { + for (var j = 0; j < part.format.length; ++j) + varName = part.format[j] + '(' + varName + ')'; + } + + vals.push(varName); + } + else + vals.push('"'+part.replace(/"/g, '\\"')+'"'); + } + + return vals.join('+'); + } + else + { + args.push(val); + return 's' + path.staticIndex++; + } +} + +function addParts(val, delim, block, info, escapeIt) +{ + var vals = []; + if (val instanceof Parts) + { + for (var i = 0; i < val.parts.length; ++i) + { + var part = val.parts[i]; + if (part instanceof Variable) + { + var partName = part.name; + if (part.format) + { + for (var j = 0; j < part.format.length; ++j) + partName = part.format[j] + "(" + partName + ")"; + } + + if (escapeIt) + vals.push("__escape__(" + partName + ")"); + else + vals.push(partName); + } + else + vals.push('"'+ part + '"'); + } + } + else if (isTag(val)) + { + info.args.push(val); + vals.push('s'+info.argIndex++); + } + else + vals.push('"'+ val + '"'); + + var parts = vals.join(delim); + if (parts) + block.push(delim, parts); +} + +function isTag(obj) +{ + return (typeof(obj) == "function" || obj instanceof Function) && !!obj.tag; +} + +function creator(tag, cons) +{ + var fn = new Function( + "var tag = arguments.callee.tag;" + + "var cons = arguments.callee.cons;" + + "var newTag = new cons();" + + "return newTag.merge(arguments, tag);"); + + fn.tag = tag; + fn.cons = cons; + extend(fn, Renderer); + + return fn; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +function copyArray(oldArray) +{ + var ary = []; + if (oldArray) + for (var i = 0; i < oldArray.length; ++i) + ary.push(oldArray[i]); + return ary; +} + +function copyObject(l, r) +{ + var m = {}; + extend(m, l); + extend(m, r); + return m; +} + +function extend(l, r) +{ + for (var n in r) + l[n] = r[n]; +} + +function addEvent(object, name, handler) +{ + if (document.all) + object.attachEvent("on"+name, handler); + else + object.addEventListener(name, handler, false); +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +function ArrayIterator(array) +{ + var index = -1; + + this.next = function() + { + if (++index >= array.length) + throw StopIteration; + + return array[index]; + }; +} + +function StopIteration() {} + +FBL.$break = function() +{ + throw StopIteration; +}; + +// ************************************************************************************************ + +var Renderer = +{ + renderHTML: function(args, outputs, self) + { + var code = []; + var markupArgs = [code, this.tag.context, args, outputs]; + markupArgs.push.apply(markupArgs, this.tag.markupArgs); + this.tag.renderMarkup.apply(self ? self : this.tag.subject, markupArgs); + return code.join(""); + }, + + insertRows: function(args, before, self) + { + this.tag.compile(); + + var outputs = []; + var html = this.renderHTML(args, outputs, self); + + var doc = before.ownerDocument; + var div = doc.createElement("div"); + div.innerHTML = ""+html+"
                  "; + + var tbody = div.firstChild.firstChild; + var parent = before.tagName == "TR" ? before.parentNode : before; + var after = before.tagName == "TR" ? before.nextSibling : null; + + var firstRow = tbody.firstChild, lastRow; + while (tbody.firstChild) + { + lastRow = tbody.firstChild; + if (after) + parent.insertBefore(lastRow, after); + else + parent.appendChild(lastRow); + } + + var offset = 0; + if (before.tagName == "TR") + { + var node = firstRow.parentNode.firstChild; + for (; node && node != firstRow; node = node.nextSibling) + ++offset; + } + + var domArgs = [firstRow, this.tag.context, offset]; + domArgs.push.apply(domArgs, this.tag.domArgs); + domArgs.push.apply(domArgs, outputs); + + this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs); + return [firstRow, lastRow]; + }, + + insertBefore: function(args, before, self) + { + return this.insertNode(args, before.ownerDocument, before, false, self); + }, + + insertAfter: function(args, after, self) + { + return this.insertNode(args, after.ownerDocument, after, true, self); + }, + + insertNode: function(args, doc, element, isAfter, self) + { + if (!args) + args = {}; + + this.tag.compile(); + + var outputs = []; + var html = this.renderHTML(args, outputs, self); + + //if (FBTrace.DBG_DOM) + // FBTrace.sysout("domplate.insertNode html: "+html+"\n"); + + var doc = element.ownerDocument; + if (!womb || womb.ownerDocument != doc) + womb = doc.createElement("div"); + + womb.innerHTML = html; + + var root = womb.firstChild; + if (isAfter) + { + while (womb.firstChild) + if (element.nextSibling) + element.parentNode.insertBefore(womb.firstChild, element.nextSibling); + else + element.parentNode.appendChild(womb.firstChild); + } + else + { + while (womb.lastChild) + element.parentNode.insertBefore(womb.lastChild, element); + } + + var domArgs = [root, this.tag.context, 0]; + domArgs.push.apply(domArgs, this.tag.domArgs); + domArgs.push.apply(domArgs, outputs); + + //if (FBTrace.DBG_DOM) + // FBTrace.sysout("domplate.insertNode domArgs:", domArgs); + this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs); + + return root; + }, + /**/ + + /* + insertAfter: function(args, before, self) + { + this.tag.compile(); + + var outputs = []; + var html = this.renderHTML(args, outputs, self); + + var doc = before.ownerDocument; + if (!womb || womb.ownerDocument != doc) + womb = doc.createElement("div"); + + womb.innerHTML = html; + + var root = womb.firstChild; + while (womb.firstChild) + if (before.nextSibling) + before.parentNode.insertBefore(womb.firstChild, before.nextSibling); + else + before.parentNode.appendChild(womb.firstChild); + + var domArgs = [root, this.tag.context, 0]; + domArgs.push.apply(domArgs, this.tag.domArgs); + domArgs.push.apply(domArgs, outputs); + + this.tag.renderDOM.apply(self ? self : (this.tag.subject ? this.tag.subject : null), + domArgs); + + return root; + }, + /**/ + + replace: function(args, parent, self) + { + this.tag.compile(); + + var outputs = []; + var html = this.renderHTML(args, outputs, self); + + var root; + if (parent.nodeType == 1) + { + parent.innerHTML = html; + root = parent.firstChild; + } + else + { + if (!parent || parent.nodeType != 9) + parent = document; + + if (!womb || womb.ownerDocument != parent) + womb = parent.createElement("div"); + womb.innerHTML = html; + + root = womb.firstChild; + //womb.removeChild(root); + } + + var domArgs = [root, this.tag.context, 0]; + domArgs.push.apply(domArgs, this.tag.domArgs); + domArgs.push.apply(domArgs, outputs); + this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs); + + return root; + }, + + append: function(args, parent, self) + { + this.tag.compile(); + + var outputs = []; + var html = this.renderHTML(args, outputs, self); + //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate.append html: "+html+"\n"); + + if (!womb || womb.ownerDocument != parent.ownerDocument) + womb = parent.ownerDocument.createElement("div"); + womb.innerHTML = html; + + // TODO: xxxpedro domplate port to Firebug + var root = womb.firstChild; + while (womb.firstChild) + parent.appendChild(womb.firstChild); + + // clearing element reference to avoid reference error in IE8 when switching contexts + womb = null; + + var domArgs = [root, this.tag.context, 0]; + domArgs.push.apply(domArgs, this.tag.domArgs); + domArgs.push.apply(domArgs, outputs); + + //if (FBTrace.DBG_DOM) FBTrace.dumpProperties("domplate append domArgs:", domArgs); + this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs); + + return root; + } +}; + +// ************************************************************************************************ + +function defineTags() +{ + for (var i = 0; i < arguments.length; ++i) + { + var tagName = arguments[i]; + var fn = new Function("var newTag = new arguments.callee.DomplateTag('"+tagName+"'); return newTag.merge(arguments);"); + fn.DomplateTag = DomplateTag; + + var fnName = tagName.toUpperCase(); + FBL[fnName] = fn; + } +} + +defineTags( + "a", "button", "br", "canvas", "code", "col", "colgroup", "div", "fieldset", "form", "h1", "h2", "h3", "hr", + "img", "input", "label", "legend", "li", "ol", "optgroup", "option", "p", "pre", "select", + "span", "strong", "table", "tbody", "td", "textarea", "tfoot", "th", "thead", "tr", "tt", "ul", "iframe" +); + +})(); + + +/* See license.txt for terms of usage */ + +var FirebugReps = FBL.ns(function() { with (FBL) { + + +// ************************************************************************************************ +// Common Tags + +var OBJECTBOX = this.OBJECTBOX = + SPAN({"class": "objectBox objectBox-$className"}); + +var OBJECTBLOCK = this.OBJECTBLOCK = + DIV({"class": "objectBox objectBox-$className"}); + +var OBJECTLINK = this.OBJECTLINK = isIE6 ? // IE6 object link representation + A({ + "class": "objectLink objectLink-$className a11yFocus", + href: "javascript:void(0)", + _repObject: "$object" + }) + : // Other browsers + A({ + "class": "objectLink objectLink-$className a11yFocus", + _repObject: "$object" + }); + + +// ************************************************************************************************ + +this.Undefined = domplate(Firebug.Rep, +{ + tag: OBJECTBOX("undefined"), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "undefined", + + supportsObject: function(object, type) + { + return type == "undefined"; + } +}); + +// ************************************************************************************************ + +this.Null = domplate(Firebug.Rep, +{ + tag: OBJECTBOX("null"), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "null", + + supportsObject: function(object, type) + { + return object == null; + } +}); + +// ************************************************************************************************ + +this.Nada = domplate(Firebug.Rep, +{ + tag: SPAN(""), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "nada" +}); + +// ************************************************************************************************ + +this.Number = domplate(Firebug.Rep, +{ + tag: OBJECTBOX("$object"), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "number", + + supportsObject: function(object, type) + { + return type == "boolean" || type == "number"; + } +}); + +// ************************************************************************************************ + +this.String = domplate(Firebug.Rep, +{ + tag: OBJECTBOX(""$object""), + + shortTag: OBJECTBOX(""$object|cropString""), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "string", + + supportsObject: function(object, type) + { + return type == "string"; + } +}); + +// ************************************************************************************************ + +this.Text = domplate(Firebug.Rep, +{ + tag: OBJECTBOX("$object"), + + shortTag: OBJECTBOX("$object|cropString"), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "text" +}); + +// ************************************************************************************************ + +this.Caption = domplate(Firebug.Rep, +{ + tag: SPAN({"class": "caption"}, "$object") +}); + +// ************************************************************************************************ + +this.Warning = domplate(Firebug.Rep, +{ + tag: DIV({"class": "warning focusRow", role : 'listitem'}, "$object|STR") +}); + +// ************************************************************************************************ + +this.Func = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK("$object|summarizeFunction"), + + summarizeFunction: function(fn) + { + var fnRegex = /function ([^(]+\([^)]*\)) \{/; + var fnText = safeToString(fn); + + var m = fnRegex.exec(fnText); + return m ? m[1] : "function()"; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + copySource: function(fn) + { + copyToClipboard(safeToString(fn)); + }, + + monitor: function(fn, script, monitored) + { + if (monitored) + Firebug.Debugger.unmonitorScript(fn, script, "monitor"); + else + Firebug.Debugger.monitorScript(fn, script, "monitor"); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "function", + + supportsObject: function(object, type) + { + return isFunction(object); + }, + + inspectObject: function(fn, context) + { + var sourceLink = findSourceForFunction(fn, context); + if (sourceLink) + Firebug.chrome.select(sourceLink); + if (FBTrace.DBG_FUNCTION_NAME) + FBTrace.sysout("reps.function.inspectObject selected sourceLink is ", sourceLink); + }, + + getTooltip: function(fn, context) + { + var script = findScriptForFunctionInContext(context, fn); + if (script) + return $STRF("Line", [normalizeURL(script.fileName), script.baseLineNumber]); + else + if (fn.toString) + return fn.toString(); + }, + + getTitle: function(fn, context) + { + var name = fn.name ? fn.name : "function"; + return name + "()"; + }, + + getContextMenuItems: function(fn, target, context, script) + { + if (!script) + script = findScriptForFunctionInContext(context, fn); + if (!script) + return; + + var scriptInfo = getSourceFileAndLineByScript(context, script); + var monitored = scriptInfo ? fbs.isMonitored(scriptInfo.sourceFile.href, scriptInfo.lineNo) : false; + + var name = script ? getFunctionName(script, context) : fn.name; + return [ + {label: "CopySource", command: bindFixed(this.copySource, this, fn) }, + "-", + {label: $STRF("ShowCallsInConsole", [name]), nol10n: true, + type: "checkbox", checked: monitored, + command: bindFixed(this.monitor, this, fn, script, monitored) } + ]; + } +}); + +// ************************************************************************************************ +/* +this.jsdScript = domplate(Firebug.Rep, +{ + copySource: function(script) + { + var fn = script.functionObject.getWrappedValue(); + return FirebugReps.Func.copySource(fn); + }, + + monitor: function(fn, script, monitored) + { + fn = script.functionObject.getWrappedValue(); + return FirebugReps.Func.monitor(fn, script, monitored); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "jsdScript", + inspectable: false, + + supportsObject: function(object, type) + { + return object instanceof jsdIScript; + }, + + inspectObject: function(script, context) + { + var sourceLink = getSourceLinkForScript(script, context); + if (sourceLink) + Firebug.chrome.select(sourceLink); + }, + + getRealObject: function(script, context) + { + return script; + }, + + getTooltip: function(script) + { + return $STRF("jsdIScript", [script.tag]); + }, + + getTitle: function(script, context) + { + var fn = script.functionObject.getWrappedValue(); + return FirebugReps.Func.getTitle(fn, context); + }, + + getContextMenuItems: function(script, target, context) + { + var fn = script.functionObject.getWrappedValue(); + + var scriptInfo = getSourceFileAndLineByScript(context, script); + var monitored = scriptInfo ? fbs.isMonitored(scriptInfo.sourceFile.href, scriptInfo.lineNo) : false; + + var name = getFunctionName(script, context); + + return [ + {label: "CopySource", command: bindFixed(this.copySource, this, script) }, + "-", + {label: $STRF("ShowCallsInConsole", [name]), nol10n: true, + type: "checkbox", checked: monitored, + command: bindFixed(this.monitor, this, fn, script, monitored) } + ]; + } +}); +/**/ +//************************************************************************************************ + +this.Obj = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK( + SPAN({"class": "objectTitle"}, "$object|getTitle "), + + SPAN({"class": "objectProps"}, + SPAN({"class": "objectLeftBrace", role: "presentation"}, "{"), + FOR("prop", "$object|propIterator", + SPAN({"class": "objectPropName", role: "presentation"}, "$prop.name"), + SPAN({"class": "objectEqual", role: "presentation"}, "$prop.equal"), + TAG("$prop.tag", {object: "$prop.object"}), + SPAN({"class": "objectComma", role: "presentation"}, "$prop.delim") + ), + SPAN({"class": "objectRightBrace"}, "}") + ) + ), + + propNumberTag: + SPAN({"class": "objectProp-number"}, "$object"), + + propStringTag: + SPAN({"class": "objectProp-string"}, ""$object""), + + propObjectTag: + SPAN({"class": "objectProp-object"}, "$object"), + + propIterator: function (object) + { + ///Firebug.ObjectShortIteratorMax; + var maxLength = 55; // default max length for long representation + + if (!object) + return []; + + var props = []; + var length = 0; + + var numProperties = 0; + var numPropertiesShown = 0; + var maxLengthReached = false; + + var lib = this; + + var propRepsMap = + { + "boolean": this.propNumberTag, + "number": this.propNumberTag, + "string": this.propStringTag, + "object": this.propObjectTag + }; + + try + { + var title = Firebug.Rep.getTitle(object); + length += title.length; + + for (var name in object) + { + var value; + try + { + value = object[name]; + } + catch (exc) + { + continue; + } + + var type = typeof(value); + if (type == "boolean" || + type == "number" || + (type == "string" && value) || + (type == "object" && value && value.toString)) + { + var tag = propRepsMap[type]; + + var value = (type == "object") ? + Firebug.getRep(value).getTitle(value) : + value + ""; + + length += name.length + value.length + 4; + + if (length <= maxLength) + { + props.push({ + tag: tag, + name: name, + object: value, + equal: "=", + delim: ", " + }); + + numPropertiesShown++; + } + else + maxLengthReached = true; + + } + + numProperties++; + + if (maxLengthReached && numProperties > numPropertiesShown) + break; + } + + if (numProperties > numPropertiesShown) + { + props.push({ + object: "...", //xxxHonza localization + tag: FirebugReps.Caption.tag, + name: "", + equal:"", + delim:"" + }); + } + else if (props.length > 0) + { + props[props.length-1].delim = ''; + } + } + catch (exc) + { + // Sometimes we get exceptions when trying to read from certain objects, like + // StorageList, but don't let that gum up the works + // XXXjjb also History.previous fails because object is a web-page object which does not have + // permission to read the history + } + return props; + }, + + fb_1_6_propIterator: function (object, max) + { + max = max || 3; + if (!object) + return []; + + var props = []; + var len = 0, count = 0; + + try + { + for (var name in object) + { + var value; + try + { + value = object[name]; + } + catch (exc) + { + continue; + } + + var t = typeof(value); + if (t == "boolean" || t == "number" || (t == "string" && value) + || (t == "object" && value && value.toString)) + { + var rep = Firebug.getRep(value); + var tag = rep.shortTag || rep.tag; + if (t == "object") + { + value = rep.getTitle(value); + tag = rep.titleTag; + } + count++; + if (count <= max) + props.push({tag: tag, name: name, object: value, equal: "=", delim: ", "}); + else + break; + } + } + if (count > max) + { + props[Math.max(1,max-1)] = { + object: "more...", //xxxHonza localization + tag: FirebugReps.Caption.tag, + name: "", + equal:"", + delim:"" + }; + } + else if (props.length > 0) + { + props[props.length-1].delim = ''; + } + } + catch (exc) + { + // Sometimes we get exceptions when trying to read from certain objects, like + // StorageList, but don't let that gum up the works + // XXXjjb also History.previous fails because object is a web-page object which does not have + // permission to read the history + } + return props; + }, + + /* + propIterator: function (object) + { + if (!object) + return []; + + var props = []; + var len = 0; + + try + { + for (var name in object) + { + var val; + try + { + val = object[name]; + } + catch (exc) + { + continue; + } + + var t = typeof val; + if (t == "boolean" || t == "number" || (t == "string" && val) + || (t == "object" && !isFunction(val) && val && val.toString)) + { + var title = (t == "object") + ? Firebug.getRep(val).getTitle(val) + : val+""; + + len += name.length + title.length + 1; + if (len < 50) + props.push({name: name, value: title}); + else + break; + } + } + } + catch (exc) + { + // Sometimes we get exceptions when trying to read from certain objects, like + // StorageList, but don't let that gum up the works + // XXXjjb also History.previous fails because object is a web-page object which does not have + // permission to read the history + } + + return props; + }, + /**/ + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "object", + + supportsObject: function(object, type) + { + return true; + } +}); + + +// ************************************************************************************************ + +this.Arr = domplate(Firebug.Rep, +{ + tag: + OBJECTBOX({_repObject: "$object"}, + SPAN({"class": "arrayLeftBracket", role : "presentation"}, "["), + FOR("item", "$object|arrayIterator", + TAG("$item.tag", {object: "$item.object"}), + SPAN({"class": "arrayComma", role : "presentation"}, "$item.delim") + ), + SPAN({"class": "arrayRightBracket", role : "presentation"}, "]") + ), + + shortTag: + OBJECTBOX({_repObject: "$object"}, + SPAN({"class": "arrayLeftBracket", role : "presentation"}, "["), + FOR("item", "$object|shortArrayIterator", + TAG("$item.tag", {object: "$item.object"}), + SPAN({"class": "arrayComma", role : "presentation"}, "$item.delim") + ), + // TODO: xxxpedro - confirm this on Firebug + //FOR("prop", "$object|shortPropIterator", + // " $prop.name=", + // SPAN({"class": "objectPropValue"}, "$prop.value|cropString") + //), + SPAN({"class": "arrayRightBracket"}, "]") + ), + + arrayIterator: function(array) + { + var items = []; + for (var i = 0; i < array.length; ++i) + { + var value = array[i]; + var rep = Firebug.getRep(value); + var tag = rep.shortTag ? rep.shortTag : rep.tag; + var delim = (i == array.length-1 ? "" : ", "); + + items.push({object: value, tag: tag, delim: delim}); + } + + return items; + }, + + shortArrayIterator: function(array) + { + var items = []; + for (var i = 0; i < array.length && i < 3; ++i) + { + var value = array[i]; + var rep = Firebug.getRep(value); + var tag = rep.shortTag ? rep.shortTag : rep.tag; + var delim = (i == array.length-1 ? "" : ", "); + + items.push({object: value, tag: tag, delim: delim}); + } + + if (array.length > 3) + items.push({object: (array.length-3) + " more...", tag: FirebugReps.Caption.tag, delim: ""}); + + return items; + }, + + shortPropIterator: this.Obj.propIterator, + + getItemIndex: function(child) + { + var arrayIndex = 0; + for (child = child.previousSibling; child; child = child.previousSibling) + { + if (child.repObject) + ++arrayIndex; + } + return arrayIndex; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "array", + + supportsObject: function(object) + { + return this.isArray(object); + }, + + // http://code.google.com/p/fbug/issues/detail?id=874 + // BEGIN Yahoo BSD Source (modified here) YAHOO.lang.isArray, YUI 2.2.2 June 2007 + isArray: function(obj) { + try { + if (!obj) + return false; + else if (isIE && !isFunction(obj) && typeof obj == "object" && isFinite(obj.length) && obj.nodeType != 8) + return true; + else if (isFinite(obj.length) && isFunction(obj.splice)) + return true; + else if (isFinite(obj.length) && isFunction(obj.callee)) // arguments + return true; + else if (instanceOf(obj, "HTMLCollection")) + return true; + else if (instanceOf(obj, "NodeList")) + return true; + else + return false; + } + catch(exc) + { + if (FBTrace.DBG_ERRORS) + { + FBTrace.sysout("isArray FAILS:", exc); /* Something weird: without the try/catch, OOM, with no exception?? */ + FBTrace.sysout("isArray Fails on obj", obj); + } + } + + return false; + }, + // END Yahoo BSD SOURCE See license below. + + getTitle: function(object, context) + { + return "[" + object.length + "]"; + } +}); + +// ************************************************************************************************ + +this.Property = domplate(Firebug.Rep, +{ + supportsObject: function(object) + { + return object instanceof Property; + }, + + getRealObject: function(prop, context) + { + return prop.object[prop.name]; + }, + + getTitle: function(prop, context) + { + return prop.name; + } +}); + +// ************************************************************************************************ + +this.NetFile = domplate(this.Obj, +{ + supportsObject: function(object) + { + return object instanceof Firebug.NetFile; + }, + + browseObject: function(file, context) + { + openNewTab(file.href); + return true; + }, + + getRealObject: function(file, context) + { + return null; + } +}); + +// ************************************************************************************************ + +this.Except = domplate(Firebug.Rep, +{ + tag: + OBJECTBOX({_repObject: "$object"}, "$object.message"), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "exception", + + supportsObject: function(object) + { + return object instanceof ErrorCopy; + } +}); + + +// ************************************************************************************************ + +this.Element = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK( + "<", + SPAN({"class": "nodeTag"}, "$object.nodeName|toLowerCase"), + FOR("attr", "$object|attrIterator", + " $attr.nodeName="", SPAN({"class": "nodeValue"}, "$attr.nodeValue"), """ + ), + ">" + ), + + shortTag: + OBJECTLINK( + SPAN({"class": "$object|getVisible"}, + SPAN({"class": "selectorTag"}, "$object|getSelectorTag"), + SPAN({"class": "selectorId"}, "$object|getSelectorId"), + SPAN({"class": "selectorClass"}, "$object|getSelectorClass"), + SPAN({"class": "selectorValue"}, "$object|getValue") + ) + ), + + getVisible: function(elt) + { + return isVisible(elt) ? "" : "selectorHidden"; + }, + + getSelectorTag: function(elt) + { + return elt.nodeName.toLowerCase(); + }, + + getSelectorId: function(elt) + { + return elt.id ? "#" + elt.id : ""; + }, + + getSelectorClass: function(elt) + { + return elt.className ? "." + elt.className.split(" ")[0] : ""; + }, + + getValue: function(elt) + { + // TODO: xxxpedro + return ""; + var value; + if (elt instanceof HTMLImageElement) + value = getFileName(elt.src); + else if (elt instanceof HTMLAnchorElement) + value = getFileName(elt.href); + else if (elt instanceof HTMLInputElement) + value = elt.value; + else if (elt instanceof HTMLFormElement) + value = getFileName(elt.action); + else if (elt instanceof HTMLScriptElement) + value = getFileName(elt.src); + + return value ? " " + cropString(value, 20) : ""; + }, + + attrIterator: function(elt) + { + var attrs = []; + var idAttr, classAttr; + if (elt.attributes) + { + for (var i = 0; i < elt.attributes.length; ++i) + { + var attr = elt.attributes[i]; + if (attr.nodeName && attr.nodeName.indexOf("firebug-") != -1) + continue; + else if (attr.nodeName == "id") + idAttr = attr; + else if (attr.nodeName == "class") + classAttr = attr; + else + attrs.push(attr); + } + } + if (classAttr) + attrs.splice(0, 0, classAttr); + if (idAttr) + attrs.splice(0, 0, idAttr); + + return attrs; + }, + + shortAttrIterator: function(elt) + { + var attrs = []; + if (elt.attributes) + { + for (var i = 0; i < elt.attributes.length; ++i) + { + var attr = elt.attributes[i]; + if (attr.nodeName == "id" || attr.nodeName == "class") + attrs.push(attr); + } + } + + return attrs; + }, + + getHidden: function(elt) + { + return isVisible(elt) ? "" : "nodeHidden"; + }, + + getXPath: function(elt) + { + return getElementTreeXPath(elt); + }, + + // TODO: xxxpedro remove this? + getNodeText: function(element) + { + var text = element.textContent; + if (Firebug.showFullTextNodes) + return text; + else + return cropString(text, 50); + }, + /**/ + + getNodeTextGroups: function(element) + { + var text = element.textContent; + if (!Firebug.showFullTextNodes) + { + text=cropString(text,50); + } + + var escapeGroups=[]; + + if (Firebug.showTextNodesWithWhitespace) + escapeGroups.push({ + 'group': 'whitespace', + 'class': 'nodeWhiteSpace', + 'extra': { + '\t': '_Tab', + '\n': '_Para', + ' ' : '_Space' + } + }); + if (Firebug.showTextNodesWithEntities) + escapeGroups.push({ + 'group':'text', + 'class':'nodeTextEntity', + 'extra':{} + }); + + if (escapeGroups.length) + return escapeGroupsForEntities(text, escapeGroups); + else + return [{str:text,'class':'',extra:''}]; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + copyHTML: function(elt) + { + var html = getElementXML(elt); + copyToClipboard(html); + }, + + copyInnerHTML: function(elt) + { + copyToClipboard(elt.innerHTML); + }, + + copyXPath: function(elt) + { + var xpath = getElementXPath(elt); + copyToClipboard(xpath); + }, + + persistor: function(context, xpath) + { + var elts = xpath + ? getElementsByXPath(context.window.document, xpath) + : null; + + return elts && elts.length ? elts[0] : null; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "element", + + supportsObject: function(object) + { + //return object instanceof Element || object.nodeType == 1 && typeof object.nodeName == "string"; + return instanceOf(object, "Element"); + }, + + browseObject: function(elt, context) + { + var tag = elt.nodeName.toLowerCase(); + if (tag == "script") + openNewTab(elt.src); + else if (tag == "link") + openNewTab(elt.href); + else if (tag == "a") + openNewTab(elt.href); + else if (tag == "img") + openNewTab(elt.src); + + return true; + }, + + persistObject: function(elt, context) + { + var xpath = getElementXPath(elt); + + return bind(this.persistor, top, xpath); + }, + + getTitle: function(element, context) + { + return getElementCSSSelector(element); + }, + + getTooltip: function(elt) + { + return this.getXPath(elt); + }, + + getContextMenuItems: function(elt, target, context) + { + var monitored = areEventsMonitored(elt, null, context); + + return [ + {label: "CopyHTML", command: bindFixed(this.copyHTML, this, elt) }, + {label: "CopyInnerHTML", command: bindFixed(this.copyInnerHTML, this, elt) }, + {label: "CopyXPath", command: bindFixed(this.copyXPath, this, elt) }, + "-", + {label: "ShowEventsInConsole", type: "checkbox", checked: monitored, + command: bindFixed(toggleMonitorEvents, FBL, elt, null, monitored, context) }, + "-", + {label: "ScrollIntoView", command: bindFixed(elt.scrollIntoView, elt) } + ]; + } +}); + +// ************************************************************************************************ + +this.TextNode = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK( + "<", + SPAN({"class": "nodeTag"}, "TextNode"), + " textContent="", SPAN({"class": "nodeValue"}, "$object.textContent|cropString"), """, + ">" + ), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "textNode", + + supportsObject: function(object) + { + return object instanceof Text; + } +}); + +// ************************************************************************************************ + +this.Document = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK("Document ", SPAN({"class": "objectPropValue"}, "$object|getLocation")), + + getLocation: function(doc) + { + return doc.location ? getFileName(doc.location.href) : ""; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "object", + + supportsObject: function(object) + { + //return object instanceof Document || object instanceof XMLDocument; + return instanceOf(object, "Document"); + }, + + browseObject: function(doc, context) + { + openNewTab(doc.location.href); + return true; + }, + + persistObject: function(doc, context) + { + return this.persistor; + }, + + persistor: function(context) + { + return context.window.document; + }, + + getTitle: function(win, context) + { + return "document"; + }, + + getTooltip: function(doc) + { + return doc.location.href; + } +}); + +// ************************************************************************************************ + +this.StyleSheet = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK("StyleSheet ", SPAN({"class": "objectPropValue"}, "$object|getLocation")), + + getLocation: function(styleSheet) + { + return getFileName(styleSheet.href); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + copyURL: function(styleSheet) + { + copyToClipboard(styleSheet.href); + }, + + openInTab: function(styleSheet) + { + openNewTab(styleSheet.href); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "object", + + supportsObject: function(object) + { + //return object instanceof CSSStyleSheet; + return instanceOf(object, "CSSStyleSheet"); + }, + + browseObject: function(styleSheet, context) + { + openNewTab(styleSheet.href); + return true; + }, + + persistObject: function(styleSheet, context) + { + return bind(this.persistor, top, styleSheet.href); + }, + + getTooltip: function(styleSheet) + { + return styleSheet.href; + }, + + getContextMenuItems: function(styleSheet, target, context) + { + return [ + {label: "CopyLocation", command: bindFixed(this.copyURL, this, styleSheet) }, + "-", + {label: "OpenInTab", command: bindFixed(this.openInTab, this, styleSheet) } + ]; + }, + + persistor: function(context, href) + { + return getStyleSheetByHref(href, context); + } +}); + +// ************************************************************************************************ + +this.Window = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK("Window ", SPAN({"class": "objectPropValue"}, "$object|getLocation")), + + getLocation: function(win) + { + try + { + return (win && win.location && !win.closed) ? getFileName(win.location.href) : ""; + } + catch (exc) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("reps.Window window closed?"); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "object", + + supportsObject: function(object) + { + return instanceOf(object, "Window"); + }, + + browseObject: function(win, context) + { + openNewTab(win.location.href); + return true; + }, + + persistObject: function(win, context) + { + return this.persistor; + }, + + persistor: function(context) + { + return context.window; + }, + + getTitle: function(win, context) + { + return "window"; + }, + + getTooltip: function(win) + { + if (win && !win.closed) + return win.location.href; + } +}); + +// ************************************************************************************************ + +this.Event = domplate(Firebug.Rep, +{ + tag: TAG("$copyEventTag", {object: "$object|copyEvent"}), + + copyEventTag: + OBJECTLINK("$object|summarizeEvent"), + + summarizeEvent: function(event) + { + var info = [event.type, ' ']; + + var eventFamily = getEventFamily(event.type); + if (eventFamily == "mouse") + info.push("clientX=", event.clientX, ", clientY=", event.clientY); + else if (eventFamily == "key") + info.push("charCode=", event.charCode, ", keyCode=", event.keyCode); + + return info.join(""); + }, + + copyEvent: function(event) + { + return new EventCopy(event); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "object", + + supportsObject: function(object) + { + //return object instanceof Event || object instanceof EventCopy; + return instanceOf(object, "Event") || instanceOf(object, "EventCopy"); + }, + + getTitle: function(event, context) + { + return "Event " + event.type; + } +}); + +// ************************************************************************************************ + +this.SourceLink = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK({$collapsed: "$object|hideSourceLink"}, "$object|getSourceLinkTitle"), + + hideSourceLink: function(sourceLink) + { + return sourceLink ? sourceLink.href.indexOf("XPCSafeJSObjectWrapper") != -1 : true; + }, + + getSourceLinkTitle: function(sourceLink) + { + if (!sourceLink) + return ""; + + try + { + var fileName = getFileName(sourceLink.href); + fileName = decodeURIComponent(fileName); + fileName = cropString(fileName, 17); + } + catch(exc) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("reps.getSourceLinkTitle decodeURIComponent fails for \'"+fileName+"\': "+exc, exc); + } + + return typeof sourceLink.line == "number" ? + fileName + " (line " + sourceLink.line + ")" : + fileName; + + // TODO: xxxpedro + //return $STRF("Line", [fileName, sourceLink.line]); + }, + + copyLink: function(sourceLink) + { + copyToClipboard(sourceLink.href); + }, + + openInTab: function(sourceLink) + { + openNewTab(sourceLink.href); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "sourceLink", + + supportsObject: function(object) + { + return object instanceof SourceLink; + }, + + getTooltip: function(sourceLink) + { + return decodeURI(sourceLink.href); + }, + + inspectObject: function(sourceLink, context) + { + if (sourceLink.type == "js") + { + var scriptFile = getSourceFileByHref(sourceLink.href, context); + if (scriptFile) + return Firebug.chrome.select(sourceLink); + } + else if (sourceLink.type == "css") + { + // If an object is defined, treat it as the highest priority for + // inspect actions + if (sourceLink.object) { + Firebug.chrome.select(sourceLink.object); + return; + } + + var stylesheet = getStyleSheetByHref(sourceLink.href, context); + if (stylesheet) + { + var ownerNode = stylesheet.ownerNode; + if (ownerNode) + { + Firebug.chrome.select(sourceLink, "html"); + return; + } + + var panel = context.getPanel("stylesheet"); + if (panel && panel.getRuleByLine(stylesheet, sourceLink.line)) + return Firebug.chrome.select(sourceLink); + } + } + + // Fallback is to just open the view-source window on the file + viewSource(sourceLink.href, sourceLink.line); + }, + + browseObject: function(sourceLink, context) + { + openNewTab(sourceLink.href); + return true; + }, + + getContextMenuItems: function(sourceLink, target, context) + { + return [ + {label: "CopyLocation", command: bindFixed(this.copyLink, this, sourceLink) }, + "-", + {label: "OpenInTab", command: bindFixed(this.openInTab, this, sourceLink) } + ]; + } +}); + +// ************************************************************************************************ + +this.SourceFile = domplate(this.SourceLink, +{ + tag: + OBJECTLINK({$collapsed: "$object|hideSourceLink"}, "$object|getSourceLinkTitle"), + + persistor: function(context, href) + { + return getSourceFileByHref(href, context); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "sourceFile", + + supportsObject: function(object) + { + return object instanceof SourceFile; + }, + + persistObject: function(sourceFile) + { + return bind(this.persistor, top, sourceFile.href); + }, + + browseObject: function(sourceLink, context) + { + }, + + getTooltip: function(sourceFile) + { + return sourceFile.href; + } +}); + +// ************************************************************************************************ + +this.StackFrame = domplate(Firebug.Rep, // XXXjjb Since the repObject is fn the stack does not have correct line numbers +{ + tag: + OBJECTBLOCK( + A({"class": "objectLink objectLink-function focusRow a11yFocus", _repObject: "$object.fn"}, "$object|getCallName"), + " ( ", + FOR("arg", "$object|argIterator", + TAG("$arg.tag", {object: "$arg.value"}), + SPAN({"class": "arrayComma"}, "$arg.delim") + ), + " )", + SPAN({"class": "objectLink-sourceLink objectLink"}, "$object|getSourceLinkTitle") + ), + + getCallName: function(frame) + { + //TODO: xxxpedro reps StackFrame + return frame.name || "anonymous"; + + //return getFunctionName(frame.script, frame.context); + }, + + getSourceLinkTitle: function(frame) + { + //TODO: xxxpedro reps StackFrame + var fileName = cropString(getFileName(frame.href), 20); + return fileName + (frame.lineNo ? " (line " + frame.lineNo + ")" : ""); + + var fileName = cropString(getFileName(frame.href), 17); + return $STRF("Line", [fileName, frame.lineNo]); + }, + + argIterator: function(frame) + { + if (!frame.args) + return []; + + var items = []; + + for (var i = 0; i < frame.args.length; ++i) + { + var arg = frame.args[i]; + + if (!arg) + break; + + var rep = Firebug.getRep(arg.value); + var tag = rep.shortTag ? rep.shortTag : rep.tag; + + var delim = (i == frame.args.length-1 ? "" : ", "); + + items.push({name: arg.name, value: arg.value, tag: tag, delim: delim}); + } + + return items; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "stackFrame", + + supportsObject: function(object) + { + return object instanceof StackFrame; + }, + + inspectObject: function(stackFrame, context) + { + var sourceLink = new SourceLink(stackFrame.href, stackFrame.lineNo, "js"); + Firebug.chrome.select(sourceLink); + }, + + getTooltip: function(stackFrame, context) + { + return $STRF("Line", [stackFrame.href, stackFrame.lineNo]); + } + +}); + +// ************************************************************************************************ + +this.StackTrace = domplate(Firebug.Rep, +{ + tag: + FOR("frame", "$object.frames focusRow", + TAG(this.StackFrame.tag, {object: "$frame"}) + ), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "stackTrace", + + supportsObject: function(object) + { + return object instanceof StackTrace; + } +}); + +// ************************************************************************************************ + +this.jsdStackFrame = domplate(Firebug.Rep, +{ + inspectable: false, + + supportsObject: function(object) + { + return (object instanceof jsdIStackFrame) && (object.isValid); + }, + + getTitle: function(frame, context) + { + if (!frame.isValid) return "(invalid frame)"; // XXXjjb avoid frame.script == null + return getFunctionName(frame.script, context); + }, + + getTooltip: function(frame, context) + { + if (!frame.isValid) return "(invalid frame)"; // XXXjjb avoid frame.script == null + var sourceInfo = FBL.getSourceFileAndLineByScript(context, frame.script, frame); + if (sourceInfo) + return $STRF("Line", [sourceInfo.sourceFile.href, sourceInfo.lineNo]); + else + return $STRF("Line", [frame.script.fileName, frame.line]); + }, + + getContextMenuItems: function(frame, target, context) + { + var fn = frame.script.functionObject.getWrappedValue(); + return FirebugReps.Func.getContextMenuItems(fn, target, context, frame.script); + } +}); + +// ************************************************************************************************ + +this.ErrorMessage = domplate(Firebug.Rep, +{ + tag: + OBJECTBOX({ + $hasTwisty: "$object|hasStackTrace", + $hasBreakSwitch: "$object|hasBreakSwitch", + $breakForError: "$object|hasErrorBreak", + _repObject: "$object", + _stackTrace: "$object|getLastErrorStackTrace", + onclick: "$onToggleError"}, + + DIV({"class": "errorTitle a11yFocus", role : 'checkbox', 'aria-checked' : 'false'}, + "$object.message|getMessage" + ), + DIV({"class": "errorTrace"}), + DIV({"class": "errorSourceBox errorSource-$object|getSourceType"}, + IMG({"class": "errorBreak a11yFocus", src:"blank.gif", role : 'checkbox', 'aria-checked':'false', title: "Break on this error"}), + A({"class": "errorSource a11yFocus"}, "$object|getLine") + ), + TAG(this.SourceLink.tag, {object: "$object|getSourceLink"}) + ), + + getLastErrorStackTrace: function(error) + { + return error.trace; + }, + + hasStackTrace: function(error) + { + var url = error.href.toString(); + var fromCommandLine = (url.indexOf("XPCSafeJSObjectWrapper") != -1); + return !fromCommandLine && error.trace; + }, + + hasBreakSwitch: function(error) + { + return error.href && error.lineNo > 0; + }, + + hasErrorBreak: function(error) + { + return fbs.hasErrorBreakpoint(error.href, error.lineNo); + }, + + getMessage: function(message) + { + var re = /\[Exception... "(.*?)" nsresult:/; + var m = re.exec(message); + return m ? m[1] : message; + }, + + getLine: function(error) + { + if (error.category == "js") + { + if (error.source) + return cropString(error.source, 80); + else if (error.href && error.href.indexOf("XPCSafeJSObjectWrapper") == -1) + return cropString(error.getSourceLine(), 80); + } + }, + + getSourceLink: function(error) + { + var ext = error.category == "css" ? "css" : "js"; + return error.lineNo ? new SourceLink(error.href, error.lineNo, ext) : null; + }, + + getSourceType: function(error) + { + // Errors occurring inside of HTML event handlers look like "foo.html (line 1)" + // so let's try to skip those + if (error.source) + return "syntax"; + else if (error.lineNo == 1 && getFileExtension(error.href) != "js") + return "none"; + else if (error.category == "css") + return "none"; + else if (!error.href || !error.lineNo) + return "none"; + else + return "exec"; + }, + + onToggleError: function(event) + { + var target = event.currentTarget; + if (hasClass(event.target, "errorBreak")) + { + this.breakOnThisError(target.repObject); + } + else if (hasClass(event.target, "errorSource")) + { + var panel = Firebug.getElementPanel(event.target); + this.inspectObject(target.repObject, panel.context); + } + else if (hasClass(event.target, "errorTitle")) + { + var traceBox = target.childNodes[1]; + toggleClass(target, "opened"); + event.target.setAttribute('aria-checked', hasClass(target, "opened")); + if (hasClass(target, "opened")) + { + if (target.stackTrace) + var node = FirebugReps.StackTrace.tag.append({object: target.stackTrace}, traceBox); + if (Firebug.A11yModel.enabled) + { + var panel = Firebug.getElementPanel(event.target); + dispatch([Firebug.A11yModel], "onLogRowContentCreated", [panel , traceBox]); + } + } + else + clearNode(traceBox); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + copyError: function(error) + { + var message = [ + this.getMessage(error.message), + error.href, + "Line " + error.lineNo + ]; + copyToClipboard(message.join("\n")); + }, + + breakOnThisError: function(error) + { + if (this.hasErrorBreak(error)) + Firebug.Debugger.clearErrorBreakpoint(error.href, error.lineNo); + else + Firebug.Debugger.setErrorBreakpoint(error.href, error.lineNo); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "errorMessage", + inspectable: false, + + supportsObject: function(object) + { + return object instanceof ErrorMessage; + }, + + inspectObject: function(error, context) + { + var sourceLink = this.getSourceLink(error); + FirebugReps.SourceLink.inspectObject(sourceLink, context); + }, + + getContextMenuItems: function(error, target, context) + { + var breakOnThisError = this.hasErrorBreak(error); + + var items = [ + {label: "CopyError", command: bindFixed(this.copyError, this, error) } + ]; + + if (error.category == "css") + { + items.push( + "-", + {label: "BreakOnThisError", type: "checkbox", checked: breakOnThisError, + command: bindFixed(this.breakOnThisError, this, error) }, + + optionMenu("BreakOnAllErrors", "breakOnErrors") + ); + } + + return items; + } +}); + +// ************************************************************************************************ + +this.Assert = domplate(Firebug.Rep, +{ + tag: + DIV( + DIV({"class": "errorTitle"}), + DIV({"class": "assertDescription"}) + ), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "assert", + + inspectObject: function(error, context) + { + var sourceLink = this.getSourceLink(error); + Firebug.chrome.select(sourceLink); + }, + + getContextMenuItems: function(error, target, context) + { + var breakOnThisError = this.hasErrorBreak(error); + + return [ + {label: "CopyError", command: bindFixed(this.copyError, this, error) }, + "-", + {label: "BreakOnThisError", type: "checkbox", checked: breakOnThisError, + command: bindFixed(this.breakOnThisError, this, error) }, + {label: "BreakOnAllErrors", type: "checkbox", checked: Firebug.breakOnErrors, + command: bindFixed(this.breakOnAllErrors, this, error) } + ]; + } +}); + +// ************************************************************************************************ + +this.SourceText = domplate(Firebug.Rep, +{ + tag: + DIV( + FOR("line", "$object|lineIterator", + DIV({"class": "sourceRow", role : "presentation"}, + SPAN({"class": "sourceLine", role : "presentation"}, "$line.lineNo"), + SPAN({"class": "sourceRowText", role : "presentation"}, "$line.text") + ) + ) + ), + + lineIterator: function(sourceText) + { + var maxLineNoChars = (sourceText.lines.length + "").length; + var list = []; + + for (var i = 0; i < sourceText.lines.length; ++i) + { + // Make sure all line numbers are the same width (with a fixed-width font) + var lineNo = (i+1) + ""; + while (lineNo.length < maxLineNoChars) + lineNo = " " + lineNo; + + list.push({lineNo: lineNo, text: sourceText.lines[i]}); + } + + return list; + }, + + getHTML: function(sourceText) + { + return getSourceLineRange(sourceText, 1, sourceText.lines.length); + } +}); + +//************************************************************************************************ +this.nsIDOMHistory = domplate(Firebug.Rep, +{ + tag:OBJECTBOX({onclick: "$showHistory"}, + OBJECTLINK("$object|summarizeHistory") + ), + + className: "nsIDOMHistory", + + summarizeHistory: function(history) + { + try + { + var items = history.length; + return items + " history entries"; + } + catch(exc) + { + return "object does not support history (nsIDOMHistory)"; + } + }, + + showHistory: function(history) + { + try + { + var items = history.length; // if this throws, then unsupported + Firebug.chrome.select(history); + } + catch (exc) + { + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + supportsObject: function(object, type) + { + return (object instanceof Ci.nsIDOMHistory); + } +}); + +// ************************************************************************************************ +this.ApplicationCache = domplate(Firebug.Rep, +{ + tag:OBJECTBOX({onclick: "$showApplicationCache"}, + OBJECTLINK("$object|summarizeCache") + ), + + summarizeCache: function(applicationCache) + { + try + { + return applicationCache.length + " items in offline cache"; + } + catch(exc) + { + return "https://bugzilla.mozilla.org/show_bug.cgi?id=422264"; + } + }, + + showApplicationCache: function(event) + { + openNewTab("https://bugzilla.mozilla.org/show_bug.cgi?id=422264"); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "applicationCache", + + supportsObject: function(object, type) + { + if (Ci.nsIDOMOfflineResourceList) + return (object instanceof Ci.nsIDOMOfflineResourceList); + } + +}); + +this.Storage = domplate(Firebug.Rep, +{ + tag: OBJECTBOX({onclick: "$show"}, OBJECTLINK("$object|summarize")), + + summarize: function(storage) + { + return storage.length +" items in Storage"; + }, + show: function(storage) + { + openNewTab("http://dev.w3.org/html5/webstorage/#storage-0"); + }, + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "Storage", + + supportsObject: function(object, type) + { + return (object instanceof Storage); + } + +}); + +// ************************************************************************************************ +Firebug.registerRep( + //this.nsIDOMHistory, // make this early to avoid exceptions + this.Undefined, + this.Null, + this.Number, + this.String, + this.Window, + //this.ApplicationCache, // must come before Arr (array) else exceptions. + //this.ErrorMessage, + this.Element, + //this.TextNode, + this.Document, + this.StyleSheet, + this.Event, + //this.SourceLink, + //this.SourceFile, + //this.StackTrace, + //this.StackFrame, + //this.jsdStackFrame, + //this.jsdScript, + //this.NetFile, + this.Property, + this.Except, + this.Arr +); + +Firebug.setDefaultReps(this.Func, this.Obj); + +}}); + +// ************************************************************************************************ +/* + * The following is http://developer.yahoo.com/yui/license.txt and applies to only code labeled "Yahoo BSD Source" + * in only this file reps.js. John J. Barton June 2007. + * +Software License Agreement (BSD License) + +Copyright (c) 2006, Yahoo! Inc. +All rights reserved. + +Redistribution and use of this software in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of Yahoo! Inc. nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of Yahoo! Inc. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * / + */ + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// Constants + +var saveTimeout = 400; +var pageAmount = 10; + +// ************************************************************************************************ +// Globals + +var currentTarget = null; +var currentGroup = null; +var currentPanel = null; +var currentEditor = null; + +var defaultEditor = null; + +var originalClassName = null; + +var originalValue = null; +var defaultValue = null; +var previousValue = null; + +var invalidEditor = false; +var ignoreNextInput = false; + +// ************************************************************************************************ + +Firebug.Editor = extend(Firebug.Module, +{ + supportsStopEvent: true, + + dispatchName: "editor", + tabCharacter: " ", + + startEditing: function(target, value, editor) + { + this.stopEditing(); + + if (hasClass(target, "insertBefore") || hasClass(target, "insertAfter")) + return; + + var panel = Firebug.getElementPanel(target); + if (!panel.editable) + return; + + if (FBTrace.DBG_EDITOR) + FBTrace.sysout("editor.startEditing " + value, target); + + defaultValue = target.getAttribute("defaultValue"); + if (value == undefined) + { + var textContent = isIE ? "innerText" : "textContent"; + value = target[textContent]; + if (value == defaultValue) + value = ""; + } + + originalValue = previousValue = value; + + invalidEditor = false; + currentTarget = target; + currentPanel = panel; + currentGroup = getAncestorByClass(target, "editGroup"); + + currentPanel.editing = true; + + var panelEditor = currentPanel.getEditor(target, value); + currentEditor = editor ? editor : panelEditor; + if (!currentEditor) + currentEditor = getDefaultEditor(currentPanel); + + var inlineParent = getInlineParent(target); + var targetSize = getOffsetSize(inlineParent); + + setClass(panel.panelNode, "editing"); + setClass(target, "editing"); + if (currentGroup) + setClass(currentGroup, "editing"); + + currentEditor.show(target, currentPanel, value, targetSize); + //dispatch(this.fbListeners, "onBeginEditing", [currentPanel, currentEditor, target, value]); + currentEditor.beginEditing(target, value); + if (FBTrace.DBG_EDITOR) + FBTrace.sysout("Editor start panel "+currentPanel.name); + this.attachListeners(currentEditor, panel.context); + }, + + stopEditing: function(cancel) + { + if (!currentTarget) + return; + + if (FBTrace.DBG_EDITOR) + FBTrace.sysout("editor.stopEditing cancel:" + cancel+" saveTimeout: "+this.saveTimeout); + + clearTimeout(this.saveTimeout); + delete this.saveTimeout; + + this.detachListeners(currentEditor, currentPanel.context); + + removeClass(currentPanel.panelNode, "editing"); + removeClass(currentTarget, "editing"); + if (currentGroup) + removeClass(currentGroup, "editing"); + + var value = currentEditor.getValue(); + if (value == defaultValue) + value = ""; + + var removeGroup = currentEditor.endEditing(currentTarget, value, cancel); + + try + { + if (cancel) + { + //dispatch([Firebug.A11yModel], 'onInlineEditorClose', [currentPanel, currentTarget, removeGroup && !originalValue]); + if (value != originalValue) + this.saveEditAndNotifyListeners(currentTarget, originalValue, previousValue); + + if (removeGroup && !originalValue && currentGroup) + currentGroup.parentNode.removeChild(currentGroup); + } + else if (!value) + { + this.saveEditAndNotifyListeners(currentTarget, null, previousValue); + + if (removeGroup && currentGroup) + currentGroup.parentNode.removeChild(currentGroup); + } + else + this.save(value); + } + catch (exc) + { + //throw exc.message; + //ERROR(exc); + } + + currentEditor.hide(); + currentPanel.editing = false; + + //dispatch(this.fbListeners, "onStopEdit", [currentPanel, currentEditor, currentTarget]); + //if (FBTrace.DBG_EDITOR) + // FBTrace.sysout("Editor stop panel "+currentPanel.name); + + currentTarget = null; + currentGroup = null; + currentPanel = null; + currentEditor = null; + originalValue = null; + invalidEditor = false; + + return value; + }, + + cancelEditing: function() + { + return this.stopEditing(true); + }, + + update: function(saveNow) + { + if (this.saveTimeout) + clearTimeout(this.saveTimeout); + + invalidEditor = true; + + currentEditor.layout(); + + if (saveNow) + this.save(); + else + { + var context = currentPanel.context; + this.saveTimeout = context.setTimeout(bindFixed(this.save, this), saveTimeout); + if (FBTrace.DBG_EDITOR) + FBTrace.sysout("editor.update saveTimeout: "+this.saveTimeout); + } + }, + + save: function(value) + { + if (!invalidEditor) + return; + + if (value == undefined) + value = currentEditor.getValue(); + if (FBTrace.DBG_EDITOR) + FBTrace.sysout("editor.save saveTimeout: "+this.saveTimeout+" currentPanel: "+(currentPanel?currentPanel.name:"null")); + try + { + this.saveEditAndNotifyListeners(currentTarget, value, previousValue); + + previousValue = value; + invalidEditor = false; + } + catch (exc) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("editor.save FAILS "+exc, exc); + } + }, + + saveEditAndNotifyListeners: function(currentTarget, value, previousValue) + { + currentEditor.saveEdit(currentTarget, value, previousValue); + //dispatch(this.fbListeners, "onSaveEdit", [currentPanel, currentEditor, currentTarget, value, previousValue]); + }, + + setEditTarget: function(element) + { + if (!element) + { + dispatch([Firebug.A11yModel], 'onInlineEditorClose', [currentPanel, currentTarget, true]); + this.stopEditing(); + } + else if (hasClass(element, "insertBefore")) + this.insertRow(element, "before"); + else if (hasClass(element, "insertAfter")) + this.insertRow(element, "after"); + else + this.startEditing(element); + }, + + tabNextEditor: function() + { + if (!currentTarget) + return; + + var value = currentEditor.getValue(); + var nextEditable = currentTarget; + do + { + nextEditable = !value && currentGroup + ? getNextOutsider(nextEditable, currentGroup) + : getNextByClass(nextEditable, "editable"); + } + while (nextEditable && !nextEditable.offsetHeight); + + this.setEditTarget(nextEditable); + }, + + tabPreviousEditor: function() + { + if (!currentTarget) + return; + + var value = currentEditor.getValue(); + var prevEditable = currentTarget; + do + { + prevEditable = !value && currentGroup + ? getPreviousOutsider(prevEditable, currentGroup) + : getPreviousByClass(prevEditable, "editable"); + } + while (prevEditable && !prevEditable.offsetHeight); + + this.setEditTarget(prevEditable); + }, + + insertRow: function(relative, insertWhere) + { + var group = + relative || getAncestorByClass(currentTarget, "editGroup") || currentTarget; + var value = this.stopEditing(); + + currentPanel = Firebug.getElementPanel(group); + + currentEditor = currentPanel.getEditor(group, value); + if (!currentEditor) + currentEditor = getDefaultEditor(currentPanel); + + currentGroup = currentEditor.insertNewRow(group, insertWhere); + if (!currentGroup) + return; + + var editable = hasClass(currentGroup, "editable") + ? currentGroup + : getNextByClass(currentGroup, "editable"); + + if (editable) + this.setEditTarget(editable); + }, + + insertRowForObject: function(relative) + { + var container = getAncestorByClass(relative, "insertInto"); + if (container) + { + relative = getChildByClass(container, "insertBefore"); + if (relative) + this.insertRow(relative, "before"); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + attachListeners: function(editor, context) + { + var win = isIE ? + currentTarget.ownerDocument.parentWindow : + currentTarget.ownerDocument.defaultView; + + addEvent(win, "resize", this.onResize); + addEvent(win, "blur", this.onBlur); + + var chrome = Firebug.chrome; + + this.listeners = [ + chrome.keyCodeListen("ESCAPE", null, bind(this.cancelEditing, this)) + ]; + + if (editor.arrowCompletion) + { + this.listeners.push( + chrome.keyCodeListen("UP", null, bindFixed(editor.completeValue, editor, -1)), + chrome.keyCodeListen("DOWN", null, bindFixed(editor.completeValue, editor, 1)), + chrome.keyCodeListen("PAGE_UP", null, bindFixed(editor.completeValue, editor, -pageAmount)), + chrome.keyCodeListen("PAGE_DOWN", null, bindFixed(editor.completeValue, editor, pageAmount)) + ); + } + + if (currentEditor.tabNavigation) + { + this.listeners.push( + chrome.keyCodeListen("RETURN", null, bind(this.tabNextEditor, this)), + chrome.keyCodeListen("RETURN", isControl, bind(this.insertRow, this, null, "after")), + chrome.keyCodeListen("TAB", null, bind(this.tabNextEditor, this)), + chrome.keyCodeListen("TAB", isShift, bind(this.tabPreviousEditor, this)) + ); + } + else if (currentEditor.multiLine) + { + this.listeners.push( + chrome.keyCodeListen("TAB", null, insertTab) + ); + } + else + { + this.listeners.push( + chrome.keyCodeListen("RETURN", null, bindFixed(this.stopEditing, this)) + ); + + if (currentEditor.tabCompletion) + { + this.listeners.push( + chrome.keyCodeListen("TAB", null, bind(editor.completeValue, editor, 1)), + chrome.keyCodeListen("TAB", isShift, bind(editor.completeValue, editor, -1)) + ); + } + } + }, + + detachListeners: function(editor, context) + { + if (!this.listeners) + return; + + var win = isIE ? + currentTarget.ownerDocument.parentWindow : + currentTarget.ownerDocument.defaultView; + + removeEvent(win, "resize", this.onResize); + removeEvent(win, "blur", this.onBlur); + + var chrome = Firebug.chrome; + if (chrome) + { + for (var i = 0; i < this.listeners.length; ++i) + chrome.keyIgnore(this.listeners[i]); + } + + delete this.listeners; + }, + + onResize: function(event) + { + currentEditor.layout(true); + }, + + onBlur: function(event) + { + if (currentEditor.enterOnBlur && isAncestor(event.target, currentEditor.box)) + this.stopEditing(); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Module + + initialize: function() + { + Firebug.Module.initialize.apply(this, arguments); + + this.onResize = bindFixed(this.onResize, this); + this.onBlur = bind(this.onBlur, this); + }, + + disable: function() + { + this.stopEditing(); + }, + + showContext: function(browser, context) + { + this.stopEditing(); + }, + + showPanel: function(browser, panel) + { + this.stopEditing(); + } +}); + +// ************************************************************************************************ +// BaseEditor + +Firebug.BaseEditor = extend(Firebug.MeasureBox, +{ + getValue: function() + { + }, + + setValue: function(value) + { + }, + + show: function(target, panel, value, textSize, targetSize) + { + }, + + hide: function() + { + }, + + layout: function(forceAll) + { + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Support for context menus within inline editors. + + getContextMenuItems: function(target) + { + var items = []; + items.push({label: "Cut", commandID: "cmd_cut"}); + items.push({label: "Copy", commandID: "cmd_copy"}); + items.push({label: "Paste", commandID: "cmd_paste"}); + return items; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Editor Module listeners will get "onBeginEditing" just before this call + + beginEditing: function(target, value) + { + }, + + // Editor Module listeners will get "onSaveEdit" just after this call + saveEdit: function(target, value, previousValue) + { + }, + + endEditing: function(target, value, cancel) + { + // Remove empty groups by default + return true; + }, + + insertNewRow: function(target, insertWhere) + { + } +}); + +// ************************************************************************************************ +// InlineEditor + +// basic inline editor attributes +var inlineEditorAttributes = { + "class": "textEditorInner", + + type: "text", + spellcheck: "false", + + onkeypress: "$onKeyPress", + + onoverflow: "$onOverflow", + oncontextmenu: "$onContextMenu" +}; + +// IE does not support the oninput event, so we're using the onkeydown to signalize +// the relevant keyboard events, and the onpropertychange to actually handle the +// input event, which should happen after the onkeydown event is fired and after the +// value of the input is updated, but before the onkeyup and before the input (with the +// new value) is rendered +if (isIE) +{ + inlineEditorAttributes.onpropertychange = "$onInput"; + inlineEditorAttributes.onkeydown = "$onKeyDown"; +} +// for other browsers we use the oninput event +else +{ + inlineEditorAttributes.oninput = "$onInput"; +} + +Firebug.InlineEditor = function(doc) +{ + this.initializeInline(doc); +}; + +Firebug.InlineEditor.prototype = domplate(Firebug.BaseEditor, +{ + enterOnBlur: true, + outerMargin: 8, + shadowExpand: 7, + + tag: + DIV({"class": "inlineEditor"}, + DIV({"class": "textEditorTop1"}, + DIV({"class": "textEditorTop2"}) + ), + DIV({"class": "textEditorInner1"}, + DIV({"class": "textEditorInner2"}, + INPUT( + inlineEditorAttributes + ) + ) + ), + DIV({"class": "textEditorBottom1"}, + DIV({"class": "textEditorBottom2"}) + ) + ), + + inputTag : + INPUT({"class": "textEditorInner", type: "text", + /*oninput: "$onInput",*/ onkeypress: "$onKeyPress", onoverflow: "$onOverflow"} + ), + + expanderTag: + IMG({"class": "inlineExpander", src: "blank.gif"}), + + initialize: function() + { + this.fixedWidth = false; + this.completeAsYouType = true; + this.tabNavigation = true; + this.multiLine = false; + this.tabCompletion = false; + this.arrowCompletion = true; + this.noWrap = true; + this.numeric = false; + }, + + destroy: function() + { + this.destroyInput(); + }, + + initializeInline: function(doc) + { + if (FBTrace.DBG_EDITOR) + FBTrace.sysout("Firebug.InlineEditor initializeInline()"); + + //this.box = this.tag.replace({}, doc, this); + this.box = this.tag.append({}, doc.body, this); + + //this.input = this.box.childNodes[1].firstChild.firstChild; // XXXjjb childNode[1] required + this.input = this.box.getElementsByTagName("input")[0]; + + if (isIElt8) + { + this.input.style.top = "-8px"; + } + + this.expander = this.expanderTag.replace({}, doc, this); + this.initialize(); + }, + + destroyInput: function() + { + // XXXjoe Need to remove input/keypress handlers to avoid leaks + }, + + getValue: function() + { + return this.input.value; + }, + + setValue: function(value) + { + // It's only a one-line editor, so new lines shouldn't be allowed + return this.input.value = stripNewLines(value); + }, + + show: function(target, panel, value, targetSize) + { + //dispatch([Firebug.A11yModel], "onInlineEditorShow", [panel, this]); + this.target = target; + this.panel = panel; + + this.targetSize = targetSize; + + // TODO: xxxpedro editor + //this.targetOffset = getClientOffset(target); + + // Some browsers (IE, Google Chrome and Safari) will have problem trying to get the + // offset values of invisible elements, or empty elements. So, in order to get the + // correct values, we temporary inject a character in the innerHTML of the empty element, + // then we get the offset values, and next, we restore the original innerHTML value. + var innerHTML = target.innerHTML; + var isEmptyElement = !innerHTML; + if (isEmptyElement) + target.innerHTML = "."; + + // Get the position of the target element (that is about to be edited) + this.targetOffset = + { + x: target.offsetLeft, + y: target.offsetTop + }; + + // Restore the original innerHTML value of the empty element + if (isEmptyElement) + target.innerHTML = innerHTML; + + this.originalClassName = this.box.className; + + var classNames = target.className.split(" "); + for (var i = 0; i < classNames.length; ++i) + setClass(this.box, "editor-" + classNames[i]); + + // Make the editor match the target's font style + copyTextStyles(target, this.box); + + this.setValue(value); + + if (this.fixedWidth) + this.updateLayout(true); + else + { + this.startMeasuring(target); + this.textSize = this.measureInputText(value); + + // Correct the height of the box to make the funky CSS drop-shadow line up + var parent = this.input.parentNode; + if (hasClass(parent, "textEditorInner2")) + { + var yDiff = this.textSize.height - this.shadowExpand; + + // IE6 height offset + if (isIE6) + yDiff -= 2; + + parent.style.height = yDiff + "px"; + parent.parentNode.style.height = yDiff + "px"; + } + + this.updateLayout(true); + } + + this.getAutoCompleter().reset(); + + if (isIElt8) + panel.panelNode.appendChild(this.box); + else + target.offsetParent.appendChild(this.box); + + //console.log(target); + //this.input.select(); // it's called bellow, with setTimeout + + if (isIE) + { + // reset input style + this.input.style.fontFamily = "Monospace"; + this.input.style.fontSize = "11px"; + } + + // Insert the "expander" to cover the target element with white space + if (!this.fixedWidth) + { + copyBoxStyles(target, this.expander); + + target.parentNode.replaceChild(this.expander, target); + collapse(target, true); + this.expander.parentNode.insertBefore(target, this.expander); + } + + //TODO: xxxpedro + //scrollIntoCenterView(this.box, null, true); + + // Display the editor after change its size and position to avoid flickering + this.box.style.display = "block"; + + // we need to call input.focus() and input.select() with a timeout, + // otherwise it won't work on all browsers due to timing issues + var self = this; + setTimeout(function(){ + self.input.focus(); + self.input.select(); + },0); + }, + + hide: function() + { + this.box.className = this.originalClassName; + + if (!this.fixedWidth) + { + this.stopMeasuring(); + + collapse(this.target, false); + + if (this.expander.parentNode) + this.expander.parentNode.removeChild(this.expander); + } + + if (this.box.parentNode) + { + ///setSelectionRange(this.input, 0, 0); + this.input.blur(); + + this.box.parentNode.removeChild(this.box); + } + + delete this.target; + delete this.panel; + }, + + layout: function(forceAll) + { + if (!this.fixedWidth) + this.textSize = this.measureInputText(this.input.value); + + if (forceAll) + this.targetOffset = getClientOffset(this.expander); + + this.updateLayout(false, forceAll); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + beginEditing: function(target, value) + { + }, + + saveEdit: function(target, value, previousValue) + { + }, + + endEditing: function(target, value, cancel) + { + // Remove empty groups by default + return true; + }, + + insertNewRow: function(target, insertWhere) + { + }, + + advanceToNext: function(target, charCode) + { + return false; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getAutoCompleteRange: function(value, offset) + { + }, + + getAutoCompleteList: function(preExpr, expr, postExpr) + { + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getAutoCompleter: function() + { + if (!this.autoCompleter) + { + this.autoCompleter = new Firebug.AutoCompleter(null, + bind(this.getAutoCompleteRange, this), bind(this.getAutoCompleteList, this), + true, false); + } + + return this.autoCompleter; + }, + + completeValue: function(amt) + { + //console.log("completeValue"); + + var selectRangeCallback = this.getAutoCompleter().complete(currentPanel.context, this.input, true, amt < 0); + + if (selectRangeCallback) + { + Firebug.Editor.update(true); + + // We need to select the editor text after calling update in Safari/Chrome, + // otherwise the text won't be selected + if (isSafari) + setTimeout(selectRangeCallback,0); + else + selectRangeCallback(); + } + else + this.incrementValue(amt); + }, + + incrementValue: function(amt) + { + var value = this.input.value; + + // TODO: xxxpedro editor + if (isIE) + var start = getInputSelectionStart(this.input), end = start; + else + var start = this.input.selectionStart, end = this.input.selectionEnd; + + //debugger; + var range = this.getAutoCompleteRange(value, start); + if (!range || range.type != "int") + range = {start: 0, end: value.length-1}; + + var expr = value.substr(range.start, range.end-range.start+1); + preExpr = value.substr(0, range.start); + postExpr = value.substr(range.end+1); + + // See if the value is an integer, and if so increment it + var intValue = parseInt(expr); + if (!!intValue || intValue == 0) + { + var m = /\d+/.exec(expr); + var digitPost = expr.substr(m.index+m[0].length); + + var completion = intValue-amt; + this.input.value = preExpr + completion + digitPost + postExpr; + + setSelectionRange(this.input, start, end); + + Firebug.Editor.update(true); + + return true; + } + else + return false; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + onKeyPress: function(event) + { + //console.log("onKeyPress", event); + if (event.keyCode == 27 && !this.completeAsYouType) + { + var reverted = this.getAutoCompleter().revert(this.input); + if (reverted) + cancelEvent(event); + } + else if (event.charCode && this.advanceToNext(this.target, event.charCode)) + { + Firebug.Editor.tabNextEditor(); + cancelEvent(event); + } + else + { + if (this.numeric && event.charCode && (event.charCode < 48 || event.charCode > 57) + && event.charCode != 45 && event.charCode != 46) + FBL.cancelEvent(event); + else + { + // If the user backspaces, don't autocomplete after the upcoming input event + this.ignoreNextInput = event.keyCode == 8; + } + } + }, + + onOverflow: function() + { + this.updateLayout(false, false, 3); + }, + + onKeyDown: function(event) + { + //console.log("onKeyDown", event.keyCode); + if (event.keyCode > 46 || event.keyCode == 32 || event.keyCode == 8) + { + this.keyDownPressed = true; + } + }, + + onInput: function(event) + { + //debugger; + + // skip not relevant onpropertychange calls on IE + if (isIE) + { + if (event.propertyName != "value" || !isVisible(this.input) || !this.keyDownPressed) + return; + + this.keyDownPressed = false; + } + + //console.log("onInput", event); + //console.trace(); + + var selectRangeCallback; + + if (this.ignoreNextInput) + { + this.ignoreNextInput = false; + this.getAutoCompleter().reset(); + } + else if (this.completeAsYouType) + selectRangeCallback = this.getAutoCompleter().complete(currentPanel.context, this.input, false); + else + this.getAutoCompleter().reset(); + + Firebug.Editor.update(); + + if (selectRangeCallback) + { + // We need to select the editor text after calling update in Safari/Chrome, + // otherwise the text won't be selected + if (isSafari) + setTimeout(selectRangeCallback,0); + else + selectRangeCallback(); + } + }, + + onContextMenu: function(event) + { + cancelEvent(event); + + var popup = $("fbInlineEditorPopup"); + FBL.eraseNode(popup); + + var target = event.target || event.srcElement; + var menu = this.getContextMenuItems(target); + if (menu) + { + for (var i = 0; i < menu.length; ++i) + FBL.createMenuItem(popup, menu[i]); + } + + if (!popup.firstChild) + return false; + + popup.openPopupAtScreen(event.screenX, event.screenY, true); + return true; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + updateLayout: function(initial, forceAll, extraWidth) + { + if (this.fixedWidth) + { + this.box.style.left = (this.targetOffset.x) + "px"; + this.box.style.top = (this.targetOffset.y) + "px"; + + var w = this.target.offsetWidth; + var h = this.target.offsetHeight; + this.input.style.width = w + "px"; + this.input.style.height = (h-3) + "px"; + } + else + { + if (initial || forceAll) + { + this.box.style.left = this.targetOffset.x + "px"; + this.box.style.top = this.targetOffset.y + "px"; + } + + var approxTextWidth = this.textSize.width; + var maxWidth = (currentPanel.panelNode.scrollWidth - this.targetOffset.x) + - this.outerMargin; + + var wrapped = initial + ? this.noWrap && this.targetSize.height > this.textSize.height+3 + : this.noWrap && approxTextWidth > maxWidth; + + if (wrapped) + { + var style = isIE ? + this.target.currentStyle : + this.target.ownerDocument.defaultView.getComputedStyle(this.target, ""); + + targetMargin = parseInt(style.marginLeft) + parseInt(style.marginRight); + + // Make the width fit the remaining x-space from the offset to the far right + approxTextWidth = maxWidth - targetMargin; + + this.input.style.width = "100%"; + this.box.style.width = approxTextWidth + "px"; + } + else + { + // Make the input one character wider than the text value so that + // typing does not ever cause the textbox to scroll + var charWidth = this.measureInputText('m').width; + + // Sometimes we need to make the editor a little wider, specifically when + // an overflow happens, otherwise it will scroll off some text on the left + if (extraWidth) + charWidth *= extraWidth; + + var inputWidth = approxTextWidth + charWidth; + + if (initial) + { + if (isIE) + { + // TODO: xxxpedro + var xDiff = 13; + this.box.style.width = (inputWidth + xDiff) + "px"; + } + else + this.box.style.width = "auto"; + } + else + { + // TODO: xxxpedro + var xDiff = isIE ? 13: this.box.scrollWidth - this.input.offsetWidth; + this.box.style.width = (inputWidth + xDiff) + "px"; + } + + this.input.style.width = inputWidth + "px"; + } + + this.expander.style.width = approxTextWidth + "px"; + this.expander.style.height = Math.max(this.textSize.height-3,0) + "px"; + } + + if (forceAll) + scrollIntoCenterView(this.box, null, true); + } +}); + +// ************************************************************************************************ +// Autocompletion + +Firebug.AutoCompleter = function(getExprOffset, getRange, evaluator, selectMode, caseSensitive) +{ + var candidates = null; + var originalValue = null; + var originalOffset = -1; + var lastExpr = null; + var lastOffset = -1; + var exprOffset = 0; + var lastIndex = 0; + var preParsed = null; + var preExpr = null; + var postExpr = null; + + this.revert = function(textBox) + { + if (originalOffset != -1) + { + textBox.value = originalValue; + + setSelectionRange(textBox, originalOffset, originalOffset); + + this.reset(); + return true; + } + else + { + this.reset(); + return false; + } + }; + + this.reset = function() + { + candidates = null; + originalValue = null; + originalOffset = -1; + lastExpr = null; + lastOffset = 0; + exprOffset = 0; + }; + + this.complete = function(context, textBox, cycle, reverse) + { + //console.log("complete", context, textBox, cycle, reverse); + // TODO: xxxpedro important port to firebug (variable leak) + //var value = lastValue = textBox.value; + var value = textBox.value; + + //var offset = textBox.selectionStart; + var offset = getInputSelectionStart(textBox); + + // The result of selectionStart() in Safari/Chrome is 1 unit less than the result + // in Firefox. Therefore, we need to manually adjust the value here. + if (isSafari && !cycle && offset >= 0) offset++; + + if (!selectMode && originalOffset != -1) + offset = originalOffset; + + if (!candidates || !cycle || offset != lastOffset) + { + originalOffset = offset; + originalValue = value; + + // Find the part of the string that will be parsed + var parseStart = getExprOffset ? getExprOffset(value, offset, context) : 0; + preParsed = value.substr(0, parseStart); + var parsed = value.substr(parseStart); + + // Find the part of the string that is being completed + var range = getRange ? getRange(parsed, offset-parseStart, context) : null; + if (!range) + range = {start: 0, end: parsed.length-1 }; + + var expr = parsed.substr(range.start, range.end-range.start+1); + preExpr = parsed.substr(0, range.start); + postExpr = parsed.substr(range.end+1); + exprOffset = parseStart + range.start; + + if (!cycle) + { + if (!expr) + return; + else if (lastExpr && lastExpr.indexOf(expr) != 0) + { + candidates = null; + } + else if (lastExpr && lastExpr.length >= expr.length) + { + candidates = null; + lastExpr = expr; + return; + } + } + + lastExpr = expr; + lastOffset = offset; + + var searchExpr; + + // Check if the cursor is at the very right edge of the expression, or + // somewhere in the middle of it + if (expr && offset != parseStart+range.end+1) + { + if (cycle) + { + // We are in the middle of the expression, but we can + // complete by cycling to the next item in the values + // list after the expression + offset = range.start; + searchExpr = expr; + expr = ""; + } + else + { + // We can't complete unless we are at the ridge edge + return; + } + } + + var values = evaluator(preExpr, expr, postExpr, context); + if (!values) + return; + + if (expr) + { + // Filter the list of values to those which begin with expr. We + // will then go on to complete the first value in the resulting list + candidates = []; + + if (caseSensitive) + { + for (var i = 0; i < values.length; ++i) + { + var name = values[i]; + if (name.indexOf && name.indexOf(expr) == 0) + candidates.push(name); + } + } + else + { + var lowerExpr = caseSensitive ? expr : expr.toLowerCase(); + for (var i = 0; i < values.length; ++i) + { + var name = values[i]; + if (name.indexOf && name.toLowerCase().indexOf(lowerExpr) == 0) + candidates.push(name); + } + } + + lastIndex = reverse ? candidates.length-1 : 0; + } + else if (searchExpr) + { + var searchIndex = -1; + + // Find the first instance of searchExpr in the values list. We + // will then complete the string that is found + if (caseSensitive) + { + searchIndex = values.indexOf(expr); + } + else + { + var lowerExpr = searchExpr.toLowerCase(); + for (var i = 0; i < values.length; ++i) + { + var name = values[i]; + if (name && name.toLowerCase().indexOf(lowerExpr) == 0) + { + searchIndex = i; + break; + } + } + } + + // Nothing found, so there's nothing to complete to + if (searchIndex == -1) + return this.reset(); + + expr = searchExpr; + candidates = cloneArray(values); + lastIndex = searchIndex; + } + else + { + expr = ""; + candidates = []; + for (var i = 0; i < values.length; ++i) + { + if (values[i].substr) + candidates.push(values[i]); + } + lastIndex = -1; + } + } + + if (cycle) + { + expr = lastExpr; + lastIndex += reverse ? -1 : 1; + } + + if (!candidates.length) + return; + + if (lastIndex >= candidates.length) + lastIndex = 0; + else if (lastIndex < 0) + lastIndex = candidates.length-1; + + var completion = candidates[lastIndex]; + var preCompletion = expr.substr(0, offset-exprOffset); + var postCompletion = completion.substr(offset-exprOffset); + + textBox.value = preParsed + preExpr + preCompletion + postCompletion + postExpr; + var offsetEnd = preParsed.length + preExpr.length + completion.length; + + // TODO: xxxpedro remove the following commented code, if the lib.setSelectionRange() + // is working well. + /* + if (textBox.setSelectionRange) + { + // we must select the range with a timeout, otherwise the text won't + // be properly selected (because after this function executes, the editor's + // input will be resized to fit the whole text) + setTimeout(function(){ + if (selectMode) + textBox.setSelectionRange(offset, offsetEnd); + else + textBox.setSelectionRange(offsetEnd, offsetEnd); + },0); + } + /**/ + + // we must select the range with a timeout, otherwise the text won't + // be properly selected (because after this function executes, the editor's + // input will be resized to fit the whole text) + /* + setTimeout(function(){ + if (selectMode) + setSelectionRange(textBox, offset, offsetEnd); + else + setSelectionRange(textBox, offsetEnd, offsetEnd); + },0); + + return true; + /**/ + + // The editor text should be selected only after calling the editor.update() + // in Safari/Chrome, otherwise the text won't be selected. So, we're returning + // a function to be called later (in the proper time for all browsers). + // + // TODO: xxxpedro see if we can move the editor.update() calls to here, and avoid + // returning a closure. the complete() function seems to be called only twice in + // editor.js. See if this function is called anywhere else (like css.js for example). + return function(){ + //console.log("autocomplete ", textBox, offset, offsetEnd); + + if (selectMode) + setSelectionRange(textBox, offset, offsetEnd); + else + setSelectionRange(textBox, offsetEnd, offsetEnd); + }; + /**/ + }; +}; + +// ************************************************************************************************ +// Local Helpers + +var getDefaultEditor = function getDefaultEditor(panel) +{ + if (!defaultEditor) + { + var doc = panel.document; + defaultEditor = new Firebug.InlineEditor(doc); + } + + return defaultEditor; +} + +/** + * An outsider is the first element matching the stepper element that + * is not an child of group. Elements tagged with insertBefore or insertAfter + * classes are also excluded from these results unless they are the sibling + * of group, relative to group's parent editGroup. This allows for the proper insertion + * rows when groups are nested. + */ +var getOutsider = function getOutsider(element, group, stepper) +{ + var parentGroup = getAncestorByClass(group.parentNode, "editGroup"); + var next; + do + { + next = stepper(next || element); + } + while (isAncestor(next, group) || isGroupInsert(next, parentGroup)); + + return next; +} + +var isGroupInsert = function isGroupInsert(next, group) +{ + return (!group || isAncestor(next, group)) + && (hasClass(next, "insertBefore") || hasClass(next, "insertAfter")); +} + +var getNextOutsider = function getNextOutsider(element, group) +{ + return getOutsider(element, group, bind(getNextByClass, FBL, "editable")); +} + +var getPreviousOutsider = function getPreviousOutsider(element, group) +{ + return getOutsider(element, group, bind(getPreviousByClass, FBL, "editable")); +} + +var getInlineParent = function getInlineParent(element) +{ + var lastInline = element; + for (; element; element = element.parentNode) + { + //var s = element.ownerDocument.defaultView.getComputedStyle(element, ""); + var s = isIE ? + element.currentStyle : + element.ownerDocument.defaultView.getComputedStyle(element, ""); + + if (s.display != "inline") + return lastInline; + else + lastInline = element; + } + return null; +} + +var insertTab = function insertTab() +{ + insertTextIntoElement(currentEditor.input, Firebug.Editor.tabCharacter); +} + +// ************************************************************************************************ + +Firebug.registerModule(Firebug.Editor); + +// ************************************************************************************************ + +}}); + + +/* 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(); + + 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" ? FirebugChrome.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 + + + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +// next-generation Console Panel (will override consoje.js) +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +// Constants + +/* +const Cc = Components.classes; +const Ci = Components.interfaces; +const nsIPrefBranch2 = Ci.nsIPrefBranch2; +const PrefService = Cc["@mozilla.org/preferences-service;1"]; +const prefs = PrefService.getService(nsIPrefBranch2); +/**/ +/* + +// new offline message handler +o = {x:1,y:2}; + +r = Firebug.getRep(o); + +r.tag.tag.compile(); + +outputs = []; +html = r.tag.renderHTML({object:o}, outputs); + + +// finish rendering the template (the DOM part) +target = $("build"); +target.innerHTML = html; +root = target.firstChild; + +domArgs = [root, r.tag.context, 0]; +domArgs.push.apply(domArgs, r.tag.domArgs); +domArgs.push.apply(domArgs, outputs); +r.tag.tag.renderDOM.apply(self ? self : r.tag.subject, domArgs); + + + */ +var consoleQueue = []; +var lastHighlightedObject; +var FirebugContext = Env.browser; + +// ************************************************************************************************ + +var maxQueueRequests = 500; + +// ************************************************************************************************ + +Firebug.ConsoleBase = +{ + log: function(object, context, className, rep, noThrottle, sourceLink) + { + //dispatch(this.fbListeners,"log",[context, object, className, sourceLink]); + return this.logRow(appendObject, object, context, className, rep, sourceLink, noThrottle); + }, + + logFormatted: function(objects, context, className, noThrottle, sourceLink) + { + //dispatch(this.fbListeners,"logFormatted",[context, objects, className, sourceLink]); + return this.logRow(appendFormatted, objects, context, className, null, sourceLink, noThrottle); + }, + + openGroup: function(objects, context, className, rep, noThrottle, sourceLink, noPush) + { + return this.logRow(appendOpenGroup, objects, context, className, rep, sourceLink, noThrottle); + }, + + closeGroup: function(context, noThrottle) + { + return this.logRow(appendCloseGroup, null, context, null, null, null, noThrottle, true); + }, + + logRow: function(appender, objects, context, className, rep, sourceLink, noThrottle, noRow) + { + // TODO: xxxpedro console console2 + noThrottle = true; // xxxpedro forced because there is no TabContext yet + + if (!context) + context = FirebugContext; + + if (FBTrace.DBG_ERRORS && !context) + FBTrace.sysout("Console.logRow has no context, skipping objects", objects); + + if (!context) + return; + + if (noThrottle || !context) + { + var panel = this.getPanel(context); + if (panel) + { + var row = panel.append(appender, objects, className, rep, sourceLink, noRow); + var container = panel.panelNode; + + // TODO: xxxpedro what is this? console console2 + /* + var template = Firebug.NetMonitor.NetLimit; + + while (container.childNodes.length > maxQueueRequests + 1) + { + clearDomplate(container.firstChild.nextSibling); + container.removeChild(container.firstChild.nextSibling); + panel.limit.limitInfo.totalCount++; + template.updateCounter(panel.limit); + } + dispatch([Firebug.A11yModel], "onLogRowCreated", [panel , row]); + /**/ + return row; + } + else + { + consoleQueue.push([appender, objects, context, className, rep, sourceLink, noThrottle, noRow]); + } + } + else + { + if (!context.throttle) + { + //FBTrace.sysout("console.logRow has not context.throttle! "); + return; + } + var args = [appender, objects, context, className, rep, sourceLink, true, noRow]; + context.throttle(this.logRow, this, args); + } + }, + + appendFormatted: function(args, row, context) + { + if (!context) + context = FirebugContext; + + var panel = this.getPanel(context); + panel.appendFormatted(args, row); + }, + + clear: function(context) + { + if (!context) + //context = FirebugContext; + context = Firebug.context; + + /* + if (context) + Firebug.Errors.clear(context); + /**/ + + var panel = this.getPanel(context, true); + if (panel) + { + panel.clear(); + } + }, + + // Override to direct output to your panel + getPanel: function(context, noCreate) + { + //return context.getPanel("console", noCreate); + // TODO: xxxpedro console console2 + return Firebug.chrome ? Firebug.chrome.getPanel("Console") : null; + } + +}; + +// ************************************************************************************************ + +//TODO: xxxpedro +//var ActivableConsole = extend(Firebug.ActivableModule, Firebug.ConsoleBase); +var ActivableConsole = extend(Firebug.ConsoleBase, +{ + isAlwaysEnabled: function() + { + return true; + } +}); + +Firebug.Console = Firebug.Console = extend(ActivableConsole, +//Firebug.Console = extend(ActivableConsole, +{ + dispatchName: "console", + + error: function() + { + Firebug.Console.logFormatted(arguments, Firebug.browser, "error"); + }, + + flush: function() + { + dispatch(this.fbListeners,"flush",[]); + + for (var i=0, length=consoleQueue.length; i objects.length) // then too few parameters for format, assume unformatted. + { + format = ""; + objIndex = -1; + parts.length = 0; + break; + } + } + + } + for (var i = 0; i < parts.length; ++i) + { + var part = parts[i]; + if (part && typeof(part) == "object") + { + var object = objects[++objIndex]; + if (typeof(object) != "undefined") + this.appendObject(object, row, part.rep); + else + this.appendObject(part.type, row, FirebugReps.Text); + } + else + FirebugReps.Text.tag.append({object: part}, row); + } + + for (var i = objIndex+1; i < objects.length; ++i) + { + logText(" ", row); + var object = objects[i]; + if (typeof(object) == "string") + FirebugReps.Text.tag.append({object: object}, row); + else + this.appendObject(object, row); + } + }, + + appendOpenGroup: function(objects, row, rep) + { + if (!this.groups) + this.groups = []; + + setClass(row, "logGroup"); + setClass(row, "opened"); + + var innerRow = this.createRow("logRow"); + setClass(innerRow, "logGroupLabel"); + if (rep) + rep.tag.replace({"objects": objects}, innerRow); + else + this.appendFormatted(objects, innerRow, rep); + row.appendChild(innerRow); + //dispatch([Firebug.A11yModel], 'onLogRowCreated', [this, innerRow]); + var groupBody = this.createRow("logGroupBody"); + row.appendChild(groupBody); + groupBody.setAttribute('role', 'group'); + this.groups.push(groupBody); + + addEvent(innerRow, "mousedown", function(event) + { + if (isLeftClick(event)) + { + //console.log(event.currentTarget == event.target); + + var target = event.target || event.srcElement; + + target = getAncestorByClass(target, "logGroupLabel"); + + var groupRow = target.parentNode; + + if (hasClass(groupRow, "opened")) + { + removeClass(groupRow, "opened"); + target.setAttribute('aria-expanded', 'false'); + } + else + { + setClass(groupRow, "opened"); + target.setAttribute('aria-expanded', 'true'); + } + } + }); + }, + + appendCloseGroup: function(object, row, rep) + { + if (this.groups) + this.groups.pop(); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // TODO: xxxpedro console2 + onMouseMove: function(event) + { + var target = event.srcElement || event.target; + + var object = getAncestorByClass(target, "objectLink-element"); + object = object ? object.repObject : null; + + if(object && instanceOf(object, "Element") && object.nodeType == 1) + { + if(object != lastHighlightedObject) + { + Firebug.Inspector.drawBoxModel(object); + object = lastHighlightedObject; + } + } + else + Firebug.Inspector.hideBoxModel(); + + }, + + onMouseDown: function(event) + { + var target = event.srcElement || event.target; + + var object = getAncestorByClass(target, "objectLink"); + var repObject = object ? object.repObject : null; + + if (!repObject) + { + return; + } + + if (hasClass(object, "objectLink-object")) + { + Firebug.chrome.selectPanel("DOM"); + Firebug.chrome.getPanel("DOM").select(repObject, true); + } + else if (hasClass(object, "objectLink-element")) + { + Firebug.chrome.selectPanel("HTML"); + Firebug.chrome.getPanel("HTML").select(repObject, true); + } + + /* + if(object && instanceOf(object, "Element") && object.nodeType == 1) + { + if(object != lastHighlightedObject) + { + Firebug.Inspector.drawBoxModel(object); + object = lastHighlightedObject; + } + } + else + Firebug.Inspector.hideBoxModel(); + /**/ + + }, + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "Console", + title: "Console", + //searchable: true, + //breakable: true, + //editable: false, + + options: + { + hasCommandLine: true, + hasToolButtons: true, + isPreRendered: true + }, + + create: function() + { + Firebug.Panel.create.apply(this, arguments); + + this.context = Firebug.browser.window; + this.document = Firebug.chrome.document; + this.onMouseMove = bind(this.onMouseMove, this); + this.onMouseDown = bind(this.onMouseDown, this); + + this.clearButton = new Button({ + element: $("fbConsole_btClear"), + owner: Firebug.Console, + onClick: Firebug.Console.clear + }); + }, + + initialize: function() + { + Firebug.Panel.initialize.apply(this, arguments); // loads persisted content + //Firebug.ActivablePanel.initialize.apply(this, arguments); // loads persisted content + + if (!this.persistedContent && Firebug.Console.isAlwaysEnabled()) + { + this.insertLogLimit(this.context); + + // Initialize log limit and listen for changes. + this.updateMaxLimit(); + + if (this.context.consoleReloadWarning) // we have not yet injected the console + this.insertReloadWarning(); + } + + //Firebug.Console.injector.install(Firebug.browser.window); + + addEvent(this.panelNode, "mouseover", this.onMouseMove); + addEvent(this.panelNode, "mousedown", this.onMouseDown); + + this.clearButton.initialize(); + + //consolex.trace(); + //TODO: xxxpedro remove this + /* + Firebug.Console.openGroup(["asd"], null, "group", null, false); + Firebug.Console.log("asd"); + Firebug.Console.log("asd"); + Firebug.Console.log("asd"); + /**/ + + //TODO: xxxpedro preferences prefs + //prefs.addObserver(Firebug.prefDomain, this, false); + }, + + initializeNode : function() + { + //dispatch([Firebug.A11yModel], 'onInitializeNode', [this]); + if (FBTrace.DBG_CONSOLE) + { + this.onScroller = bind(this.onScroll, this); + addEvent(this.panelNode, "scroll", this.onScroller); + } + + this.onResizer = bind(this.onResize, this); + this.resizeEventTarget = Firebug.chrome.$('fbContentBox'); + addEvent(this.resizeEventTarget, "resize", this.onResizer); + }, + + destroyNode : function() + { + //dispatch([Firebug.A11yModel], 'onDestroyNode', [this]); + if (this.onScroller) + removeEvent(this.panelNode, "scroll", this.onScroller); + + //removeEvent(this.resizeEventTarget, "resize", this.onResizer); + }, + + shutdown: function() + { + //TODO: xxxpedro console console2 + this.clearButton.shutdown(); + + removeEvent(this.panelNode, "mousemove", this.onMouseMove); + removeEvent(this.panelNode, "mousedown", this.onMouseDown); + + this.destroyNode(); + + Firebug.Panel.shutdown.apply(this, arguments); + + //TODO: xxxpedro preferences prefs + //prefs.removeObserver(Firebug.prefDomain, this, false); + }, + + ishow: function(state) + { + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("Console.panel show; " + this.context.getName(), state); + + var enabled = Firebug.Console.isAlwaysEnabled(); + if (enabled) + { + Firebug.Console.disabledPanelPage.hide(this); + this.showCommandLine(true); + this.showToolbarButtons("fbConsoleButtons", true); + Firebug.chrome.setGlobalAttribute("cmd_togglePersistConsole", "checked", this.persistContent); + + if (state && state.wasScrolledToBottom) + { + this.wasScrolledToBottom = state.wasScrolledToBottom; + delete state.wasScrolledToBottom; + } + + if (this.wasScrolledToBottom) + scrollToBottom(this.panelNode); + + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.show ------------------ wasScrolledToBottom: " + + this.wasScrolledToBottom + ", " + this.context.getName()); + } + else + { + this.hide(state); + Firebug.Console.disabledPanelPage.show(this); + } + }, + + ihide: function(state) + { + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("Console.panel hide; " + this.context.getName(), state); + + this.showToolbarButtons("fbConsoleButtons", false); + this.showCommandLine(false); + + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.hide ------------------ wasScrolledToBottom: " + + this.wasScrolledToBottom + ", " + this.context.getName()); + }, + + destroy: function(state) + { + if (this.panelNode.offsetHeight) + this.wasScrolledToBottom = isScrolledToBottom(this.panelNode); + + if (state) + state.wasScrolledToBottom = this.wasScrolledToBottom; + + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.destroy ------------------ wasScrolledToBottom: " + + this.wasScrolledToBottom + ", " + this.context.getName()); + }, + + shouldBreakOnNext: function() + { + // xxxHonza: shouldn't the breakOnErrors be context related? + // xxxJJB, yes, but we can't support it because we can't yet tell + // which window the error is on. + return Firebug.getPref(Firebug.servicePrefDomain, "breakOnErrors"); + }, + + getBreakOnNextTooltip: function(enabled) + { + return (enabled ? $STR("console.Disable Break On All Errors") : + $STR("console.Break On All Errors")); + }, + + enablePanel: function(module) + { + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.ConsolePanel.enablePanel; " + this.context.getName()); + + Firebug.ActivablePanel.enablePanel.apply(this, arguments); + + this.showCommandLine(true); + + if (this.wasScrolledToBottom) + scrollToBottom(this.panelNode); + }, + + disablePanel: function(module) + { + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.ConsolePanel.disablePanel; " + this.context.getName()); + + Firebug.ActivablePanel.disablePanel.apply(this, arguments); + + this.showCommandLine(false); + }, + + getOptionsMenuItems: function() + { + return [ + optionMenu("ShowJavaScriptErrors", "showJSErrors"), + optionMenu("ShowJavaScriptWarnings", "showJSWarnings"), + optionMenu("ShowCSSErrors", "showCSSErrors"), + optionMenu("ShowXMLErrors", "showXMLErrors"), + optionMenu("ShowXMLHttpRequests", "showXMLHttpRequests"), + optionMenu("ShowChromeErrors", "showChromeErrors"), + optionMenu("ShowChromeMessages", "showChromeMessages"), + optionMenu("ShowExternalErrors", "showExternalErrors"), + optionMenu("ShowNetworkErrors", "showNetworkErrors"), + this.getShowStackTraceMenuItem(), + this.getStrictOptionMenuItem(), + "-", + optionMenu("LargeCommandLine", "largeCommandLine") + ]; + }, + + getShowStackTraceMenuItem: function() + { + var menuItem = serviceOptionMenu("ShowStackTrace", "showStackTrace"); + if (FirebugContext && !Firebug.Debugger.isAlwaysEnabled()) + menuItem.disabled = true; + return menuItem; + }, + + getStrictOptionMenuItem: function() + { + var strictDomain = "javascript.options"; + var strictName = "strict"; + var strictValue = prefs.getBoolPref(strictDomain+"."+strictName); + return {label: "JavascriptOptionsStrict", type: "checkbox", checked: strictValue, + command: bindFixed(Firebug.setPref, Firebug, strictDomain, strictName, !strictValue) }; + }, + + getBreakOnMenuItems: function() + { + //xxxHonza: no BON options for now. + /*return [ + optionMenu("console.option.Persist Break On Error", "persistBreakOnError") + ];*/ + return []; + }, + + search: function(text) + { + if (!text) + return; + + // Make previously visible nodes invisible again + if (this.matchSet) + { + for (var i in this.matchSet) + removeClass(this.matchSet[i], "matched"); + } + + this.matchSet = []; + + function findRow(node) { return getAncestorByClass(node, "logRow"); } + var search = new TextSearch(this.panelNode, findRow); + + var logRow = search.find(text); + if (!logRow) + { + dispatch([Firebug.A11yModel], 'onConsoleSearchMatchFound', [this, text, []]); + return false; + } + for (; logRow; logRow = search.findNext()) + { + setClass(logRow, "matched"); + this.matchSet.push(logRow); + } + dispatch([Firebug.A11yModel], 'onConsoleSearchMatchFound', [this, text, this.matchSet]); + return true; + }, + + breakOnNext: function(breaking) + { + Firebug.setPref(Firebug.servicePrefDomain, "breakOnErrors", breaking); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // private + + createRow: function(rowName, className) + { + var elt = this.document.createElement("div"); + elt.className = rowName + (className ? " " + rowName + "-" + className : ""); + return elt; + }, + + getTopContainer: function() + { + if (this.groups && this.groups.length) + return this.groups[this.groups.length-1]; + else + return this.panelNode; + }, + + filterLogRow: function(logRow, scrolledToBottom) + { + if (this.searchText) + { + setClass(logRow, "matching"); + setClass(logRow, "matched"); + + // Search after a delay because we must wait for a frame to be created for + // the new logRow so that the finder will be able to locate it + setTimeout(bindFixed(function() + { + if (this.searchFilter(this.searchText, logRow)) + this.matchSet.push(logRow); + else + removeClass(logRow, "matched"); + + removeClass(logRow, "matching"); + + if (scrolledToBottom) + scrollToBottom(this.panelNode); + }, this), 100); + } + }, + + searchFilter: function(text, logRow) + { + var count = this.panelNode.childNodes.length; + var searchRange = this.document.createRange(); + searchRange.setStart(this.panelNode, 0); + searchRange.setEnd(this.panelNode, count); + + var startPt = this.document.createRange(); + startPt.setStartBefore(logRow); + + var endPt = this.document.createRange(); + endPt.setStartAfter(logRow); + + return finder.Find(text, searchRange, startPt, endPt) != null; + }, + + // nsIPrefObserver + observe: function(subject, topic, data) + { + // We're observing preferences only. + if (topic != "nsPref:changed") + return; + + // xxxHonza check this out. + var prefDomain = "Firebug.extension."; + var prefName = data.substr(prefDomain.length); + if (prefName == "console.logLimit") + this.updateMaxLimit(); + }, + + updateMaxLimit: function() + { + var value = 1000; + //TODO: xxxpedro preferences log limit? + //var value = Firebug.getPref(Firebug.prefDomain, "console.logLimit"); + maxQueueRequests = value ? value : maxQueueRequests; + }, + + showCommandLine: function(shouldShow) + { + //TODO: xxxpedro show command line important + return; + + if (shouldShow) + { + collapse(Firebug.chrome.$("fbCommandBox"), false); + Firebug.CommandLine.setMultiLine(Firebug.largeCommandLine, Firebug.chrome); + } + else + { + // Make sure that entire content of the Console panel is hidden when + // the panel is disabled. + Firebug.CommandLine.setMultiLine(false, Firebug.chrome, Firebug.largeCommandLine); + collapse(Firebug.chrome.$("fbCommandBox"), true); + } + }, + + onScroll: function(event) + { + // Update the scroll position flag if the position changes. + this.wasScrolledToBottom = FBL.isScrolledToBottom(this.panelNode); + + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.onScroll ------------------ wasScrolledToBottom: " + + this.wasScrolledToBottom + ", wasScrolledToBottom: " + + this.context.getName(), event); + }, + + onResize: function(event) + { + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.onResize ------------------ wasScrolledToBottom: " + + this.wasScrolledToBottom + ", offsetHeight: " + this.panelNode.offsetHeight + + ", scrollTop: " + this.panelNode.scrollTop + ", scrollHeight: " + + this.panelNode.scrollHeight + ", " + this.context.getName(), event); + + if (this.wasScrolledToBottom) + scrollToBottom(this.panelNode); + } +}); + +// ************************************************************************************************ + +function parseFormat(format) +{ + var parts = []; + if (format.length <= 0) + return parts; + + var reg = /((^%|.%)(\d+)?(\.)([a-zA-Z]))|((^%|.%)([a-zA-Z]))/; + for (var m = reg.exec(format); m; m = reg.exec(format)) + { + if (m[0].substr(0, 2) == "%%") + { + parts.push(format.substr(0, m.index)); + parts.push(m[0].substr(1)); + } + else + { + var type = m[8] ? m[8] : m[5]; + var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0); + + var rep = null; + switch (type) + { + case "s": + rep = FirebugReps.Text; + break; + case "f": + case "i": + case "d": + rep = FirebugReps.Number; + break; + case "o": + rep = null; + break; + } + + parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1)); + parts.push({rep: rep, precision: precision, type: ("%" + type)}); + } + + format = format.substr(m.index+m[0].length); + } + + parts.push(format); + return parts; +} + +// ************************************************************************************************ + +var appendObject = Firebug.ConsolePanel.prototype.appendObject; +var appendFormatted = Firebug.ConsolePanel.prototype.appendFormatted; +var appendOpenGroup = Firebug.ConsolePanel.prototype.appendOpenGroup; +var appendCloseGroup = Firebug.ConsolePanel.prototype.appendCloseGroup; + +// ************************************************************************************************ + +//Firebug.registerActivableModule(Firebug.Console); +Firebug.registerModule(Firebug.Console); +Firebug.registerPanel(Firebug.ConsolePanel); + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// Constants + +//const Cc = Components.classes; +//const Ci = Components.interfaces; + +var frameCounters = {}; +var traceRecursion = 0; + +Firebug.Console.injector = +{ + install: function(context) + { + var win = context.window; + + var consoleHandler = new FirebugConsoleHandler(context, win); + + var properties = + [ + "log", + "debug", + "info", + "warn", + "error", + "assert", + "dir", + "dirxml", + "group", + "groupCollapsed", + "groupEnd", + "time", + "timeEnd", + "count", + "trace", + "profile", + "profileEnd", + "clear", + "open", + "close" + ]; + + var Handler = function(name) + { + var c = consoleHandler; + var f = consoleHandler[name]; + return function(){return f.apply(c,arguments)}; + }; + + var installer = function(c) + { + for (var i=0, l=properties.length; i 1) + { + traceRecursion--; + return; + } + + var frames = []; + + for (var fn = arguments.callee.caller.caller; fn; fn = fn.caller) + { + if (wasVisited(fn)) break; + + var args = []; + + for (var i = 0, l = fn.arguments.length; i < l; ++i) + { + args.push({value: fn.arguments[i]}); + } + + frames.push({fn: fn, name: getFuncName(fn), args: args}); + } + + + // **************************************************************************************** + + try + { + (0)(); + } + catch(e) + { + var result = e; + + var stack = + result.stack || // Firefox / Google Chrome + result.stacktrace || // Opera + ""; + + stack = stack.replace(/\n\r|\r\n/g, "\n"); // normalize line breaks + var items = stack.split(/[\n\r]/); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Google Chrome + if (FBL.isSafari) + { + //var reChromeStackItem = /^\s+at\s+([^\(]+)\s\((.*)\)$/; + //var reChromeStackItem = /^\s+at\s+(.*)((?:http|https|ftp|file):\/\/.*)$/; + var reChromeStackItem = /^\s+at\s+(.*)((?:http|https|ftp|file):\/\/.*)$/; + + var reChromeStackItemName = /\s*\($/; + var reChromeStackItemValue = /^(.+)\:(\d+\:\d+)\)?$/; + + var framePos = 0; + for (var i=4, length=items.length; i 1) + { + objects = [errorObject]; + for (var i = 1; i < args.length; i++) + objects.push(args[i]); + } + + var row = Firebug.Console.log(objects, context, "errorMessage", null, true); // noThrottle + row.scrollIntoView(); + } + + function getComponentsStackDump() + { + // Starting with our stack, walk back to the user-level code + var frame = Components.stack; + var userURL = win.location.href.toString(); + + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("consoleInjector.getComponentsStackDump initial stack for userURL "+userURL, frame); + + // Drop frames until we get into user code. + while (frame && FBL.isSystemURL(frame.filename) ) + frame = frame.caller; + + // Drop two more frames, the injected console function and firebugAppendConsole() + if (frame) + frame = frame.caller; + if (frame) + frame = frame.caller; + + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("consoleInjector.getComponentsStackDump final stack for userURL "+userURL, frame); + + return frame; + } + + function getStackLink() + { + // TODO: xxxpedro console2 + return; + //return FBL.getFrameSourceLink(getComponentsStackDump()); + } + + function getJSDUserStack() + { + var trace = FBL.getCurrentStackTrace(context); + + var frames = trace ? trace.frames : null; + if (frames && (frames.length > 0) ) + { + var oldest = frames.length - 1; // 6 - 1 = 5 + for (var i = 0; i < frames.length; i++) + { + if (frames[oldest - i].href.indexOf("chrome:") == 0) break; + var fn = frames[oldest - i].fn + ""; + if (fn && (fn.indexOf("_firebugEvalEvent") != -1) ) break; // command line + } + FBTrace.sysout("consoleInjector getJSDUserStack: "+frames.length+" oldest: "+oldest+" i: "+i+" i - oldest + 2: "+(i - oldest + 2), trace); + trace.frames = trace.frames.slice(2 - i); // take the oldest frames, leave 2 behind they are injection code + + return trace; + } + else + return "Firebug failed to get stack trace with any frames"; + } +} + +// ************************************************************************************************ +// Register console namespace + +FBL.registerConsole = function() +{ + //TODO: xxxpedro console options override + //if (Env.Options.overrideConsole) + var win = Env.browser.window; + Firebug.Console.injector.install(win); +}; + +registerConsole(); + +}}); + + +/* 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) +{ + commandHistory.push(command); + commandPointer = 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(); + + 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 (commandPointer > 0 && commandHistory.length > 0) + this.element.value = commandHistory[--commandPointer]; + }, + + nextCommand: function() + { + var element = this.element; + + var limit = commandHistory.length -1; + var i = commandPointer; + + if (i < limit) + element.value = commandHistory[++commandPointer]; + + else if (i == limit) + { + ++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; + + // TODO: xxxpedro html3 + ///Firebug.Console.log(o, Firebug.context, "dirxml", Firebug.HTMLPanel.SoloElement); + var div = Firebug.Console.log(o, Firebug.context, "dirxml"); + var html = []; + Firebug.Reps.appendNode(o, html); + div.innerHTML = html.join(""); + + } +}; + +// ************************************************************************************************ + +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]; + } +}; + +// ************************************************************************************************ +}}); + +/* 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(); + }; +} + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var reIgnore = /about:|javascript:|resource:|chrome:|jar:/; +var layoutInterval = 300; +var indentWidth = 18; + +var cacheSession = null; +var contexts = new Array(); +var panelName = "net"; +var maxQueueRequests = 500; +//var panelBar1 = $("fbPanelBar1"); // chrome not available at startup +var activeRequests = []; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var mimeExtensionMap = +{ + "txt": "text/plain", + "html": "text/html", + "htm": "text/html", + "xhtml": "text/html", + "xml": "text/xml", + "css": "text/css", + "js": "application/x-javascript", + "jss": "application/x-javascript", + "jpg": "image/jpg", + "jpeg": "image/jpeg", + "gif": "image/gif", + "png": "image/png", + "bmp": "image/bmp", + "swf": "application/x-shockwave-flash", + "flv": "video/x-flv" +}; + +var fileCategories = +{ + "undefined": 1, + "html": 1, + "css": 1, + "js": 1, + "xhr": 1, + "image": 1, + "flash": 1, + "txt": 1, + "bin": 1 +}; + +var textFileCategories = +{ + "txt": 1, + "html": 1, + "xhr": 1, + "css": 1, + "js": 1 +}; + +var binaryFileCategories = +{ + "bin": 1, + "flash": 1 +}; + +var mimeCategoryMap = +{ + "text/plain": "txt", + "application/octet-stream": "bin", + "text/html": "html", + "text/xml": "html", + "text/css": "css", + "application/x-javascript": "js", + "text/javascript": "js", + "application/javascript" : "js", + "image/jpeg": "image", + "image/jpg": "image", + "image/gif": "image", + "image/png": "image", + "image/bmp": "image", + "application/x-shockwave-flash": "flash", + "video/x-flv": "flash" +}; + +var binaryCategoryMap = +{ + "image": 1, + "flash" : 1 +}; + +// ************************************************************************************************ + +/** + * @module Represents a module object for the Net panel. This object is derived + * from Firebug.ActivableModule in order to support activation (enable/disable). + * This allows to avoid (performance) expensive features if the functionality is not necessary + * for the user. + */ +Firebug.NetMonitor = extend(Firebug.ActivableModule, +{ + dispatchName: "netMonitor", + + clear: function(context) + { + // The user pressed a Clear button so, remove content of the panel... + var panel = context.getPanel(panelName, true); + if (panel) + panel.clear(); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Module + + initialize: function() + { + return; + + this.panelName = panelName; + + Firebug.ActivableModule.initialize.apply(this, arguments); + + if (Firebug.TraceModule) + Firebug.TraceModule.addListener(this.TraceListener); + + // HTTP observer must be registered now (and not in monitorContext, since if a + // page is opened in a new tab the top document request would be missed otherwise. + NetHttpObserver.registerObserver(); + NetHttpActivityObserver.registerObserver(); + + Firebug.Debugger.addListener(this.DebuggerListener); + }, + + shutdown: function() + { + return; + + prefs.removeObserver(Firebug.prefDomain, this, false); + if (Firebug.TraceModule) + Firebug.TraceModule.removeListener(this.TraceListener); + + NetHttpObserver.unregisterObserver(); + NetHttpActivityObserver.unregisterObserver(); + + Firebug.Debugger.removeListener(this.DebuggerListener); + } +}); + + +/** + * @domplate Represents a template that is used to reneder detailed info about a request. + * This template is rendered when a request is expanded. + */ +Firebug.NetMonitor.NetInfoBody = domplate(Firebug.Rep, new Firebug.Listener(), +{ + tag: + DIV({"class": "netInfoBody", _repObject: "$file"}, + TAG("$infoTabs", {file: "$file"}), + TAG("$infoBodies", {file: "$file"}) + ), + + infoTabs: + DIV({"class": "netInfoTabs focusRow subFocusRow", "role": "tablist"}, + A({"class": "netInfoParamsTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Params", + $collapsed: "$file|hideParams"}, + $STR("URLParameters") + ), + A({"class": "netInfoHeadersTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Headers"}, + $STR("Headers") + ), + A({"class": "netInfoPostTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Post", + $collapsed: "$file|hidePost"}, + $STR("Post") + ), + A({"class": "netInfoPutTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Put", + $collapsed: "$file|hidePut"}, + $STR("Put") + ), + A({"class": "netInfoResponseTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Response", + $collapsed: "$file|hideResponse"}, + $STR("Response") + ), + A({"class": "netInfoCacheTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Cache", + $collapsed: "$file|hideCache"}, + $STR("Cache") + ), + A({"class": "netInfoHtmlTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Html", + $collapsed: "$file|hideHtml"}, + $STR("HTML") + ) + ), + + infoBodies: + DIV({"class": "netInfoBodies outerFocusRow"}, + TABLE({"class": "netInfoParamsText netInfoText netInfoParamsTable", "role": "tabpanel", + cellpadding: 0, cellspacing: 0}, TBODY()), + DIV({"class": "netInfoHeadersText netInfoText", "role": "tabpanel"}), + DIV({"class": "netInfoPostText netInfoText", "role": "tabpanel"}), + DIV({"class": "netInfoPutText netInfoText", "role": "tabpanel"}), + PRE({"class": "netInfoResponseText netInfoText", "role": "tabpanel"}), + DIV({"class": "netInfoCacheText netInfoText", "role": "tabpanel"}, + TABLE({"class": "netInfoCacheTable", cellpadding: 0, cellspacing: 0, "role": "presentation"}, + TBODY({"role": "list", "aria-label": $STR("Cache")}) + ) + ), + DIV({"class": "netInfoHtmlText netInfoText", "role": "tabpanel"}, + IFRAME({"class": "netInfoHtmlPreview", "role": "document"}) + ) + ), + + headerDataTag: + FOR("param", "$headers", + TR({"role": "listitem"}, + TD({"class": "netInfoParamName", "role": "presentation"}, + TAG("$param|getNameTag", {param: "$param"}) + ), + TD({"class": "netInfoParamValue", "role": "list", "aria-label": "$param.name"}, + FOR("line", "$param|getParamValueIterator", + CODE({"class": "focusRow subFocusRow", "role": "listitem"}, "$line") + ) + ) + ) + ), + + customTab: + A({"class": "netInfo$tabId\\Tab netInfoTab", onclick: "$onClickTab", view: "$tabId", "role": "tab"}, + "$tabTitle" + ), + + customBody: + DIV({"class": "netInfo$tabId\\Text netInfoText", "role": "tabpanel"}), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + nameTag: + SPAN("$param|getParamName"), + + nameWithTooltipTag: + SPAN({title: "$param.name"}, "$param|getParamName"), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getNameTag: function(param) + { + return (this.getParamName(param) == param.name) ? this.nameTag : this.nameWithTooltipTag; + }, + + getParamName: function(param) + { + var limit = 25; + var name = param.name; + if (name.length > limit) + name = name.substr(0, limit) + "..."; + return name; + }, + + getParamTitle: function(param) + { + var limit = 25; + var name = param.name; + if (name.length > limit) + return name; + return ""; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + hideParams: function(file) + { + return !file.urlParams || !file.urlParams.length; + }, + + hidePost: function(file) + { + return file.method.toUpperCase() != "POST"; + }, + + hidePut: function(file) + { + return file.method.toUpperCase() != "PUT"; + }, + + hideResponse: function(file) + { + return false; + //return file.category in binaryFileCategories; + }, + + hideCache: function(file) + { + return true; + //xxxHonza: I don't see any reason why not to display the cache also info for images. + return !file.cacheEntry; // || file.category=="image"; + }, + + hideHtml: function(file) + { + return (file.mimeType != "text/html") && (file.mimeType != "application/xhtml+xml"); + }, + + onClickTab: function(event) + { + this.selectTab(event.currentTarget || event.srcElement); + }, + + getParamValueIterator: function(param) + { + // TODO: xxxpedro console2 + return param.value; + + // This value is inserted into CODE element and so, make sure the HTML isn't escaped (1210). + // This is why the second parameter is true. + // The CODE (with style white-space:pre) element preserves whitespaces so they are + // displayed the same, as they come from the server (1194). + // In case of a long header values of post parameters the value must be wrapped (2105). + return wrapText(param.value, true); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + appendTab: function(netInfoBox, tabId, tabTitle) + { + // Create new tab and body. + var args = {tabId: tabId, tabTitle: tabTitle}; + ///this.customTab.append(args, netInfoBox.getElementsByClassName("netInfoTabs").item(0)); + ///this.customBody.append(args, netInfoBox.getElementsByClassName("netInfoBodies").item(0)); + this.customTab.append(args, $$(".netInfoTabs", netInfoBox)[0]); + this.customBody.append(args, $$(".netInfoBodies", netInfoBox)[0]); + }, + + selectTabByName: function(netInfoBox, tabName) + { + var tab = getChildByClass(netInfoBox, "netInfoTabs", "netInfo"+tabName+"Tab"); + if (tab) + this.selectTab(tab); + }, + + selectTab: function(tab) + { + var view = tab.getAttribute("view"); + + var netInfoBox = getAncestorByClass(tab, "netInfoBody"); + + var selectedTab = netInfoBox.selectedTab; + + if (selectedTab) + { + //netInfoBox.selectedText.removeAttribute("selected"); + removeClass(netInfoBox.selectedText, "netInfoTextSelected"); + + removeClass(selectedTab, "netInfoTabSelected"); + //selectedTab.removeAttribute("selected"); + selectedTab.setAttribute("aria-selected", "false"); + } + + var textBodyName = "netInfo" + view + "Text"; + + selectedTab = netInfoBox.selectedTab = tab; + + netInfoBox.selectedText = $$("."+textBodyName, netInfoBox)[0]; + //netInfoBox.selectedText = netInfoBox.getElementsByClassName(textBodyName).item(0); + + //netInfoBox.selectedText.setAttribute("selected", "true"); + setClass(netInfoBox.selectedText, "netInfoTextSelected"); + + setClass(selectedTab, "netInfoTabSelected"); + selectedTab.setAttribute("selected", "true"); + selectedTab.setAttribute("aria-selected", "true"); + + var file = Firebug.getRepObject(netInfoBox); + + //var context = Firebug.getElementPanel(netInfoBox).context; + var context = Firebug.chrome; + + this.updateInfo(netInfoBox, file, context); + }, + + updateInfo: function(netInfoBox, file, context) + { + if (FBTrace.DBG_NET) + FBTrace.sysout("net.updateInfo; file", file); + + if (!netInfoBox) + { + if (FBTrace.DBG_NET || FBTrace.DBG_ERRORS) + FBTrace.sysout("net.updateInfo; ERROR netInfo == null " + file.href, file); + return; + } + + var tab = netInfoBox.selectedTab; + + if (hasClass(tab, "netInfoParamsTab")) + { + if (file.urlParams && !netInfoBox.urlParamsPresented) + { + netInfoBox.urlParamsPresented = true; + this.insertHeaderRows(netInfoBox, file.urlParams, "Params"); + } + } + + else if (hasClass(tab, "netInfoHeadersTab")) + { + var headersText = $$(".netInfoHeadersText", netInfoBox)[0]; + //var headersText = netInfoBox.getElementsByClassName("netInfoHeadersText").item(0); + + if (file.responseHeaders && !netInfoBox.responseHeadersPresented) + { + netInfoBox.responseHeadersPresented = true; + NetInfoHeaders.renderHeaders(headersText, file.responseHeaders, "ResponseHeaders"); + } + + if (file.requestHeaders && !netInfoBox.requestHeadersPresented) + { + netInfoBox.requestHeadersPresented = true; + NetInfoHeaders.renderHeaders(headersText, file.requestHeaders, "RequestHeaders"); + } + } + + else if (hasClass(tab, "netInfoPostTab")) + { + if (!netInfoBox.postPresented) + { + netInfoBox.postPresented = true; + //var postText = netInfoBox.getElementsByClassName("netInfoPostText").item(0); + var postText = $$(".netInfoPostText", netInfoBox)[0]; + NetInfoPostData.render(context, postText, file); + } + } + + else if (hasClass(tab, "netInfoPutTab")) + { + if (!netInfoBox.putPresented) + { + netInfoBox.putPresented = true; + //var putText = netInfoBox.getElementsByClassName("netInfoPutText").item(0); + var putText = $$(".netInfoPutText", netInfoBox)[0]; + NetInfoPostData.render(context, putText, file); + } + } + + else if (hasClass(tab, "netInfoResponseTab") && file.loaded && !netInfoBox.responsePresented) + { + ///var responseTextBox = netInfoBox.getElementsByClassName("netInfoResponseText").item(0); + var responseTextBox = $$(".netInfoResponseText", netInfoBox)[0]; + if (file.category == "image") + { + netInfoBox.responsePresented = true; + + var responseImage = netInfoBox.ownerDocument.createElement("img"); + responseImage.src = file.href; + + clearNode(responseTextBox); + responseTextBox.appendChild(responseImage, responseTextBox); + } + else ///if (!(binaryCategoryMap.hasOwnProperty(file.category))) + { + this.setResponseText(file, netInfoBox, responseTextBox, context); + } + } + + else if (hasClass(tab, "netInfoCacheTab") && file.loaded && !netInfoBox.cachePresented) + { + var responseTextBox = netInfoBox.getElementsByClassName("netInfoCacheText").item(0); + if (file.cacheEntry) { + netInfoBox.cachePresented = true; + this.insertHeaderRows(netInfoBox, file.cacheEntry, "Cache"); + } + } + + else if (hasClass(tab, "netInfoHtmlTab") && file.loaded && !netInfoBox.htmlPresented) + { + netInfoBox.htmlPresented = true; + + var text = Utils.getResponseText(file, context); + + ///var iframe = netInfoBox.getElementsByClassName("netInfoHtmlPreview").item(0); + var iframe = $$(".netInfoHtmlPreview", netInfoBox)[0]; + + ///iframe.contentWindow.document.body.innerHTML = text; + + // TODO: xxxpedro net - remove scripts + var reScript = //gi; + + text = text.replace(reScript, ""); + + iframe.contentWindow.document.write(text); + iframe.contentWindow.document.close(); + } + + // Notify listeners about update so, content of custom tabs can be updated. + dispatch(NetInfoBody.fbListeners, "updateTabBody", [netInfoBox, file, context]); + }, + + setResponseText: function(file, netInfoBox, responseTextBox, context) + { + //********************************************** + //********************************************** + //********************************************** + netInfoBox.responsePresented = true; + // line breaks somehow are different in IE + // make this only once in the initialization? we don't have net panels and modules yet. + if (isIE) + responseTextBox.style.whiteSpace = "nowrap"; + + responseTextBox[ + typeof responseTextBox.textContent != "undefined" ? + "textContent" : + "innerText" + ] = file.responseText; + + return; + //********************************************** + //********************************************** + //********************************************** + + // Get response text and make sure it doesn't exceed the max limit. + var text = Utils.getResponseText(file, context); + var limit = Firebug.netDisplayedResponseLimit + 15; + var limitReached = text ? (text.length > limit) : false; + if (limitReached) + text = text.substr(0, limit) + "..."; + + // Insert the response into the UI. + if (text) + insertWrappedText(text, responseTextBox); + else + insertWrappedText("", responseTextBox); + + // Append a message informing the user that the response isn't fully displayed. + if (limitReached) + { + var object = { + text: $STR("net.responseSizeLimitMessage"), + onClickLink: function() { + var panel = context.getPanel("net", true); + panel.openResponseInTab(file); + } + }; + Firebug.NetMonitor.ResponseSizeLimit.append(object, responseTextBox); + } + + netInfoBox.responsePresented = true; + + if (FBTrace.DBG_NET) + FBTrace.sysout("net.setResponseText; response text updated"); + }, + + insertHeaderRows: function(netInfoBox, headers, tableName, rowName) + { + if (!headers.length) + return; + + var headersTable = $$(".netInfo"+tableName+"Table", netInfoBox)[0]; + //var headersTable = netInfoBox.getElementsByClassName("netInfo"+tableName+"Table").item(0); + var tbody = getChildByClass(headersTable, "netInfo" + rowName + "Body"); + if (!tbody) + tbody = headersTable.firstChild; + var titleRow = getChildByClass(tbody, "netInfo" + rowName + "Title"); + + this.headerDataTag.insertRows({headers: headers}, titleRow ? titleRow : tbody); + removeClass(titleRow, "collapsed"); + } +}); + +var NetInfoBody = Firebug.NetMonitor.NetInfoBody; + +// ************************************************************************************************ + +/** + * @domplate Used within the Net panel to display raw source of request and response headers + * as well as pretty-formatted summary of these headers. + */ +Firebug.NetMonitor.NetInfoHeaders = domplate(Firebug.Rep, //new Firebug.Listener(), +{ + tag: + DIV({"class": "netInfoHeadersTable", "role": "tabpanel"}, + DIV({"class": "netInfoHeadersGroup netInfoResponseHeadersTitle"}, + SPAN($STR("ResponseHeaders")), + SPAN({"class": "netHeadersViewSource response collapsed", onclick: "$onViewSource", + _sourceDisplayed: false, _rowName: "ResponseHeaders"}, + $STR("net.headers.view source") + ) + ), + TABLE({cellpadding: 0, cellspacing: 0}, + TBODY({"class": "netInfoResponseHeadersBody", "role": "list", + "aria-label": $STR("ResponseHeaders")}) + ), + DIV({"class": "netInfoHeadersGroup netInfoRequestHeadersTitle"}, + SPAN($STR("RequestHeaders")), + SPAN({"class": "netHeadersViewSource request collapsed", onclick: "$onViewSource", + _sourceDisplayed: false, _rowName: "RequestHeaders"}, + $STR("net.headers.view source") + ) + ), + TABLE({cellpadding: 0, cellspacing: 0}, + TBODY({"class": "netInfoRequestHeadersBody", "role": "list", + "aria-label": $STR("RequestHeaders")}) + ) + ), + + sourceTag: + TR({"role": "presentation"}, + TD({colspan: 2, "role": "presentation"}, + PRE({"class": "source"}) + ) + ), + + onViewSource: function(event) + { + var target = event.target; + var requestHeaders = (target.rowName == "RequestHeaders"); + + var netInfoBox = getAncestorByClass(target, "netInfoBody"); + var file = netInfoBox.repObject; + + if (target.sourceDisplayed) + { + var headers = requestHeaders ? file.requestHeaders : file.responseHeaders; + this.insertHeaderRows(netInfoBox, headers, target.rowName); + target.innerHTML = $STR("net.headers.view source"); + } + else + { + var source = requestHeaders ? file.requestHeadersText : file.responseHeadersText; + this.insertSource(netInfoBox, source, target.rowName); + target.innerHTML = $STR("net.headers.pretty print"); + } + + target.sourceDisplayed = !target.sourceDisplayed; + + cancelEvent(event); + }, + + insertSource: function(netInfoBox, source, rowName) + { + // This breaks copy to clipboard. + //if (source) + // source = source.replace(/\r\n/gm, "\\r\\n\r\n"); + + ///var tbody = netInfoBox.getElementsByClassName("netInfo" + rowName + "Body").item(0); + var tbody = $$(".netInfo" + rowName + "Body", netInfoBox)[0]; + var node = this.sourceTag.replace({}, tbody); + ///var sourceNode = node.getElementsByClassName("source").item(0); + var sourceNode = $$(".source", node)[0]; + sourceNode.innerHTML = source; + }, + + insertHeaderRows: function(netInfoBox, headers, rowName) + { + var headersTable = $$(".netInfoHeadersTable", netInfoBox)[0]; + var tbody = $$(".netInfo" + rowName + "Body", headersTable)[0]; + + //var headersTable = netInfoBox.getElementsByClassName("netInfoHeadersTable").item(0); + //var tbody = headersTable.getElementsByClassName("netInfo" + rowName + "Body").item(0); + + clearNode(tbody); + + if (!headers.length) + return; + + NetInfoBody.headerDataTag.insertRows({headers: headers}, tbody); + + var titleRow = getChildByClass(headersTable, "netInfo" + rowName + "Title"); + removeClass(titleRow, "collapsed"); + }, + + init: function(parent) + { + var rootNode = this.tag.append({}, parent); + + var netInfoBox = getAncestorByClass(parent, "netInfoBody"); + var file = netInfoBox.repObject; + + var viewSource; + + viewSource = $$(".request", rootNode)[0]; + //viewSource = rootNode.getElementsByClassName("netHeadersViewSource request").item(0); + if (file.requestHeadersText) + removeClass(viewSource, "collapsed"); + + viewSource = $$(".response", rootNode)[0]; + //viewSource = rootNode.getElementsByClassName("netHeadersViewSource response").item(0); + if (file.responseHeadersText) + removeClass(viewSource, "collapsed"); + }, + + renderHeaders: function(parent, headers, rowName) + { + if (!parent.firstChild) + this.init(parent); + + this.insertHeaderRows(parent, headers, rowName); + } +}); + +var NetInfoHeaders = Firebug.NetMonitor.NetInfoHeaders; + +// ************************************************************************************************ + +/** + * @domplate Represents posted data within request info (the info, which is visible when + * a request entry is expanded. This template renders content of the Post tab. + */ +Firebug.NetMonitor.NetInfoPostData = domplate(Firebug.Rep, /*new Firebug.Listener(),*/ +{ + // application/x-www-form-urlencoded + paramsTable: + TABLE({"class": "netInfoPostParamsTable", cellpadding: 0, cellspacing: 0, "role": "presentation"}, + TBODY({"role": "list", "aria-label": $STR("net.label.Parameters")}, + TR({"class": "netInfoPostParamsTitle", "role": "presentation"}, + TD({colspan: 3, "role": "presentation"}, + DIV({"class": "netInfoPostParams"}, + $STR("net.label.Parameters"), + SPAN({"class": "netInfoPostContentType"}, + "application/x-www-form-urlencoded" + ) + ) + ) + ) + ) + ), + + // multipart/form-data + partsTable: + TABLE({"class": "netInfoPostPartsTable", cellpadding: 0, cellspacing: 0, "role": "presentation"}, + TBODY({"role": "list", "aria-label": $STR("net.label.Parts")}, + TR({"class": "netInfoPostPartsTitle", "role": "presentation"}, + TD({colspan: 2, "role":"presentation" }, + DIV({"class": "netInfoPostParams"}, + $STR("net.label.Parts"), + SPAN({"class": "netInfoPostContentType"}, + "multipart/form-data" + ) + ) + ) + ) + ) + ), + + // application/json + jsonTable: + TABLE({"class": "netInfoPostJSONTable", cellpadding: 0, cellspacing: 0, "role": "presentation"}, + ///TBODY({"role": "list", "aria-label": $STR("jsonviewer.tab.JSON")}, + TBODY({"role": "list", "aria-label": $STR("JSON")}, + TR({"class": "netInfoPostJSONTitle", "role": "presentation"}, + TD({"role": "presentation" }, + DIV({"class": "netInfoPostParams"}, + ///$STR("jsonviewer.tab.JSON") + $STR("JSON") + ) + ) + ), + TR( + TD({"class": "netInfoPostJSONBody"}) + ) + ) + ), + + // application/xml + xmlTable: + TABLE({"class": "netInfoPostXMLTable", cellpadding: 0, cellspacing: 0, "role": "presentation"}, + TBODY({"role": "list", "aria-label": $STR("xmlviewer.tab.XML")}, + TR({"class": "netInfoPostXMLTitle", "role": "presentation"}, + TD({"role": "presentation" }, + DIV({"class": "netInfoPostParams"}, + $STR("xmlviewer.tab.XML") + ) + ) + ), + TR( + TD({"class": "netInfoPostXMLBody"}) + ) + ) + ), + + sourceTable: + TABLE({"class": "netInfoPostSourceTable", cellpadding: 0, cellspacing: 0, "role": "presentation"}, + TBODY({"role": "list", "aria-label": $STR("net.label.Source")}, + TR({"class": "netInfoPostSourceTitle", "role": "presentation"}, + TD({colspan: 2, "role": "presentation"}, + DIV({"class": "netInfoPostSource"}, + $STR("net.label.Source") + ) + ) + ) + ) + ), + + sourceBodyTag: + TR({"role": "presentation"}, + TD({colspan: 2, "role": "presentation"}, + FOR("line", "$param|getParamValueIterator", + CODE({"class":"focusRow subFocusRow" , "role": "listitem"},"$line") + ) + ) + ), + + getParamValueIterator: function(param) + { + return NetInfoBody.getParamValueIterator(param); + }, + + render: function(context, parentNode, file) + { + //debugger; + var spy = getAncestorByClass(parentNode, "spyHead"); + var spyObject = spy.repObject; + var data = spyObject.data; + + ///var contentType = Utils.findHeader(file.requestHeaders, "content-type"); + var contentType = file.mimeType; + + ///var text = Utils.getPostText(file, context, true); + ///if (text == undefined) + /// return; + + ///if (Utils.isURLEncodedRequest(file, context)) + // fake Utils.isURLEncodedRequest identification + if (contentType && contentType == "application/x-www-form-urlencoded" || + data && data.indexOf("=") != -1) + { + ///var lines = text.split("\n"); + ///var params = parseURLEncodedText(lines[lines.length-1]); + var params = parseURLEncodedTextArray(data); + if (params) + this.insertParameters(parentNode, params); + } + + ///if (Utils.isMultiPartRequest(file, context)) + ///{ + /// var data = this.parseMultiPartText(file, context); + /// if (data) + /// this.insertParts(parentNode, data); + ///} + + // moved to the top + ///var contentType = Utils.findHeader(file.requestHeaders, "content-type"); + + ///if (Firebug.JSONViewerModel.isJSON(contentType)) + var jsonData = { + responseText: data + }; + + if (Firebug.JSONViewerModel.isJSON(contentType, data)) + ///this.insertJSON(parentNode, file, context); + this.insertJSON(parentNode, jsonData, context); + + ///if (Firebug.XMLViewerModel.isXML(contentType)) + /// this.insertXML(parentNode, file, context); + + ///var postText = Utils.getPostText(file, context); + ///postText = Utils.formatPostText(postText); + var postText = data; + if (postText) + this.insertSource(parentNode, postText); + }, + + insertParameters: function(parentNode, params) + { + if (!params || !params.length) + return; + + var paramTable = this.paramsTable.append({object:{}}, parentNode); + var row = $$(".netInfoPostParamsTitle", paramTable)[0]; + //var paramTable = this.paramsTable.append(null, parentNode); + //var row = paramTable.getElementsByClassName("netInfoPostParamsTitle").item(0); + + var tbody = paramTable.getElementsByTagName("tbody")[0]; + + NetInfoBody.headerDataTag.insertRows({headers: params}, row); + }, + + insertParts: function(parentNode, data) + { + if (!data.params || !data.params.length) + return; + + var partsTable = this.partsTable.append({object:{}}, parentNode); + var row = $$(".netInfoPostPartsTitle", paramTable)[0]; + //var partsTable = this.partsTable.append(null, parentNode); + //var row = partsTable.getElementsByClassName("netInfoPostPartsTitle").item(0); + + NetInfoBody.headerDataTag.insertRows({headers: data.params}, row); + }, + + insertJSON: function(parentNode, file, context) + { + ///var text = Utils.getPostText(file, context); + var text = file.responseText; + ///var data = parseJSONString(text, "http://" + file.request.originalURI.host); + var data = parseJSONString(text); + if (!data) + return; + + ///var jsonTable = this.jsonTable.append(null, parentNode); + var jsonTable = this.jsonTable.append({}, parentNode); + ///var jsonBody = jsonTable.getElementsByClassName("netInfoPostJSONBody").item(0); + var jsonBody = $$(".netInfoPostJSONBody", jsonTable)[0]; + + if (!this.toggles) + this.toggles = {}; + + Firebug.DOMPanel.DirTable.tag.replace( + {object: data, toggles: this.toggles}, jsonBody); + }, + + insertXML: function(parentNode, file, context) + { + var text = Utils.getPostText(file, context); + + var jsonTable = this.xmlTable.append(null, parentNode); + ///var jsonBody = jsonTable.getElementsByClassName("netInfoPostXMLBody").item(0); + var jsonBody = $$(".netInfoPostXMLBody", jsonTable)[0]; + + Firebug.XMLViewerModel.insertXML(jsonBody, text); + }, + + insertSource: function(parentNode, text) + { + var sourceTable = this.sourceTable.append({object:{}}, parentNode); + var row = $$(".netInfoPostSourceTitle", sourceTable)[0]; + //var sourceTable = this.sourceTable.append(null, parentNode); + //var row = sourceTable.getElementsByClassName("netInfoPostSourceTitle").item(0); + + var param = {value: [text]}; + this.sourceBodyTag.insertRows({param: param}, row); + }, + + parseMultiPartText: function(file, context) + { + var text = Utils.getPostText(file, context); + if (text == undefined) + return null; + + FBTrace.sysout("net.parseMultiPartText; boundary: ", text); + + var boundary = text.match(/\s*boundary=\s*(.*)/)[1]; + + var divider = "\r\n\r\n"; + var bodyStart = text.indexOf(divider); + var body = text.substr(bodyStart + divider.length); + + var postData = {}; + postData.mimeType = "multipart/form-data"; + postData.params = []; + + var parts = body.split("--" + boundary); + for (var i=0; i 1) ? m[1] : "", + value: trim(part[1]) + }); + } + + return postData; + } +}); + +var NetInfoPostData = Firebug.NetMonitor.NetInfoPostData; + +// ************************************************************************************************ + + +// TODO: xxxpedro net i18n +var $STRP = function(a){return a;}; + +Firebug.NetMonitor.NetLimit = domplate(Firebug.Rep, +{ + collapsed: true, + + tableTag: + DIV( + TABLE({width: "100%", cellpadding: 0, cellspacing: 0}, + TBODY() + ) + ), + + limitTag: + TR({"class": "netRow netLimitRow", $collapsed: "$isCollapsed"}, + TD({"class": "netCol netLimitCol", colspan: 6}, + TABLE({cellpadding: 0, cellspacing: 0}, + TBODY( + TR( + TD( + SPAN({"class": "netLimitLabel"}, + $STRP("plural.Limit_Exceeded", [0]) + ) + ), + TD({style: "width:100%"}), + TD( + BUTTON({"class": "netLimitButton", title: "$limitPrefsTitle", + onclick: "$onPreferences"}, + $STR("LimitPrefs") + ) + ), + TD(" ") + ) + ) + ) + ) + ), + + isCollapsed: function() + { + return this.collapsed; + }, + + onPreferences: function(event) + { + openNewTab("about:config"); + }, + + updateCounter: function(row) + { + removeClass(row, "collapsed"); + + // Update info within the limit row. + var limitLabel = row.getElementsByClassName("netLimitLabel").item(0); + limitLabel.firstChild.nodeValue = $STRP("plural.Limit_Exceeded", [row.limitInfo.totalCount]); + }, + + createTable: function(parent, limitInfo) + { + var table = this.tableTag.replace({}, parent); + var row = this.createRow(table.firstChild.firstChild, limitInfo); + return [table, row]; + }, + + createRow: function(parent, limitInfo) + { + var row = this.limitTag.insertRows(limitInfo, parent, this)[0]; + row.limitInfo = limitInfo; + return row; + }, + + // nsIPrefObserver + observe: function(subject, topic, data) + { + // We're observing preferences only. + if (topic != "nsPref:changed") + return; + + if (data.indexOf("net.logLimit") != -1) + this.updateMaxLimit(); + }, + + updateMaxLimit: function() + { + var value = Firebug.getPref(Firebug.prefDomain, "net.logLimit"); + maxQueueRequests = value ? value : maxQueueRequests; + } +}); + +var NetLimit = Firebug.NetMonitor.NetLimit; + +// ************************************************************************************************ + +Firebug.NetMonitor.ResponseSizeLimit = domplate(Firebug.Rep, +{ + tag: + DIV({"class": "netInfoResponseSizeLimit"}, + SPAN("$object.beforeLink"), + A({"class": "objectLink", onclick: "$onClickLink"}, + "$object.linkText" + ), + SPAN("$object.afterLink") + ), + + reLink: /^(.*)(.*)<\/a>(.*$)/, + append: function(obj, parent) + { + var m = obj.text.match(this.reLink); + return this.tag.append({onClickLink: obj.onClickLink, + object: { + beforeLink: m[1], + linkText: m[2], + afterLink: m[3] + }}, parent, this); + } +}); + +// ************************************************************************************************ +// ************************************************************************************************ + +Firebug.NetMonitor.Utils = +{ + findHeader: function(headers, name) + { + if (!headers) + return null; + + name = name.toLowerCase(); + for (var i = 0; i < headers.length; ++i) + { + var headerName = headers[i].name.toLowerCase(); + if (headerName == name) + return headers[i].value; + } + }, + + formatPostText: function(text) + { + if (text instanceof XMLDocument) + return getElementXML(text.documentElement); + else + return text; + }, + + getPostText: function(file, context, noLimit) + { + if (!file.postText) + { + file.postText = readPostTextFromRequest(file.request, context); + + if (!file.postText && context) + file.postText = readPostTextFromPage(file.href, context); + } + + if (!file.postText) + return file.postText; + + var limit = Firebug.netDisplayedPostBodyLimit; + if (file.postText.length > limit && !noLimit) + { + return cropString(file.postText, limit, + "\n\n... " + $STR("net.postDataSizeLimitMessage") + " ...\n\n"); + } + + return file.postText; + }, + + getResponseText: function(file, context) + { + // The response can be also empty string so, check agains "undefined". + return (typeof(file.responseText) != "undefined")? file.responseText : + context.sourceCache.loadText(file.href, file.method, file); + }, + + isURLEncodedRequest: function(file, context) + { + var text = Utils.getPostText(file, context); + if (text && text.toLowerCase().indexOf("content-type: application/x-www-form-urlencoded") == 0) + return true; + + // The header value doesn't have to be always exactly "application/x-www-form-urlencoded", + // there can be even charset specified. So, use indexOf rather than just "==". + var headerValue = Utils.findHeader(file.requestHeaders, "content-type"); + if (headerValue && headerValue.indexOf("application/x-www-form-urlencoded") == 0) + return true; + + return false; + }, + + isMultiPartRequest: function(file, context) + { + var text = Utils.getPostText(file, context); + if (text && text.toLowerCase().indexOf("content-type: multipart/form-data") == 0) + return true; + return false; + }, + + getMimeType: function(mimeType, uri) + { + if (!mimeType || !(mimeCategoryMap.hasOwnProperty(mimeType))) + { + var ext = getFileExtension(uri); + if (!ext) + return mimeType; + else + { + var extMimeType = mimeExtensionMap[ext.toLowerCase()]; + return extMimeType ? extMimeType : mimeType; + } + } + else + return mimeType; + }, + + getDateFromSeconds: function(s) + { + var d = new Date(); + d.setTime(s*1000); + return d; + }, + + getHttpHeaders: function(request, file) + { + try + { + var http = QI(request, Ci.nsIHttpChannel); + file.status = request.responseStatus; + + // xxxHonza: is there any problem to do this in requestedFile method? + file.method = http.requestMethod; + file.urlParams = parseURLParams(file.href); + file.mimeType = Utils.getMimeType(request.contentType, request.name); + + if (!file.responseHeaders && Firebug.collectHttpHeaders) + { + var requestHeaders = [], responseHeaders = []; + + http.visitRequestHeaders({ + visitHeader: function(name, value) + { + requestHeaders.push({name: name, value: value}); + } + }); + http.visitResponseHeaders({ + visitHeader: function(name, value) + { + responseHeaders.push({name: name, value: value}); + } + }); + + file.requestHeaders = requestHeaders; + file.responseHeaders = responseHeaders; + } + } + catch (exc) + { + // An exception can be throwed e.g. when the request is aborted and + // request.responseStatus is accessed. + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("net.getHttpHeaders FAILS " + file.href, exc); + } + }, + + isXHR: function(request) + { + try + { + var callbacks = request.notificationCallbacks; + var xhrRequest = callbacks ? callbacks.getInterface(Ci.nsIXMLHttpRequest) : null; + if (FBTrace.DBG_NET) + FBTrace.sysout("net.isXHR; " + (xhrRequest != null) + ", " + safeGetName(request)); + + return (xhrRequest != null); + } + catch (exc) + { + } + + return false; + }, + + getFileCategory: function(file) + { + if (file.category) + { + if (FBTrace.DBG_NET) + FBTrace.sysout("net.getFileCategory; current: " + file.category + " for: " + file.href, file); + return file.category; + } + + if (file.isXHR) + { + if (FBTrace.DBG_NET) + FBTrace.sysout("net.getFileCategory; XHR for: " + file.href, file); + return file.category = "xhr"; + } + + if (!file.mimeType) + { + var ext = getFileExtension(file.href); + if (ext) + file.mimeType = mimeExtensionMap[ext.toLowerCase()]; + } + + /*if (FBTrace.DBG_NET) + FBTrace.sysout("net.getFileCategory; " + mimeCategoryMap[file.mimeType] + + ", mimeType: " + file.mimeType + " for: " + file.href, file);*/ + + if (!file.mimeType) + return ""; + + // Solve cases when charset is also specified, eg "text/html; charset=UTF-8". + var mimeType = file.mimeType; + if (mimeType) + mimeType = mimeType.split(";")[0]; + + return (file.category = mimeCategoryMap[mimeType]); + } +}; + +var Utils = Firebug.NetMonitor.Utils; + +// ************************************************************************************************ + +//Firebug.registerRep(Firebug.NetMonitor.NetRequestTable); +//Firebug.registerActivableModule(Firebug.NetMonitor); +//Firebug.registerPanel(NetPanel); + +Firebug.registerModule(Firebug.NetMonitor); +//Firebug.registerRep(Firebug.NetMonitor.BreakpointRep); + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// Constants + +//const Cc = Components.classes; +//const Ci = Components.interfaces; + +// List of contexts with XHR spy attached. +var contexts = []; + +// ************************************************************************************************ +// Spy Module + +/** + * @module Represents a XHR Spy module. The main purpose of the XHR Spy feature is to monitor + * XHR activity of the current page and create appropriate log into the Console panel. + * This feature can be controlled by an option Show XMLHttpRequests (from within the + * console panel). + * + * The module is responsible for attaching/detaching a HTTP Observers when Firebug is + * activated/deactivated for a site. + */ +Firebug.Spy = extend(Firebug.Module, +/** @lends Firebug.Spy */ +{ + dispatchName: "spy", + + initialize: function() + { + if (Firebug.TraceModule) + Firebug.TraceModule.addListener(this.TraceListener); + + Firebug.Module.initialize.apply(this, arguments); + }, + + shutdown: function() + { + Firebug.Module.shutdown.apply(this, arguments); + + if (Firebug.TraceModule) + Firebug.TraceModule.removeListener(this.TraceListener); + }, + + initContext: function(context) + { + context.spies = []; + + if (Firebug.showXMLHttpRequests && Firebug.Console.isAlwaysEnabled()) + this.attachObserver(context, context.window); + + if (FBTrace.DBG_SPY) + FBTrace.sysout("spy.initContext " + contexts.length + " ", context.getName()); + }, + + destroyContext: function(context) + { + // For any spies that are in progress, remove our listeners so that they don't leak + this.detachObserver(context, null); + + if (FBTrace.DBG_SPY && context.spies.length) + FBTrace.sysout("spy.destroyContext; ERROR There are leaking Spies (" + + context.spies.length + ") " + context.getName()); + + delete context.spies; + + if (FBTrace.DBG_SPY) + FBTrace.sysout("spy.destroyContext " + contexts.length + " ", context.getName()); + }, + + watchWindow: function(context, win) + { + if (Firebug.showXMLHttpRequests && Firebug.Console.isAlwaysEnabled()) + this.attachObserver(context, win); + }, + + unwatchWindow: function(context, win) + { + try + { + // This make sure that the existing context is properly removed from "contexts" array. + this.detachObserver(context, win); + } + catch (ex) + { + // Get exceptions here sometimes, so let's just ignore them + // since the window is going away anyhow + ERROR(ex); + } + }, + + updateOption: function(name, value) + { + // XXXjjb Honza, if Console.isEnabled(context) false, then this can't be called, + // but somehow seems not correct + if (name == "showXMLHttpRequests") + { + var tach = value ? this.attachObserver : this.detachObserver; + for (var i = 0; i < TabWatcher.contexts.length; ++i) + { + var context = TabWatcher.contexts[i]; + iterateWindows(context.window, function(win) + { + tach.apply(this, [context, win]); + }); + } + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Attaching Spy to XHR requests. + + /** + * Returns false if Spy should not be attached to XHRs executed by the specified window. + */ + skipSpy: function(win) + { + if (!win) + return true; + + // Don't attach spy to chrome. + var uri = safeGetWindowLocation(win); + if (uri && (uri.indexOf("about:") == 0 || uri.indexOf("chrome:") == 0)) + return true; + }, + + attachObserver: function(context, win) + { + if (Firebug.Spy.skipSpy(win)) + return; + + for (var i=0; insIHttpChannel
                  . + * Returns null if the request doesn't represent XHR. + */ + getXHR: function(request) + { + // Does also query-interface for nsIHttpChannel. + if (!(request instanceof Ci.nsIHttpChannel)) + return null; + + try + { + var callbacks = request.notificationCallbacks; + return (callbacks ? callbacks.getInterface(Ci.nsIXMLHttpRequest) : null); + } + catch (exc) + { + if (exc.name == "NS_NOINTERFACE") + { + if (FBTrace.DBG_SPY) + FBTrace.sysout("spy.getXHR; Request is not nsIXMLHttpRequest: " + + safeGetRequestName(request)); + } + } + + return null; + } +}); + + + + + +// ************************************************************************************************ + +/* +function getSpyForXHR(request, xhrRequest, context, noCreate) +{ + var spy = null; + + // Iterate all existing spy objects in this context and look for one that is + // already created for this request. + var length = context.spies.length; + for (var i=0; i= 3) + { + var netInfoBox = getChildByClass(spy.logRow, "spyHead", "netInfoBody"); + if (netInfoBox) + { + netInfoBox.htmlPresented = false; + netInfoBox.responsePresented = false; + } + } + + // If the request is loading update the end time. + if (spy.xhrRequest.readyState == 3) + { + spy.responseTime = spy.endTime - spy.sendTime; + updateTime(spy); + } + + // Request loaded. Get all the info from the request now, just in case the + // XHR would be aborted in the original onReadyStateChange handler. + if (spy.xhrRequest.readyState == 4) + { + // Cumulate response so, multipart response content is properly displayed. + if (SpyHttpActivityObserver.getActivityDistributor()) + spy.responseText += spy.xhrRequest.responseText; + else + { + // xxxHonza: remove from FB 1.6 + if (!spy.responseText) + spy.responseText = spy.xhrRequest.responseText; + } + + // The XHR is loaded now (used also by the activity observer). + spy.loaded = true; + + // Update UI. + updateHttpSpyInfo(spy); + + // Notify Net pane about a request beeing loaded. + // xxxHonza: I don't think this is necessary. + var netProgress = spy.context.netProgress; + if (netProgress) + netProgress.post(netProgress.stopFile, [spy.request, spy.endTime, spy.postText, spy.responseText]); + + // Notify registered listeners about finish of the XHR. + dispatch(Firebug.Spy.fbListeners, "onLoad", [spy.context, spy]); + } + + // Pass the event to the original page handler. + callPageHandler(spy, event, originalHandler); +} + +function onHTTPSpyLoad(spy) +{ + if (FBTrace.DBG_SPY) + FBTrace.sysout("spy.onHTTPSpyLoad: " + spy.href, spy); + + // Detach must be done in onLoad (not in onreadystatechange) otherwise + // onAbort would not be handled. + spy.detach(); + + // xxxHonza: Still needed for Fx 3.5 (#502959) + if (!SpyHttpActivityObserver.getActivityDistributor()) + onHTTPSpyReadyStateChange(spy, null); +} + +function onHTTPSpyError(spy) +{ + if (FBTrace.DBG_SPY) + FBTrace.sysout("spy.onHTTPSpyError; " + spy.href, spy); + + spy.detach(); + spy.loaded = true; + + if (spy.logRow) + { + removeClass(spy.logRow, "loading"); + setClass(spy.logRow, "error"); + } +} + +function onHTTPSpyAbort(spy) +{ + if (FBTrace.DBG_SPY) + FBTrace.sysout("spy.onHTTPSpyAbort: " + spy.href, spy); + + spy.detach(); + spy.loaded = true; + + if (spy.logRow) + { + removeClass(spy.logRow, "loading"); + setClass(spy.logRow, "error"); + } + + spy.statusText = "Aborted"; + updateLogRow(spy); + + // Notify Net pane about a request beeing aborted. + // xxxHonza: the net panel shoud find out this itself. + var netProgress = spy.context.netProgress; + if (netProgress) + netProgress.post(netProgress.abortFile, [spy.request, spy.endTime, spy.postText, spy.responseText]); +} +/**/ + +// ************************************************************************************************ + +/** + * @domplate Represents a template for XHRs logged in the Console panel. The body of the + * log (displayed when expanded) is rendered using {@link Firebug.NetMonitor.NetInfoBody}. + */ + +Firebug.Spy.XHR = domplate(Firebug.Rep, +/** @lends Firebug.Spy.XHR */ + +{ + tag: + DIV({"class": "spyHead", _repObject: "$object"}, + TABLE({"class": "spyHeadTable focusRow outerFocusRow", cellpadding: 0, cellspacing: 0, + "role": "listitem", "aria-expanded": "false"}, + TBODY({"role": "presentation"}, + TR({"class": "spyRow"}, + TD({"class": "spyTitleCol spyCol", onclick: "$onToggleBody"}, + DIV({"class": "spyTitle"}, + "$object|getCaption" + ), + DIV({"class": "spyFullTitle spyTitle"}, + "$object|getFullUri" + ) + ), + TD({"class": "spyCol"}, + DIV({"class": "spyStatus"}, "$object|getStatus") + ), + TD({"class": "spyCol"}, + SPAN({"class": "spyIcon"}) + ), + TD({"class": "spyCol"}, + SPAN({"class": "spyTime"}) + ), + TD({"class": "spyCol"}, + TAG(FirebugReps.SourceLink.tag, {object: "$object.sourceLink"}) + ) + ) + ) + ) + ), + + getCaption: function(spy) + { + return spy.method.toUpperCase() + " " + cropString(spy.getURL(), 100); + }, + + getFullUri: function(spy) + { + return spy.method.toUpperCase() + " " + spy.getURL(); + }, + + getStatus: function(spy) + { + var text = ""; + if (spy.statusCode) + text += spy.statusCode + " "; + + if (spy.statusText) + return text += spy.statusText; + + return text; + }, + + onToggleBody: function(event) + { + var target = event.currentTarget || event.srcElement; + var logRow = getAncestorByClass(target, "logRow-spy"); + + if (isLeftClick(event)) + { + toggleClass(logRow, "opened"); + + var spy = getChildByClass(logRow, "spyHead").repObject; + var spyHeadTable = getAncestorByClass(target, "spyHeadTable"); + + if (hasClass(logRow, "opened")) + { + updateHttpSpyInfo(spy, logRow); + if (spyHeadTable) + spyHeadTable.setAttribute('aria-expanded', 'true'); + } + else + { + //var netInfoBox = getChildByClass(spy.logRow, "spyHead", "netInfoBody"); + //dispatch(Firebug.NetMonitor.NetInfoBody.fbListeners, "destroyTabBody", [netInfoBox, spy]); + //if (spyHeadTable) + // spyHeadTable.setAttribute('aria-expanded', 'false'); + } + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + copyURL: function(spy) + { + copyToClipboard(spy.getURL()); + }, + + copyParams: function(spy) + { + var text = spy.postText; + if (!text) + return; + + var url = reEncodeURL(spy, text, true); + copyToClipboard(url); + }, + + copyResponse: function(spy) + { + copyToClipboard(spy.responseText); + }, + + openInTab: function(spy) + { + openNewTab(spy.getURL(), spy.postText); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + supportsObject: function(object) + { + // TODO: xxxpedro spy xhr + return false; + + return object instanceof Firebug.Spy.XMLHttpRequestSpy; + }, + + browseObject: function(spy, context) + { + var url = spy.getURL(); + openNewTab(url); + return true; + }, + + getRealObject: function(spy, context) + { + return spy.xhrRequest; + }, + + getContextMenuItems: function(spy) + { + var items = [ + {label: "CopyLocation", command: bindFixed(this.copyURL, this, spy) } + ]; + + if (spy.postText) + { + items.push( + {label: "CopyLocationParameters", command: bindFixed(this.copyParams, this, spy) } + ); + } + + items.push( + {label: "CopyResponse", command: bindFixed(this.copyResponse, this, spy) }, + "-", + {label: "OpenInTab", command: bindFixed(this.openInTab, this, spy) } + ); + + return items; + } +}); + +// ************************************************************************************************ + +function updateTime(spy) +{ + var timeBox = spy.logRow.getElementsByClassName("spyTime").item(0); + if (spy.responseTime) + timeBox.textContent = " " + formatTime(spy.responseTime); +} + +function updateLogRow(spy) +{ + updateTime(spy); + + var statusBox = spy.logRow.getElementsByClassName("spyStatus").item(0); + statusBox.textContent = Firebug.Spy.XHR.getStatus(spy); + + removeClass(spy.logRow, "loading"); + setClass(spy.logRow, "loaded"); + + try + { + var errorRange = Math.floor(spy.xhrRequest.status/100); + if (errorRange == 4 || errorRange == 5) + setClass(spy.logRow, "error"); + } + catch (exc) + { + } +} + +var updateHttpSpyInfo = function updateHttpSpyInfo(spy, logRow) +{ + if (!spy.logRow && logRow) + spy.logRow = logRow; + + if (!spy.logRow || !hasClass(spy.logRow, "opened")) + return; + + if (!spy.params) + //spy.params = parseURLParams(spy.href+""); + spy.params = parseURLParams(spy.href+""); + + if (!spy.requestHeaders) + spy.requestHeaders = getRequestHeaders(spy); + + if (!spy.responseHeaders && spy.loaded) + spy.responseHeaders = getResponseHeaders(spy); + + var template = Firebug.NetMonitor.NetInfoBody; + var netInfoBox = getChildByClass(spy.logRow, "spyHead", "netInfoBody"); + if (!netInfoBox) + { + var head = getChildByClass(spy.logRow, "spyHead"); + netInfoBox = template.tag.append({"file": spy}, head); + dispatch(template.fbListeners, "initTabBody", [netInfoBox, spy]); + template.selectTabByName(netInfoBox, "Response"); + } + else + { + template.updateInfo(netInfoBox, spy, spy.context); + } +}; + + + +// ************************************************************************************************ + +function getRequestHeaders(spy) +{ + var headers = []; + + var channel = spy.xhrRequest.channel; + if (channel instanceof Ci.nsIHttpChannel) + { + channel.visitRequestHeaders({ + visitHeader: function(name, value) + { + headers.push({name: name, value: value}); + } + }); + } + + return headers; +} + +function getResponseHeaders(spy) +{ + var headers = []; + + try + { + var channel = spy.xhrRequest.channel; + if (channel instanceof Ci.nsIHttpChannel) + { + channel.visitResponseHeaders({ + visitHeader: function(name, value) + { + headers.push({name: name, value: value}); + } + }); + } + } + catch (exc) + { + if (FBTrace.DBG_SPY || FBTrace.DBG_ERRORS) + FBTrace.sysout("spy.getResponseHeaders; EXCEPTION " + + safeGetRequestName(spy.request), exc); + } + + return headers; +} + +// ************************************************************************************************ +// Registration + +Firebug.registerModule(Firebug.Spy); +//Firebug.registerRep(Firebug.Spy.XHR); + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ + +// List of JSON content types. +var contentTypes = +{ + "text/plain": 1, + "text/javascript": 1, + "text/x-javascript": 1, + "text/json": 1, + "text/x-json": 1, + "application/json": 1, + "application/x-json": 1, + "application/javascript": 1, + "application/x-javascript": 1, + "application/json-rpc": 1 +}; + +// ************************************************************************************************ +// Model implementation + +Firebug.JSONViewerModel = extend(Firebug.Module, +{ + dispatchName: "jsonViewer", + initialize: function() + { + Firebug.NetMonitor.NetInfoBody.addListener(this); + + // Used by Firebug.DOMPanel.DirTable domplate. + this.toggles = {}; + }, + + shutdown: function() + { + Firebug.NetMonitor.NetInfoBody.removeListener(this); + }, + + initTabBody: function(infoBox, file) + { + if (FBTrace.DBG_JSONVIEWER) + FBTrace.sysout("jsonviewer.initTabBody", infoBox); + + // Let listeners to parse the JSON. + dispatch(this.fbListeners, "onParseJSON", [file]); + + // The JSON is still no there, try to parse most common cases. + if (!file.jsonObject) + { + ///if (this.isJSON(safeGetContentType(file.request), file.responseText)) + if (this.isJSON(file.mimeType, file.responseText)) + file.jsonObject = this.parseJSON(file); + } + + // The jsonObject is created so, the JSON tab can be displayed. + if (file.jsonObject && hasProperties(file.jsonObject)) + { + Firebug.NetMonitor.NetInfoBody.appendTab(infoBox, "JSON", + ///$STR("jsonviewer.tab.JSON")); + $STR("JSON")); + + if (FBTrace.DBG_JSONVIEWER) + FBTrace.sysout("jsonviewer.initTabBody; JSON object available " + + (typeof(file.jsonObject) != "undefined"), file.jsonObject); + } + }, + + isJSON: function(contentType, data) + { + // Workaround for JSON responses without proper content type + // Let's consider all responses starting with "{" as JSON. In the worst + // case there will be an exception when parsing. This means that no-JSON + // responses (and post data) (with "{") can be parsed unnecessarily, + // which represents a little overhead, but this happens only if the request + // is actually expanded by the user in the UI (Net & Console panels). + + ///var responseText = data ? trimLeft(data) : null; + ///if (responseText && responseText.indexOf("{") == 0) + /// return true; + var responseText = data ? trim(data) : null; + if (responseText && responseText.indexOf("{") == 0) + return true; + + if (!contentType) + return false; + + contentType = contentType.split(";")[0]; + contentType = trim(contentType); + return contentTypes[contentType]; + }, + + // Update listener for TabView + updateTabBody: function(infoBox, file, context) + { + var tab = infoBox.selectedTab; + ///var tabBody = infoBox.getElementsByClassName("netInfoJSONText").item(0); + var tabBody = $$(".netInfoJSONText", infoBox)[0]; + if (!hasClass(tab, "netInfoJSONTab") || tabBody.updated) + return; + + tabBody.updated = true; + + if (file.jsonObject) { + Firebug.DOMPanel.DirTable.tag.replace( + {object: file.jsonObject, toggles: this.toggles}, tabBody); + } + }, + + parseJSON: function(file) + { + var jsonString = new String(file.responseText); + ///return parseJSONString(jsonString, "http://" + file.request.originalURI.host); + return parseJSONString(jsonString); + } +}); + +// ************************************************************************************************ +// Registration + +Firebug.registerModule(Firebug.JSONViewerModel); + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// Constants + +// List of XML related content types. +var xmlContentTypes = +[ + "text/xml", + "application/xml", + "application/xhtml+xml", + "application/rss+xml", + "application/atom+xml",, + "application/vnd.mozilla.maybe.feed", + "application/rdf+xml", + "application/vnd.mozilla.xul+xml" +]; + +// ************************************************************************************************ +// Model implementation + +/** + * @module Implements viewer for XML based network responses. In order to create a new + * tab wihin network request detail, a listener is registered into + * Firebug.NetMonitor.NetInfoBody object. + */ +Firebug.XMLViewerModel = extend(Firebug.Module, +{ + dispatchName: "xmlViewer", + + initialize: function() + { + ///Firebug.ActivableModule.initialize.apply(this, arguments); + Firebug.Module.initialize.apply(this, arguments); + Firebug.NetMonitor.NetInfoBody.addListener(this); + }, + + shutdown: function() + { + ///Firebug.ActivableModule.shutdown.apply(this, arguments); + Firebug.Module.shutdown.apply(this, arguments); + Firebug.NetMonitor.NetInfoBody.removeListener(this); + }, + + /** + * Check response's content-type and if it's a XML, create a new tab with XML preview. + */ + initTabBody: function(infoBox, file) + { + if (FBTrace.DBG_XMLVIEWER) + FBTrace.sysout("xmlviewer.initTabBody", infoBox); + + // If the response is XML let's display a pretty preview. + ///if (this.isXML(safeGetContentType(file.request))) + if (this.isXML(file.mimeType, file.responseText)) + { + Firebug.NetMonitor.NetInfoBody.appendTab(infoBox, "XML", + ///$STR("xmlviewer.tab.XML")); + $STR("XML")); + + if (FBTrace.DBG_XMLVIEWER) + FBTrace.sysout("xmlviewer.initTabBody; XML response available"); + } + }, + + isXML: function(contentType) + { + if (!contentType) + return false; + + // Look if the response is XML based. + for (var i=0; i\s*/, ""); + + var div = parentNode.ownerDocument.createElement("div"); + div.innerHTML = xmlText; + + var root = div.getElementsByTagName("*")[0]; + + /*** + var parser = CCIN("@mozilla.org/xmlextras/domparser;1", "nsIDOMParser"); + var doc = parser.parseFromString(text, "text/xml"); + var root = doc.documentElement; + + // Error handling + var nsURI = "http://www.mozilla.org/newlayout/xml/parsererror.xml"; + if (root.namespaceURI == nsURI && root.nodeName == "parsererror") + { + this.ParseError.tag.replace({error: { + message: root.firstChild.nodeValue, + source: root.lastChild.textContent + }}, parentNode); + return; + } + /**/ + + if (FBTrace.DBG_XMLVIEWER) + FBTrace.sysout("xmlviewer.updateTabBody; XML response parsed", doc); + + // Override getHidden in these templates. The parsed XML documen is + // hidden, but we want to display it using 'visible' styling. + /* + var templates = [ + Firebug.HTMLPanel.CompleteElement, + Firebug.HTMLPanel.Element, + Firebug.HTMLPanel.TextElement, + Firebug.HTMLPanel.EmptyElement, + Firebug.HTMLPanel.XEmptyElement, + ]; + + var originals = []; + for (var i=0; iFirebug.XMLViewerModel. + */ +Firebug.XMLViewerModel.ParseError = domplate(Firebug.Rep, +{ + tag: + DIV({"class": "xmlInfoError"}, + DIV({"class": "xmlInfoErrorMsg"}, "$error.message"), + PRE({"class": "xmlInfoErrorSource"}, "$error|getSource") + ), + + getSource: function(error) + { + var parts = error.source.split("\n"); + if (parts.length != 2) + return error.source; + + var limit = 50; + var column = parts[1].length; + if (column >= limit) { + parts[0] = "..." + parts[0].substr(column - limit); + parts[1] = "..." + parts[1].substr(column - limit); + } + + if (parts[0].length > 80) + parts[0] = parts[0].substr(0, 80) + "..."; + + return parts.join("\n"); + } +}); + +// ************************************************************************************************ +// Registration + +Firebug.registerModule(Firebug.XMLViewerModel); + +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +// Globals + +var ElementCache = Firebug.Lite.Cache.Element; +var cacheID = Firebug.Lite.Cache.ID; + +var ignoreHTMLProps = +{ + // ignores the attributes injected by Sizzle, otherwise it will + // be visible on IE (when enumerating element.attributes) + sizcache: 1, + sizset: 1 +}; + +// ignores also the cache property injected by firebug +ignoreHTMLProps[cacheID] = 1; + + +// ************************************************************************************************ +// HTML Module + +Firebug.HTML = extend(Firebug.Module, +{ + appendTreeNode: function(nodeArray, html) + { + var reTrim = /^\s+|\s+$/g; + + if (!nodeArray.length) nodeArray = [nodeArray]; + + for (var n=0, node; node=nodeArray[n]; n++) + { + if (node.nodeType == 1) + { + if (Firebug.ignoreFirebugElements && node.firebugIgnore) continue; + + var uid = ElementCache(node); + var child = node.childNodes; + var childLength = child.length; + + var nodeName = node.nodeName.toLowerCase(); + + var nodeVisible = isVisible(node); + + var hasSingleTextChild = childLength == 1 && node.firstChild.nodeType == 3 && + nodeName != "script" && nodeName != "style"; + + var nodeControl = !hasSingleTextChild && childLength > 0 ? + ('
                  ') : ''; + + 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 || 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; + + 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; + + 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: true, + 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.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.HTML.selectTreeNode(ElementCache(Firebug.browser.document.body)); + } + + // 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(FirebugChrome.selectedHTMLElementId) + Firebug.HTML.selectTreeNode(FirebugChrome.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"; + + selectedElement = e; + + FirebugChrome.selectedHTMLElementId = e.id; + + var target = ElementCache.get(e.id); + var selectedSidePanel = Firebug.chrome.getPanel("HTML").sidePanelBar.selectedPanel; + + var stack = FirebugChrome.htmlSelectionStack; + + stack.unshift(target); + + if (stack.length > 2) + stack.pop(); + + var lazySelect = function() + { + selectedSidePanelTS = new Date().getTime(); + + 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') + { + 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(' ]'); + } + +}; + + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +/* + +Hack: +Firebug.chrome.currentPanel = Firebug.chrome.selectedPanel; +Firebug.showInfoTips = true; +Firebug.InfoTip.initializeBrowser(Firebug.chrome); + +/**/ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// Constants + +var maxWidth = 100, maxHeight = 80; +var infoTipMargin = 10; +var infoTipWindowPadding = 25; + +// ************************************************************************************************ + +Firebug.InfoTip = extend(Firebug.Module, +{ + dispatchName: "infoTip", + tags: domplate( + { + infoTipTag: DIV({"class": "infoTip"}), + + colorTag: + DIV({style: "background: $rgbValue; width: 100px; height: 40px"}, " "), + + imgTag: + DIV({"class": "infoTipImageBox infoTipLoading"}, + IMG({"class": "infoTipImage", src: "$urlValue", repeat: "$repeat", + onload: "$onLoadImage"}), + IMG({"class": "infoTipBgImage", collapsed: true, src: "blank.gif"}), + DIV({"class": "infoTipCaption"}) + ), + + onLoadImage: function(event) + { + var img = event.currentTarget || event.srcElement; + ///var bgImg = img.nextSibling; + ///if (!bgImg) + /// return; // Sometimes gets called after element is dead + + ///var caption = bgImg.nextSibling; + var innerBox = img.parentNode; + + /// TODO: xxxpedro infoTip hack + var caption = getElementByClass(innerBox, "infoTipCaption"); + var bgImg = getElementByClass(innerBox, "infoTipBgImage"); + if (!bgImg) + return; // Sometimes gets called after element is dead + + // TODO: xxxpedro infoTip IE and timing issue + // TODO: use offline document to avoid flickering + if (isIE) + removeClass(innerBox, "infoTipLoading"); + + var updateInfoTip = function(){ + + var w = img.naturalWidth || img.width || 10, + h = img.naturalHeight || img.height || 10; + + var repeat = img.getAttribute("repeat"); + + if (repeat == "repeat-x" || (w == 1 && h > 1)) + { + collapse(img, true); + collapse(bgImg, false); + bgImg.style.background = "url(" + img.src + ") repeat-x"; + bgImg.style.width = maxWidth + "px"; + if (h > maxHeight) + bgImg.style.height = maxHeight + "px"; + else + bgImg.style.height = h + "px"; + } + else if (repeat == "repeat-y" || (h == 1 && w > 1)) + { + collapse(img, true); + collapse(bgImg, false); + bgImg.style.background = "url(" + img.src + ") repeat-y"; + bgImg.style.height = maxHeight + "px"; + if (w > maxWidth) + bgImg.style.width = maxWidth + "px"; + else + bgImg.style.width = w + "px"; + } + else if (repeat == "repeat" || (w == 1 && h == 1)) + { + collapse(img, true); + collapse(bgImg, false); + bgImg.style.background = "url(" + img.src + ") repeat"; + bgImg.style.width = maxWidth + "px"; + bgImg.style.height = maxHeight + "px"; + } + else + { + if (w > maxWidth || h > maxHeight) + { + if (w > h) + { + img.style.width = maxWidth + "px"; + img.style.height = Math.round((h / w) * maxWidth) + "px"; + } + else + { + img.style.width = Math.round((w / h) * maxHeight) + "px"; + img.style.height = maxHeight + "px"; + } + } + } + + //caption.innerHTML = $STRF("Dimensions", [w, h]); + caption.innerHTML = $STRF(w + " x " + h); + + + }; + + if (isIE) + setTimeout(updateInfoTip, 0); + else + { + updateInfoTip(); + removeClass(innerBox, "infoTipLoading"); + } + + /// + } + + /* + /// onLoadImage original + onLoadImage: function(event) + { + var img = event.currentTarget; + var bgImg = img.nextSibling; + if (!bgImg) + return; // Sometimes gets called after element is dead + + var caption = bgImg.nextSibling; + var innerBox = img.parentNode; + + var w = img.naturalWidth, h = img.naturalHeight; + var repeat = img.getAttribute("repeat"); + + if (repeat == "repeat-x" || (w == 1 && h > 1)) + { + collapse(img, true); + collapse(bgImg, false); + bgImg.style.background = "url(" + img.src + ") repeat-x"; + bgImg.style.width = maxWidth + "px"; + if (h > maxHeight) + bgImg.style.height = maxHeight + "px"; + else + bgImg.style.height = h + "px"; + } + else if (repeat == "repeat-y" || (h == 1 && w > 1)) + { + collapse(img, true); + collapse(bgImg, false); + bgImg.style.background = "url(" + img.src + ") repeat-y"; + bgImg.style.height = maxHeight + "px"; + if (w > maxWidth) + bgImg.style.width = maxWidth + "px"; + else + bgImg.style.width = w + "px"; + } + else if (repeat == "repeat" || (w == 1 && h == 1)) + { + collapse(img, true); + collapse(bgImg, false); + bgImg.style.background = "url(" + img.src + ") repeat"; + bgImg.style.width = maxWidth + "px"; + bgImg.style.height = maxHeight + "px"; + } + else + { + if (w > maxWidth || h > maxHeight) + { + if (w > h) + { + img.style.width = maxWidth + "px"; + img.style.height = Math.round((h / w) * maxWidth) + "px"; + } + else + { + img.style.width = Math.round((w / h) * maxHeight) + "px"; + img.style.height = maxHeight + "px"; + } + } + } + + caption.innerHTML = $STRF("Dimensions", [w, h]); + + removeClass(innerBox, "infoTipLoading"); + } + /**/ + + }), + + initializeBrowser: function(browser) + { + browser.onInfoTipMouseOut = bind(this.onMouseOut, this, browser); + browser.onInfoTipMouseMove = bind(this.onMouseMove, this, browser); + + ///var doc = browser.contentDocument; + var doc = browser.document; + if (!doc) + return; + + ///doc.addEventListener("mouseover", browser.onInfoTipMouseMove, true); + ///doc.addEventListener("mouseout", browser.onInfoTipMouseOut, true); + ///doc.addEventListener("mousemove", browser.onInfoTipMouseMove, true); + addEvent(doc, "mouseover", browser.onInfoTipMouseMove); + addEvent(doc, "mouseout", browser.onInfoTipMouseOut); + addEvent(doc, "mousemove", browser.onInfoTipMouseMove); + + return browser.infoTip = this.tags.infoTipTag.append({}, getBody(doc)); + }, + + uninitializeBrowser: function(browser) + { + if (browser.infoTip) + { + ///var doc = browser.contentDocument; + var doc = browser.document; + ///doc.removeEventListener("mouseover", browser.onInfoTipMouseMove, true); + ///doc.removeEventListener("mouseout", browser.onInfoTipMouseOut, true); + ///doc.removeEventListener("mousemove", browser.onInfoTipMouseMove, true); + removeEvent(doc, "mouseover", browser.onInfoTipMouseMove); + removeEvent(doc, "mouseout", browser.onInfoTipMouseOut); + removeEvent(doc, "mousemove", browser.onInfoTipMouseMove); + + browser.infoTip.parentNode.removeChild(browser.infoTip); + delete browser.infoTip; + delete browser.onInfoTipMouseMove; + } + }, + + showInfoTip: function(infoTip, panel, target, x, y, rangeParent, rangeOffset) + { + if (!Firebug.showInfoTips) + return; + + var scrollParent = getOverflowParent(target); + var scrollX = x + (scrollParent ? scrollParent.scrollLeft : 0); + + if (panel.showInfoTip(infoTip, target, scrollX, y, rangeParent, rangeOffset)) + { + var htmlElt = infoTip.ownerDocument.documentElement; + var panelWidth = htmlElt.clientWidth; + var panelHeight = htmlElt.clientHeight; + + if (x+infoTip.offsetWidth+infoTipMargin > panelWidth) + { + infoTip.style.left = Math.max(0, panelWidth-(infoTip.offsetWidth+infoTipMargin)) + "px"; + infoTip.style.right = "auto"; + } + else + { + infoTip.style.left = (x+infoTipMargin) + "px"; + infoTip.style.right = "auto"; + } + + if (y+infoTip.offsetHeight+infoTipMargin > panelHeight) + { + infoTip.style.top = Math.max(0, panelHeight-(infoTip.offsetHeight+infoTipMargin)) + "px"; + infoTip.style.bottom = "auto"; + } + else + { + infoTip.style.top = (y+infoTipMargin) + "px"; + infoTip.style.bottom = "auto"; + } + + if (FBTrace.DBG_INFOTIP) + FBTrace.sysout("infotip.showInfoTip; top: " + infoTip.style.top + + ", left: " + infoTip.style.left + ", bottom: " + infoTip.style.bottom + + ", right:" + infoTip.style.right + ", offsetHeight: " + infoTip.offsetHeight + + ", offsetWidth: " + infoTip.offsetWidth + + ", x: " + x + ", panelWidth: " + panelWidth + + ", y: " + y + ", panelHeight: " + panelHeight); + + infoTip.setAttribute("active", "true"); + } + else + this.hideInfoTip(infoTip); + }, + + hideInfoTip: function(infoTip) + { + if (infoTip) + infoTip.removeAttribute("active"); + }, + + onMouseOut: function(event, browser) + { + if (!event.relatedTarget) + this.hideInfoTip(browser.infoTip); + }, + + onMouseMove: function(event, browser) + { + // Ignore if the mouse is moving over the existing info tip. + if (getAncestorByClass(event.target, "infoTip")) + return; + + if (browser.currentPanel) + { + var x = event.clientX, y = event.clientY, target = event.target || event.srcElement; + this.showInfoTip(browser.infoTip, browser.currentPanel, target, x, y, event.rangeParent, event.rangeOffset); + } + else + this.hideInfoTip(browser.infoTip); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + populateColorInfoTip: function(infoTip, color) + { + this.tags.colorTag.replace({rgbValue: color}, infoTip); + return true; + }, + + populateImageInfoTip: function(infoTip, url, repeat) + { + if (!repeat) + repeat = "no-repeat"; + + this.tags.imgTag.replace({urlValue: url, repeat: repeat}, infoTip); + + return true; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Module + + disable: function() + { + // XXXjoe For each browser, call uninitializeBrowser + }, + + showPanel: function(browser, panel) + { + if (panel) + { + var infoTip = panel.panelBrowser.infoTip; + if (!infoTip) + infoTip = this.initializeBrowser(panel.panelBrowser); + this.hideInfoTip(infoTip); + } + + }, + + showSidePanel: function(browser, panel) + { + this.showPanel(browser, panel); + } +}); + +// ************************************************************************************************ + +Firebug.registerModule(Firebug.InfoTip); + +// ************************************************************************************************ + +}}); + + +/* See license.txt for terms of usage */ + +// move to FBL +(function() { + +// ************************************************************************************************ +// XPath + +/** + * Gets an XPath for an element which describes its hierarchical location. + */ +this.getElementXPath = function(element) +{ + if (element && element.id) + return '//*[@id="' + element.id + '"]'; + else + return this.getElementTreeXPath(element); +}; + +this.getElementTreeXPath = function(element) +{ + var paths = []; + + for (; element && element.nodeType == 1; element = element.parentNode) + { + var index = 0; + for (var sibling = element.previousSibling; sibling; sibling = sibling.previousSibling) + { + if (sibling.nodeName == element.nodeName) + ++index; + } + + var tagName = element.nodeName.toLowerCase(); + var pathIndex = (index ? "[" + (index+1) + "]" : ""); + paths.splice(0, 0, tagName + pathIndex); + } + + return paths.length ? "/" + paths.join("/") : null; +}; + +this.getElementsByXPath = function(doc, xpath) +{ + var nodes = []; + + try { + var result = doc.evaluate(xpath, doc, null, XPathResult.ANY_TYPE, null); + for (var item = result.iterateNext(); item; item = result.iterateNext()) + nodes.push(item); + } + catch (exc) + { + // Invalid xpath expressions make their way here sometimes. If that happens, + // we still want to return an empty set without an exception. + } + + return nodes; +}; + +this.getRuleMatchingElements = function(rule, doc) +{ + var css = rule.selectorText; + var xpath = this.cssToXPath(css); + return this.getElementsByXPath(doc, xpath); +}; + + +}).call(FBL); + + + + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ + +var toCamelCase = function toCamelCase(s) +{ + return s.replace(reSelectorCase, toCamelCaseReplaceFn); +}; + +var toSelectorCase = function toSelectorCase(s) +{ + return s.replace(reCamelCase, "-$1").toLowerCase(); + +}; + +var reCamelCase = /([A-Z])/g; +var reSelectorCase = /\-(.)/g; +var toCamelCaseReplaceFn = function toCamelCaseReplaceFn(m,g) +{ + return g.toUpperCase(); +}; + + + + + +// ************************************************************************************************ + +var ElementCache = Firebug.Lite.Cache.Element; +var StyleSheetCache = Firebug.Lite.Cache.StyleSheet; + +var globalCSSRuleIndex; + +var externalStyleSheetURLs = []; +var 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") + ) +}); + + +var processAllStyleSheetsTimeout = null; +var loadExternalStylesheet = function(doc, styleSheetIterator, styleSheet) +{ + var url = styleSheet.href; + styleSheet.firebugIgnore = true; + + var source = Firebug.Lite.Proxy.load(url); + + // TODO: check for null and error responses + + + // remove comments + //var reMultiComment = /(\/\*([^\*]|\*(?!\/))*\*\/)/g; + //source = source.replace(reMultiComment, ""); + + // convert relative addresses to absolute ones + source = source.replace(/url\(([^\)]+)\)/g, function(a,name){ + + var hasDomain = /\w+:\/\/./.test(name); + + if (!hasDomain) + { + name = name.replace(/^(["'])(.+)\1$/, "$2"); + var first = name.charAt(0); + + // relative path, based on root + if (first == "/") + { + // TODO: xxxpedro move to lib or Firebug.Lite.something + // getURLRoot + var m = /^([^:]+:\/{1,3}[^\/]+)/.exec(url); + + return m ? + "url(" + m[1] + name + ")" : + "url(" + name + ")"; + } + // relative path, based on current location + else + { + // TODO: xxxpedro move to lib or Firebug.Lite.something + // getURLPath + var path = url.replace(/[^\/]+\.[\w\d]+(\?.+|#.+)?$/g, ""); + + path = path + name; + + var reBack = /[^\/]+\/\.\.\//; + while(reBack.test(path)) + { + path = path.replace(reBack, ""); + } + + //console.log("url(" + path + ")"); + + return "url(" + path + ")"; + } + } + + // if it is an absolute path, there is nothing to do + return a; + }); + + var oldStyle = styleSheet.ownerNode; + + if (!oldStyle) return; + + if (!oldStyle.parentNode) return; + + var style = createGlobalElement("style"); + style.setAttribute("charset","utf-8"); + style.setAttribute("type", "text/css"); + style.innerHTML = source; + + //debugger; + oldStyle.parentNode.insertBefore(style, oldStyle.nextSibling); + oldStyle.parentNode.removeChild(oldStyle); + + + //doc.getElementsByTagName("head")[0].appendChild(style); + + doc.styleSheets[doc.styleSheets.length-1].externalURL = url; + + console.log(url, "call " + externalStyleSheetURLs.length, source); + + externalStyleSheetURLs.pop(); + + if (processAllStyleSheetsTimeout) + { + clearTimeout(processAllStyleSheetsTimeout); + } + + processAllStyleSheetsTimeout = setTimeout(function(){ + console.log("processing"); + FBL.processAllStyleSheets(doc, styleSheetIterator); + processAllStyleSheetsTimeout = null; + },200); + +}; + + +FBL.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 maxSpecificity) + { + maxSpecificity = spec; + mostSpecificSelector = sel; + } + } + } + + rule.specificity = maxSpecificity; + } + } + + rules.sort(sortElementRules); + //rules.sort(solveRulesTied); + + return rules; +}; + +var sortElementRules = function(a, b) +{ + var ruleA = CSSRuleMap[a]; + var ruleB = CSSRuleMap[b]; + + var specificityA = ruleA.specificity; + var specificityB = ruleB.specificity; + + if (specificityA > specificityB) + return 1; + + else if (specificityA < specificityB) + return -1; + + else + return ruleA.order > ruleB.order ? 1 : -1; +}; + +var solveRulesTied = function(a, b) +{ + var ruleA = CSSRuleMap[a]; + var ruleB = CSSRuleMap[b]; + + if (ruleA.specificity == ruleB.specificity) + return ruleA.order > ruleB.order ? 1 : -1; + + return null; +}; + +var reSelectorTag = /(^|\s)(?:\w+)/g; +var reSelectorClass = /\.[\w\d_-]+/g; +var reSelectorId = /#[\w\d_-]+/g; + +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; +}; + +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ + + +// ************************************************************************************************ +// Constants + +//const Cc = Components.classes; +//const Ci = Components.interfaces; +//const nsIDOMCSSStyleRule = Ci.nsIDOMCSSStyleRule; +//const nsIInterfaceRequestor = Ci.nsIInterfaceRequestor; +//const nsISelectionDisplay = Ci.nsISelectionDisplay; +//const nsISelectionController = Ci.nsISelectionController; + +// See: http://mxr.mozilla.org/mozilla1.9.2/source/content/events/public/nsIEventStateManager.h#153 +//const STATE_ACTIVE = 0x01; +//const STATE_FOCUS = 0x02; +//const STATE_HOVER = 0x04; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +Firebug.SourceBoxPanel = Firebug.Panel; + +var domUtils = null; + +var textContent = isIE ? "innerText" : "textContent"; +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var CSSDomplateBase = { + isEditable: function(rule) + { + return !rule.isSystemSheet; + }, + isSelectorEditable: function(rule) + { + return rule.isSelectorEditable && this.isEditable(rule); + } +}; + +var CSSPropTag = domplate(CSSDomplateBase, { + tag: DIV({"class": "cssProp focusRow", $disabledStyle: "$prop.disabled", + $editGroup: "$rule|isEditable", + $cssOverridden: "$prop.overridden", role : "option"}, + A({"class": "cssPropDisable"}, "  "), + SPAN({"class": "cssPropName", $editable: "$rule|isEditable"}, "$prop.name"), + SPAN({"class": "cssColon"}, ":"), + SPAN({"class": "cssPropValue", $editable: "$rule|isEditable"}, "$prop.value$prop.important"), + SPAN({"class": "cssSemi"}, ";") + ) +}); + +var CSSRuleTag = + TAG("$rule.tag", {rule: "$rule"}); + +var CSSImportRuleTag = domplate({ + tag: DIV({"class": "cssRule insertInto focusRow importRule", _repObject: "$rule.rule"}, + "@import "", + A({"class": "objectLink", _repObject: "$rule.rule.styleSheet"}, "$rule.rule.href"), + "";" + ) +}); + +var CSSStyleRuleTag = domplate(CSSDomplateBase, { + tag: DIV({"class": "cssRule insertInto", + $cssEditableRule: "$rule|isEditable", + $editGroup: "$rule|isSelectorEditable", + _repObject: "$rule.rule", + "ruleId": "$rule.id", role : 'presentation'}, + DIV({"class": "cssHead focusRow", role : 'listitem'}, + SPAN({"class": "cssSelector", $editable: "$rule|isSelectorEditable"}, "$rule.selector"), " {" + ), + DIV({role : 'group'}, + DIV({"class": "cssPropertyListBox", role : 'listbox'}, + FOR("prop", "$rule.props", + TAG(CSSPropTag.tag, {rule: "$rule", prop: "$prop"}) + ) + ) + ), + DIV({"class": "editable insertBefore", role:"presentation"}, "}") + ) +}); + +var reSplitCSS = /(url\("?[^"\)]+?"?\))|(rgb\(.*?\))|(#[\dA-Fa-f]+)|(-?\d+(\.\d+)?(%|[a-z]{1,2})?)|([^,\s]+)|"(.*?)"/; + +var reURL = /url\("?([^"\)]+)?"?\)/; + +var reRepeat = /no-repeat|repeat-x|repeat-y|repeat/; + +//const sothinkInstalled = !!$("swfcatcherKey_sidebar"); +var sothinkInstalled = false; +var styleGroups = +{ + text: [ + "font-family", + "font-size", + "font-weight", + "font-style", + "color", + "text-transform", + "text-decoration", + "letter-spacing", + "word-spacing", + "line-height", + "text-align", + "vertical-align", + "direction", + "column-count", + "column-gap", + "column-width" + ], + + background: [ + "background-color", + "background-image", + "background-repeat", + "background-position", + "background-attachment", + "opacity" + ], + + box: [ + "width", + "height", + "top", + "right", + "bottom", + "left", + "margin-top", + "margin-right", + "margin-bottom", + "margin-left", + "padding-top", + "padding-right", + "padding-bottom", + "padding-left", + "border-top-width", + "border-right-width", + "border-bottom-width", + "border-left-width", + "border-top-color", + "border-right-color", + "border-bottom-color", + "border-left-color", + "border-top-style", + "border-right-style", + "border-bottom-style", + "border-left-style", + "-moz-border-top-radius", + "-moz-border-right-radius", + "-moz-border-bottom-radius", + "-moz-border-left-radius", + "outline-top-width", + "outline-right-width", + "outline-bottom-width", + "outline-left-width", + "outline-top-color", + "outline-right-color", + "outline-bottom-color", + "outline-left-color", + "outline-top-style", + "outline-right-style", + "outline-bottom-style", + "outline-left-style" + ], + + layout: [ + "position", + "display", + "visibility", + "z-index", + "overflow-x", // http://www.w3.org/TR/2002/WD-css3-box-20021024/#overflow + "overflow-y", + "overflow-clip", + "white-space", + "clip", + "float", + "clear", + "-moz-box-sizing" + ], + + other: [ + "cursor", + "list-style-image", + "list-style-position", + "list-style-type", + "marker-offset", + "user-focus", + "user-select", + "user-modify", + "user-input" + ] +}; + +var styleGroupTitles = +{ + text: "Text", + background: "Background", + box: "Box Model", + layout: "Layout", + other: "Other" +}; + +Firebug.CSSModule = extend(Firebug.Module, +{ + freeEdit: function(styleSheet, value) + { + if (!styleSheet.editStyleSheet) + { + var ownerNode = getStyleSheetOwnerNode(styleSheet); + styleSheet.disabled = true; + + var url = CCSV("@mozilla.org/network/standard-url;1", Components.interfaces.nsIURL); + url.spec = styleSheet.href; + + var editStyleSheet = ownerNode.ownerDocument.createElementNS( + "http://www.w3.org/1999/xhtml", + "style"); + unwrapObject(editStyleSheet).firebugIgnore = true; + editStyleSheet.setAttribute("type", "text/css"); + editStyleSheet.setAttributeNS( + "http://www.w3.org/XML/1998/namespace", + "base", + url.directory); + if (ownerNode.hasAttribute("media")) + { + editStyleSheet.setAttribute("media", ownerNode.getAttribute("media")); + } + + // Insert the edited stylesheet directly after the old one to ensure the styles + // cascade properly. + ownerNode.parentNode.insertBefore(editStyleSheet, ownerNode.nextSibling); + + styleSheet.editStyleSheet = editStyleSheet; + } + + styleSheet.editStyleSheet.innerHTML = value; + if (FBTrace.DBG_CSS) + FBTrace.sysout("css.saveEdit styleSheet.href:"+styleSheet.href+" got innerHTML:"+value+"\n"); + + dispatch(this.fbListeners, "onCSSFreeEdit", [styleSheet, value]); + }, + + insertRule: function(styleSheet, cssText, ruleIndex) + { + if (FBTrace.DBG_CSS) FBTrace.sysout("Insert: " + ruleIndex + " " + cssText); + var insertIndex = styleSheet.insertRule(cssText, ruleIndex); + + dispatch(this.fbListeners, "onCSSInsertRule", [styleSheet, cssText, ruleIndex]); + + return insertIndex; + }, + + deleteRule: function(styleSheet, ruleIndex) + { + if (FBTrace.DBG_CSS) FBTrace.sysout("deleteRule: " + ruleIndex + " " + styleSheet.cssRules.length, styleSheet.cssRules); + dispatch(this.fbListeners, "onCSSDeleteRule", [styleSheet, ruleIndex]); + + styleSheet.deleteRule(ruleIndex); + }, + + setProperty: function(rule, propName, propValue, propPriority) + { + var style = rule.style || rule; + + // Record the original CSS text for the inline case so we can reconstruct at a later + // point for diffing purposes + var baseText = style.cssText; + + // good browsers + if (style.getPropertyValue) + { + var prevValue = style.getPropertyValue(propName); + var prevPriority = style.getPropertyPriority(propName); + + // XXXjoe Gecko bug workaround: Just changing priority doesn't have any effect + // unless we remove the property first + style.removeProperty(propName); + + style.setProperty(propName, propValue, propPriority); + } + // sad browsers + else + { + // TODO: xxxpedro parse CSS rule to find property priority in IE? + //console.log(propName, propValue); + style[toCamelCase(propName)] = propValue; + } + + if (propName) { + dispatch(this.fbListeners, "onCSSSetProperty", [style, propName, propValue, propPriority, prevValue, prevPriority, rule, baseText]); + } + }, + + removeProperty: function(rule, propName, parent) + { + var style = rule.style || rule; + + // Record the original CSS text for the inline case so we can reconstruct at a later + // point for diffing purposes + var baseText = style.cssText; + + if (style.getPropertyValue) + { + + var prevValue = style.getPropertyValue(propName); + var prevPriority = style.getPropertyPriority(propName); + + style.removeProperty(propName); + } + else + { + style[toCamelCase(propName)] = ""; + } + + if (propName) { + dispatch(this.fbListeners, "onCSSRemoveProperty", [style, propName, prevValue, prevPriority, rule, baseText]); + } + }/*, + + cleanupSheets: function(doc, context) + { + // Due to the manner in which the layout engine handles multiple + // references to the same sheet we need to kick it a little bit. + // The injecting a simple stylesheet then removing it will force + // Firefox to regenerate it's CSS hierarchy. + // + // WARN: This behavior was determined anecdotally. + // See http://code.google.com/p/fbug/issues/detail?id=2440 + var style = doc.createElementNS("http://www.w3.org/1999/xhtml", "style"); + style.setAttribute("charset","utf-8"); + unwrapObject(style).firebugIgnore = true; + style.setAttribute("type", "text/css"); + style.innerHTML = "#fbIgnoreStyleDO_NOT_USE {}"; + addStyleSheet(doc, style); + style.parentNode.removeChild(style); + + // https://bugzilla.mozilla.org/show_bug.cgi?id=500365 + // This voodoo touches each style sheet to force some Firefox internal change to allow edits. + var styleSheets = getAllStyleSheets(context); + for(var i = 0; i < styleSheets.length; i++) + { + try + { + var rules = styleSheets[i].cssRules; + if (rules.length > 0) + var touch = rules[0]; + if (FBTrace.DBG_CSS && touch) + FBTrace.sysout("css.show() touch "+typeof(touch)+" in "+(styleSheets[i].href?styleSheets[i].href:context.getName())); + } + catch(e) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("css.show: sheet.cssRules FAILS for "+(styleSheets[i]?styleSheets[i].href:"null sheet")+e, e); + } + } + }, + cleanupSheetHandler: function(event, context) + { + var target = event.target || event.srcElement, + tagName = (target.tagName || "").toLowerCase(); + if (tagName == "link") + { + this.cleanupSheets(target.ownerDocument, context); + } + }, + watchWindow: function(context, win) + { + var cleanupSheets = bind(this.cleanupSheets, this), + cleanupSheetHandler = bind(this.cleanupSheetHandler, this, context), + doc = win.document; + + //doc.addEventListener("DOMAttrModified", cleanupSheetHandler, false); + //doc.addEventListener("DOMNodeInserted", cleanupSheetHandler, false); + }, + loadedContext: function(context) + { + var self = this; + iterateWindows(context.browser.contentWindow, function(subwin) + { + self.cleanupSheets(subwin.document, context); + }); + } + /**/ +}); + +// ************************************************************************************************ + +Firebug.CSSStyleSheetPanel = function() {}; + +Firebug.CSSStyleSheetPanel.prototype = extend(Firebug.SourceBoxPanel, +{ + template: domplate( + { + tag: + DIV({"class": "cssSheet insertInto a11yCSSView"}, + FOR("rule", "$rules", + CSSRuleTag + ), + DIV({"class": "cssSheet editable insertBefore"}, "") + ) + }), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + refresh: function() + { + if (this.location) + this.updateLocation(this.location); + else if (this.selection) + this.updateSelection(this.selection); + }, + + toggleEditing: function() + { + if (!this.stylesheetEditor) + this.stylesheetEditor = new StyleSheetEditor(this.document); + + if (this.editing) + Firebug.Editor.stopEditing(); + else + { + if (!this.location) + return; + + var styleSheet = this.location.editStyleSheet + ? this.location.editStyleSheet.sheet + : this.location; + + var css = getStyleSheetCSS(styleSheet, this.context); + //var topmost = getTopmostRuleLine(this.panelNode); + + this.stylesheetEditor.styleSheet = this.location; + Firebug.Editor.startEditing(this.panelNode, css, this.stylesheetEditor); + //this.stylesheetEditor.scrollToLine(topmost.line, topmost.offset); + } + }, + + getStylesheetURL: function(rule) + { + if (this.location.href) + return this.location.href; + else + return this.context.window.location.href; + }, + + getRuleByLine: function(styleSheet, line) + { + if (!domUtils) + return null; + + var cssRules = styleSheet.cssRules; + for (var i = 0; i < cssRules.length; ++i) + { + var rule = cssRules[i]; + if (rule instanceof CSSStyleRule) + { + var ruleLine = domUtils.getRuleLine(rule); + if (ruleLine >= line) + return rule; + } + } + }, + + highlightRule: function(rule) + { + var ruleElement = Firebug.getElementByRepObject(this.panelNode.firstChild, rule); + if (ruleElement) + { + scrollIntoCenterView(ruleElement, this.panelNode); + setClassTimed(ruleElement, "jumpHighlight", this.context); + } + }, + + getStyleSheetRules: function(context, styleSheet) + { + var isSystemSheet = isSystemStyleSheet(styleSheet); + + function appendRules(cssRules) + { + for (var i = 0; i < cssRules.length; ++i) + { + var rule = cssRules[i]; + + // TODO: xxxpedro opera instanceof stylesheet remove the following comments when + // the issue with opera and style sheet Classes has been solved. + + //if (rule instanceof CSSStyleRule) + if (instanceOf(rule, "CSSStyleRule")) + { + var props = this.getRuleProperties(context, rule); + //var line = domUtils.getRuleLine(rule); + var line = null; + + var selector = rule.selectorText; + + if (isIE) + { + selector = selector.replace(reSelectorTag, + function(s){return s.toLowerCase();}); + } + + var ruleId = rule.selectorText+"/"+line; + rules.push({tag: CSSStyleRuleTag.tag, rule: rule, id: ruleId, + selector: selector, props: props, + isSystemSheet: isSystemSheet, + isSelectorEditable: true}); + } + //else if (rule instanceof CSSImportRule) + else if (instanceOf(rule, "CSSImportRule")) + rules.push({tag: CSSImportRuleTag.tag, rule: rule}); + //else if (rule instanceof CSSMediaRule) + else if (instanceOf(rule, "CSSMediaRule")) + appendRules.apply(this, [rule.cssRules]); + else + { + if (FBTrace.DBG_ERRORS || FBTrace.DBG_CSS) + FBTrace.sysout("css getStyleSheetRules failed to classify a rule ", rule); + } + } + } + + var rules = []; + appendRules.apply(this, [styleSheet.cssRules || styleSheet.rules]); + return rules; + }, + + parseCSSProps: function(style, inheritMode) + { + var props = []; + + if (Firebug.expandShorthandProps) + { + var count = style.length-1, + index = style.length; + while (index--) + { + var propName = style.item(count - index); + this.addProperty(propName, style.getPropertyValue(propName), !!style.getPropertyPriority(propName), false, inheritMode, props); + } + } + else + { + var lines = style.cssText.match(/(?:[^;\(]*(?:\([^\)]*?\))?[^;\(]*)*;?/g); + var propRE = /\s*([^:\s]*)\s*:\s*(.*?)\s*(! important)?;?$/; + var line,i=0; + // TODO: xxxpedro port to firebug: variable leaked into global namespace + var m; + + while(line=lines[i++]){ + m = propRE.exec(line); + if(!m) + continue; + //var name = m[1], value = m[2], important = !!m[3]; + if (m[2]) + this.addProperty(m[1], m[2], !!m[3], false, inheritMode, props); + }; + } + + return props; + }, + + getRuleProperties: function(context, rule, inheritMode) + { + var props = this.parseCSSProps(rule.style, inheritMode); + + // TODO: xxxpedro port to firebug: variable leaked into global namespace + //var line = domUtils.getRuleLine(rule); + var line; + var ruleId = rule.selectorText+"/"+line; + this.addOldProperties(context, ruleId, inheritMode, props); + sortProperties(props); + + return props; + }, + + addOldProperties: function(context, ruleId, inheritMode, props) + { + if (context.selectorMap && context.selectorMap.hasOwnProperty(ruleId) ) + { + var moreProps = context.selectorMap[ruleId]; + for (var i = 0; i < moreProps.length; ++i) + { + var prop = moreProps[i]; + this.addProperty(prop.name, prop.value, prop.important, true, inheritMode, props); + } + } + }, + + addProperty: function(name, value, important, disabled, inheritMode, props) + { + name = name.toLowerCase(); + + if (inheritMode && !inheritedStyleNames[name]) + return; + + name = this.translateName(name, value); + if (name) + { + value = stripUnits(rgbToHex(value)); + important = important ? " !important" : ""; + + var prop = {name: name, value: value, important: important, disabled: disabled}; + props.push(prop); + } + }, + + translateName: function(name, value) + { + // Don't show these proprietary Mozilla properties + if ((value == "-moz-initial" + && (name == "-moz-background-clip" || name == "-moz-background-origin" + || name == "-moz-background-inline-policy")) + || (value == "physical" + && (name == "margin-left-ltr-source" || name == "margin-left-rtl-source" + || name == "margin-right-ltr-source" || name == "margin-right-rtl-source")) + || (value == "physical" + && (name == "padding-left-ltr-source" || name == "padding-left-rtl-source" + || name == "padding-right-ltr-source" || name == "padding-right-rtl-source"))) + return null; + + // Translate these back to the form the user probably expects + if (name == "margin-left-value") + return "margin-left"; + else if (name == "margin-right-value") + return "margin-right"; + else if (name == "margin-top-value") + return "margin-top"; + else if (name == "margin-bottom-value") + return "margin-bottom"; + else if (name == "padding-left-value") + return "padding-left"; + else if (name == "padding-right-value") + return "padding-right"; + else if (name == "padding-top-value") + return "padding-top"; + else if (name == "padding-bottom-value") + return "padding-bottom"; + // XXXjoe What about border! + else + return name; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + editElementStyle: function() + { + ///var rulesBox = this.panelNode.getElementsByClassName("cssElementRuleContainer")[0]; + var rulesBox = $$(".cssElementRuleContainer", this.panelNode)[0]; + var styleRuleBox = rulesBox && Firebug.getElementByRepObject(rulesBox, this.selection); + if (!styleRuleBox) + { + var rule = {rule: this.selection, inherited: false, selector: "element.style", props: []}; + if (!rulesBox) + { + // The element did not have any displayed styles. We need to create the whole tree and remove + // the no styles message + styleRuleBox = this.template.cascadedTag.replace({ + rules: [rule], inherited: [], inheritLabel: "Inherited from" // $STR("InheritedFrom") + }, this.panelNode); + + ///styleRuleBox = styleRuleBox.getElementsByClassName("cssElementRuleContainer")[0]; + styleRuleBox = $$(".cssElementRuleContainer", styleRuleBox)[0]; + } + else + styleRuleBox = this.template.ruleTag.insertBefore({rule: rule}, rulesBox); + + ///styleRuleBox = styleRuleBox.getElementsByClassName("insertInto")[0]; + styleRuleBox = $$(".insertInto", styleRuleBox)[0]; + } + + Firebug.Editor.insertRowForObject(styleRuleBox); + }, + + insertPropertyRow: function(row) + { + Firebug.Editor.insertRowForObject(row); + }, + + insertRule: function(row) + { + var location = getAncestorByClass(row, "cssRule"); + if (!location) + { + location = getChildByClass(this.panelNode, "cssSheet"); + Firebug.Editor.insertRowForObject(location); + } + else + { + Firebug.Editor.insertRow(location, "before"); + } + }, + + editPropertyRow: function(row) + { + var propValueBox = getChildByClass(row, "cssPropValue"); + Firebug.Editor.startEditing(propValueBox); + }, + + deletePropertyRow: function(row) + { + var rule = Firebug.getRepObject(row); + var propName = getChildByClass(row, "cssPropName")[textContent]; + Firebug.CSSModule.removeProperty(rule, propName); + + // Remove the property from the selector map, if it was disabled + var ruleId = Firebug.getRepNode(row).getAttribute("ruleId"); + if ( this.context.selectorMap && this.context.selectorMap.hasOwnProperty(ruleId) ) + { + var map = this.context.selectorMap[ruleId]; + for (var i = 0; i < map.length; ++i) + { + if (map[i].name == propName) + { + map.splice(i, 1); + break; + } + } + } + if (this.name == "stylesheet") + dispatch([Firebug.A11yModel], 'onInlineEditorClose', [this, row.firstChild, true]); + row.parentNode.removeChild(row); + + this.markChange(this.name == "stylesheet"); + }, + + disablePropertyRow: function(row) + { + toggleClass(row, "disabledStyle"); + + var rule = Firebug.getRepObject(row); + var propName = getChildByClass(row, "cssPropName")[textContent]; + + if (!this.context.selectorMap) + this.context.selectorMap = {}; + + // XXXjoe Generate unique key for elements too + var ruleId = Firebug.getRepNode(row).getAttribute("ruleId"); + if (!(this.context.selectorMap.hasOwnProperty(ruleId))) + this.context.selectorMap[ruleId] = []; + + var map = this.context.selectorMap[ruleId]; + var propValue = getChildByClass(row, "cssPropValue")[textContent]; + var parsedValue = parsePriority(propValue); + if (hasClass(row, "disabledStyle")) + { + Firebug.CSSModule.removeProperty(rule, propName); + + map.push({"name": propName, "value": parsedValue.value, + "important": parsedValue.priority}); + } + else + { + Firebug.CSSModule.setProperty(rule, propName, parsedValue.value, parsedValue.priority); + + var index = findPropByName(map, propName); + map.splice(index, 1); + } + + this.markChange(this.name == "stylesheet"); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + onMouseDown: function(event) + { + //console.log("onMouseDown", event.target || event.srcElement, event); + + // xxxpedro adjusting coordinates because the panel isn't a window yet + var offset = event.clientX - this.panelNode.parentNode.offsetLeft; + + // XXjoe Hack to only allow clicking on the checkbox + if (!isLeftClick(event) || offset > 20) + return; + + var target = event.target || event.srcElement; + if (hasClass(target, "textEditor")) + return; + + var row = getAncestorByClass(target, "cssProp"); + if (row && hasClass(row, "editGroup")) + { + this.disablePropertyRow(row); + cancelEvent(event); + } + }, + + onDoubleClick: function(event) + { + //console.log("onDoubleClick", event.target || event.srcElement, event); + + // xxxpedro adjusting coordinates because the panel isn't a window yet + var offset = event.clientX - this.panelNode.parentNode.offsetLeft; + + if (!isLeftClick(event) || offset <= 20) + return; + + var target = event.target || event.srcElement; + + //console.log("ok", target, hasClass(target, "textEditorInner"), !isLeftClick(event), offset <= 20); + + // if the inline editor was clicked, don't insert a new rule + if (hasClass(target, "textEditorInner")) + return; + + var row = getAncestorByClass(target, "cssRule"); + if (row && !getAncestorByClass(target, "cssPropName") + && !getAncestorByClass(target, "cssPropValue")) + { + this.insertPropertyRow(row); + cancelEvent(event); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "stylesheet", + title: "CSS", + parentPanel: null, + searchable: true, + dependents: ["css", "stylesheet", "dom", "domSide", "layout"], + + options: + { + hasToolButtons: true + }, + + create: function() + { + Firebug.Panel.create.apply(this, arguments); + + this.onMouseDown = bind(this.onMouseDown, this); + this.onDoubleClick = bind(this.onDoubleClick, this); + + if (this.name == "stylesheet") + { + this.onChangeSelect = bind(this.onChangeSelect, this); + + var doc = Firebug.browser.document; + var selectNode = this.selectNode = createElement("select"); + + processAllStyleSheets(doc, function(doc, styleSheet) + { + var key = StyleSheetCache.key(styleSheet); + var fileName = getFileName(styleSheet.href) || getFileName(doc.location.href); + var option = createElement("option", {value: key}); + + option.appendChild(Firebug.chrome.document.createTextNode(fileName)); + selectNode.appendChild(option); + }); + + this.toolButtonsNode.appendChild(selectNode); + } + /**/ + }, + + onChangeSelect: function(event) + { + event = event || window.event; + var target = event.srcElement || event.currentTarget; + var key = target.value; + var styleSheet = StyleSheetCache.get(key); + + this.updateLocation(styleSheet); + }, + + initialize: function() + { + Firebug.Panel.initialize.apply(this, arguments); + + //if (!domUtils) + //{ + // try { + // domUtils = CCSV("@mozilla.org/inspector/dom-utils;1", "inIDOMUtils"); + // } catch (exc) { + // if (FBTrace.DBG_ERRORS) + // FBTrace.sysout("@mozilla.org/inspector/dom-utils;1 FAILED to load: "+exc, exc); + // } + //} + + //TODO: xxxpedro + this.context = Firebug.chrome; // TODO: xxxpedro css2 + this.document = Firebug.chrome.document; // TODO: xxxpedro css2 + + this.initializeNode(); + + if (this.name == "stylesheet") + { + var styleSheets = Firebug.browser.document.styleSheets; + + if (styleSheets.length > 0) + { + addEvent(this.selectNode, "change", this.onChangeSelect); + + this.updateLocation(styleSheets[0]); + } + } + + //Firebug.SourceBoxPanel.initialize.apply(this, arguments); + }, + + shutdown: function() + { + // must destroy the editor when we leave the panel to avoid problems (Issue 2981) + Firebug.Editor.stopEditing(); + + if (this.name == "stylesheet") + { + removeEvent(this.selectNode, "change", this.onChangeSelect); + } + + this.destroyNode(); + + Firebug.Panel.shutdown.apply(this, arguments); + }, + + destroy: function(state) + { + //state.scrollTop = this.panelNode.scrollTop ? this.panelNode.scrollTop : this.lastScrollTop; + + //persistObjects(this, state); + + // xxxpedro we are stopping the editor in the shutdown method already + //Firebug.Editor.stopEditing(); + Firebug.Panel.destroy.apply(this, arguments); + }, + + initializeNode: function(oldPanelNode) + { + addEvent(this.panelNode, "mousedown", this.onMouseDown); + addEvent(this.panelNode, "dblclick", this.onDoubleClick); + //Firebug.SourceBoxPanel.initializeNode.apply(this, arguments); + //dispatch([Firebug.A11yModel], 'onInitializeNode', [this, 'css']); + }, + + destroyNode: function() + { + removeEvent(this.panelNode, "mousedown", this.onMouseDown); + removeEvent(this.panelNode, "dblclick", this.onDoubleClick); + //Firebug.SourceBoxPanel.destroyNode.apply(this, arguments); + //dispatch([Firebug.A11yModel], 'onDestroyNode', [this, 'css']); + }, + + ishow: function(state) + { + Firebug.Inspector.stopInspecting(true); + + this.showToolbarButtons("fbCSSButtons", true); + + if (this.context.loaded && !this.location) // wait for loadedContext to restore the panel + { + restoreObjects(this, state); + + if (!this.location) + this.location = this.getDefaultLocation(); + + if (state && state.scrollTop) + this.panelNode.scrollTop = state.scrollTop; + } + }, + + ihide: function() + { + this.showToolbarButtons("fbCSSButtons", false); + + this.lastScrollTop = this.panelNode.scrollTop; + }, + + supportsObject: function(object) + { + if (object instanceof CSSStyleSheet) + return 1; + else if (object instanceof CSSStyleRule) + return 2; + else if (object instanceof CSSStyleDeclaration) + return 2; + else if (object instanceof SourceLink && object.type == "css" && reCSS.test(object.href)) + return 2; + else + return 0; + }, + + updateLocation: function(styleSheet) + { + if (!styleSheet) + return; + if (styleSheet.editStyleSheet) + styleSheet = styleSheet.editStyleSheet.sheet; + + // if it is a restricted stylesheet, show the warning message and abort the update process + if (styleSheet.restricted) + { + FirebugReps.Warning.tag.replace({object: "AccessRestricted"}, this.panelNode); + + // TODO: xxxpedro remove when there the external resource problem is fixed + externalStyleSheetWarning.tag.append({ + object: "The stylesheet could not be loaded due to access restrictions. ", + link: "more...", + href: "http://getfirebug.com/wiki/index.php/Firebug_Lite_FAQ#I_keep_seeing_.22Access_to_restricted_URI_denied.22" + }, this.panelNode); + + return; + } + + var rules = this.getStyleSheetRules(this.context, styleSheet); + + var result; + if (rules.length) + result = this.template.tag.replace({rules: rules}, this.panelNode); + else + result = FirebugReps.Warning.tag.replace({object: "EmptyStyleSheet"}, this.panelNode); + + // TODO: xxxpedro need to fix showToolbarButtons function + //this.showToolbarButtons("fbCSSButtons", !isSystemStyleSheet(this.location)); + + //dispatch([Firebug.A11yModel], 'onCSSRulesAdded', [this, this.panelNode]); + }, + + updateSelection: function(object) + { + this.selection = null; + + if (object instanceof CSSStyleDeclaration) { + object = object.parentRule; + } + + if (object instanceof CSSStyleRule) + { + this.navigate(object.parentStyleSheet); + this.highlightRule(object); + } + else if (object instanceof CSSStyleSheet) + { + this.navigate(object); + } + else if (object instanceof SourceLink) + { + try + { + var sourceLink = object; + + var sourceFile = getSourceFileByHref(sourceLink.href, this.context); + if (sourceFile) + { + clearNode(this.panelNode); // replace rendered stylesheets + this.showSourceFile(sourceFile); + + var lineNo = object.line; + if (lineNo) + this.scrollToLine(lineNo, this.jumpHighlightFactory(lineNo, this.context)); + } + else // XXXjjb we should not be taking this path + { + var stylesheet = getStyleSheetByHref(sourceLink.href, this.context); + if (stylesheet) + this.navigate(stylesheet); + else + { + if (FBTrace.DBG_CSS) + FBTrace.sysout("css.updateSelection no sourceFile for "+sourceLink.href, sourceLink); + } + } + } + catch(exc) { + if (FBTrace.DBG_CSS) + FBTrace.sysout("css.upDateSelection FAILS "+exc, exc); + } + } + }, + + updateOption: function(name, value) + { + if (name == "expandShorthandProps") + this.refresh(); + }, + + getLocationList: function() + { + var styleSheets = getAllStyleSheets(this.context); + return styleSheets; + }, + + getOptionsMenuItems: function() + { + return [ + {label: "Expand Shorthand Properties", type: "checkbox", checked: Firebug.expandShorthandProps, + command: bindFixed(Firebug.togglePref, Firebug, "expandShorthandProps") }, + "-", + {label: "Refresh", command: bind(this.refresh, this) } + ]; + }, + + getContextMenuItems: function(style, target) + { + var items = []; + + if (this.infoTipType == "color") + { + items.push( + {label: "CopyColor", + command: bindFixed(copyToClipboard, FBL, this.infoTipObject) } + ); + } + else if (this.infoTipType == "image") + { + items.push( + {label: "CopyImageLocation", + command: bindFixed(copyToClipboard, FBL, this.infoTipObject) }, + {label: "OpenImageInNewTab", + command: bindFixed(openNewTab, FBL, this.infoTipObject) } + ); + } + + ///if (this.selection instanceof Element) + if (isElement(this.selection)) + { + items.push( + //"-", + {label: "EditStyle", + command: bindFixed(this.editElementStyle, this) } + ); + } + else if (!isSystemStyleSheet(this.selection)) + { + items.push( + //"-", + {label: "NewRule", + command: bindFixed(this.insertRule, this, target) } + ); + } + + var cssRule = getAncestorByClass(target, "cssRule"); + if (cssRule && hasClass(cssRule, "cssEditableRule")) + { + items.push( + "-", + {label: "NewProp", + command: bindFixed(this.insertPropertyRow, this, target) } + ); + + var propRow = getAncestorByClass(target, "cssProp"); + if (propRow) + { + var propName = getChildByClass(propRow, "cssPropName")[textContent]; + var isDisabled = hasClass(propRow, "disabledStyle"); + + items.push( + {label: $STRF("EditProp", [propName]), nol10n: true, + command: bindFixed(this.editPropertyRow, this, propRow) }, + {label: $STRF("DeleteProp", [propName]), nol10n: true, + command: bindFixed(this.deletePropertyRow, this, propRow) }, + {label: $STRF("DisableProp", [propName]), nol10n: true, + type: "checkbox", checked: isDisabled, + command: bindFixed(this.disablePropertyRow, this, propRow) } + ); + } + } + + items.push( + "-", + {label: "Refresh", command: bind(this.refresh, this) } + ); + + return items; + }, + + browseObject: function(object) + { + if (this.infoTipType == "image") + { + openNewTab(this.infoTipObject); + return true; + } + }, + + showInfoTip: function(infoTip, target, x, y) + { + var propValue = getAncestorByClass(target, "cssPropValue"); + if (propValue) + { + var offset = getClientOffset(propValue); + var offsetX = x-offset.x; + + var text = propValue[textContent]; + var charWidth = propValue.offsetWidth/text.length; + var charOffset = Math.floor(offsetX/charWidth); + + var cssValue = parseCSSValue(text, charOffset); + if (cssValue) + { + if (cssValue.value == this.infoTipValue) + return true; + + this.infoTipValue = cssValue.value; + + if (cssValue.type == "rgb" || (!cssValue.type && isColorKeyword(cssValue.value))) + { + this.infoTipType = "color"; + this.infoTipObject = cssValue.value; + + return Firebug.InfoTip.populateColorInfoTip(infoTip, cssValue.value); + } + else if (cssValue.type == "url") + { + ///var propNameNode = target.parentNode.getElementsByClassName("cssPropName").item(0); + var propNameNode = getElementByClass(target.parentNode, "cssPropName"); + if (propNameNode && isImageRule(propNameNode[textContent])) + { + var rule = Firebug.getRepObject(target); + var baseURL = this.getStylesheetURL(rule); + var relURL = parseURLValue(cssValue.value); + var absURL = isDataURL(relURL) ? relURL:absoluteURL(relURL, baseURL); + var repeat = parseRepeatValue(text); + + this.infoTipType = "image"; + this.infoTipObject = absURL; + + return Firebug.InfoTip.populateImageInfoTip(infoTip, absURL, repeat); + } + } + } + } + + delete this.infoTipType; + delete this.infoTipValue; + delete this.infoTipObject; + }, + + getEditor: function(target, value) + { + if (target == this.panelNode + || hasClass(target, "cssSelector") || hasClass(target, "cssRule") + || hasClass(target, "cssSheet")) + { + if (!this.ruleEditor) + this.ruleEditor = new CSSRuleEditor(this.document); + + return this.ruleEditor; + } + else + { + if (!this.editor) + this.editor = new CSSEditor(this.document); + + return this.editor; + } + }, + + getDefaultLocation: function() + { + try + { + var styleSheets = this.context.window.document.styleSheets; + if (styleSheets.length) + { + var sheet = styleSheets[0]; + return (Firebug.filterSystemURLs && isSystemURL(getURLForStyleSheet(sheet))) ? null : sheet; + } + } + catch (exc) + { + if (FBTrace.DBG_LOCATIONS) + FBTrace.sysout("css.getDefaultLocation FAILS "+exc, exc); + } + }, + + getObjectDescription: function(styleSheet) + { + var url = getURLForStyleSheet(styleSheet); + var instance = getInstanceForStyleSheet(styleSheet); + + var baseDescription = splitURLBase(url); + if (instance) { + baseDescription.name = baseDescription.name + " #" + (instance + 1); + } + return baseDescription; + }, + + search: function(text, reverse) + { + var curDoc = this.searchCurrentDoc(!Firebug.searchGlobal, text, reverse); + if (!curDoc && Firebug.searchGlobal) + { + return this.searchOtherDocs(text, reverse); + } + return curDoc; + }, + + searchOtherDocs: function(text, reverse) + { + var scanRE = Firebug.Search.getTestingRegex(text); + function scanDoc(styleSheet) { + // we don't care about reverse here as we are just looking for existence, + // if we do have a result we will handle the reverse logic on display + for (var i = 0; i < styleSheet.cssRules.length; i++) + { + if (scanRE.test(styleSheet.cssRules[i].cssText)) + { + return true; + } + } + } + + if (this.navigateToNextDocument(scanDoc, reverse)) + { + return this.searchCurrentDoc(true, text, reverse); + } + }, + + searchCurrentDoc: function(wrapSearch, text, reverse) + { + if (!text) + { + delete this.currentSearch; + return false; + } + + var row; + if (this.currentSearch && text == this.currentSearch.text) + { + row = this.currentSearch.findNext(wrapSearch, false, reverse, Firebug.Search.isCaseSensitive(text)); + } + else + { + if (this.editing) + { + this.currentSearch = new TextSearch(this.stylesheetEditor.box); + row = this.currentSearch.find(text, reverse, Firebug.Search.isCaseSensitive(text)); + + if (row) + { + var sel = this.document.defaultView.getSelection(); + sel.removeAllRanges(); + sel.addRange(this.currentSearch.range); + scrollSelectionIntoView(this); + return true; + } + else + return false; + } + else + { + function findRow(node) { return node.nodeType == 1 ? node : node.parentNode; } + this.currentSearch = new TextSearch(this.panelNode, findRow); + row = this.currentSearch.find(text, reverse, Firebug.Search.isCaseSensitive(text)); + } + } + + if (row) + { + this.document.defaultView.getSelection().selectAllChildren(row); + scrollIntoCenterView(row, this.panelNode); + dispatch([Firebug.A11yModel], 'onCSSSearchMatchFound', [this, text, row]); + return true; + } + else + { + dispatch([Firebug.A11yModel], 'onCSSSearchMatchFound', [this, text, null]); + return false; + } + }, + + getSearchOptionsMenuItems: function() + { + return [ + Firebug.Search.searchOptionMenu("search.Case_Sensitive", "searchCaseSensitive"), + Firebug.Search.searchOptionMenu("search.Multiple_Files", "searchGlobal") + ]; + } +}); +/**/ +// ************************************************************************************************ + +function CSSElementPanel() {} + +CSSElementPanel.prototype = extend(Firebug.CSSStyleSheetPanel.prototype, +{ + template: domplate( + { + cascadedTag: + DIV({"class": "a11yCSSView", role : 'presentation'}, + DIV({role : 'list', 'aria-label' : $STR('aria.labels.style rules') }, + FOR("rule", "$rules", + TAG("$ruleTag", {rule: "$rule"}) + ) + ), + DIV({role : "list", 'aria-label' :$STR('aria.labels.inherited style rules')}, + FOR("section", "$inherited", + H1({"class": "cssInheritHeader groupHeader focusRow", role : 'listitem' }, + SPAN({"class": "cssInheritLabel"}, "$inheritLabel"), + TAG(FirebugReps.Element.shortTag, {object: "$section.element"}) + ), + DIV({role : 'group'}, + FOR("rule", "$section.rules", + TAG("$ruleTag", {rule: "$rule"}) + ) + ) + ) + ) + ), + + ruleTag: + isIE ? + // IE needs the sourceLink first, otherwise it will be rendered outside the panel + DIV({"class": "cssElementRuleContainer"}, + TAG(FirebugReps.SourceLink.tag, {object: "$rule.sourceLink"}), + TAG(CSSStyleRuleTag.tag, {rule: "$rule"}) + ) + : + // other browsers need the sourceLink last, otherwise it will cause an extra space + // before the rule representation + DIV({"class": "cssElementRuleContainer"}, + TAG(CSSStyleRuleTag.tag, {rule: "$rule"}), + TAG(FirebugReps.SourceLink.tag, {object: "$rule.sourceLink"}) + ) + }), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + updateCascadeView: function(element) + { + //dispatch([Firebug.A11yModel], 'onBeforeCSSRulesAdded', [this]); + var rules = [], sections = [], usedProps = {}; + this.getInheritedRules(element, sections, usedProps); + this.getElementRules(element, rules, usedProps); + + if (rules.length || sections.length) + { + var inheritLabel = "Inherited from"; // $STR("InheritedFrom"); + var result = this.template.cascadedTag.replace({rules: rules, inherited: sections, + inheritLabel: inheritLabel}, this.panelNode); + //dispatch([Firebug.A11yModel], 'onCSSRulesAdded', [this, result]); + } + else + { + var result = FirebugReps.Warning.tag.replace({object: "EmptyElementCSS"}, this.panelNode); + //dispatch([Firebug.A11yModel], 'onCSSRulesAdded', [this, result]); + } + + // TODO: xxxpedro remove when there the external resource problem is fixed + if (externalStyleSheetURLs.length > 0) + externalStyleSheetWarning.tag.append({ + object: "The results here may be inaccurate because some " + + "stylesheets could not be loaded due to access restrictions. ", + link: "more...", + href: "http://getfirebug.com/wiki/index.php/Firebug_Lite_FAQ#I_keep_seeing_.22This_element_has_no_style_rules.22" + }, this.panelNode); + }, + + getStylesheetURL: function(rule) + { + // if the parentStyleSheet.href is null, CSS std says its inline style. + // TODO: xxxpedro IE doesn't have rule.parentStyleSheet so we must fall back to the doc.location + if (rule && rule.parentStyleSheet && rule.parentStyleSheet.href) + return rule.parentStyleSheet.href; + else + return this.selection.ownerDocument.location.href; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getInheritedRules: function(element, sections, usedProps) + { + var parent = element.parentNode; + if (parent && parent.nodeType == 1) + { + this.getInheritedRules(parent, sections, usedProps); + + var rules = []; + this.getElementRules(parent, rules, usedProps, true); + + if (rules.length) + sections.splice(0, 0, {element: parent, rules: rules}); + } + }, + + getElementRules: function(element, rules, usedProps, inheritMode) + { + var inspectedRules, displayedRules = {}; + + // TODO: xxxpedro remove document specificity issue + //var eid = ElementCache(element); + //inspectedRules = ElementCSSRulesMap[eid]; + + inspectedRules = getElementCSSRules(element); + + if (inspectedRules) + { + for (var i = 0, length=inspectedRules.length; i < length; ++i) + { + var ruleId = inspectedRules[i]; + var ruleData = CSSRuleMap[ruleId]; + var rule = ruleData.rule; + + var ssid = ruleData.styleSheetId; + var parentStyleSheet = StyleSheetCache.get(ssid); + + var href = parentStyleSheet.externalURL ? parentStyleSheet.externalURL : parentStyleSheet.href; // Null means inline + + var instance = null; + //var instance = getInstanceForStyleSheet(rule.parentStyleSheet, element.ownerDocument); + + var isSystemSheet = false; + //var isSystemSheet = isSystemStyleSheet(rule.parentStyleSheet); + + if (!Firebug.showUserAgentCSS && isSystemSheet) // This removes user agent rules + continue; + + if (!href) + href = element.ownerDocument.location.href; // http://code.google.com/p/fbug/issues/detail?id=452 + + var props = this.getRuleProperties(this.context, rule, inheritMode); + if (inheritMode && !props.length) + continue; + + // + //var line = domUtils.getRuleLine(rule); + var line; + + var ruleId = rule.selectorText+"/"+line; + var sourceLink = new SourceLink(href, line, "css", rule, instance); + + this.markOverridenProps(props, usedProps, inheritMode); + + rules.splice(0, 0, {rule: rule, id: ruleId, + selector: ruleData.selector, sourceLink: sourceLink, + props: props, inherited: inheritMode, + isSystemSheet: isSystemSheet}); + } + } + + if (element.style) + this.getStyleProperties(element, rules, usedProps, inheritMode); + + if (FBTrace.DBG_CSS) + FBTrace.sysout("getElementRules "+rules.length+" rules for "+getElementXPath(element), rules); + }, + /* + getElementRules: function(element, rules, usedProps, inheritMode) + { + var inspectedRules, displayedRules = {}; + try + { + inspectedRules = domUtils ? domUtils.getCSSStyleRules(element) : null; + } catch (exc) {} + + if (inspectedRules) + { + for (var i = 0; i < inspectedRules.Count(); ++i) + { + var rule = QI(inspectedRules.GetElementAt(i), nsIDOMCSSStyleRule); + + var href = rule.parentStyleSheet.href; // Null means inline + + var instance = getInstanceForStyleSheet(rule.parentStyleSheet, element.ownerDocument); + + var isSystemSheet = isSystemStyleSheet(rule.parentStyleSheet); + if (!Firebug.showUserAgentCSS && isSystemSheet) // This removes user agent rules + continue; + if (!href) + href = element.ownerDocument.location.href; // http://code.google.com/p/fbug/issues/detail?id=452 + + var props = this.getRuleProperties(this.context, rule, inheritMode); + if (inheritMode && !props.length) + continue; + + var line = domUtils.getRuleLine(rule); + var ruleId = rule.selectorText+"/"+line; + var sourceLink = new SourceLink(href, line, "css", rule, instance); + + this.markOverridenProps(props, usedProps, inheritMode); + + rules.splice(0, 0, {rule: rule, id: ruleId, + selector: rule.selectorText, sourceLink: sourceLink, + props: props, inherited: inheritMode, + isSystemSheet: isSystemSheet}); + } + } + + if (element.style) + this.getStyleProperties(element, rules, usedProps, inheritMode); + + if (FBTrace.DBG_CSS) + FBTrace.sysout("getElementRules "+rules.length+" rules for "+getElementXPath(element), rules); + }, + /**/ + markOverridenProps: function(props, usedProps, inheritMode) + { + for (var i = 0; i < props.length; ++i) + { + var prop = props[i]; + if ( usedProps.hasOwnProperty(prop.name) ) + { + var deadProps = usedProps[prop.name]; // all previous occurrences of this property + for (var j = 0; j < deadProps.length; ++j) + { + var deadProp = deadProps[j]; + if (!deadProp.disabled && !deadProp.wasInherited && deadProp.important && !prop.important) + prop.overridden = true; // new occurrence overridden + else if (!prop.disabled) + deadProp.overridden = true; // previous occurrences overridden + } + } + else + usedProps[prop.name] = []; + + prop.wasInherited = inheritMode ? true : false; + usedProps[prop.name].push(prop); // all occurrences of a property seen so far, by name + } + }, + + getStyleProperties: function(element, rules, usedProps, inheritMode) + { + var props = this.parseCSSProps(element.style, inheritMode); + this.addOldProperties(this.context, getElementXPath(element), inheritMode, props); + + sortProperties(props); + this.markOverridenProps(props, usedProps, inheritMode); + + if (props.length) + rules.splice(0, 0, + {rule: element, id: getElementXPath(element), + selector: "element.style", props: props, inherited: inheritMode}); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "css", + title: "Style", + parentPanel: "HTML", + order: 0, + + initialize: function() + { + this.context = Firebug.chrome; // TODO: xxxpedro css2 + this.document = Firebug.chrome.document; // TODO: xxxpedro css2 + + Firebug.CSSStyleSheetPanel.prototype.initialize.apply(this, arguments); + + // TODO: xxxpedro css2 + var selection = ElementCache.get(FirebugChrome.selectedHTMLElementId); + if (selection) + this.select(selection, true); + + //this.updateCascadeView(document.getElementsByTagName("h1")[0]); + //this.updateCascadeView(document.getElementById("build")); + + /* + this.onStateChange = bindFixed(this.contentStateCheck, this); + this.onHoverChange = bindFixed(this.contentStateCheck, this, STATE_HOVER); + this.onActiveChange = bindFixed(this.contentStateCheck, this, STATE_ACTIVE); + /**/ + }, + + ishow: function(state) + { + }, + + watchWindow: function(win) + { + if (domUtils) + { + // Normally these would not be required, but in order to update after the state is set + // using the options menu we need to monitor these global events as well + var doc = win.document; + ///addEvent(doc, "mouseover", this.onHoverChange); + ///addEvent(doc, "mousedown", this.onActiveChange); + } + }, + unwatchWindow: function(win) + { + var doc = win.document; + ///removeEvent(doc, "mouseover", this.onHoverChange); + ///removeEvent(doc, "mousedown", this.onActiveChange); + + if (isAncestor(this.stateChangeEl, doc)) + { + this.removeStateChangeHandlers(); + } + }, + + supportsObject: function(object) + { + return object instanceof Element ? 1 : 0; + }, + + updateView: function(element) + { + this.updateCascadeView(element); + if (domUtils) + { + this.contentState = safeGetContentState(element); + this.addStateChangeHandlers(element); + } + }, + + updateSelection: function(element) + { + if ( !instanceOf(element , "Element") ) // html supports SourceLink + return; + + if (sothinkInstalled) + { + FirebugReps.Warning.tag.replace({object: "SothinkWarning"}, this.panelNode); + return; + } + + /* + if (!domUtils) + { + FirebugReps.Warning.tag.replace({object: "DOMInspectorWarning"}, this.panelNode); + return; + } + /**/ + + if (!element) + return; + + this.updateView(element); + }, + + updateOption: function(name, value) + { + if (name == "showUserAgentCSS" || name == "expandShorthandProps") + this.refresh(); + }, + + getOptionsMenuItems: function() + { + var ret = [ + {label: "Show User Agent CSS", type: "checkbox", checked: Firebug.showUserAgentCSS, + command: bindFixed(Firebug.togglePref, Firebug, "showUserAgentCSS") }, + {label: "Expand Shorthand Properties", type: "checkbox", checked: Firebug.expandShorthandProps, + command: bindFixed(Firebug.togglePref, Firebug, "expandShorthandProps") } + ]; + if (domUtils && this.selection) + { + var state = safeGetContentState(this.selection); + + ret.push("-"); + ret.push({label: ":active", type: "checkbox", checked: state & STATE_ACTIVE, + command: bindFixed(this.updateContentState, this, STATE_ACTIVE, state & STATE_ACTIVE)}); + ret.push({label: ":hover", type: "checkbox", checked: state & STATE_HOVER, + command: bindFixed(this.updateContentState, this, STATE_HOVER, state & STATE_HOVER)}); + } + return ret; + }, + + updateContentState: function(state, remove) + { + domUtils.setContentState(remove ? this.selection.ownerDocument.documentElement : this.selection, state); + this.refresh(); + }, + + addStateChangeHandlers: function(el) + { + this.removeStateChangeHandlers(); + + /* + addEvent(el, "focus", this.onStateChange); + addEvent(el, "blur", this.onStateChange); + addEvent(el, "mouseup", this.onStateChange); + addEvent(el, "mousedown", this.onStateChange); + addEvent(el, "mouseover", this.onStateChange); + addEvent(el, "mouseout", this.onStateChange); + /**/ + + this.stateChangeEl = el; + }, + + removeStateChangeHandlers: function() + { + var sel = this.stateChangeEl; + if (sel) + { + /* + removeEvent(sel, "focus", this.onStateChange); + removeEvent(sel, "blur", this.onStateChange); + removeEvent(sel, "mouseup", this.onStateChange); + removeEvent(sel, "mousedown", this.onStateChange); + removeEvent(sel, "mouseover", this.onStateChange); + removeEvent(sel, "mouseout", this.onStateChange); + /**/ + } + }, + + contentStateCheck: function(state) + { + if (!state || this.contentState & state) + { + var timeoutRunner = bindFixed(function() + { + var newState = safeGetContentState(this.selection); + if (newState != this.contentState) + { + this.context.invalidatePanels(this.name); + } + }, this); + + // Delay exec until after the event has processed and the state has been updated + setTimeout(timeoutRunner, 0); + } + } +}); + +function safeGetContentState(selection) +{ + try + { + return domUtils.getContentState(selection); + } + catch (e) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("css.safeGetContentState; EXCEPTION", e); + } +} + +// ************************************************************************************************ + +function CSSComputedElementPanel() {} + +CSSComputedElementPanel.prototype = extend(CSSElementPanel.prototype, +{ + template: domplate( + { + computedTag: + DIV({"class": "a11yCSSView", role : "list", "aria-label" : $STR('aria.labels.computed styles')}, + FOR("group", "$groups", + H1({"class": "cssInheritHeader groupHeader focusRow", role : "listitem"}, + SPAN({"class": "cssInheritLabel"}, "$group.title") + ), + TABLE({width: "100%", role : 'group'}, + TBODY({role : 'presentation'}, + FOR("prop", "$group.props", + TR({"class": 'focusRow computedStyleRow', role : 'listitem'}, + TD({"class": "stylePropName", role : 'presentation'}, "$prop.name"), + TD({"class": "stylePropValue", role : 'presentation'}, "$prop.value") + ) + ) + ) + ) + ) + ) + }), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + updateComputedView: function(element) + { + var win = isIE ? + element.ownerDocument.parentWindow : + element.ownerDocument.defaultView; + + var style = isIE ? + element.currentStyle : + win.getComputedStyle(element, ""); + + var groups = []; + + for (var groupName in styleGroups) + { + // TODO: xxxpedro i18n $STR + //var title = $STR("StyleGroup-" + groupName); + var title = styleGroupTitles[groupName]; + var group = {title: title, props: []}; + groups.push(group); + + var props = styleGroups[groupName]; + for (var i = 0; i < props.length; ++i) + { + var propName = props[i]; + var propValue = style.getPropertyValue ? + style.getPropertyValue(propName) : + ""+style[toCamelCase(propName)]; + + if (propValue === undefined || propValue === null) + continue; + + propValue = stripUnits(rgbToHex(propValue)); + if (propValue) + group.props.push({name: propName, value: propValue}); + } + } + + var result = this.template.computedTag.replace({groups: groups}, this.panelNode); + //dispatch([Firebug.A11yModel], 'onCSSRulesAdded', [this, result]); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "computed", + title: "Computed", + parentPanel: "HTML", + order: 1, + + updateView: function(element) + { + this.updateComputedView(element); + }, + + getOptionsMenuItems: function() + { + return [ + {label: "Refresh", command: bind(this.refresh, this) } + ]; + } +}); + +// ************************************************************************************************ +// CSSEditor + +function CSSEditor(doc) +{ + this.initializeInline(doc); +} + +CSSEditor.prototype = domplate(Firebug.InlineEditor.prototype, +{ + insertNewRow: function(target, insertWhere) + { + var rule = Firebug.getRepObject(target); + var emptyProp = + { + // TODO: xxxpedro - uses charCode(255) to force the element being rendered, + // allowing webkit to get the correct position of the property name "span", + // when inserting a new CSS rule? + name: "", + value: "", + important: "" + }; + + if (insertWhere == "before") + return CSSPropTag.tag.insertBefore({prop: emptyProp, rule: rule}, target); + else + return CSSPropTag.tag.insertAfter({prop: emptyProp, rule: rule}, target); + }, + + saveEdit: function(target, value, previousValue) + { + // We need to check the value first in order to avoid a problem in IE8 + // See Issue 3038: Empty (null) styles when adding CSS styles in Firebug Lite + if (!value) return; + + target.innerHTML = escapeForCss(value); + + var row = getAncestorByClass(target, "cssProp"); + if (hasClass(row, "disabledStyle")) + toggleClass(row, "disabledStyle"); + + var rule = Firebug.getRepObject(target); + + if (hasClass(target, "cssPropName")) + { + if (value && previousValue != value) // name of property has changed. + { + var propValue = getChildByClass(row, "cssPropValue")[textContent]; + var parsedValue = parsePriority(propValue); + + if (propValue && propValue != "undefined") { + if (FBTrace.DBG_CSS) + FBTrace.sysout("CSSEditor.saveEdit : "+previousValue+"->"+value+" = "+propValue+"\n"); + if (previousValue) + Firebug.CSSModule.removeProperty(rule, previousValue); + Firebug.CSSModule.setProperty(rule, value, parsedValue.value, parsedValue.priority); + } + } + else if (!value) // name of the property has been deleted, so remove the property. + Firebug.CSSModule.removeProperty(rule, previousValue); + } + else if (getAncestorByClass(target, "cssPropValue")) + { + var propName = getChildByClass(row, "cssPropName")[textContent]; + var propValue = getChildByClass(row, "cssPropValue")[textContent]; + + if (FBTrace.DBG_CSS) + { + FBTrace.sysout("CSSEditor.saveEdit propName=propValue: "+propName +" = "+propValue+"\n"); + // FBTrace.sysout("CSSEditor.saveEdit BEFORE style:",style); + } + + if (value && value != "null") + { + var parsedValue = parsePriority(value); + Firebug.CSSModule.setProperty(rule, propName, parsedValue.value, parsedValue.priority); + } + else if (previousValue && previousValue != "null") + Firebug.CSSModule.removeProperty(rule, propName); + } + + this.panel.markChange(this.panel.name == "stylesheet"); + }, + + advanceToNext: function(target, charCode) + { + if (charCode == 58 /*":"*/ && hasClass(target, "cssPropName")) + return true; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getAutoCompleteRange: function(value, offset) + { + if (hasClass(this.target, "cssPropName")) + return {start: 0, end: value.length-1}; + else + return parseCSSValue(value, offset); + }, + + getAutoCompleteList: function(preExpr, expr, postExpr) + { + if (hasClass(this.target, "cssPropName")) + { + return getCSSPropertyNames(); + } + else + { + var row = getAncestorByClass(this.target, "cssProp"); + var propName = getChildByClass(row, "cssPropName")[textContent]; + return getCSSKeywordsByProperty(propName); + } + } +}); + +//************************************************************************************************ +//CSSRuleEditor + +function CSSRuleEditor(doc) +{ + this.initializeInline(doc); + this.completeAsYouType = false; +} +CSSRuleEditor.uniquifier = 0; +CSSRuleEditor.prototype = domplate(Firebug.InlineEditor.prototype, +{ + insertNewRow: function(target, insertWhere) + { + var emptyRule = { + selector: "", + id: "", + props: [], + isSelectorEditable: true + }; + + if (insertWhere == "before") + return CSSStyleRuleTag.tag.insertBefore({rule: emptyRule}, target); + else + return CSSStyleRuleTag.tag.insertAfter({rule: emptyRule}, target); + }, + + saveEdit: function(target, value, previousValue) + { + if (FBTrace.DBG_CSS) + FBTrace.sysout("CSSRuleEditor.saveEdit: '" + value + "' '" + previousValue + "'", target); + + target.innerHTML = escapeForCss(value); + + if (value === previousValue) return; + + var row = getAncestorByClass(target, "cssRule"); + var styleSheet = this.panel.location; + styleSheet = styleSheet.editStyleSheet ? styleSheet.editStyleSheet.sheet : styleSheet; + + var cssRules = styleSheet.cssRules; + var rule = Firebug.getRepObject(target), oldRule = rule; + var ruleIndex = cssRules.length; + if (rule || Firebug.getRepObject(row.nextSibling)) + { + var searchRule = rule || Firebug.getRepObject(row.nextSibling); + for (ruleIndex=0; ruleIndex b.name ? 1 : -1; + }); +} + +function getTopmostRuleLine(panelNode) +{ + for (var child = panelNode.firstChild; child; child = child.nextSibling) + { + if (child.offsetTop+child.offsetHeight > panelNode.scrollTop) + { + var rule = child.repObject; + if (rule) + return { + line: domUtils.getRuleLine(rule), + offset: panelNode.scrollTop-child.offsetTop + }; + } + } + return 0; +} + +function getStyleSheetCSS(sheet, context) +{ + if (sheet.ownerNode instanceof HTMLStyleElement) + return sheet.ownerNode.innerHTML; + else + return context.sourceCache.load(sheet.href).join(""); +} + +function getStyleSheetOwnerNode(sheet) { + for (; sheet && !sheet.ownerNode; sheet = sheet.parentStyleSheet); + + return sheet.ownerNode; +} + +function scrollSelectionIntoView(panel) +{ + var selCon = getSelectionController(panel); + selCon.scrollSelectionIntoView( + nsISelectionController.SELECTION_NORMAL, + nsISelectionController.SELECTION_FOCUS_REGION, true); +} + +function getSelectionController(panel) +{ + var browser = Firebug.chrome.getPanelBrowser(panel); + return browser.docShell.QueryInterface(nsIInterfaceRequestor) + .getInterface(nsISelectionDisplay) + .QueryInterface(nsISelectionController); +} + +// ************************************************************************************************ + +Firebug.registerModule(Firebug.CSSModule); +Firebug.registerPanel(Firebug.CSSStyleSheetPanel); +Firebug.registerPanel(CSSElementPanel); +Firebug.registerPanel(CSSComputedElementPanel); + +// ************************************************************************************************ + +}}); + + +/* 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 (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; +}; + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var ElementCache = Firebug.Lite.Cache.Element; + +var insertSliceSize = 18; +var insertInterval = 40; + +var ignoreVars = +{ + "__firebug__": 1, + "eval": 1, + + // We are forced to ignore Java-related variables, because + // trying to access them causes browser freeze + "java": 1, + "sun": 1, + "Packages": 1, + "JavaArray": 1, + "JavaMember": 1, + "JavaObject": 1, + "JavaClass": 1, + "JavaPackage": 1, + "_firebug": 1, + "_FirebugConsole": 1, + "_FirebugCommandLine": 1 +}; + +if (Firebug.ignoreFirebugElements) + ignoreVars[Firebug.Lite.Cache.ID] = 1; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var memberPanelRep = + isIE6 ? + {"class": "memberLabel $member.type\\Label", href: "javacript:void(0)"} + : + {"class": "memberLabel $member.type\\Label"}; + +var RowTag = + TR({"class": "memberRow $member.open $member.type\\Row", $hasChildren: "$member.hasChildren", role : 'presentation', + level: "$member.level"}, + TD({"class": "memberLabelCell", style: "padding-left: $member.indent\\px", role : 'presentation'}, + A(memberPanelRep, + SPAN({}, "$member.name") + ) + ), + TD({"class": "memberValueCell", role : 'presentation'}, + TAG("$member.tag", {object: "$member.value"}) + ) + ); + +var WatchRowTag = + TR({"class": "watchNewRow", level: 0}, + TD({"class": "watchEditCell", colspan: 2}, + DIV({"class": "watchEditBox a11yFocusNoTab", role: "button", 'tabindex' : '0', + 'aria-label' : $STR('press enter to add new watch expression')}, + $STR("NewWatch") + ) + ) + ); + +var SizerRow = + TR({role : 'presentation'}, + TD({width: "30%"}), + TD({width: "70%"}) + ); + +var domTableClass = isIElt8 ? "domTable domTableIE" : "domTable"; +var DirTablePlate = domplate(Firebug.Rep, +{ + tag: + TABLE({"class": domTableClass, cellpadding: 0, cellspacing: 0, onclick: "$onClick", role :"tree"}, + TBODY({role: 'presentation'}, + SizerRow, + FOR("member", "$object|memberIterator", RowTag) + ) + ), + + watchTag: + TABLE({"class": domTableClass, cellpadding: 0, cellspacing: 0, + _toggles: "$toggles", _domPanel: "$domPanel", onclick: "$onClick", role : 'tree'}, + TBODY({role : 'presentation'}, + SizerRow, + WatchRowTag + ) + ), + + tableTag: + TABLE({"class": domTableClass, cellpadding: 0, cellspacing: 0, + _toggles: "$toggles", _domPanel: "$domPanel", onclick: "$onClick", role : 'tree'}, + TBODY({role : 'presentation'}, + SizerRow + ) + ), + + rowTag: + FOR("member", "$members", RowTag), + + memberIterator: function(object, level) + { + return getMembers(object, level); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + onClick: function(event) + { + if (!isLeftClick(event)) + return; + + var target = event.target || event.srcElement; + + var row = getAncestorByClass(target, "memberRow"); + var label = getAncestorByClass(target, "memberLabel"); + if (label && hasClass(row, "hasChildren")) + { + var row = label.parentNode.parentNode; + this.toggleRow(row); + } + else + { + var object = Firebug.getRepObject(target); + if (typeof(object) == "function") + { + Firebug.chrome.select(object, "script"); + cancelEvent(event); + } + else if (event.detail == 2 && !object) + { + var panel = row.parentNode.parentNode.domPanel; + if (panel) + { + var rowValue = panel.getRowPropertyValue(row); + if (typeof(rowValue) == "boolean") + panel.setPropertyValue(row, !rowValue); + else + panel.editProperty(row); + + cancelEvent(event); + } + } + } + + return false; + }, + + toggleRow: function(row) + { + var level = parseInt(row.getAttribute("level")); + var toggles = row.parentNode.parentNode.toggles; + + if (hasClass(row, "opened")) + { + removeClass(row, "opened"); + + if (toggles) + { + var path = getPath(row); + + // Remove the path from the toggle tree + for (var i = 0; i < path.length; ++i) + { + if (i == path.length-1) + delete toggles[path[i]]; + else + toggles = toggles[path[i]]; + } + } + + var rowTag = this.rowTag; + var tbody = row.parentNode; + + setTimeout(function() + { + for (var firstRow = row.nextSibling; firstRow; firstRow = row.nextSibling) + { + if (parseInt(firstRow.getAttribute("level")) <= level) + break; + + tbody.removeChild(firstRow); + } + }, row.insertTimeout ? row.insertTimeout : 0); + } + else + { + setClass(row, "opened"); + + if (toggles) + { + var path = getPath(row); + + // Mark the path in the toggle tree + for (var i = 0; i < path.length; ++i) + { + var name = path[i]; + if (toggles.hasOwnProperty(name)) + toggles = toggles[name]; + else + toggles = toggles[name] = {}; + } + } + + var value = row.lastChild.firstChild.repObject; + var members = getMembers(value, level+1); + + var rowTag = this.rowTag; + var lastRow = row; + + var delay = 0; + //var setSize = members.length; + //var rowCount = 1; + while (members.length) + { + with({slice: members.splice(0, insertSliceSize), isLast: !members.length}) + { + setTimeout(function() + { + if (lastRow.parentNode) + { + var result = rowTag.insertRows({members: slice}, lastRow); + lastRow = result[1]; + //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [null, result, rowCount, setSize]); + //rowCount += insertSliceSize; + } + if (isLast) + row.removeAttribute("insertTimeout"); + }, delay); + } + + delay += insertInterval; + } + + row.insertTimeout = delay; + } + } +}); + + + +// ************************************************************************************************ + +Firebug.DOMBasePanel = function() {} + +Firebug.DOMBasePanel.prototype = extend(Firebug.Panel, +{ + tag: DirTablePlate.tableTag, + + getRealObject: function(object) + { + // TODO: Move this to some global location + // TODO: Unwrapping should be centralized rather than sprinkling it around ad hoc. + // TODO: We might be able to make this check more authoritative with QueryInterface. + if (!object) return object; + if (object.wrappedJSObject) return object.wrappedJSObject; + return object; + }, + + rebuild: function(update, scrollTop) + { + //dispatch([Firebug.A11yModel], 'onBeforeDomUpdateSelection', [this]); + var members = getMembers(this.selection); + expandMembers(members, this.toggles, 0, 0); + + this.showMembers(members, update, scrollTop); + + //TODO: xxxpedro statusbar + if (!this.parentPanel) + updateStatusBar(this); + }, + + showMembers: function(members, update, scrollTop) + { + // If we are still in the midst of inserting rows, cancel all pending + // insertions here - this is a big speedup when stepping in the debugger + if (this.timeouts) + { + for (var i = 0; i < this.timeouts.length; ++i) + this.context.clearTimeout(this.timeouts[i]); + delete this.timeouts; + } + + if (!members.length) + return this.showEmptyMembers(); + + var panelNode = this.panelNode; + var priorScrollTop = scrollTop == undefined ? panelNode.scrollTop : scrollTop; + + // If we are asked to "update" the current view, then build the new table + // offscreen and swap it in when it's done + var offscreen = update && panelNode.firstChild; + var dest = offscreen ? panelNode.ownerDocument : panelNode; + + var table = this.tag.replace({domPanel: this, toggles: this.toggles}, dest); + var tbody = table.lastChild; + var rowTag = DirTablePlate.rowTag; + + // Insert the first slice immediately + //var slice = members.splice(0, insertSliceSize); + //var result = rowTag.insertRows({members: slice}, tbody.lastChild); + + //var setSize = members.length; + //var rowCount = 1; + + var panel = this; + var result; + + //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [panel, result, rowCount, setSize]); + var timeouts = []; + + var delay = 0; + + // enable to measure rendering performance + var renderStart = new Date().getTime(); + while (members.length) + { + with({slice: members.splice(0, insertSliceSize), isLast: !members.length}) + { + timeouts.push(this.context.setTimeout(function() + { + // TODO: xxxpedro can this be a timing error related to the + // "iteration number" approach insted of "duration time"? + // avoid error in IE8 + if (!tbody.lastChild) return; + + result = rowTag.insertRows({members: slice}, tbody.lastChild); + + //rowCount += insertSliceSize; + //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [panel, result, rowCount, setSize]); + + if ((panelNode.scrollHeight+panelNode.offsetHeight) >= priorScrollTop) + panelNode.scrollTop = priorScrollTop; + + + // enable to measure rendering performance + //if (isLast) alert(new Date().getTime() - renderStart + "ms"); + + + }, delay)); + + delay += insertInterval; + } + } + + if (offscreen) + { + timeouts.push(this.context.setTimeout(function() + { + if (panelNode.firstChild) + panelNode.replaceChild(table, panelNode.firstChild); + else + panelNode.appendChild(table); + + // Scroll back to where we were before + panelNode.scrollTop = priorScrollTop; + }, delay)); + } + else + { + timeouts.push(this.context.setTimeout(function() + { + panelNode.scrollTop = scrollTop == undefined ? 0 : scrollTop; + }, delay)); + } + this.timeouts = timeouts; + }, + + /* + // new + showMembers: function(members, update, scrollTop) + { + // If we are still in the midst of inserting rows, cancel all pending + // insertions here - this is a big speedup when stepping in the debugger + if (this.timeouts) + { + for (var i = 0; i < this.timeouts.length; ++i) + this.context.clearTimeout(this.timeouts[i]); + delete this.timeouts; + } + + if (!members.length) + return this.showEmptyMembers(); + + var panelNode = this.panelNode; + var priorScrollTop = scrollTop == undefined ? panelNode.scrollTop : scrollTop; + + // If we are asked to "update" the current view, then build the new table + // offscreen and swap it in when it's done + var offscreen = update && panelNode.firstChild; + var dest = offscreen ? panelNode.ownerDocument : panelNode; + + var table = this.tag.replace({domPanel: this, toggles: this.toggles}, dest); + var tbody = table.lastChild; + var rowTag = DirTablePlate.rowTag; + + // Insert the first slice immediately + //var slice = members.splice(0, insertSliceSize); + //var result = rowTag.insertRows({members: slice}, tbody.lastChild); + + //var setSize = members.length; + //var rowCount = 1; + + var panel = this; + var result; + + //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [panel, result, rowCount, setSize]); + var timeouts = []; + + var delay = 0; + var _insertSliceSize = insertSliceSize; + var _insertInterval = insertInterval; + + // enable to measure rendering performance + var renderStart = new Date().getTime(); + var lastSkip = renderStart, now; + + while (members.length) + { + with({slice: members.splice(0, _insertSliceSize), isLast: !members.length}) + { + var _tbody = tbody; + var _rowTag = rowTag; + var _panelNode = panelNode; + var _priorScrollTop = priorScrollTop; + + timeouts.push(this.context.setTimeout(function() + { + // TODO: xxxpedro can this be a timing error related to the + // "iteration number" approach insted of "duration time"? + // avoid error in IE8 + if (!_tbody.lastChild) return; + + result = _rowTag.insertRows({members: slice}, _tbody.lastChild); + + //rowCount += _insertSliceSize; + //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [panel, result, rowCount, setSize]); + + if ((_panelNode.scrollHeight + _panelNode.offsetHeight) >= _priorScrollTop) + _panelNode.scrollTop = _priorScrollTop; + + + // enable to measure rendering performance + //alert("gap: " + (new Date().getTime() - lastSkip)); + //lastSkip = new Date().getTime(); + + //if (isLast) alert("new: " + (new Date().getTime() - renderStart) + "ms"); + + }, delay)); + + delay += _insertInterval; + } + } + + if (offscreen) + { + timeouts.push(this.context.setTimeout(function() + { + if (panelNode.firstChild) + panelNode.replaceChild(table, panelNode.firstChild); + else + panelNode.appendChild(table); + + // Scroll back to where we were before + panelNode.scrollTop = priorScrollTop; + }, delay)); + } + else + { + timeouts.push(this.context.setTimeout(function() + { + panelNode.scrollTop = scrollTop == undefined ? 0 : scrollTop; + }, delay)); + } + this.timeouts = timeouts; + }, + /**/ + + showEmptyMembers: function() + { + FirebugReps.Warning.tag.replace({object: "NoMembersWarning"}, this.panelNode); + }, + + findPathObject: function(object) + { + var pathIndex = -1; + for (var i = 0; i < this.objectPath.length; ++i) + { + // IE needs === instead of == or otherwise some objects will + // be considered equal to different objects, returning the + // wrong index of the objectPath array + if (this.getPathObject(i) === object) + return i; + } + + return -1; + }, + + getPathObject: function(index) + { + var object = this.objectPath[index]; + + if (object instanceof Property) + return object.getObject(); + else + return object; + }, + + getRowObject: function(row) + { + var object = getRowOwnerObject(row); + return object ? object : this.selection; + }, + + getRowPropertyValue: function(row) + { + var object = this.getRowObject(row); + object = this.getRealObject(object); + if (object) + { + var propName = getRowName(row); + + if (object instanceof jsdIStackFrame) + return Firebug.Debugger.evaluate(propName, this.context); + else + return object[propName]; + } + }, + /* + copyProperty: function(row) + { + var value = this.getRowPropertyValue(row); + copyToClipboard(value); + }, + + editProperty: function(row, editValue) + { + if (hasClass(row, "watchNewRow")) + { + if (this.context.stopped) + Firebug.Editor.startEditing(row, ""); + else if (Firebug.Console.isAlwaysEnabled()) // not stopped in debugger, need command line + { + if (Firebug.CommandLine.onCommandLineFocus()) + Firebug.Editor.startEditing(row, ""); + else + row.innerHTML = $STR("warning.Command line blocked?"); + } + else + row.innerHTML = $STR("warning.Console must be enabled"); + } + else if (hasClass(row, "watchRow")) + Firebug.Editor.startEditing(row, getRowName(row)); + else + { + var object = this.getRowObject(row); + this.context.thisValue = object; + + if (!editValue) + { + var propValue = this.getRowPropertyValue(row); + + var type = typeof(propValue); + if (type == "undefined" || type == "number" || type == "boolean") + editValue = propValue; + else if (type == "string") + editValue = "\"" + escapeJS(propValue) + "\""; + else if (propValue == null) + editValue = "null"; + else if (object instanceof Window || object instanceof jsdIStackFrame) + editValue = getRowName(row); + else + editValue = "this." + getRowName(row); + } + + + Firebug.Editor.startEditing(row, editValue); + } + }, + + deleteProperty: function(row) + { + if (hasClass(row, "watchRow")) + this.deleteWatch(row); + else + { + var object = getRowOwnerObject(row); + if (!object) + object = this.selection; + object = this.getRealObject(object); + + if (object) + { + var name = getRowName(row); + try + { + delete object[name]; + } + catch (exc) + { + return; + } + + this.rebuild(true); + this.markChange(); + } + } + }, + + setPropertyValue: function(row, value) // value must be string + { + if(FBTrace.DBG_DOM) + { + FBTrace.sysout("row: "+row); + FBTrace.sysout("value: "+value+" type "+typeof(value), value); + } + + var name = getRowName(row); + if (name == "this") + return; + + var object = this.getRowObject(row); + object = this.getRealObject(object); + if (object && !(object instanceof jsdIStackFrame)) + { + // unwrappedJSObject.property = unwrappedJSObject + Firebug.CommandLine.evaluate(value, this.context, object, this.context.getGlobalScope(), + function success(result, context) + { + if (FBTrace.DBG_DOM) + FBTrace.sysout("setPropertyValue evaluate success object["+name+"]="+result+" type "+typeof(result), result); + object[name] = result; + }, + function failed(exc, context) + { + try + { + if (FBTrace.DBG_DOM) + FBTrace.sysout("setPropertyValue evaluate failed with exc:"+exc+" object["+name+"]="+value+" type "+typeof(value), exc); + // If the value doesn't parse, then just store it as a string. Some users will + // not realize they're supposed to enter a JavaScript expression and just type + // literal text + object[name] = String(value); // unwrappedJSobject.property = string + } + catch (exc) + { + return; + } + } + ); + } + else if (this.context.stopped) + { + try + { + Firebug.CommandLine.evaluate(name+"="+value, this.context); + } + catch (exc) + { + try + { + // See catch block above... + object[name] = String(value); // unwrappedJSobject.property = string + } + catch (exc) + { + return; + } + } + } + + this.rebuild(true); + this.markChange(); + }, + + highlightRow: function(row) + { + if (this.highlightedRow) + cancelClassTimed(this.highlightedRow, "jumpHighlight", this.context); + + this.highlightedRow = row; + + if (row) + setClassTimed(row, "jumpHighlight", this.context); + },/**/ + + onMouseMove: function(event) + { + var target = event.srcElement || event.target; + + var object = getAncestorByClass(target, "objectLink-element"); + object = object ? object.repObject : null; + + if(object && instanceOf(object, "Element") && object.nodeType == 1) + { + if(object != lastHighlightedObject) + { + Firebug.Inspector.drawBoxModel(object); + object = lastHighlightedObject; + } + } + else + Firebug.Inspector.hideBoxModel(); + + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + create: function() + { + // TODO: xxxpedro + this.context = Firebug.browser; + + this.objectPath = []; + this.propertyPath = []; + this.viewPath = []; + this.pathIndex = -1; + this.toggles = {}; + + Firebug.Panel.create.apply(this, arguments); + + this.panelNode.style.padding = "0 1px"; + }, + + initialize: function(){ + Firebug.Panel.initialize.apply(this, arguments); + + addEvent(this.panelNode, "mousemove", this.onMouseMove); + }, + + shutdown: function() + { + removeEvent(this.panelNode, "mousemove", this.onMouseMove); + + Firebug.Panel.shutdown.apply(this, arguments); + }, + + /* + destroy: function(state) + { + var view = this.viewPath[this.pathIndex]; + if (view && this.panelNode.scrollTop) + view.scrollTop = this.panelNode.scrollTop; + + if (this.pathIndex) + state.pathIndex = this.pathIndex; + if (this.viewPath) + state.viewPath = this.viewPath; + if (this.propertyPath) + state.propertyPath = this.propertyPath; + + if (this.propertyPath.length > 0 && !this.propertyPath[1]) + state.firstSelection = persistObject(this.getPathObject(1), this.context); + + Firebug.Panel.destroy.apply(this, arguments); + }, + /**/ + + ishow: function(state) + { + if (this.context.loaded && !this.selection) + { + if (!state) + { + this.select(null); + return; + } + if (state.viewPath) + this.viewPath = state.viewPath; + if (state.propertyPath) + this.propertyPath = state.propertyPath; + + var defaultObject = this.getDefaultSelection(this.context); + var selectObject = defaultObject; + + if (state.firstSelection) + { + var restored = state.firstSelection(this.context); + if (restored) + { + selectObject = restored; + this.objectPath = [defaultObject, restored]; + } + else + this.objectPath = [defaultObject]; + } + else + this.objectPath = [defaultObject]; + + if (this.propertyPath.length > 1) + { + for (var i = 1; i < this.propertyPath.length; ++i) + { + var name = this.propertyPath[i]; + if (!name) + continue; + + var object = selectObject; + try + { + selectObject = object[name]; + } + catch (exc) + { + selectObject = null; + } + + if (selectObject) + { + this.objectPath.push(new Property(object, name)); + } + else + { + // If we can't access a property, just stop + this.viewPath.splice(i); + this.propertyPath.splice(i); + this.objectPath.splice(i); + selectObject = this.getPathObject(this.objectPath.length-1); + break; + } + } + } + + var selection = state.pathIndex <= this.objectPath.length-1 + ? this.getPathObject(state.pathIndex) + : this.getPathObject(this.objectPath.length-1); + + this.select(selection); + } + }, + /* + hide: function() + { + var view = this.viewPath[this.pathIndex]; + if (view && this.panelNode.scrollTop) + view.scrollTop = this.panelNode.scrollTop; + }, + /**/ + + supportsObject: function(object) + { + if (object == null) + return 1000; + + if (typeof(object) == "undefined") + return 1000; + else if (object instanceof SourceLink) + return 0; + else + return 1; // just agree to support everything but not agressively. + }, + + refresh: function() + { + this.rebuild(true); + }, + + updateSelection: function(object) + { + var previousIndex = this.pathIndex; + var previousView = previousIndex == -1 ? null : this.viewPath[previousIndex]; + + var newPath = this.pathToAppend; + delete this.pathToAppend; + + var pathIndex = this.findPathObject(object); + if (newPath || pathIndex == -1) + { + this.toggles = {}; + + if (newPath) + { + // Remove everything after the point where we are inserting, so we + // essentially replace it with the new path + if (previousView) + { + if (this.panelNode.scrollTop) + previousView.scrollTop = this.panelNode.scrollTop; + + var start = previousIndex + 1, + // Opera needs the length argument in splice(), otherwise + // it will consider that only one element should be removed + length = this.objectPath.length - start; + + this.objectPath.splice(start, length); + this.propertyPath.splice(start, length); + this.viewPath.splice(start, length); + } + + var value = this.getPathObject(previousIndex); + if (!value) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("dom.updateSelection no pathObject for "+previousIndex+"\n"); + return; + } + + for (var i = 0, length = newPath.length; i < length; ++i) + { + var name = newPath[i]; + var object = value; + try + { + value = value[name]; + } + catch(exc) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("dom.updateSelection FAILS at path_i="+i+" for name:"+name+"\n"); + return; + } + + ++this.pathIndex; + this.objectPath.push(new Property(object, name)); + this.propertyPath.push(name); + this.viewPath.push({toggles: this.toggles, scrollTop: 0}); + } + } + else + { + this.toggles = {}; + + var win = Firebug.browser.window; + //var win = this.context.getGlobalScope(); + if (object === win) + { + this.pathIndex = 0; + this.objectPath = [win]; + this.propertyPath = [null]; + this.viewPath = [{toggles: this.toggles, scrollTop: 0}]; + } + else + { + this.pathIndex = 1; + this.objectPath = [win, object]; + this.propertyPath = [null, null]; + this.viewPath = [ + {toggles: {}, scrollTop: 0}, + {toggles: this.toggles, scrollTop: 0} + ]; + } + } + + this.panelNode.scrollTop = 0; + this.rebuild(); + } + else + { + this.pathIndex = pathIndex; + + var view = this.viewPath[pathIndex]; + this.toggles = view.toggles; + + // Persist the current scroll location + if (previousView && this.panelNode.scrollTop) + previousView.scrollTop = this.panelNode.scrollTop; + + this.rebuild(false, view.scrollTop); + } + }, + + getObjectPath: function(object) + { + return this.objectPath; + }, + + getDefaultSelection: function() + { + return Firebug.browser.window; + //return this.context.getGlobalScope(); + }/*, + + updateOption: function(name, value) + { + const optionMap = {showUserProps: 1, showUserFuncs: 1, showDOMProps: 1, + showDOMFuncs: 1, showDOMConstants: 1}; + if ( optionMap.hasOwnProperty(name) ) + this.rebuild(true); + }, + + getOptionsMenuItems: function() + { + return [ + optionMenu("ShowUserProps", "showUserProps"), + optionMenu("ShowUserFuncs", "showUserFuncs"), + optionMenu("ShowDOMProps", "showDOMProps"), + optionMenu("ShowDOMFuncs", "showDOMFuncs"), + optionMenu("ShowDOMConstants", "showDOMConstants"), + "-", + {label: "Refresh", command: bindFixed(this.rebuild, this, true) } + ]; + }, + + getContextMenuItems: function(object, target) + { + var row = getAncestorByClass(target, "memberRow"); + + var items = []; + + if (row) + { + var rowName = getRowName(row); + var rowObject = this.getRowObject(row); + var rowValue = this.getRowPropertyValue(row); + + var isWatch = hasClass(row, "watchRow"); + var isStackFrame = rowObject instanceof jsdIStackFrame; + + if (typeof(rowValue) == "string" || typeof(rowValue) == "number") + { + // Functions already have a copy item in their context menu + items.push( + "-", + {label: "CopyValue", + command: bindFixed(this.copyProperty, this, row) } + ); + } + + items.push( + "-", + {label: isWatch ? "EditWatch" : (isStackFrame ? "EditVariable" : "EditProperty"), + command: bindFixed(this.editProperty, this, row) } + ); + + if (isWatch || (!isStackFrame && !isDOMMember(rowObject, rowName))) + { + items.push( + {label: isWatch ? "DeleteWatch" : "DeleteProperty", + command: bindFixed(this.deleteProperty, this, row) } + ); + } + } + + items.push( + "-", + {label: "Refresh", command: bindFixed(this.rebuild, this, true) } + ); + + return items; + }, + + getEditor: function(target, value) + { + if (!this.editor) + this.editor = new DOMEditor(this.document); + + return this.editor; + }/**/ +}); + +// ************************************************************************************************ + +// TODO: xxxpedro statusbar +var updateStatusBar = function(panel) +{ + var path = panel.propertyPath; + var index = panel.pathIndex; + + var r = []; + + for (var i=0, l=path.length; i'); + r.push(i==0 ? "window" : path[i] || "Object"); + r.push('
                  '); + + if(i < l-1) + r.push('>'); + } + panel.statusBarNode.innerHTML = r.join(""); +}; + + +var DOMMainPanel = Firebug.DOMPanel = function () {}; + +Firebug.DOMPanel.DirTable = DirTablePlate; + +DOMMainPanel.prototype = extend(Firebug.DOMBasePanel.prototype, +{ + onClickStatusBar: function(event) + { + var target = event.srcElement || event.target; + var element = getAncestorByClass(target, "fbHover"); + + if(element) + { + var pathIndex = element.getAttribute("pathIndex"); + + if(pathIndex) + { + this.select(this.getPathObject(pathIndex)); + } + } + }, + + selectRow: function(row, target) + { + if (!target) + target = row.lastChild.firstChild; + + if (!target || !target.repObject) + return; + + this.pathToAppend = getPath(row); + + // If the object is inside an array, look up its index + var valueBox = row.lastChild.firstChild; + if (hasClass(valueBox, "objectBox-array")) + { + var arrayIndex = FirebugReps.Arr.getItemIndex(target); + this.pathToAppend.push(arrayIndex); + } + + // Make sure we get a fresh status path for the object, since otherwise + // it might find the object in the existing path and not refresh it + //Firebug.chrome.clearStatusPath(); + + this.select(target.repObject, true); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + onClick: function(event) + { + var target = event.srcElement || event.target; + var repNode = Firebug.getRepNode(target); + if (repNode) + { + var row = getAncestorByClass(target, "memberRow"); + if (row) + { + this.selectRow(row, repNode); + cancelEvent(event); + } + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "DOM", + title: "DOM", + searchable: true, + statusSeparator: ">", + + options: { + hasToolButtons: true, + hasStatusBar: true + }, + + create: function() + { + Firebug.DOMBasePanel.prototype.create.apply(this, arguments); + + this.onClick = bind(this.onClick, this); + + //TODO: xxxpedro + this.onClickStatusBar = bind(this.onClickStatusBar, this); + + this.panelNode.style.padding = "0 1px"; + }, + + initialize: function(oldPanelNode) + { + //this.panelNode.addEventListener("click", this.onClick, false); + //dispatch([Firebug.A11yModel], 'onInitializeNode', [this, 'console']); + + Firebug.DOMBasePanel.prototype.initialize.apply(this, arguments); + + addEvent(this.panelNode, "click", this.onClick); + + // TODO: xxxpedro dom + this.ishow(); + + //TODO: xxxpedro + addEvent(this.statusBarNode, "click", this.onClickStatusBar); + }, + + shutdown: function() + { + //this.panelNode.removeEventListener("click", this.onClick, false); + //dispatch([Firebug.A11yModel], 'onDestroyNode', [this, 'console']); + + removeEvent(this.panelNode, "click", this.onClick); + + Firebug.DOMBasePanel.prototype.shutdown.apply(this, arguments); + }/*, + + search: function(text, reverse) + { + if (!text) + { + delete this.currentSearch; + this.highlightRow(null); + return false; + } + + var row; + if (this.currentSearch && text == this.currentSearch.text) + row = this.currentSearch.findNext(true, undefined, reverse, Firebug.searchCaseSensitive); + else + { + function findRow(node) { return getAncestorByClass(node, "memberRow"); } + this.currentSearch = new TextSearch(this.panelNode, findRow); + row = this.currentSearch.find(text, reverse, Firebug.searchCaseSensitive); + } + + if (row) + { + var sel = this.document.defaultView.getSelection(); + sel.removeAllRanges(); + sel.addRange(this.currentSearch.range); + + scrollIntoCenterView(row, this.panelNode); + + this.highlightRow(row); + dispatch([Firebug.A11yModel], 'onDomSearchMatchFound', [this, text, row]); + return true; + } + else + { + dispatch([Firebug.A11yModel], 'onDomSearchMatchFound', [this, text, null]); + return false; + } + }/**/ +}); + +Firebug.registerPanel(DOMMainPanel); + + +// ************************************************************************************************ + + + +// ************************************************************************************************ +// Local Helpers + +var getMembers = function getMembers(object, level) // we expect object to be user-level object wrapped in security blanket +{ + if (!level) + level = 0; + + var ordinals = [], userProps = [], userClasses = [], userFuncs = [], + domProps = [], domFuncs = [], domConstants = []; + + try + { + var domMembers = getDOMMembers(object); + //var domMembers = {}; // TODO: xxxpedro + //var domConstantMap = {}; // TODO: xxxpedro + + if (object.wrappedJSObject) + var insecureObject = object.wrappedJSObject; + else + var insecureObject = object; + + // IE function prototype is not listed in (for..in) + if (isIE && isFunction(object)) + addMember("user", userProps, "prototype", object.prototype, level); + + for (var name in insecureObject) // enumeration is safe + { + if (ignoreVars[name] == 1) // javascript.options.strict says ignoreVars is undefined. + continue; + + var val; + try + { + val = insecureObject[name]; // getter is safe + } + catch (exc) + { + // Sometimes we get exceptions trying to access certain members + if (FBTrace.DBG_ERRORS && FBTrace.DBG_DOM) + FBTrace.sysout("dom.getMembers cannot access "+name, exc); + } + + var ordinal = parseInt(name); + if (ordinal || ordinal == 0) + { + addMember("ordinal", ordinals, name, val, level); + } + else if (isFunction(val)) + { + if (isClassFunction(val) && !(name in domMembers)) + addMember("userClass", userClasses, name, val, level); + else if (name in domMembers) + addMember("domFunction", domFuncs, name, val, level, domMembers[name]); + else + addMember("userFunction", userFuncs, name, val, level); + } + else + { + //TODO: xxxpedro + /* + var getterFunction = insecureObject.__lookupGetter__(name), + setterFunction = insecureObject.__lookupSetter__(name), + prefix = ""; + + if(getterFunction && !setterFunction) + prefix = "get "; + /**/ + + var prefix = ""; + + if (name in domMembers && !(name in domConstantMap)) + addMember("dom", domProps, (prefix+name), val, level, domMembers[name]); + else if (name in domConstantMap) + addMember("dom", domConstants, (prefix+name), val, level); + else + addMember("user", userProps, (prefix+name), val, level); + } + } + } + catch (exc) + { + // Sometimes we get exceptions just from trying to iterate the members + // of certain objects, like StorageList, but don't let that gum up the works + throw exc; + if (FBTrace.DBG_ERRORS && FBTrace.DBG_DOM) + FBTrace.sysout("dom.getMembers FAILS: ", exc); + //throw exc; + } + + function sortName(a, b) { return a.name > b.name ? 1 : -1; } + function sortOrder(a, b) { return a.order > b.order ? 1 : -1; } + + var members = []; + + members.push.apply(members, ordinals); + + Firebug.showUserProps = true; // TODO: xxxpedro + Firebug.showUserFuncs = true; // TODO: xxxpedro + Firebug.showDOMProps = true; + Firebug.showDOMFuncs = true; + Firebug.showDOMConstants = true; + + if (Firebug.showUserProps) + { + userProps.sort(sortName); + members.push.apply(members, userProps); + } + + if (Firebug.showUserFuncs) + { + userClasses.sort(sortName); + members.push.apply(members, userClasses); + + userFuncs.sort(sortName); + members.push.apply(members, userFuncs); + } + + if (Firebug.showDOMProps) + { + domProps.sort(sortName); + members.push.apply(members, domProps); + } + + if (Firebug.showDOMFuncs) + { + domFuncs.sort(sortName); + members.push.apply(members, domFuncs); + } + + if (Firebug.showDOMConstants) + members.push.apply(members, domConstants); + + return members; +} + +function expandMembers(members, toggles, offset, level) // recursion starts with offset=0, level=0 +{ + var expanded = 0; + for (var i = offset; i < members.length; ++i) + { + var member = members[i]; + if (member.level > level) + break; + + if ( toggles.hasOwnProperty(member.name) ) + { + member.open = "opened"; // member.level <= level && member.name in toggles. + + var newMembers = getMembers(member.value, level+1); // sets newMembers.level to level+1 + + var args = [i+1, 0]; + args.push.apply(args, newMembers); + members.splice.apply(members, args); + + /* + if (FBTrace.DBG_DOM) + { + FBTrace.sysout("expandMembers member.name", member.name); + FBTrace.sysout("expandMembers toggles", toggles); + FBTrace.sysout("expandMembers toggles[member.name]", toggles[member.name]); + FBTrace.sysout("dom.expandedMembers level: "+level+" member", member); + } + /**/ + + expanded += newMembers.length; + i += newMembers.length + expandMembers(members, toggles[member.name], i+1, level+1); + } + } + + return expanded; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + +function isClassFunction(fn) +{ + try + { + for (var name in fn.prototype) + return true; + } catch (exc) {} + return false; +} + +var hasProperties = function hasProperties(ob) +{ + try + { + for (var name in ob) + return true; + } catch (exc) {} + + // IE function prototype is not listed in (for..in) + if (isFunction(ob)) return true; + + return false; +} + +FBL.ErrorCopy = function(message) +{ + this.message = message; +}; + +var addMember = function addMember(type, props, name, value, level, order) +{ + var rep = Firebug.getRep(value); // do this first in case a call to instanceof reveals contents + var tag = rep.shortTag ? rep.shortTag : rep.tag; + + var ErrorCopy = function(){}; //TODO: xxxpedro + + var valueType = typeof(value); + var hasChildren = hasProperties(value) && !(value instanceof ErrorCopy) && + (isFunction(value) || (valueType == "object" && value != null) + || (valueType == "string" && value.length > Firebug.stringCropLength)); + + props.push({ + name: name, + value: value, + type: type, + rowClass: "memberRow-"+type, + open: "", + order: order, + level: level, + indent: level*16, + hasChildren: hasChildren, + tag: tag + }); +} + +var getWatchRowIndex = function getWatchRowIndex(row) +{ + var index = -1; + for (; row && hasClass(row, "watchRow"); row = row.previousSibling) + ++index; + return index; +} + +var getRowName = function getRowName(row) +{ + var node = row.firstChild; + return node.textContent ? node.textContent : node.innerText; +} + +var getRowValue = function getRowValue(row) +{ + return row.lastChild.firstChild.repObject; +} + +var getRowOwnerObject = function getRowOwnerObject(row) +{ + var parentRow = getParentRow(row); + if (parentRow) + return getRowValue(parentRow); +} + +var getParentRow = function getParentRow(row) +{ + var level = parseInt(row.getAttribute("level"))-1; + for (row = row.previousSibling; row; row = row.previousSibling) + { + if (parseInt(row.getAttribute("level")) == level) + return row; + } +} + +var getPath = function getPath(row) +{ + var name = getRowName(row); + var path = [name]; + + var level = parseInt(row.getAttribute("level"))-1; + for (row = row.previousSibling; row; row = row.previousSibling) + { + if (parseInt(row.getAttribute("level")) == level) + { + var name = getRowName(row); + path.splice(0, 0, name); + + --level; + } + } + + return path; +} + +// ************************************************************************************************ + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + +// ************************************************************************************************ +// DOM Module + +Firebug.DOM = extend(Firebug.Module, +{ + getPanel: function() + { + return Firebug.chrome ? Firebug.chrome.getPanel("DOM") : null; + } +}); + +Firebug.registerModule(Firebug.DOM); + + +// ************************************************************************************************ +// DOM Panel + +var lastHighlightedObject; + +function DOMSidePanel(){}; + +DOMSidePanel.prototype = extend(Firebug.DOMBasePanel.prototype, +{ + selectRow: function(row, target) + { + if (!target) + target = row.lastChild.firstChild; + + if (!target || !target.repObject) + return; + + this.pathToAppend = getPath(row); + + // If the object is inside an array, look up its index + var valueBox = row.lastChild.firstChild; + if (hasClass(valueBox, "objectBox-array")) + { + var arrayIndex = FirebugReps.Arr.getItemIndex(target); + this.pathToAppend.push(arrayIndex); + } + + // Make sure we get a fresh status path for the object, since otherwise + // it might find the object in the existing path and not refresh it + //Firebug.chrome.clearStatusPath(); + + var object = target.repObject; + + if (instanceOf(object, "Element")) + { + Firebug.HTML.selectTreeNode(ElementCache(object)); + } + else + { + Firebug.chrome.selectPanel("DOM"); + Firebug.chrome.getPanel("DOM").select(object, true); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + onClick: function(event) + { + /* + var target = event.srcElement || event.target; + + var object = getAncestorByClass(target, "objectLink"); + object = object ? object.repObject : null; + + if(!object) return; + + if (instanceOf(object, "Element")) + { + Firebug.HTML.selectTreeNode(ElementCache(object)); + } + else + { + Firebug.chrome.selectPanel("DOM"); + Firebug.chrome.getPanel("DOM").select(object, true); + } + /**/ + + + var target = event.srcElement || event.target; + var repNode = Firebug.getRepNode(target); + if (repNode) + { + var row = getAncestorByClass(target, "memberRow"); + if (row) + { + this.selectRow(row, repNode); + cancelEvent(event); + } + } + /**/ + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "DOMSidePanel", + parentPanel: "HTML", + title: "DOM", + + options: { + hasToolButtons: true + }, + + isInitialized: false, + + create: function() + { + Firebug.DOMBasePanel.prototype.create.apply(this, arguments); + + this.onClick = bind(this.onClick, this); + }, + + initialize: function(){ + Firebug.DOMBasePanel.prototype.initialize.apply(this, arguments); + + addEvent(this.panelNode, "click", this.onClick); + + // TODO: xxxpedro css2 + var selection = ElementCache.get(FirebugChrome.selectedHTMLElementId); + if (selection) + this.select(selection, true); + }, + + shutdown: function() + { + removeEvent(this.panelNode, "click", this.onClick); + + Firebug.DOMBasePanel.prototype.shutdown.apply(this, arguments); + }, + + reattach: function(oldChrome) + { + //this.isInitialized = oldChrome.getPanel("DOM").isInitialized; + this.toggles = oldChrome.getPanel("DOMSidePanel").toggles; + } + +}); + +Firebug.registerPanel(DOMSidePanel); + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +FBL.FBTrace = {}; + +(function() { +// ************************************************************************************************ + +var traceOptions = { + DBG_TIMESTAMP: 1, + DBG_INITIALIZE: 1, + DBG_CHROME: 1, + DBG_ERRORS: 1, + DBG_DISPATCH: 1, + DBG_CSS: 1 +}; + +this.module = null; + +this.initialize = function() +{ + if (!this.messageQueue) + this.messageQueue = []; + + for (var name in traceOptions) + this[name] = traceOptions[name]; +}; + +// ************************************************************************************************ +// FBTrace API + +this.sysout = function() +{ + return this.logFormatted(arguments, ""); +}; + +this.dumpProperties = function(title, object) +{ + return this.logFormatted("dumpProperties() not supported.", "warning"); +}; + +this.dumpStack = function() +{ + return this.logFormatted("dumpStack() not supported.", "warning"); +}; + +this.flush = function(module) +{ + this.module = module; + + var queue = this.messageQueue; + this.messageQueue = []; + + for (var i = 0; i < queue.length; ++i) + this.writeMessage(queue[i][0], queue[i][1], queue[i][2]); +}; + +this.getPanel = function() +{ + return this.module ? this.module.getPanel() : null; +}; + +//************************************************************************************************* + +this.logFormatted = function(objects, className) +{ + var html = this.DBG_TIMESTAMP ? [getTimestamp(), " | "] : []; + var length = objects.length; + + for (var i = 0; i < length; ++i) + { + appendText(" ", html); + + var object = objects[i]; + + if (i == 0) + { + html.push(""); + 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); + +/* 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(); + } + +}); + +Firebug.registerPanel(TracePanel); + +// ************************************************************************************************ +}}); + +/* 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); + } + +}); + + + + +// ************************************************************************************************ +}}); + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +FirebugChrome.Skin = +{ + CSS: '.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;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;}#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;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 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;}', + HTML: '
                   
                   
                  >>>
                  2 errors' +}; + +// ************************************************************************************************ +}}); + +// ************************************************************************************************ +FBL.initialize(); +// ************************************************************************************************ + +})(); \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/firebug-lite-debug.js b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/firebug-lite-debug.js new file mode 100755 index 0000000..41c7d58 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/firebug-lite-debug.js @@ -0,0 +1,29624 @@ +(function(){ + +/*!************************************************************* + * + * Firebug Lite 1.3.2 + * + * 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 */ +var FBL = {}; + +/** @name ns @namespace */ + +( /** @scope ns-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 = {}; + + FBL.Ajax.initialize(); + + // 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... + var prefs = eval("(" + FBL.readCookie("FirebugLite") + ")"); + if (prefs) + { + FBL.Env.Options.startOpened = prefs.startOpened; + FBL.Env.Options.enableTrace = prefs.enableTrace; + FBL.Env.Options.enablePersistent = prefs.enablePersistent; + FBL.Env.Options.disableXHRListener = prefs.disableXHRListener; + } + + 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"); + } + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // finish environment initialization + + FBL.Firebug.loadPrefs(prefs); + + 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: false, + + saveWindowPosition: false, + saveCommandLineHistory: false, + + startOpened: false, + startInNewWindow: false, + showIconWhenHidden: true, + + overrideConsole: true, + ignoreFirebugElements: true, + disableWhenFirebugActive: true, + + disableXHRListener: 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 rePath = /^(.*\/)/; + var reProtocol = /^\w+:\/\//; + var path = null; + var doc = document; + + // Firebug Lite 1.3.0 bookmarklet identification + var script = doc.getElementById("FirebugLite"); + + if (script) + { + file = reFirebugFile.exec(script.src); + + var version = script.getAttribute("FirebugLite"); + var number = version ? parseInt(version) : 0; + + if (!version || !number || number < bookmarkletVersion) + { + FBL.Env.bookmarkletOutdated = true; + } + } + else + { + for(var i=0, s=doc.getElementsByTagName("script"), si; si=s[i]; i++) + { + var file = null; + if ( si.nodeName.toLowerCase() == "script" && (file = reFirebugFile.exec(si.src)) ) + { + script = si; + break; + } + } + } + + if (script) + script.firebugIgnore = true; + + 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(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}"}; + } + + 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; + + // 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 + 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; + } + } + } + + // 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) + return ob + ""; + + 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, ""); + + if (elt.offsetLeft) + coords.x += elt.offsetLeft + parseInt(style.borderLeftWidth); + if (elt.offsetTop) + coords.y += elt.offsetTop + parseInt(style.borderTopWidth); + + if (p) + { + if (p.nodeType == 1) + addOffset(p, coords, view); + } + else + { + var otherView = isIE ? elt.ownerDocument.parentWindow : elt.ownerDocument.defaultView; + if (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; + + return toString.call(object) === "[object Function]" || + this.isIE && typeof object != "string" && reFunction.test(""+object); +}; + + +// ************************************************************************************************ +// 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 = this.getXHRObject(); + }, + + 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); + +/* See license.txt for terms of usage */ + +FBL.ns( /** @scope ns-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; +}; + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +FBL.ns( /** @scope ns-firebug */ function() { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +// Globals + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Internals + +var modules = []; +var panelTypes = []; +var panelTypeMap = {}; +var reps = []; + +var parentPanelMap = {}; + + +// ************************************************************************************************ +// Firebug + +/** + * @namespace describe Firebug + * @exports window.Firebug as Firebug + */ +window.Firebug = FBL.Firebug = +{ + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + version: "Firebug Lite 1.3.2", + revision: "$Revision: 9760 $", + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + 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; + + // Document must be cached before chrome initialization + cacheDocument(); + + if (Firebug.Inspector) + Firebug.Inspector.create(); + + if (FBL.processAllStyleSheets) + processAllStyleSheets(Firebug.browser.document); + + FirebugChrome.initialize(); + + dispatch(modules, "initialize", []); + + if (Env.onLoad) + { + var onLoad = Env.onLoad; + delete Env.onLoad; + + setTimeout(onLoad, 200); + } + }, + + shutdown: function() + { + if (Firebug.Inspector) + Firebug.Inspector.destroy(); + + dispatch(modules, "shutdown", []); + + var chromeMap = FirebugChrome.chromeMap; + + for (var name in chromeMap) + { + if (chromeMap.hasOwnProperty(name)) + { + chromeMap[name].destroy(); + } + } + + 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; + + this.savePrefs(); + }, + + setPrefs: function(prefs) + { + for (var name in prefs) + { + if (prefs.hasOwnProperty(name)) + Firebug[name] = prefs[name]; + } + + this.savePrefs(); + }, + + restorePrefs: function() + { + var Options = Env.Options; + + for (var name in Options) + { + Firebug[name] = Options[name]; + } + }, + + loadPrefs: function(prefs) + { + this.restorePrefs(); + + prefs = prefs || eval("(" + readCookie("FirebugLite") + ")"); + + for (var name in prefs) + { + if (prefs.hasOwnProperty(name)) + Firebug[name] = prefs[name]; + } + }, + + savePrefs: function() + { + var json = ['{'], jl = 0; + var Options = Env.Options; + + for (var name in Options) + { + if (Options.hasOwnProperty(name)) + { + var value = Firebug[name]; + + json[++jl] = '"'; + json[++jl] = name; + + var type = typeof value; + if (type == "boolean" || type == "number") + { + json[++jl] = '":'; + json[++jl] = value; + json[++jl] = ','; + } + else + { + json[++jl] = '":"'; + json[++jl] = value; + json[++jl] = '",'; + } + } + } + + json.length = jl--; + json[++jl] = '}'; + + createCookie("FirebugLite", json.join("")); + }, + + erasePrefs: function() + { + removeCookie("FirebugLite"); + } +}; + +Firebug.restorePrefs(); + +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; + Firebug.InfoTip.initializeBrowser(Firebug.chrome); + }, + + shutdown: function() + { + if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.Panel.shutdown", this.name); + + /// TODO: xxxpedro infoTip Hack + 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.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"; + } +}); + +// ************************************************************************************************ + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +FBL.ns( /** @scope ns-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) + FirebugChrome.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 width || el.scrollHeight > height)) + { + width = el.scrollWidth; + height = el.scrollHeight; + } + + return {width: width, height: height}; + }, + + getWindowScrollPosition: function() + { + var top=0, left=0, el; + + if(typeof this.window.pageYOffset == "number") + { + top = this.window.pageYOffset; + left = this.window.pageXOffset; + } + else if((el=this.document.body) && (el.scrollTop || el.scrollLeft)) + { + top = el.scrollTop; + left = el.scrollLeft; + } + else if((el=this.document.documentElement) && (el.scrollTop || el.scrollLeft)) + { + top = el.scrollTop; + left = el.scrollLeft; + } + + return {top:top, left:left}; + }, + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Element Methods + + getElementFromPoint: function(x, y) + { + if (shouldFixElementFromPoint) + { + var scroll = this.getWindowScrollPosition(); + return this.document.elementFromPoint(x + scroll.left, y + scroll.top); + } + else + return this.document.elementFromPoint(x, y); + }, + + getElementPosition: function(el) + { + var left = 0 + var top = 0; + + do + { + left += el.offsetLeft; + top += el.offsetTop; + } + while (el = el.offsetParent); + + return {left:left, top:top}; + }, + + getElementBox: function(el) + { + var result = {}; + + if (el.getBoundingClientRect) + { + var rect = el.getBoundingClientRect(); + + // fix IE problem with offset when not in fullscreen mode + var offset = isIE ? this.document.body.clientTop || this.document.documentElement.clientTop: 0; + + var scroll = this.getWindowScrollPosition(); + + result.top = Math.round(rect.top - offset + scroll.top); + result.left = Math.round(rect.left - offset + scroll.left); + result.height = Math.round(rect.bottom - rect.top); + result.width = Math.round(rect.right - rect.left); + } + else + { + var position = this.getElementPosition(el); + + result.top = position.top; + result.left = position.left; + result.height = el.offsetHeight; + result.width = el.offsetWidth; + } + + return result; + }, + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Measurement Methods + + getMeasurement: function(el, name) + { + var result = {value: 0, unit: "px"}; + + var cssValue = this.getStyle(el, name); + + if (!cssValue) return result; + if (cssValue.toLowerCase() == "auto") return result; + + var reMeasure = /(\d+\.?\d*)(.*)/; + var m = cssValue.match(reMeasure); + + if (m) + { + result.value = m[1]-0; + result.unit = m[2].toLowerCase(); + } + + return result; + }, + + getMeasurementInPixels: function(el, name) + { + if (!el) return null; + + var m = this.getMeasurement(el, name); + var value = m.value; + var unit = m.unit; + + if (unit == "px") + return value; + + else if (unit == "pt") + return this.pointsToPixels(name, value); + + if (unit == "em") + return this.emToPixels(el, value); + + else if (unit == "%") + return this.percentToPixels(el, value); + }, + + getMeasurementBox1: function(el, name) + { + var sufixes = ["Top", "Left", "Bottom", "Right"]; + var result = []; + + for(var i=0, sufix; sufix=sufixes[i]; i++) + result[i] = Math.round(this.getMeasurementInPixels(el, name + sufix)); + + return {top:result[0], left:result[1], bottom:result[2], right:result[3]}; + }, + + getMeasurementBox: function(el, name) + { + var result = []; + var sufixes = name == "border" ? + ["TopWidth", "LeftWidth", "BottomWidth", "RightWidth"] : + ["Top", "Left", "Bottom", "Right"]; + + if (isIE) + { + var propName, cssValue; + var autoMargin = null; + + for(var i=0, sufix; sufix=sufixes[i]; i++) + { + propName = name + sufix; + + cssValue = el.currentStyle[propName] || el.style[propName]; + + if (cssValue == "auto") + { + if (!autoMargin) + autoMargin = this.getCSSAutoMarginBox(el); + + result[i] = autoMargin[sufix.toLowerCase()]; + } + else + result[i] = this.getMeasurementInPixels(el, propName); + + } + + } + else + { + for(var i=0, sufix; sufix=sufixes[i]; i++) + result[i] = this.getMeasurementInPixels(el, name + sufix); + } + + return {top:result[0], left:result[1], bottom:result[2], right:result[3]}; + }, + + getCSSAutoMarginBox: function(el) + { + if (isIE && " meta title input script link a ".indexOf(" "+el.nodeName.toLowerCase()+" ") != -1) + return {top:0, left:0, bottom:0, right:0}; + /**/ + + if (isIE && " h1 h2 h3 h4 h5 h6 h7 ul p ".indexOf(" "+el.nodeName.toLowerCase()+" ") == -1) + return {top:0, left:0, bottom:0, right:0}; + /**/ + + var offsetTop = 0; + if (false && isIEStantandMode) + { + var scrollSize = Firebug.browser.getWindowScrollSize(); + offsetTop = scrollSize.height; + } + + var box = this.document.createElement("div"); + //box.style.cssText = "margin:0; padding:1px; border: 0; position:static; overflow:hidden; visibility: hidden;"; + box.style.cssText = "margin:0; padding:1px; border: 0; visibility: hidden;"; + + var clone = el.cloneNode(false); + var text = this.document.createTextNode(" "); + clone.appendChild(text); + + box.appendChild(clone); + + this.document.body.appendChild(box); + + var marginTop = clone.offsetTop - box.offsetTop - 1; + var marginBottom = box.offsetHeight - clone.offsetHeight - 2 - marginTop; + + var marginLeft = clone.offsetLeft - box.offsetLeft - 1; + var marginRight = box.offsetWidth - clone.offsetWidth - 2 - marginLeft; + + this.document.body.removeChild(box); + + return {top:marginTop+offsetTop, left:marginLeft, bottom:marginBottom-offsetTop, right:marginRight}; + }, + + getFontSizeInPixels: function(el) + { + var size = this.getMeasurement(el, "fontSize"); + + if (size.unit == "px") return size.value; + + // get font size, the dirty way + var computeDirtyFontSize = function(el, calibration) + { + var div = this.document.createElement("div"); + var divStyle = offscreenStyle; + + if (calibration) + divStyle += " font-size:"+calibration+"px;"; + + div.style.cssText = divStyle; + div.innerHTML = "A"; + el.appendChild(div); + + var value = div.offsetHeight; + el.removeChild(div); + return value; + } + + /* + var calibrationBase = 200; + var calibrationValue = computeDirtyFontSize(el, calibrationBase); + var rate = calibrationBase / calibrationValue; + /**/ + + // the "dirty technique" fails in some environments, so we're using a static value + // based in some tests. + var rate = 200 / 225; + + var value = computeDirtyFontSize(el); + + return value * rate; + }, + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Unit Funtions + + pointsToPixels: function(name, value, returnFloat) + { + var axis = /Top$|Bottom$/.test(name) ? "y" : "x"; + + var result = value * pixelsPerInch[axis] / 72; + + return returnFloat ? result : Math.round(result); + }, + + emToPixels: function(el, value) + { + if (!el) return null; + + var fontSize = this.getFontSizeInPixels(el); + + return Math.round(value * fontSize); + }, + + exToPixels: function(el, value) + { + if (!el) return null; + + // get ex value, the dirty way + var div = this.document.createElement("div"); + div.style.cssText = offscreenStyle + "width:"+value + "ex;"; + + el.appendChild(div); + var value = div.offsetWidth; + el.removeChild(div); + + return value; + }, + + percentToPixels: function(el, value) + { + if (!el) return null; + + // get % value, the dirty way + var div = this.document.createElement("div"); + div.style.cssText = offscreenStyle + "width:"+value + "%;"; + + el.appendChild(div); + var value = div.offsetWidth; + el.removeChild(div); + + return value; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getStyle: isIE ? function(el, name) + { + return el.currentStyle[name] || el.style[name] || undefined; + } + : function(el, name) + { + return this.document.defaultView.getComputedStyle(el,null)[name] + || el.style[name] || undefined; + } + +}; + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +FBL.ns( /**@scope ns-chrome*/ function() { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +// Globals + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Window Options + +var WindowDefaultOptions = + { + type: "frame", + id: "FirebugUI", + height: 250 + }, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Instantiated objects + + commandLine, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Interface Elements Cache + + fbTop, + fbContent, + fbContentStyle, + fbBottom, + fbBtnInspect, + + fbToolbar, + + fbPanelBox1, + fbPanelBox1Style, + fbPanelBox2, + fbPanelBox2Style, + fbPanelBar2Box, + fbPanelBar2BoxStyle, + + fbHSplitter, + fbVSplitter, + fbVSplitterStyle, + + fbPanel1, + fbPanel1Style, + fbPanel2, + fbPanel2Style, + + fbConsole, + fbConsoleStyle, + fbHTML, + + fbCommandLine, + fbLargeCommandLine, + fbLargeCommandButtons, + +//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Cached size values + + topHeight, + topPartialHeight, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + chromeRedrawSkipRate = isIE ? 75 : isOpera ? 80 : 75, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + lastSelectedPanelName, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + focusCommandLineState = 0, + lastFocusedPanelName, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + lastHSplitterMouseMove = 0, + onHSplitterMouseMoveBuffer = null, + onHSplitterMouseMoveTimer = null, + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + lastVSplitterMouseMove = 0; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + +// ************************************************************************************************ +// FirebugChrome + +/**@namespace*/ +FBL.FirebugChrome = +{ + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + isOpen: false, + height: 250, + sidePanelWidth: 350, + + selectedPanelName: "Console", + selectedHTMLElementId: null, + + chromeMap: {}, + + htmlSelectionStack: [], + consoleMessageQueue: [], + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + create: function() + { + if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("FirebugChrome.create", "creating chrome window"); + + createChromeWindow(); + }, + + initialize: function() + { + if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("FirebugChrome.initialize", "initializing chrome window"); + + if (Env.chrome.type == "frame" || Env.chrome.type == "div") + ChromeMini.create(Env.chrome); + + var chrome = Firebug.chrome = new Chrome(Env.chrome); + FirebugChrome.chromeMap[chrome.type] = chrome; + + addGlobalEvent("keydown", onGlobalKeyDown); + + if (Env.Options.enablePersistent && chrome.type == "popup") + { + // TODO: xxxpedro persist - revise chrome synchronization when in persistent mode + var frame = FirebugChrome.chromeMap.frame; + if (frame) + frame.close(); + + //chrome.reattach(frame, chrome); + //TODO: xxxpedro persist synchronize? + chrome.initialize(); + } + }, + + clone: function(FBChrome) + { + for (var name in FBChrome) + { + var prop = FBChrome[name]; + if (FBChrome.hasOwnProperty(name) && !isFunction(prop)) + { + this[name] = prop; + } + } + } +}; + + + +// ************************************************************************************************ +// Chrome Window Creation + +var createChromeWindow = function(options) +{ + options = extend(WindowDefaultOptions, options || {}); + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Locals + + var chrome = {}, + + context = options.context || Env.browser, + + type = chrome.type = Env.Options.enablePersistent ? + "popup" : + options.type, + + isChromeFrame = type == "frame", + + useLocalSkin = Env.useLocalSkin, + + url = useLocalSkin ? + Env.Location.skin : + "about:blank", + + // document.body not available in XML+XSL documents in Firefox + body = context.document.getElementsByTagName("body")[0], + + formatNode = function(node) + { + if (!Env.isDebugMode) + { + node.firebugIgnore = true; + } + + node.style.border = "0"; + node.style.visibility = "hidden"; + node.style.zIndex = "2147483647"; // MAX z-index = 2147483647 + node.style.position = noFixedPosition ? "absolute" : "fixed"; + node.style.width = "100%"; // "102%"; IE auto margin bug + node.style.left = "0"; + node.style.bottom = noFixedPosition ? "-1px" : "0"; + node.style.height = options.height + "px"; + + // avoid flickering during chrome rendering + if (isFirefox) + node.style.display = "none"; + }, + + createChromeDiv = function() + { + //Firebug.Console.warn("Firebug Lite GUI is working in 'windowless mode'. It may behave slower and receive interferences from the page in which it is installed."); + + var node = chrome.node = createGlobalElement("div"), + style = createGlobalElement("style"), + + css = FirebugChrome.Skin.CSS + /* + .replace(/;/g, " !important;") + .replace(/!important\s!important/g, "!important") + .replace(/display\s*:\s*(\w+)\s*!important;/g, "display:$1;")*/, + + // reset some styles to minimize interference from the main page's style + rules = ".fbBody *{margin:0;padding:0;font-size:11px;line-height:13px;color:inherit;}" + + // load the chrome styles + css + + // adjust some remaining styles + ".fbBody #fbHSplitter{position:absolute !important;} .fbBody #fbHTML span{line-height:14px;} .fbBody .lineNo div{line-height:inherit !important;}"; + /* + if (isIE) + { + // IE7 CSS bug (FbChrome table bigger than its parent div) + rules += ".fbBody table.fbChrome{position: static !important;}"; + }/**/ + + style.type = "text/css"; + + if (style.styleSheet) + style.styleSheet.cssText = rules; + else + style.appendChild(context.document.createTextNode(rules)); + + document.getElementsByTagName("head")[0].appendChild(style); + + node.className = "fbBody"; + node.style.overflow = "hidden"; + node.innerHTML = getChromeDivTemplate(); + + if (isIE) + { + // IE7 CSS bug (FbChrome table bigger than its parent div) + setTimeout(function(){ + node.firstChild.style.height = "1px"; + node.firstChild.style.position = "static"; + },0); + /**/ + } + + formatNode(node); + + body.appendChild(node); + + chrome.window = window; + chrome.document = document; + onChromeLoad(chrome); + }; + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + try + { + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // create the Chrome as a "div" (windowless mode) + if (type == "div") + { + createChromeDiv(); + return; + } + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // cretate the Chrome as an "iframe" + else if (isChromeFrame) + { + // Create the Chrome Frame + var node = chrome.node = createGlobalElement("iframe"); + node.setAttribute("src", url); + node.setAttribute("frameBorder", "0"); + + formatNode(node); + + body.appendChild(node); + + // must set the id after appending to the document, otherwise will cause an + // strange error in IE, making the iframe load the page in which the bookmarklet + // was created (like getfirebug.com), before loading the injected UI HTML, + // generating an "Access Denied" error. + node.id = options.id; + } + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // create the Chrome as a "popup" + else + { + var height = FirebugChrome.height || options.height, + + options = [ + "true,top=", + Math.max(screen.availHeight - height - 61 /* Google Chrome bug */, 0), + ",left=0,height=", + height, + ",width=", + screen.availWidth-10, // Opera opens popup in a new tab if it's too big! + ",resizable" + ].join(""), + + node = chrome.node = context.window.open( + url, + "popup", + options + ); + + if (node) + { + try + { + node.focus(); + } + catch(E) + { + alert("Firebug Error: Firebug popup was blocked."); + return; + } + } + else + { + alert("Firebug Error: Firebug popup was blocked."); + return; + } + } + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Inject the interface HTML if it is not using the local skin + + if (!useLocalSkin) + { + var tpl = getChromeTemplate(!isChromeFrame), + doc = isChromeFrame ? node.contentWindow.document : node.document; + + doc.write(tpl); + doc.close(); + } + + //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Wait the Window to be loaded + + var win, + + waitDelay = useLocalSkin ? isChromeFrame ? 200 : 300 : 100, + + waitForWindow = function() + { + if ( // Frame loaded... OR + isChromeFrame && (win=node.contentWindow) && + node.contentWindow.document.getElementById("fbCommandLine") || + + // Popup loaded + !isChromeFrame && (win=node.window) && node.document && + node.document.getElementById("fbCommandLine") ) + { + chrome.window = win.window; + chrome.document = win.document; + + // Prevent getting the wrong chrome height in FF when opening a popup + setTimeout(function(){ + onChromeLoad(chrome); + },0); + } + else + setTimeout(waitForWindow, waitDelay); + }; + + waitForWindow(); + } + catch(e) + { + var msg = e.message || e; + + if (/access/i.test(msg)) + { + // Firebug Lite could not create a window for its Graphical User Interface due to + // a access restriction. This happens in some pages, when loading via bookmarklet. + // In such cases, the only way is to load the GUI in a "windowless mode". + + if (isChromeFrame) + body.removeChild(node); + else if(type == "popup") + node.close(); + + // Load the GUI in a "windowless mode" + createChromeDiv(); + } + else + { + alert("Firebug Error: Firebug GUI could not be created."); + } + } +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var onChromeLoad = function onChromeLoad(chrome) +{ + Env.chrome = chrome; + + if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Chrome onChromeLoad", "chrome window loaded"); + + if (Env.Options.enablePersistent) + { + // TODO: xxxpedro persist - make better chrome synchronization when in persistent mode + Env.FirebugChrome = FirebugChrome; + + chrome.window.Firebug = chrome.window.Firebug || {}; + chrome.window.Firebug.SharedEnv = Env; + + if (Env.isDevelopmentMode) + { + Env.browser.window.FBDev.loadChromeApplication(chrome); + } + else + { + var doc = chrome.document; + var script = doc.createElement("script"); + script.src = Env.Location.app + "#remote,persist"; + doc.getElementsByTagName("head")[0].appendChild(script); + } + } + else + { + if (chrome.type == "frame" || chrome.type == "div") + { + // initialize the chrome application + setTimeout(function(){ + FBL.Firebug.initialize(); + },0); + } + else if (chrome.type == "popup") + { + var oldChrome = FirebugChrome.chromeMap.frame; + + var newChrome = new Chrome(chrome); + + // TODO: xxxpedro sync detach reattach attach + dispatch(newChrome.panelMap, "detach", [oldChrome, newChrome]); + + if (oldChrome) + oldChrome.close(); + + newChrome.reattach(oldChrome, newChrome); + } + } +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var getChromeDivTemplate = function() +{ + return FirebugChrome.Skin.HTML; +}; + +var getChromeTemplate = function(isPopup) +{ + var tpl = FirebugChrome.Skin; + var r = [], i = -1; + + r[++i] = ''; + r[++i] = ''; + r[++i] = Firebug.version; + + /* + r[++i] = ''; + /**/ + + r[++i] = ''; + /**/ + + r[++i] = ''; + r[++i] = tpl.HTML; + r[++i] = ''; + + return r.join(""); +}; + + +// ************************************************************************************************ +// Chrome Class + +/**@class*/ +var Chrome = function Chrome(chrome) +{ + var type = chrome.type; + var Base = type == "frame" || type == "div" ? ChromeFrameBase : ChromePopupBase; + + append(this, Base); // inherit from base class (ChromeFrameBase or ChromePopupBase) + append(this, chrome); // inherit chrome window properties + append(this, new Context(chrome.window)); // inherit from Context class + + FirebugChrome.chromeMap[type] = this; + Firebug.chrome = this; + Env.chrome = chrome.window; + + this.commandLineVisible = false; + this.sidePanelVisible = false; + + this.create(); + + return this; +}; + +// ************************************************************************************************ +// ChromeBase + +/** + * @namespace + * @extends FBL.Controller + * @extends FBL.PanelBar + **/ +var ChromeBase = {}; +append(ChromeBase, Controller); +append(ChromeBase, PanelBar); +append(ChromeBase, +/**@extend ns-chrome-ChromeBase*/ +{ + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // inherited properties + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // inherited from createChrome function + + node: null, + type: null, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // inherited from Context.prototype + + document: null, + window: null, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // value properties + + sidePanelVisible: false, + commandLineVisible: false, + largeCommandLineVisible: false, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // object properties + + inspectButton: null, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + create: function() + { + PanelBar.create.call(this); + + if (Firebug.Inspector) + this.inspectButton = new Button({ + type: "toggle", + element: $("fbChrome_btInspect"), + owner: Firebug.Inspector, + + onPress: Firebug.Inspector.startInspecting, + onUnpress: Firebug.Inspector.stopInspecting + }); + }, + + destroy: function() + { + if(Firebug.Inspector) + this.inspectButton.destroy(); + + PanelBar.destroy.call(this); + + this.shutdown(); + }, + + testMenu: function() + { + var firebugMenu = new Menu( + { + id: "fbFirebugMenu", + + items: + [ + { + label: "Open Firebug", + type: "shortcut", + key: isFirefox ? "Shift+F12" : "F12", + checked: true, + command: "toggleChrome" + }, + { + label: "Open Firebug in New Window", + type: "shortcut", + key: isFirefox ? "Ctrl+Shift+F12" : "Ctrl+F12", + command: "openPopup" + }, + { + label: "Inspect Element", + type: "shortcut", + key: "Ctrl+Shift+C", + command: "toggleInspect" + }, + { + label: "Command Line", + type: "shortcut", + key: "Ctrl+Shift+L", + command: "focusCommandLine" + }, + "-", + { + label: "Options", + type: "group", + child: "fbFirebugOptionsMenu" + }, + "-", + { + label: "Firebug Lite Website...", + command: "visitWebsite" + }, + { + label: "Discussion Group...", + command: "visitDiscussionGroup" + }, + { + label: "Issue Tracker...", + command: "visitIssueTracker" + } + ], + + onHide: function() + { + iconButton.restore(); + }, + + toggleChrome: function() + { + Firebug.chrome.toggle(); + }, + + openPopup: function() + { + Firebug.chrome.toggle(true, true); + }, + + toggleInspect: function() + { + Firebug.Inspector.toggleInspect(); + }, + + focusCommandLine: function() + { + Firebug.chrome.focusCommandLine(); + }, + + visitWebsite: function() + { + this.visit("http://getfirebug.com/lite.html"); + }, + + visitDiscussionGroup: function() + { + this.visit("http://groups.google.com/group/firebug"); + }, + + visitIssueTracker: function() + { + this.visit("http://code.google.com/p/fbug/issues/list"); + }, + + visit: function(url) + { + window.open(url); + } + + }); + + /**@private*/ + var firebugOptionsMenu = + { + id: "fbFirebugOptionsMenu", + + getItems: function() + { + var cookiesDisabled = !Firebug.saveCookies; + + return [ + { + label: "Save Options in Cookies", + type: "checkbox", + value: "saveCookies", + checked: Firebug.saveCookies, + command: "saveOptions" + }, + "-", + { + label: "Start Opened", + type: "checkbox", + value: "startOpened", + checked: Firebug.startOpened, + disabled: cookiesDisabled + }, + { + label: "Start in New Window", + type: "checkbox", + value: "startInNewWindow", + checked: Firebug.startInNewWindow, + disabled: cookiesDisabled + }, + { + label: "Show Icon When Hidden", + type: "checkbox", + value: "showIconWhenHidden", + checked: Firebug.showIconWhenHidden, + disabled: cookiesDisabled + }, + { + label: "Override Console Object", + type: "checkbox", + value: "overrideConsole", + checked: Firebug.overrideConsole, + disabled: cookiesDisabled + }, + { + label: "Ignore Firebug Elements", + type: "checkbox", + value: "ignoreFirebugElements", + checked: Firebug.ignoreFirebugElements, + disabled: cookiesDisabled + }, + { + label: "Disable When Firebug Active", + type: "checkbox", + value: "disableWhenFirebugActive", + checked: Firebug.disableWhenFirebugActive, + disabled: cookiesDisabled + }, + { + label: "Disable XHR Listener", + type: "checkbox", + value: "disableXHRListener", + checked: Firebug.disableXHRListener, + disabled: cookiesDisabled + }, + { + label: "Enable Trace Mode", + type: "checkbox", + value: "enableTrace", + checked: Firebug.enableTrace, + disabled: cookiesDisabled + }, + { + label: "Enable Persistent Mode (experimental)", + type: "checkbox", + value: "enablePersistent", + checked: Firebug.enablePersistent, + disabled: cookiesDisabled + }, + "-", + { + label: "Reset All Firebug Options", + command: "restorePrefs", + disabled: cookiesDisabled + } + ]; + }, + + onCheck: function(target, value, checked) + { + Firebug.setPref(value, checked); + }, + + saveOptions: function(target) + { + var saveEnabled = target.getAttribute("checked"); + + if (!saveEnabled) this.restorePrefs(); + + this.updateMenu(target); + + return false; + }, + + restorePrefs: function(target) + { + Firebug.restorePrefs(); + + if(Firebug.saveCookies) + Firebug.savePrefs(); + else + Firebug.erasePrefs(); + + if (target) + this.updateMenu(target); + + return false; + }, + + updateMenu: function(target) + { + var options = getElementsByClass(target.parentNode, "fbMenuOption"); + + var firstOption = options[0]; + var enabled = Firebug.saveCookies; + if (enabled) + Menu.check(firstOption); + else + Menu.uncheck(firstOption); + + if (enabled) + Menu.check(options[0]); + else + Menu.uncheck(options[0]); + + for (var i = 1, length = options.length; i < length; i++) + { + var option = options[i]; + + var value = option.getAttribute("value"); + var pref = Firebug[value]; + + if (pref) + Menu.check(option); + else + Menu.uncheck(option); + + if (enabled) + Menu.enable(option); + else + Menu.disable(option); + } + } + }; + + Menu.register(firebugOptionsMenu); + + var menu = firebugMenu; + + var testMenuClick = function(event) + { + //console.log("testMenuClick"); + cancelEvent(event, true); + + var target = event.target || event.srcElement; + + if (menu.isVisible) + menu.hide(); + else + { + var offsetLeft = isIE6 ? 1 : -4, // IE6 problem with fixed position + + chrome = Firebug.chrome, + + box = chrome.getElementBox(target), + + offset = chrome.type == "div" ? + chrome.getElementPosition(chrome.node) : + {top: 0, left: 0}; + + menu.show( + box.left + offsetLeft - offset.left, + box.top + box.height -5 - offset.top + ); + } + + return false; + }; + + var iconButton = new IconButton({ + type: "toggle", + element: $("fbFirebugButton"), + + onClick: testMenuClick + }); + + iconButton.initialize(); + + //addEvent($("fbToolbarIcon"), "click", testMenuClick); + }, + + initialize: function() + { + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + if (Env.bookmarkletOutdated) + Firebug.Console.logFormatted([ + "A new bookmarklet version is available. " + + "Please visit http://getfirebug.com/firebuglite#Install and update it." + ], Firebug.context, "warn"); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + if (Firebug.Console) + Firebug.Console.flush(); + + if (Firebug.Trace) + FBTrace.flush(Firebug.Trace); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.chrome.initialize", "initializing chrome application"); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // initialize inherited classes + Controller.initialize.call(this); + PanelBar.initialize.call(this); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // create the interface elements cache + + fbTop = $("fbTop"); + fbContent = $("fbContent"); + fbContentStyle = fbContent.style; + fbBottom = $("fbBottom"); + fbBtnInspect = $("fbBtnInspect"); + + fbToolbar = $("fbToolbar"); + + fbPanelBox1 = $("fbPanelBox1"); + fbPanelBox1Style = fbPanelBox1.style; + fbPanelBox2 = $("fbPanelBox2"); + fbPanelBox2Style = fbPanelBox2.style; + fbPanelBar2Box = $("fbPanelBar2Box"); + fbPanelBar2BoxStyle = fbPanelBar2Box.style; + + fbHSplitter = $("fbHSplitter"); + fbVSplitter = $("fbVSplitter"); + fbVSplitterStyle = fbVSplitter.style; + + fbPanel1 = $("fbPanel1"); + fbPanel1Style = fbPanel1.style; + fbPanel2 = $("fbPanel2"); + fbPanel2Style = fbPanel2.style; + + fbConsole = $("fbConsole"); + fbConsoleStyle = fbConsole.style; + fbHTML = $("fbHTML"); + + fbCommandLine = $("fbCommandLine"); + fbLargeCommandLine = $("fbLargeCommandLine"); + fbLargeCommandButtons = $("fbLargeCommandButtons"); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // static values cache + topHeight = fbTop.offsetHeight; + topPartialHeight = fbToolbar.offsetHeight; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + disableTextSelection($("fbToolbar")); + disableTextSelection($("fbPanelBarBox")); + disableTextSelection($("fbPanelBar1")); + disableTextSelection($("fbPanelBar2")); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Add the "javascript:void(0)" href attributes used to make the hover effect in IE6 + if (isIE6 && Firebug.Selector) + { + // TODO: xxxpedro change to getElementsByClass + var as = $$(".fbHover"); + for (var i=0, a; a=as[i]; i++) + { + a.setAttribute("href", "javascript:void(0)"); + } + } + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // initialize all panels + /* + var panelMap = Firebug.panelTypes; + for (var i=0, p; p=panelMap[i]; i++) + { + if (!p.parentPanel) + { + this.addPanel(p.prototype.name); + } + } + /**/ + + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + + if(Firebug.Inspector) + this.inspectButton.initialize(); + + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + + this.addController( + [$("fbLargeCommandLineIcon"), "click", this.showLargeCommandLine] + ); + + // ************************************************************************************************ + + // Select the first registered panel + // TODO: BUG IE7 + var self = this; + setTimeout(function(){ + self.selectPanel(FirebugChrome.selectedPanelName); + + if (FirebugChrome.selectedPanelName == "Console" && Firebug.CommandLine) + Firebug.chrome.focusCommandLine(); + },0); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + //this.draw(); + + + + + + + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + var onPanelMouseDown = function onPanelMouseDown(event) + { + //console.log("onPanelMouseDown", event.target || event.srcElement, event); + + var target = event.target || event.srcElement; + + if (FBL.isLeftClick(event)) + { + var editable = FBL.getAncestorByClass(target, "editable"); + + // if an editable element has been clicked then start editing + if (editable) + { + Firebug.Editor.startEditing(editable); + FBL.cancelEvent(event); + } + // if any other element has been clicked then stop editing + else + { + if (!hasClass(target, "textEditorInner")) + Firebug.Editor.stopEditing(); + } + } + else if (FBL.isMiddleClick(event) && Firebug.getRepNode(target)) + { + // Prevent auto-scroll when middle-clicking a rep object + FBL.cancelEvent(event); + } + }; + + Firebug.getElementPanel = function(element) + { + var panelNode = getAncestorByClass(element, "fbPanel"); + var id = panelNode.id.substr(2); + + var panel = Firebug.chrome.panelMap[id]; + + if (!panel) + { + if (Firebug.chrome.selectedPanel.sidePanelBar) + panel = Firebug.chrome.selectedPanel.sidePanelBar.panelMap[id]; + } + + return panel; + }; + + + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + // TODO: xxxpedro port to Firebug + + // Improved window key code event listener. Only one "keydown" event will be attached + // to the window, and the onKeyCodeListen() function will delegate which listeners + // should be called according to the event.keyCode fired. + var onKeyCodeListenersMap = []; + var onKeyCodeListen = function(event) + { + for (var keyCode in onKeyCodeListenersMap) + { + var listeners = onKeyCodeListenersMap[keyCode]; + + for (var i = 0, listener; listener = listeners[i]; i++) + { + var filter = listener.filter || FBL.noKeyModifiers; + + if (event.keyCode == keyCode && (!filter || filter(event))) + { + listener.listener(); + FBL.cancelEvent(event, true); + return false; + } + } + } + }; + + addEvent(Firebug.chrome.document, "keydown", onKeyCodeListen); + + /** + * @name keyCodeListen + * @memberOf FBL.FirebugChrome + */ + Firebug.chrome.keyCodeListen = function(key, filter, listener, capture) + { + var keyCode = KeyEvent["DOM_VK_"+key]; + + if (!onKeyCodeListenersMap[keyCode]) + onKeyCodeListenersMap[keyCode] = []; + + onKeyCodeListenersMap[keyCode].push({ + filter: filter, + listener: listener + }); + + return keyCode; + }; + + /** + * @name keyIgnore + * @memberOf FBL.FirebugChrome + */ + Firebug.chrome.keyIgnore = function(keyCode) + { + onKeyCodeListenersMap[keyCode] = null; + delete onKeyCodeListenersMap[keyCode]; + }; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + /**/ + // move to shutdown + //removeEvent(Firebug.chrome.document, "keydown", listener[0]); + + + /* + Firebug.chrome.keyCodeListen = function(key, filter, listener, capture) + { + if (!filter) + filter = FBL.noKeyModifiers; + + var keyCode = KeyEvent["DOM_VK_"+key]; + + var fn = function fn(event) + { + if (event.keyCode == keyCode && (!filter || filter(event))) + { + listener(); + FBL.cancelEvent(event, true); + return false; + } + } + + addEvent(Firebug.chrome.document, "keydown", fn); + + return [fn, capture]; + }; + + Firebug.chrome.keyIgnore = function(listener) + { + removeEvent(Firebug.chrome.document, "keydown", listener[0]); + }; + /**/ + + + this.addController( + [fbPanel1, "mousedown", onPanelMouseDown], + [fbPanel2, "mousedown", onPanelMouseDown] + ); +/**/ + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + + // menus can be used without domplate + if (FBL.domplate) + this.testMenu(); + /**/ + + //test XHR + /* + setTimeout(function(){ + + FBL.Ajax.request({url: "../content/firebug/boot.js"}); + FBL.Ajax.request({url: "../content/firebug/boot.js.invalid"}); + + },1000); + /**/ + }, + + shutdown: function() + { + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + + if(Firebug.Inspector) + this.inspectButton.shutdown(); + + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + // ************************************************************************************************ + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + // remove disableTextSelection event handlers + restoreTextSelection($("fbToolbar")); + restoreTextSelection($("fbPanelBarBox")); + restoreTextSelection($("fbPanelBar1")); + restoreTextSelection($("fbPanelBar2")); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // shutdown inherited classes + Controller.shutdown.call(this); + PanelBar.shutdown.call(this); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Remove the interface elements cache (this must happen after calling + // the shutdown method of all dependent components to avoid errors) + + fbTop = null; + fbContent = null; + fbContentStyle = null; + fbBottom = null; + fbBtnInspect = null; + + fbToolbar = null; + + fbPanelBox1 = null; + fbPanelBox1Style = null; + fbPanelBox2 = null; + fbPanelBox2Style = null; + fbPanelBar2Box = null; + fbPanelBar2BoxStyle = null; + + fbHSplitter = null; + fbVSplitter = null; + fbVSplitterStyle = null; + + fbPanel1 = null; + fbPanel1Style = null; + fbPanel2 = null; + + fbConsole = null; + fbConsoleStyle = null; + fbHTML = null; + + fbCommandLine = null; + fbLargeCommandLine = null; + fbLargeCommandButtons = null; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // static values cache + + topHeight = null; + topPartialHeight = null; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + toggle: function(forceOpen, popup) + { + if(popup) + { + this.detach(); + } + else + { + if (isOpera && Firebug.chrome.type == "popup" && Firebug.chrome.node.closed) + { + var frame = FirebugChrome.chromeMap.frame; + frame.reattach(); + + FirebugChrome.chromeMap.popup = null; + + frame.open(); + + return; + } + + // If the context is a popup, ignores the toggle process + if (Firebug.chrome.type == "popup") return; + + var shouldOpen = forceOpen || !FirebugChrome.isOpen; + + if(shouldOpen) + this.open(); + else + this.close(); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + detach: function() + { + if(!FirebugChrome.chromeMap.popup) + { + createChromeWindow({type: "popup"}); + } + }, + + reattach: function(oldChrome, newChrome) + { + Firebug.browser.window.Firebug = Firebug; + + // chrome synchronization + var newPanelMap = newChrome.panelMap; + var oldPanelMap = oldChrome.panelMap; + + var panel; + for(var name in newPanelMap) + { + // TODO: xxxpedro innerHTML + panel = newPanelMap[name]; + if (panel.options.innerHTMLSync) + panel.panelNode.innerHTML = oldPanelMap[name].panelNode.innerHTML; + } + + Firebug.chrome = newChrome; + + // TODO: xxxpedro sync detach reattach attach + //dispatch(Firebug.chrome.panelMap, "detach", [oldChrome, newChrome]); + + if (newChrome.type == "popup") + { + newChrome.initialize(); + //dispatch(Firebug.modules, "initialize", []); + } + else + { + // TODO: xxxpedro only needed in persistent + // should use FirebugChrome.clone, but popup FBChrome + // isn't acessible + FirebugChrome.selectedPanelName = oldChrome.selectedPanel.name; + } + + dispatch(newPanelMap, "reattach", [oldChrome, newChrome]); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + draw: function() + { + var size = this.getSize(); + + // Height related values + var commandLineHeight = Firebug.chrome.commandLineVisible ? fbCommandLine.offsetHeight : 0, + + y = Math.max(size.height /* chrome height */, topHeight), + + heightValue = Math.max(y - topHeight - commandLineHeight /* fixed height */, 0), + + height = heightValue + "px", + + // Width related values + sideWidthValue = Firebug.chrome.sidePanelVisible ? FirebugChrome.sidePanelWidth : 0, + + width = Math.max(size.width /* chrome width */ - sideWidthValue, 0) + "px"; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Height related rendering + fbPanelBox1Style.height = height; + fbPanel1Style.height = height; + + if (isIE || isOpera) + { + // Fix IE and Opera problems with auto resizing the verticall splitter + fbVSplitterStyle.height = Math.max(y - topPartialHeight - commandLineHeight, 0) + "px"; + } + //xxxpedro FF2 only? + /* + else if (isFirefox) + { + // Fix Firefox problem with table rows with 100% height (fit height) + fbContentStyle.maxHeight = Math.max(y - fixedHeight, 0)+ "px"; + }/**/ + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Width related rendering + fbPanelBox1Style.width = width; + fbPanel1Style.width = width; + + // SidePanel rendering + if (Firebug.chrome.sidePanelVisible) + { + sideWidthValue = Math.max(sideWidthValue - 6, 0); + + var sideWidth = sideWidthValue + "px"; + + fbPanelBox2Style.width = sideWidth; + + fbVSplitterStyle.right = sideWidth; + + if (Firebug.chrome.largeCommandLineVisible) + { + fbLargeCommandLine = $("fbLargeCommandLine"); + + fbLargeCommandLine.style.height = heightValue - 4 + "px"; + fbLargeCommandLine.style.width = sideWidthValue - 2 + "px"; + + fbLargeCommandButtons = $("fbLargeCommandButtons"); + fbLargeCommandButtons.style.width = sideWidth; + } + else + { + fbPanel2Style.height = height; + fbPanel2Style.width = sideWidth; + + fbPanelBar2BoxStyle.width = sideWidth; + } + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getSize: function() + { + return this.type == "div" ? + { + height: this.node.offsetHeight, + width: this.node.offsetWidth + } + : + this.getWindowSize(); + }, + + resize: function() + { + var self = this; + + // avoid partial resize when maximizing window + setTimeout(function(){ + self.draw(); + + if (noFixedPosition && (self.type == "frame" || self.type == "div")) + self.fixIEPosition(); + }, 0); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + layout: function(panel) + { + if (FBTrace.DBG_CHROME) FBTrace.sysout("Chrome.layout", ""); + + var options = panel.options; + + changeCommandLineVisibility(options.hasCommandLine); + changeSidePanelVisibility(panel.hasSidePanel); + + Firebug.chrome.draw(); + }, + + showLargeCommandLine: function(hideToggleIcon) + { + var chrome = Firebug.chrome; + + if (!chrome.largeCommandLineVisible) + { + chrome.largeCommandLineVisible = true; + + if (chrome.selectedPanel.options.hasCommandLine) + { + if (Firebug.CommandLine) + Firebug.CommandLine.blur(); + + changeCommandLineVisibility(false); + } + + changeSidePanelVisibility(true); + + fbLargeCommandLine.style.display = "block"; + fbLargeCommandButtons.style.display = "block"; + + fbPanel2Style.display = "none"; + fbPanelBar2BoxStyle.display = "none"; + + chrome.draw(); + + fbLargeCommandLine.focus(); + + if (Firebug.CommandLine) + Firebug.CommandLine.setMultiLine(true); + } + }, + + hideLargeCommandLine: function() + { + if (Firebug.chrome.largeCommandLineVisible) + { + Firebug.chrome.largeCommandLineVisible = false; + + if (Firebug.CommandLine) + Firebug.CommandLine.setMultiLine(false); + + fbLargeCommandLine.blur(); + + fbPanel2Style.display = "block"; + fbPanelBar2BoxStyle.display = "block"; + + fbLargeCommandLine.style.display = "none"; + fbLargeCommandButtons.style.display = "none"; + + changeSidePanelVisibility(false); + + if (Firebug.chrome.selectedPanel.options.hasCommandLine) + changeCommandLineVisibility(true); + + Firebug.chrome.draw(); + + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + focusCommandLine: function() + { + var selectedPanelName = this.selectedPanel.name, panelToSelect; + + if (focusCommandLineState == 0 || selectedPanelName != "Console") + { + focusCommandLineState = 0; + lastFocusedPanelName = selectedPanelName; + + panelToSelect = "Console"; + } + if (focusCommandLineState == 1) + { + panelToSelect = lastFocusedPanelName; + } + + this.selectPanel(panelToSelect); + + try + { + if (Firebug.CommandLine) + { + if (panelToSelect == "Console") + Firebug.CommandLine.focus(); + else + Firebug.CommandLine.blur(); + } + } + catch(e) + { + //TODO: xxxpedro trace error + } + + focusCommandLineState = ++focusCommandLineState % 2; + } + +}); + +// ************************************************************************************************ +// ChromeFrameBase + +/** + * @namespace + * @extends ns-chrome-ChromeBase + */ +var ChromeFrameBase = extend(ChromeBase, +/**@extend ns-chrome-ChromeFrameBase*/ +{ + create: function() + { + ChromeBase.create.call(this); + + // restore display for the anti-flicker trick + if (isFirefox) + this.node.style.display = "block"; + + if (Env.Options.startInNewWindow) + { + this.close(); + this.toggle(true, true); + return; + } + + if (Env.Options.startOpened) + this.open(); + else + this.close(); + }, + + destroy: function() + { + removeGlobalEvent("keydown", onGlobalKeyDown); + + ChromeBase.destroy.call(this); + + this.document = null; + delete this.document; + + this.window = null; + delete this.window; + + this.node.parentNode.removeChild(this.node); + this.node = null; + delete this.node; + }, + + initialize: function() + { + //FBTrace.sysout("Frame", "initialize();") + ChromeBase.initialize.call(this); + + this.addController( + [Firebug.browser.window, "resize", this.resize], + [$("fbWindow_btClose"), "click", this.close], + [$("fbWindow_btDetach"), "click", this.detach], + [$("fbWindow_btDeactivate"), "click", this.deactivate] + ); + + if (!Env.Options.enablePersistent) + this.addController([Firebug.browser.window, "unload", Firebug.shutdown]); + + if (noFixedPosition) + { + this.addController( + [Firebug.browser.window, "scroll", this.fixIEPosition] + ); + } + + fbVSplitter.onmousedown = onVSplitterMouseDown; + fbHSplitter.onmousedown = onHSplitterMouseDown; + + this.isInitialized = true; + }, + + shutdown: function() + { + fbVSplitter.onmousedown = null; + fbHSplitter.onmousedown = null; + + ChromeBase.shutdown.apply(this); + + this.isInitialized = false; + }, + + reattach: function() + { + var frame = FirebugChrome.chromeMap.frame; + + ChromeBase.reattach(FirebugChrome.chromeMap.popup, this); + }, + + open: function() + { + if (!FirebugChrome.isOpen) + { + FirebugChrome.isOpen = true; + + if (Env.isChromeExtension) + localStorage.setItem("Firebug", "1,1"); + + var node = this.node; + + node.style.visibility = "hidden"; // Avoid flickering + + if (Firebug.showIconWhenHidden) + { + if (ChromeMini.isInitialized) + { + ChromeMini.shutdown(); + } + + } + else + node.style.display = "block"; + + var main = $("fbChrome"); + + // IE6 throws an error when setting this property! why? + //main.style.display = "table"; + main.style.display = ""; + + var self = this; + setTimeout(function(){ + node.style.visibility = "visible"; + + //dispatch(Firebug.modules, "initialize", []); + self.initialize(); + + if (noFixedPosition) + self.fixIEPosition(); + + self.draw(); + + }, 10); + } + }, + + close: function() + { + if (FirebugChrome.isOpen || !this.isInitialized) + { + if (this.isInitialized) + { + //dispatch(Firebug.modules, "shutdown", []); + this.shutdown(); + } + + FirebugChrome.isOpen = false; + + if (Env.isChromeExtension) + localStorage.setItem("Firebug", "1,0"); + + var node = this.node; + + if (Firebug.showIconWhenHidden) + { + node.style.visibility = "hidden"; // Avoid flickering + + // TODO: xxxpedro - persist IE fixed? + var main = $("fbChrome", FirebugChrome.chromeMap.frame.document); + main.style.display = "none"; + + ChromeMini.initialize(); + + node.style.visibility = "visible"; + } + else + node.style.display = "none"; + } + }, + + deactivate: function() + { + // if it is running as a Chrome extension, dispatch a message to the extension signaling + // that Firebug should be deactivated for the current tab + if (Env.isChromeExtension) + { + localStorage.removeItem("Firebug"); + Firebug.GoogleChrome.dispatch("FB_deactivate"); + + // xxxpedro problem here regarding Chrome extension. We can't deactivate the whole + // app, otherwise it won't be able to be reactivated without reloading the page. + // but we need to stop listening global keys, otherwise the key activation won't work. + Firebug.chrome.close(); + } + else + { + Firebug.shutdown(); + } + }, + + fixIEPosition: function() + { + // fix IE problem with offset when not in fullscreen mode + var doc = this.document; + var offset = isIE ? doc.body.clientTop || doc.documentElement.clientTop: 0; + + var size = Firebug.browser.getWindowSize(); + var scroll = Firebug.browser.getWindowScrollPosition(); + var maxHeight = size.height; + var height = this.node.offsetHeight; + + var bodyStyle = doc.body.currentStyle; + + this.node.style.top = maxHeight - height + scroll.top + "px"; + + if ((this.type == "frame" || this.type == "div") && + (bodyStyle.marginLeft || bodyStyle.marginRight)) + { + this.node.style.width = size.width + "px"; + } + + if (fbVSplitterStyle) + fbVSplitterStyle.right = FirebugChrome.sidePanelWidth + "px"; + + this.draw(); + } + +}); + + +// ************************************************************************************************ +// ChromeMini + +/** + * @namespace + * @extends FBL.Controller + */ +var ChromeMini = extend(Controller, +/**@extend ns-chrome-ChromeMini*/ +{ + create: function(chrome) + { + append(this, chrome); + this.type = "mini"; + }, + + initialize: function() + { + Controller.initialize.apply(this); + + var doc = FirebugChrome.chromeMap.frame.document; + + var mini = $("fbMiniChrome", doc); + mini.style.display = "block"; + + var miniIcon = $("fbMiniIcon", doc); + var width = miniIcon.offsetWidth + 10; + miniIcon.title = "Open " + Firebug.version; + + var errors = $("fbMiniErrors", doc); + if (errors.offsetWidth) + width += errors.offsetWidth + 10; + + var node = this.node; + node.style.height = "27px"; + node.style.width = width + "px"; + node.style.left = ""; + node.style.right = 0; + + if (this.node.nodeName.toLowerCase() == "iframe") + { + node.setAttribute("allowTransparency", "true"); + this.document.body.style.backgroundColor = "transparent"; + } + else + node.style.background = "transparent"; + + if (noFixedPosition) + this.fixIEPosition(); + + this.addController( + [$("fbMiniIcon", doc), "click", onMiniIconClick] + ); + + if (noFixedPosition) + { + this.addController( + [Firebug.browser.window, "scroll", this.fixIEPosition] + ); + } + + this.isInitialized = true; + }, + + shutdown: function() + { + var node = this.node; + node.style.height = FirebugChrome.height + "px"; + node.style.width = "100%"; + node.style.left = 0; + node.style.right = ""; + + if (this.node.nodeName.toLowerCase() == "iframe") + { + node.setAttribute("allowTransparency", "false"); + this.document.body.style.backgroundColor = "#fff"; + } + else + node.style.background = "#fff"; + + if (noFixedPosition) + this.fixIEPosition(); + + var doc = FirebugChrome.chromeMap.frame.document; + + var mini = $("fbMiniChrome", doc); + mini.style.display = "none"; + + Controller.shutdown.apply(this); + + this.isInitialized = false; + }, + + draw: function() + { + + }, + + fixIEPosition: ChromeFrameBase.fixIEPosition + +}); + + +// ************************************************************************************************ +// ChromePopupBase + +/** + * @namespace + * @extends ns-chrome-ChromeBase + */ +var ChromePopupBase = extend(ChromeBase, +/**@extend ns-chrome-ChromePopupBase*/ +{ + + initialize: function() + { + setClass(this.document.body, "FirebugPopup"); + + ChromeBase.initialize.call(this); + + this.addController( + [Firebug.chrome.window, "resize", this.resize], + [Firebug.chrome.window, "unload", this.destroy] + ); + + if (Env.Options.enablePersistent) + { + this.persist = bind(this.persist, this); + addEvent(Firebug.browser.window, "unload", this.persist); + } + else + this.addController( + [Firebug.browser.window, "unload", this.close] + ); + + fbVSplitter.onmousedown = onVSplitterMouseDown; + }, + + destroy: function() + { + // TODO: xxxpedro sync detach reattach attach + var frame = FirebugChrome.chromeMap.frame; + + if(frame) + { + dispatch(frame.panelMap, "detach", [this, frame]); + + frame.reattach(this, frame); + } + + if (Env.Options.enablePersistent) + { + removeEvent(Firebug.browser.window, "unload", this.persist); + } + + ChromeBase.destroy.apply(this); + + FirebugChrome.chromeMap.popup = null; + + this.node.close(); + }, + + persist: function() + { + persistTimeStart = new Date().getTime(); + + removeEvent(Firebug.browser.window, "unload", this.persist); + + Firebug.Inspector.destroy(); + Firebug.browser.window.FirebugOldBrowser = true; + + var persistTimeStart = new Date().getTime(); + + var waitMainWindow = function() + { + var doc, head; + + try + { + if (window.opener && !window.opener.FirebugOldBrowser && (doc = window.opener.document)/* && + doc.documentElement && (head = doc.documentElement.firstChild)*/) + { + + try + { + // exposes the FBL to the global namespace when in debug mode + if (Env.isDebugMode) + { + window.FBL = FBL; + } + + window.Firebug = Firebug; + window.opener.Firebug = Firebug; + + Env.browser = window.opener; + Firebug.browser = Firebug.context = new Context(Env.browser); + + registerConsole(); + + // the delay time should be calculated right after registering the + // console, once right after the console registration, call log messages + // will be properly handled + var persistDelay = new Date().getTime() - persistTimeStart; + + var chrome = Firebug.chrome; + addEvent(Firebug.browser.window, "unload", chrome.persist); + + FBL.cacheDocument(); + Firebug.Inspector.create(); + + var htmlPanel = chrome.getPanel("HTML"); + htmlPanel.createUI(); + + Firebug.Console.logFormatted( + ["Firebug could not capture console calls during " + + persistDelay + "ms"], + Firebug.context, + "info" + ); + } + catch(pE) + { + alert("persist error: " + (pE.message || pE)); + } + + } + else + { + window.setTimeout(waitMainWindow, 0); + } + + } catch (E) { + window.close(); + } + }; + + waitMainWindow(); + }, + + close: function() + { + this.destroy(); + } + +}); + + +//************************************************************************************************ +// UI helpers + +var changeCommandLineVisibility = function changeCommandLineVisibility(visibility) +{ + var last = Firebug.chrome.commandLineVisible; + var visible = Firebug.chrome.commandLineVisible = + typeof visibility == "boolean" ? visibility : !Firebug.chrome.commandLineVisible; + + if (visible != last) + { + if (visible) + { + fbBottom.className = ""; + + if (Firebug.CommandLine) + Firebug.CommandLine.activate(); + } + else + { + if (Firebug.CommandLine) + Firebug.CommandLine.deactivate(); + + fbBottom.className = "hide"; + } + } +}; + +var changeSidePanelVisibility = function changeSidePanelVisibility(visibility) +{ + var last = Firebug.chrome.sidePanelVisible; + Firebug.chrome.sidePanelVisible = + typeof visibility == "boolean" ? visibility : !Firebug.chrome.sidePanelVisible; + + if (Firebug.chrome.sidePanelVisible != last) + { + fbPanelBox2.className = Firebug.chrome.sidePanelVisible ? "" : "hide"; + fbPanelBar2Box.className = Firebug.chrome.sidePanelVisible ? "" : "hide"; + } +}; + + +// ************************************************************************************************ +// F12 Handler + +var onGlobalKeyDown = function onGlobalKeyDown(event) +{ + var keyCode = event.keyCode; + var shiftKey = event.shiftKey; + var ctrlKey = event.ctrlKey; + + if (keyCode == 123 /* F12 */ && (!isFirefox && !shiftKey || shiftKey && isFirefox)) + { + Firebug.chrome.toggle(false, ctrlKey); + cancelEvent(event, true); + + // TODO: xxxpedro replace with a better solution. we're doing this + // to allow reactivating with the F12 key after being deactivated + if (Env.isChromeExtension) + { + Firebug.GoogleChrome.dispatch("FB_enableIcon"); + } + } + else if (keyCode == 67 /* C */ && ctrlKey && shiftKey) + { + Firebug.Inspector.toggleInspect(); + cancelEvent(event, true); + } + else if (keyCode == 76 /* L */ && ctrlKey && shiftKey) + { + Firebug.chrome.focusCommandLine(); + cancelEvent(event, true); + } +}; + +var onMiniIconClick = function onMiniIconClick(event) +{ + Firebug.chrome.toggle(false, event.ctrlKey); + cancelEvent(event, true); +}; + + +// ************************************************************************************************ +// Horizontal Splitter Handling + +var onHSplitterMouseDown = function onHSplitterMouseDown(event) +{ + addGlobalEvent("mousemove", onHSplitterMouseMove); + addGlobalEvent("mouseup", onHSplitterMouseUp); + + if (isIE) + addEvent(Firebug.browser.document.documentElement, "mouseleave", onHSplitterMouseUp); + + fbHSplitter.className = "fbOnMovingHSplitter"; + + return false; +}; + +var onHSplitterMouseMove = function onHSplitterMouseMove(event) +{ + cancelEvent(event, true); + + var clientY = event.clientY; + var win = isIE + ? event.srcElement.ownerDocument.parentWindow + : event.target.ownerDocument && event.target.ownerDocument.defaultView; + + if (!win) + return; + + if (win != win.parent) + { + var frameElement = win.frameElement; + if (frameElement) + { + var framePos = Firebug.browser.getElementPosition(frameElement).top; + clientY += framePos; + + if (frameElement.style.position != "fixed") + clientY -= Firebug.browser.getWindowScrollPosition().top; + } + } + + if (isOpera && isQuiksMode && win.frameElement.id == "FirebugUI") + { + clientY = Firebug.browser.getWindowSize().height - win.frameElement.offsetHeight + clientY; + } + /* + console.log( + typeof win.FBL != "undefined" ? "no-Chrome" : "Chrome", + //win.frameElement.id, + event.target, + clientY + );/**/ + + onHSplitterMouseMoveBuffer = clientY; // buffer + + if (new Date().getTime() - lastHSplitterMouseMove > chromeRedrawSkipRate) // frame skipping + { + lastHSplitterMouseMove = new Date().getTime(); + handleHSplitterMouseMove(); + } + else + if (!onHSplitterMouseMoveTimer) + onHSplitterMouseMoveTimer = setTimeout(handleHSplitterMouseMove, chromeRedrawSkipRate); + + // improving the resizing performance by canceling the mouse event. + // canceling events will prevent the page to receive such events, which would imply + // in more processing being expended. + cancelEvent(event, true); + return false; +}; + +var handleHSplitterMouseMove = function() +{ + if (onHSplitterMouseMoveTimer) + { + clearTimeout(onHSplitterMouseMoveTimer); + onHSplitterMouseMoveTimer = null; + } + + var clientY = onHSplitterMouseMoveBuffer; + + var windowSize = Firebug.browser.getWindowSize(); + var scrollSize = Firebug.browser.getWindowScrollSize(); + + // compute chrome fixed size (top bar and command line) + var commandLineHeight = Firebug.chrome.commandLineVisible ? fbCommandLine.offsetHeight : 0; + var fixedHeight = topHeight + commandLineHeight; + var chromeNode = Firebug.chrome.node; + + var scrollbarSize = !isIE && (scrollSize.width > windowSize.width) ? 17 : 0; + + //var height = !isOpera ? chromeNode.offsetTop + chromeNode.clientHeight : windowSize.height; + var height = windowSize.height; + + // compute the min and max size of the chrome + var chromeHeight = Math.max(height - clientY + 5 - scrollbarSize, fixedHeight); + chromeHeight = Math.min(chromeHeight, windowSize.height - scrollbarSize); + + FirebugChrome.height = chromeHeight; + chromeNode.style.height = chromeHeight + "px"; + + if (noFixedPosition) + Firebug.chrome.fixIEPosition(); + + Firebug.chrome.draw(); +}; + +var onHSplitterMouseUp = function onHSplitterMouseUp(event) +{ + removeGlobalEvent("mousemove", onHSplitterMouseMove); + removeGlobalEvent("mouseup", onHSplitterMouseUp); + + if (isIE) + removeEvent(Firebug.browser.document.documentElement, "mouseleave", onHSplitterMouseUp); + + fbHSplitter.className = ""; + + Firebug.chrome.draw(); + + // avoid text selection in IE when returning to the document + // after the mouse leaves the document during the resizing + return false; +}; + + +// ************************************************************************************************ +// Vertical Splitter Handling + +var onVSplitterMouseDown = function onVSplitterMouseDown(event) +{ + addGlobalEvent("mousemove", onVSplitterMouseMove); + addGlobalEvent("mouseup", onVSplitterMouseUp); + + return false; +}; + +var onVSplitterMouseMove = function onVSplitterMouseMove(event) +{ + if (new Date().getTime() - lastVSplitterMouseMove > chromeRedrawSkipRate) // frame skipping + { + var target = event.target || event.srcElement; + if (target && target.ownerDocument) // avoid error when cursor reaches out of the chrome + { + var clientX = event.clientX; + var win = document.all + ? event.srcElement.ownerDocument.parentWindow + : event.target.ownerDocument.defaultView; + + if (win != win.parent) + clientX += win.frameElement ? win.frameElement.offsetLeft : 0; + + var size = Firebug.chrome.getSize(); + var x = Math.max(size.width - clientX + 3, 6); + + FirebugChrome.sidePanelWidth = x; + Firebug.chrome.draw(); + } + + lastVSplitterMouseMove = new Date().getTime(); + } + + cancelEvent(event, true); + return false; +}; + +var onVSplitterMouseUp = function onVSplitterMouseUp(event) +{ + removeGlobalEvent("mousemove", onVSplitterMouseMove); + removeGlobalEvent("mouseup", onVSplitterMouseUp); + + Firebug.chrome.draw(); +}; + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +Firebug.Lite = +{ +}; + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + + +Firebug.Lite.Browser = function(window) +{ + this.contentWindow = window; + this.contentDocument = window.document; + this.currentURI = + { + spec: window.location.href + }; +}; + +Firebug.Lite.Browser.prototype = +{ + toString: function() + { + return "Firebug.Lite.Browser"; + } +}; + + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +Firebug.Lite.Cache = +{ + ID: "firebug" + new Date().getTime() +}; + +// ************************************************************************************************ + +/** + * TODO: if a cached element is cloned, the expando property will be cloned too in IE + * which will result in a bug. Firebug Lite will think the new cloned node is the old + * one. + * + * TODO: Investigate a possibility of cache validation, to be customized by each + * kind of cache. For ElementCache it should validate if the element still is + * inserted at the DOM. + */ +var cacheUID = 0; +var createCache = function() +{ + var map = {}; + var 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 = element[CID]; + + if (!id) + { + id = ++cacheUID; + element[CID] = id; + } + + if (!map.hasOwnProperty(id)) + { + map[id] = element; + } + + return id; + }, + + unset: function(element) + { + var id = element[CID]; + + if (supportsDeleteExpando) + { + delete element[CID]; + } + else if (element.removeAttribute) + { + element.removeAttribute(CID); + } + + delete map[id]; + + }, + + key: function(element) + { + return element[CID]; + }, + + has: function(element) + { + return map.hasOwnProperty(element[CID]); + }, + + clear: function() + { + for (var id in map) + { + var element = map[id]; + cacheAPI.unset(element); + } + } + }; + + 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(); + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + + +Firebug.Lite.Proxy = +{ + // jsonp callbacks + _callbacks: {}, + + /** + * Load a resource, either locally (directly) or externally (via proxy) using + * synchronous XHR calls. Loading external resources requires the proxy plugin to + * be installed and configured (see /plugin/proxy/proxy.php). + */ + load: function(url) + { + var resourceDomain = getDomain(url); + var isLocalResource = + // empty domain means local URL + !resourceDomain || + // same domain means local too + resourceDomain == Firebug.context.window.location.host; // TODO: xxxpedro context + + return isLocalResource ? fetchResource(url) : fetchProxyResource(url); + }, + + /** + * Load a resource using JSONP technique. + */ + loadJSONP: function(url, callback) + { + var script = createGlobalElement("script"), + doc = Firebug.context.document, + + uid = "" + new Date().getTime(), + callbackName = "callback=Firebug.Lite.Proxy._callbacks." + uid, + + jsonpURL = url.indexOf("?") != -1 ? + url + "&" + callbackName : + url + "?" + callbackName; + + Firebug.Lite.Proxy._callbacks[uid] = function(data) + { + if (callback) + callback(data); + + script.parentNode.removeChild(script); + delete Firebug.Lite.Proxy._callbacks[uid]; + }; + + script.src = jsonpURL; + + if (doc.documentElement) + doc.documentElement.appendChild(script); + }, + + /** + * Load a resource using YQL (not reliable). + */ + YQL: function(url, callback) + { + var yql = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22" + + encodeURIComponent(url) + "%22&format=xml"; + + this.loadJSONP(yql, function(data) + { + var source = data.results[0]; + + // clean up YQL bogus elements + var match = /\s+

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

                  "; + + // Safari can't handle uppercase or unicode characters when + // in quirks mode. + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function(query, context, extra, seed){ + context = context || document; + + // Only use querySelectorAll on non-XML documents + // (ID selectors don't work in non-HTML documents) + if ( !seed && context.nodeType === 9 && !isXML(context) ) { + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(e){} + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; + } + + div = null; // release memory in IE +})(); + +if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){ + var div = document.createElement("div"); + div.innerHTML = "
                  "; + + // Opera can't find a second classname (in 9.6) + if ( div.getElementsByClassName("e").length === 0 ) + return; + + // Safari caches class attributes, doesn't catch changes (in 3.2) + div.lastChild.className = "e"; + + if ( div.getElementsByClassName("e").length === 1 ) + return; + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS = function(match, context, isXML) { + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { + return context.getElementsByClassName(match[1]); + } + }; + + div = null; // release memory in IE +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + var sibDir = dir == "previousSibling" && !isXML; + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + if ( elem ) { + if ( sibDir && elem.nodeType === 1 ){ + elem.sizcache = doneName; + elem.sizset = i; + } + elem = elem[dir]; + var match = false; + + while ( elem ) { + if ( elem.sizcache === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem.sizcache = doneName; + elem.sizset = i; + } + + if ( elem.nodeName === cur ) { + match = elem; + break; + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + var sibDir = dir == "previousSibling" && !isXML; + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + if ( elem ) { + if ( sibDir && elem.nodeType === 1 ) { + elem.sizcache = doneName; + elem.sizset = i; + } + elem = elem[dir]; + var match = false; + + while ( elem ) { + if ( elem.sizcache === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem.sizcache = doneName; + elem.sizset = i; + } + if ( typeof cur !== "string" ) { + if ( elem === cur ) { + match = true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match = elem; + break; + } + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +var contains = document.compareDocumentPosition ? function(a, b){ + return a.compareDocumentPosition(b) & 16; +} : function(a, b){ + return a !== b && (a.contains ? a.contains(b) : true); +}; + +var isXML = function(elem){ + return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" || + !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML"; +}; + +var posProcess = function(selector, context){ + var tmpSet = [], later = "", match, + root = context.nodeType ? [context] : context; + + // Position selectors must be done after the filter + // And so must :not(positional) so we move all PSEUDOs to the end + while ( (match = Expr.match.PSEUDO.exec( selector )) ) { + later += match[0]; + selector = selector.replace( Expr.match.PSEUDO, "" ); + } + + selector = Expr.relative[selector] ? selector + "*" : selector; + + for ( var i = 0, l = root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE + +Firebug.Selector = Sizzle; + +/**#@-*/ + +// ************************************************************************************************ +}}); + +// Problems in IE +// FIXED - eval return +// FIXED - addEventListener problem in IE +// FIXED doc.createRange? +// +// class reserved word +// test all honza examples in IE6 and IE7 + + +/* See license.txt for terms of usage */ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +function DomplateTag(tagName) +{ + this.tagName = tagName; +} + +function DomplateEmbed() +{ +} + +function DomplateLoop() +{ +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +( /** @scope ns-domplate */ function() { + +var womb = null; + +var domplate = FBL.domplate = function() +{ + var lastSubject; + for (var i = 0; i < arguments.length; ++i) + lastSubject = lastSubject ? copyObject(lastSubject, arguments[i]) : arguments[i]; + + for (var name in lastSubject) + { + var val = lastSubject[name]; + if (isTag(val)) + val.tag.subject = lastSubject; + } + + return lastSubject; +}; + +domplate.context = function(context, fn) +{ + var lastContext = domplate.lastContext; + domplate.topContext = context; + fn.apply(context); + domplate.topContext = lastContext; +}; + +FBL.TAG = function() +{ + var embed = new DomplateEmbed(); + return embed.merge(arguments); +}; + +FBL.FOR = function() +{ + var loop = new DomplateLoop(); + return loop.merge(arguments); +}; + +DomplateTag.prototype = +{ + merge: function(args, oldTag) + { + if (oldTag) + this.tagName = oldTag.tagName; + + this.context = oldTag ? oldTag.context : null; + this.subject = oldTag ? oldTag.subject : null; + this.attrs = oldTag ? copyObject(oldTag.attrs) : {}; + this.classes = oldTag ? copyObject(oldTag.classes) : {}; + this.props = oldTag ? copyObject(oldTag.props) : null; + this.listeners = oldTag ? copyArray(oldTag.listeners) : null; + this.children = oldTag ? copyArray(oldTag.children) : []; + this.vars = oldTag ? copyArray(oldTag.vars) : []; + + var attrs = args.length ? args[0] : null; + var hasAttrs = typeof(attrs) == "object" && !isTag(attrs); + + this.children = []; + + if (domplate.topContext) + this.context = domplate.topContext; + + if (args.length) + parseChildren(args, hasAttrs ? 1 : 0, this.vars, this.children); + + if (hasAttrs) + this.parseAttrs(attrs); + + return creator(this, DomplateTag); + }, + + parseAttrs: function(args) + { + for (var name in args) + { + var val = parseValue(args[name]); + readPartNames(val, this.vars); + + if (name.indexOf("on") == 0) + { + var eventName = name.substr(2); + if (!this.listeners) + this.listeners = []; + this.listeners.push(eventName, val); + } + else if (name.indexOf("_") == 0) + { + var propName = name.substr(1); + if (!this.props) + this.props = {}; + this.props[propName] = val; + } + else if (name.indexOf("$") == 0) + { + var className = name.substr(1); + if (!this.classes) + this.classes = {}; + this.classes[className] = val; + } + else + { + if (name == "class" && this.attrs.hasOwnProperty(name) ) + this.attrs[name] += " " + val; + else + this.attrs[name] = val; + } + } + }, + + compile: function() + { + if (this.renderMarkup) + return; + + this.compileMarkup(); + this.compileDOM(); + + //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate renderMarkup: ", this.renderMarkup); + //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate renderDOM:", this.renderDOM); + //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate domArgs:", this.domArgs); + }, + + compileMarkup: function() + { + this.markupArgs = []; + var topBlock = [], topOuts = [], blocks = [], info = {args: this.markupArgs, argIndex: 0}; + + this.generateMarkup(topBlock, topOuts, blocks, info); + this.addCode(topBlock, topOuts, blocks); + + var fnBlock = ['r=(function (__code__, __context__, __in__, __out__']; + for (var i = 0; i < info.argIndex; ++i) + fnBlock.push(', s', i); + fnBlock.push(') {'); + + if (this.subject) + fnBlock.push('with (this) {'); + if (this.context) + fnBlock.push('with (__context__) {'); + fnBlock.push('with (__in__) {'); + + fnBlock.push.apply(fnBlock, blocks); + + if (this.subject) + fnBlock.push('}'); + if (this.context) + fnBlock.push('}'); + + fnBlock.push('}})'); + + function __link__(tag, code, outputs, args) + { + if (!tag || !tag.tag) + return; + + tag.tag.compile(); + + var tagOutputs = []; + var markupArgs = [code, tag.tag.context, args, tagOutputs]; + markupArgs.push.apply(markupArgs, tag.tag.markupArgs); + tag.tag.renderMarkup.apply(tag.tag.subject, markupArgs); + + outputs.push(tag); + outputs.push(tagOutputs); + } + + function __escape__(value) + { + function replaceChars(ch) + { + switch (ch) + { + case "<": + return "<"; + case ">": + return ">"; + case "&": + return "&"; + case "'": + return "'"; + case '"': + return """; + } + return "?"; + }; + return String(value).replace(/[<>&"']/g, replaceChars); + } + + function __loop__(iter, outputs, fn) + { + var iterOuts = []; + outputs.push(iterOuts); + + if (iter instanceof Array) + iter = new ArrayIterator(iter); + + try + { + while (1) + { + var value = iter.next(); + var itemOuts = [0,0]; + iterOuts.push(itemOuts); + fn.apply(this, [value, itemOuts]); + } + } + catch (exc) + { + if (exc != StopIteration) + throw exc; + } + } + + var js = fnBlock.join(""); + var r = null; + eval(js); + this.renderMarkup = r; + }, + + getVarNames: function(args) + { + if (this.vars) + args.push.apply(args, this.vars); + + for (var i = 0; i < this.children.length; ++i) + { + var child = this.children[i]; + if (isTag(child)) + child.tag.getVarNames(args); + else if (child instanceof Parts) + { + for (var i = 0; i < child.parts.length; ++i) + { + if (child.parts[i] instanceof Variable) + { + var name = child.parts[i].name; + var names = name.split("."); + args.push(names[0]); + } + } + } + } + }, + + generateMarkup: function(topBlock, topOuts, blocks, info) + { + topBlock.push(',"<', this.tagName, '"'); + + for (var name in this.attrs) + { + if (name != "class") + { + var val = this.attrs[name]; + topBlock.push(', " ', name, '=\\""'); + addParts(val, ',', topBlock, info, true); + topBlock.push(', "\\""'); + } + } + + if (this.listeners) + { + for (var i = 0; i < this.listeners.length; i += 2) + readPartNames(this.listeners[i+1], topOuts); + } + + if (this.props) + { + for (var name in this.props) + readPartNames(this.props[name], topOuts); + } + + if ( this.attrs.hasOwnProperty("class") || this.classes) + { + topBlock.push(', " class=\\""'); + if (this.attrs.hasOwnProperty("class")) + addParts(this.attrs["class"], ',', topBlock, info, true); + topBlock.push(', " "'); + for (var name in this.classes) + { + topBlock.push(', ('); + addParts(this.classes[name], '', topBlock, info); + topBlock.push(' ? "', name, '" + " " : "")'); + } + topBlock.push(', "\\""'); + } + topBlock.push(',">"'); + + this.generateChildMarkup(topBlock, topOuts, blocks, info); + topBlock.push(',""'); + }, + + generateChildMarkup: function(topBlock, topOuts, blocks, info) + { + for (var i = 0; i < this.children.length; ++i) + { + var child = this.children[i]; + if (isTag(child)) + child.tag.generateMarkup(topBlock, topOuts, blocks, info); + else + addParts(child, ',', topBlock, info, true); + } + }, + + addCode: function(topBlock, topOuts, blocks) + { + if (topBlock.length) + blocks.push('__code__.push(""', topBlock.join(""), ');'); + if (topOuts.length) + blocks.push('__out__.push(', topOuts.join(","), ');'); + topBlock.splice(0, topBlock.length); + topOuts.splice(0, topOuts.length); + }, + + addLocals: function(blocks) + { + var varNames = []; + this.getVarNames(varNames); + + var map = {}; + for (var i = 0; i < varNames.length; ++i) + { + var name = varNames[i]; + if ( map.hasOwnProperty(name) ) + continue; + + map[name] = 1; + var names = name.split("."); + blocks.push('var ', names[0] + ' = ' + '__in__.' + names[0] + ';'); + } + }, + + compileDOM: function() + { + var path = []; + var blocks = []; + this.domArgs = []; + path.embedIndex = 0; + path.loopIndex = 0; + path.staticIndex = 0; + path.renderIndex = 0; + var nodeCount = this.generateDOM(path, blocks, this.domArgs); + + var fnBlock = ['r=(function (root, context, o']; + + for (var i = 0; i < path.staticIndex; ++i) + fnBlock.push(', ', 's'+i); + + for (var i = 0; i < path.renderIndex; ++i) + fnBlock.push(', ', 'd'+i); + + fnBlock.push(') {'); + for (var i = 0; i < path.loopIndex; ++i) + fnBlock.push('var l', i, ' = 0;'); + for (var i = 0; i < path.embedIndex; ++i) + fnBlock.push('var e', i, ' = 0;'); + + if (this.subject) + fnBlock.push('with (this) {'); + if (this.context) + fnBlock.push('with (context) {'); + + fnBlock.push(blocks.join("")); + + if (this.subject) + fnBlock.push('}'); + if (this.context) + fnBlock.push('}'); + + fnBlock.push('return ', nodeCount, ';'); + fnBlock.push('})'); + + function __bind__(object, fn) + { + return function(event) { return fn.apply(object, [event]); }; + } + + function __link__(node, tag, args) + { + if (!tag || !tag.tag) + return; + + tag.tag.compile(); + + var domArgs = [node, tag.tag.context, 0]; + domArgs.push.apply(domArgs, tag.tag.domArgs); + domArgs.push.apply(domArgs, args); + //if (FBTrace.DBG_DOM) FBTrace.dumpProperties("domplate__link__ domArgs:", domArgs); + return tag.tag.renderDOM.apply(tag.tag.subject, domArgs); + } + + var self = this; + function __loop__(iter, fn) + { + var nodeCount = 0; + for (var i = 0; i < iter.length; ++i) + { + iter[i][0] = i; + iter[i][1] = nodeCount; + nodeCount += fn.apply(this, iter[i]); + //if (FBTrace.DBG_DOM) FBTrace.sysout("nodeCount", nodeCount); + } + return nodeCount; + } + + function __path__(parent, offset) + { + //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate __path__ offset: "+ offset+"\n"); + var root = parent; + + for (var i = 2; i < arguments.length; ++i) + { + var index = arguments[i]; + if (i == 3) + index += offset; + + if (index == -1) + parent = parent.parentNode; + else + parent = parent.childNodes[index]; + } + + //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate: "+arguments[2]+", root: "+ root+", parent: "+ parent+"\n"); + return parent; + } + + var js = fnBlock.join(""); + //if (FBTrace.DBG_DOM) FBTrace.sysout(js.replace(/(\;|\{)/g, "$1\n")); + var r = null; + eval(js); + this.renderDOM = r; + }, + + generateDOM: function(path, blocks, args) + { + if (this.listeners || this.props) + this.generateNodePath(path, blocks); + + if (this.listeners) + { + for (var i = 0; i < this.listeners.length; i += 2) + { + var val = this.listeners[i+1]; + var arg = generateArg(val, path, args); + //blocks.push('node.addEventListener("', this.listeners[i], '", __bind__(this, ', arg, '), false);'); + blocks.push('addEvent(node, "', this.listeners[i], '", __bind__(this, ', arg, '), false);'); + } + } + + if (this.props) + { + for (var name in this.props) + { + var val = this.props[name]; + var arg = generateArg(val, path, args); + blocks.push('node.', name, ' = ', arg, ';'); + } + } + + this.generateChildDOM(path, blocks, args); + return 1; + }, + + generateNodePath: function(path, blocks) + { + blocks.push("var node = __path__(root, o"); + for (var i = 0; i < path.length; ++i) + blocks.push(",", path[i]); + blocks.push(");"); + }, + + generateChildDOM: function(path, blocks, args) + { + path.push(0); + for (var i = 0; i < this.children.length; ++i) + { + var child = this.children[i]; + if (isTag(child)) + path[path.length-1] += '+' + child.tag.generateDOM(path, blocks, args); + else + path[path.length-1] += '+1'; + } + path.pop(); + } +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +DomplateEmbed.prototype = copyObject(DomplateTag.prototype, +{ + merge: function(args, oldTag) + { + this.value = oldTag ? oldTag.value : parseValue(args[0]); + this.attrs = oldTag ? oldTag.attrs : {}; + this.vars = oldTag ? copyArray(oldTag.vars) : []; + + var attrs = args[1]; + for (var name in attrs) + { + var val = parseValue(attrs[name]); + this.attrs[name] = val; + readPartNames(val, this.vars); + } + + return creator(this, DomplateEmbed); + }, + + getVarNames: function(names) + { + if (this.value instanceof Parts) + names.push(this.value.parts[0].name); + + if (this.vars) + names.push.apply(names, this.vars); + }, + + generateMarkup: function(topBlock, topOuts, blocks, info) + { + this.addCode(topBlock, topOuts, blocks); + + blocks.push('__link__('); + addParts(this.value, '', blocks, info); + blocks.push(', __code__, __out__, {'); + + var lastName = null; + for (var name in this.attrs) + { + if (lastName) + blocks.push(','); + lastName = name; + + var val = this.attrs[name]; + blocks.push('"', name, '":'); + addParts(val, '', blocks, info); + } + + blocks.push('});'); + //this.generateChildMarkup(topBlock, topOuts, blocks, info); + }, + + generateDOM: function(path, blocks, args) + { + var embedName = 'e'+path.embedIndex++; + + this.generateNodePath(path, blocks); + + var valueName = 'd' + path.renderIndex++; + var argsName = 'd' + path.renderIndex++; + blocks.push(embedName + ' = __link__(node, ', valueName, ', ', argsName, ');'); + + return embedName; + } +}); + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +DomplateLoop.prototype = copyObject(DomplateTag.prototype, +{ + merge: function(args, oldTag) + { + this.varName = oldTag ? oldTag.varName : args[0]; + this.iter = oldTag ? oldTag.iter : parseValue(args[1]); + this.vars = []; + + this.children = oldTag ? copyArray(oldTag.children) : []; + + var offset = Math.min(args.length, 2); + parseChildren(args, offset, this.vars, this.children); + + return creator(this, DomplateLoop); + }, + + getVarNames: function(names) + { + if (this.iter instanceof Parts) + names.push(this.iter.parts[0].name); + + DomplateTag.prototype.getVarNames.apply(this, [names]); + }, + + generateMarkup: function(topBlock, topOuts, blocks, info) + { + this.addCode(topBlock, topOuts, blocks); + + var iterName; + if (this.iter instanceof Parts) + { + var part = this.iter.parts[0]; + iterName = part.name; + + if (part.format) + { + for (var i = 0; i < part.format.length; ++i) + iterName = part.format[i] + "(" + iterName + ")"; + } + } + else + iterName = this.iter; + + blocks.push('__loop__.apply(this, [', iterName, ', __out__, function(', this.varName, ', __out__) {'); + this.generateChildMarkup(topBlock, topOuts, blocks, info); + this.addCode(topBlock, topOuts, blocks); + blocks.push('}]);'); + }, + + generateDOM: function(path, blocks, args) + { + var iterName = 'd'+path.renderIndex++; + var counterName = 'i'+path.loopIndex; + var loopName = 'l'+path.loopIndex++; + + if (!path.length) + path.push(-1, 0); + + var preIndex = path.renderIndex; + path.renderIndex = 0; + + var nodeCount = 0; + + var subBlocks = []; + var basePath = path[path.length-1]; + for (var i = 0; i < this.children.length; ++i) + { + path[path.length-1] = basePath+'+'+loopName+'+'+nodeCount; + + var child = this.children[i]; + if (isTag(child)) + nodeCount += '+' + child.tag.generateDOM(path, subBlocks, args); + else + nodeCount += '+1'; + } + + path[path.length-1] = basePath+'+'+loopName; + + blocks.push(loopName,' = __loop__.apply(this, [', iterName, ', function(', counterName,',',loopName); + for (var i = 0; i < path.renderIndex; ++i) + blocks.push(',d'+i); + blocks.push(') {'); + blocks.push(subBlocks.join("")); + blocks.push('return ', nodeCount, ';'); + blocks.push('}]);'); + + path.renderIndex = preIndex; + + return loopName; + } +}); + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +function Variable(name, format) +{ + this.name = name; + this.format = format; +} + +function Parts(parts) +{ + this.parts = parts; +} + +// ************************************************************************************************ + +function parseParts(str) +{ + var re = /\$([_A-Za-z][_A-Za-z0-9.|]*)/g; + var index = 0; + var parts = []; + + var m; + while (m = re.exec(str)) + { + var pre = str.substr(index, (re.lastIndex-m[0].length)-index); + if (pre) + parts.push(pre); + + var expr = m[1].split("|"); + parts.push(new Variable(expr[0], expr.slice(1))); + index = re.lastIndex; + } + + if (!index) + return str; + + var post = str.substr(index); + if (post) + parts.push(post); + + return new Parts(parts); +} + +function parseValue(val) +{ + return typeof(val) == 'string' ? parseParts(val) : val; +} + +function parseChildren(args, offset, vars, children) +{ + for (var i = offset; i < args.length; ++i) + { + var val = parseValue(args[i]); + children.push(val); + readPartNames(val, vars); + } +} + +function readPartNames(val, vars) +{ + if (val instanceof Parts) + { + for (var i = 0; i < val.parts.length; ++i) + { + var part = val.parts[i]; + if (part instanceof Variable) + vars.push(part.name); + } + } +} + +function generateArg(val, path, args) +{ + if (val instanceof Parts) + { + var vals = []; + for (var i = 0; i < val.parts.length; ++i) + { + var part = val.parts[i]; + if (part instanceof Variable) + { + var varName = 'd'+path.renderIndex++; + if (part.format) + { + for (var j = 0; j < part.format.length; ++j) + varName = part.format[j] + '(' + varName + ')'; + } + + vals.push(varName); + } + else + vals.push('"'+part.replace(/"/g, '\\"')+'"'); + } + + return vals.join('+'); + } + else + { + args.push(val); + return 's' + path.staticIndex++; + } +} + +function addParts(val, delim, block, info, escapeIt) +{ + var vals = []; + if (val instanceof Parts) + { + for (var i = 0; i < val.parts.length; ++i) + { + var part = val.parts[i]; + if (part instanceof Variable) + { + var partName = part.name; + if (part.format) + { + for (var j = 0; j < part.format.length; ++j) + partName = part.format[j] + "(" + partName + ")"; + } + + if (escapeIt) + vals.push("__escape__(" + partName + ")"); + else + vals.push(partName); + } + else + vals.push('"'+ part + '"'); + } + } + else if (isTag(val)) + { + info.args.push(val); + vals.push('s'+info.argIndex++); + } + else + vals.push('"'+ val + '"'); + + var parts = vals.join(delim); + if (parts) + block.push(delim, parts); +} + +function isTag(obj) +{ + return (typeof(obj) == "function" || obj instanceof Function) && !!obj.tag; +} + +function creator(tag, cons) +{ + var fn = new Function( + "var tag = arguments.callee.tag;" + + "var cons = arguments.callee.cons;" + + "var newTag = new cons();" + + "return newTag.merge(arguments, tag);"); + + fn.tag = tag; + fn.cons = cons; + extend(fn, Renderer); + + return fn; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +function copyArray(oldArray) +{ + var ary = []; + if (oldArray) + for (var i = 0; i < oldArray.length; ++i) + ary.push(oldArray[i]); + return ary; +} + +function copyObject(l, r) +{ + var m = {}; + extend(m, l); + extend(m, r); + return m; +} + +function extend(l, r) +{ + for (var n in r) + l[n] = r[n]; +} + +function addEvent(object, name, handler) +{ + if (document.all) + object.attachEvent("on"+name, handler); + else + object.addEventListener(name, handler, false); +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +function ArrayIterator(array) +{ + var index = -1; + + this.next = function() + { + if (++index >= array.length) + throw StopIteration; + + return array[index]; + }; +} + +function StopIteration() {} + +FBL.$break = function() +{ + throw StopIteration; +}; + +// ************************************************************************************************ + +var Renderer = +{ + renderHTML: function(args, outputs, self) + { + var code = []; + var markupArgs = [code, this.tag.context, args, outputs]; + markupArgs.push.apply(markupArgs, this.tag.markupArgs); + this.tag.renderMarkup.apply(self ? self : this.tag.subject, markupArgs); + return code.join(""); + }, + + insertRows: function(args, before, self) + { + this.tag.compile(); + + var outputs = []; + var html = this.renderHTML(args, outputs, self); + + var doc = before.ownerDocument; + var div = doc.createElement("div"); + div.innerHTML = ""+html+"
                  "; + + var tbody = div.firstChild.firstChild; + var parent = before.tagName == "TR" ? before.parentNode : before; + var after = before.tagName == "TR" ? before.nextSibling : null; + + var firstRow = tbody.firstChild, lastRow; + while (tbody.firstChild) + { + lastRow = tbody.firstChild; + if (after) + parent.insertBefore(lastRow, after); + else + parent.appendChild(lastRow); + } + + var offset = 0; + if (before.tagName == "TR") + { + var node = firstRow.parentNode.firstChild; + for (; node && node != firstRow; node = node.nextSibling) + ++offset; + } + + var domArgs = [firstRow, this.tag.context, offset]; + domArgs.push.apply(domArgs, this.tag.domArgs); + domArgs.push.apply(domArgs, outputs); + + this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs); + return [firstRow, lastRow]; + }, + + insertBefore: function(args, before, self) + { + return this.insertNode(args, before.ownerDocument, before, false, self); + }, + + insertAfter: function(args, after, self) + { + return this.insertNode(args, after.ownerDocument, after, true, self); + }, + + insertNode: function(args, doc, element, isAfter, self) + { + if (!args) + args = {}; + + this.tag.compile(); + + var outputs = []; + var html = this.renderHTML(args, outputs, self); + + //if (FBTrace.DBG_DOM) + // FBTrace.sysout("domplate.insertNode html: "+html+"\n"); + + var doc = element.ownerDocument; + if (!womb || womb.ownerDocument != doc) + womb = doc.createElement("div"); + + womb.innerHTML = html; + + var root = womb.firstChild; + if (isAfter) + { + while (womb.firstChild) + if (element.nextSibling) + element.parentNode.insertBefore(womb.firstChild, element.nextSibling); + else + element.parentNode.appendChild(womb.firstChild); + } + else + { + while (womb.lastChild) + element.parentNode.insertBefore(womb.lastChild, element); + } + + var domArgs = [root, this.tag.context, 0]; + domArgs.push.apply(domArgs, this.tag.domArgs); + domArgs.push.apply(domArgs, outputs); + + //if (FBTrace.DBG_DOM) + // FBTrace.sysout("domplate.insertNode domArgs:", domArgs); + this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs); + + return root; + }, + /**/ + + /* + insertAfter: function(args, before, self) + { + this.tag.compile(); + + var outputs = []; + var html = this.renderHTML(args, outputs, self); + + var doc = before.ownerDocument; + if (!womb || womb.ownerDocument != doc) + womb = doc.createElement("div"); + + womb.innerHTML = html; + + var root = womb.firstChild; + while (womb.firstChild) + if (before.nextSibling) + before.parentNode.insertBefore(womb.firstChild, before.nextSibling); + else + before.parentNode.appendChild(womb.firstChild); + + var domArgs = [root, this.tag.context, 0]; + domArgs.push.apply(domArgs, this.tag.domArgs); + domArgs.push.apply(domArgs, outputs); + + this.tag.renderDOM.apply(self ? self : (this.tag.subject ? this.tag.subject : null), + domArgs); + + return root; + }, + /**/ + + replace: function(args, parent, self) + { + this.tag.compile(); + + var outputs = []; + var html = this.renderHTML(args, outputs, self); + + var root; + if (parent.nodeType == 1) + { + parent.innerHTML = html; + root = parent.firstChild; + } + else + { + if (!parent || parent.nodeType != 9) + parent = document; + + if (!womb || womb.ownerDocument != parent) + womb = parent.createElement("div"); + womb.innerHTML = html; + + root = womb.firstChild; + //womb.removeChild(root); + } + + var domArgs = [root, this.tag.context, 0]; + domArgs.push.apply(domArgs, this.tag.domArgs); + domArgs.push.apply(domArgs, outputs); + this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs); + + return root; + }, + + append: function(args, parent, self) + { + this.tag.compile(); + + var outputs = []; + var html = this.renderHTML(args, outputs, self); + //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate.append html: "+html+"\n"); + + if (!womb || womb.ownerDocument != parent.ownerDocument) + womb = parent.ownerDocument.createElement("div"); + womb.innerHTML = html; + + // TODO: xxxpedro domplate port to Firebug + var root = womb.firstChild; + while (womb.firstChild) + parent.appendChild(womb.firstChild); + + // clearing element reference to avoid reference error in IE8 when switching contexts + womb = null; + + var domArgs = [root, this.tag.context, 0]; + domArgs.push.apply(domArgs, this.tag.domArgs); + domArgs.push.apply(domArgs, outputs); + + //if (FBTrace.DBG_DOM) FBTrace.dumpProperties("domplate append domArgs:", domArgs); + this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs); + + return root; + } +}; + +// ************************************************************************************************ + +function defineTags() +{ + for (var i = 0; i < arguments.length; ++i) + { + var tagName = arguments[i]; + var fn = new Function("var newTag = new arguments.callee.DomplateTag('"+tagName+"'); return newTag.merge(arguments);"); + fn.DomplateTag = DomplateTag; + + var fnName = tagName.toUpperCase(); + FBL[fnName] = fn; + } +} + +defineTags( + "a", "button", "br", "canvas", "code", "col", "colgroup", "div", "fieldset", "form", "h1", "h2", "h3", "hr", + "img", "input", "label", "legend", "li", "ol", "optgroup", "option", "p", "pre", "select", + "span", "strong", "table", "tbody", "td", "textarea", "tfoot", "th", "thead", "tr", "tt", "ul", "iframe" +); + +})(); + + +/* See license.txt for terms of usage */ + +var FirebugReps = FBL.ns(function() { with (FBL) { + + +// ************************************************************************************************ +// Common Tags + +var OBJECTBOX = this.OBJECTBOX = + SPAN({"class": "objectBox objectBox-$className"}); + +var OBJECTBLOCK = this.OBJECTBLOCK = + DIV({"class": "objectBox objectBox-$className"}); + +var OBJECTLINK = this.OBJECTLINK = isIE6 ? // IE6 object link representation + A({ + "class": "objectLink objectLink-$className a11yFocus", + href: "javascript:void(0)", + _repObject: "$object" + }) + : // Other browsers + A({ + "class": "objectLink objectLink-$className a11yFocus", + _repObject: "$object" + }); + + +// ************************************************************************************************ + +this.Undefined = domplate(Firebug.Rep, +{ + tag: OBJECTBOX("undefined"), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "undefined", + + supportsObject: function(object, type) + { + return type == "undefined"; + } +}); + +// ************************************************************************************************ + +this.Null = domplate(Firebug.Rep, +{ + tag: OBJECTBOX("null"), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "null", + + supportsObject: function(object, type) + { + return object == null; + } +}); + +// ************************************************************************************************ + +this.Nada = domplate(Firebug.Rep, +{ + tag: SPAN(""), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "nada" +}); + +// ************************************************************************************************ + +this.Number = domplate(Firebug.Rep, +{ + tag: OBJECTBOX("$object"), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "number", + + supportsObject: function(object, type) + { + return type == "boolean" || type == "number"; + } +}); + +// ************************************************************************************************ + +this.String = domplate(Firebug.Rep, +{ + tag: OBJECTBOX(""$object""), + + shortTag: OBJECTBOX(""$object|cropString""), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "string", + + supportsObject: function(object, type) + { + return type == "string"; + } +}); + +// ************************************************************************************************ + +this.Text = domplate(Firebug.Rep, +{ + tag: OBJECTBOX("$object"), + + shortTag: OBJECTBOX("$object|cropString"), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "text" +}); + +// ************************************************************************************************ + +this.Caption = domplate(Firebug.Rep, +{ + tag: SPAN({"class": "caption"}, "$object") +}); + +// ************************************************************************************************ + +this.Warning = domplate(Firebug.Rep, +{ + tag: DIV({"class": "warning focusRow", role : 'listitem'}, "$object|STR") +}); + +// ************************************************************************************************ + +this.Func = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK("$object|summarizeFunction"), + + summarizeFunction: function(fn) + { + var fnRegex = /function ([^(]+\([^)]*\)) \{/; + var fnText = safeToString(fn); + + var m = fnRegex.exec(fnText); + return m ? m[1] : "function()"; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + copySource: function(fn) + { + copyToClipboard(safeToString(fn)); + }, + + monitor: function(fn, script, monitored) + { + if (monitored) + Firebug.Debugger.unmonitorScript(fn, script, "monitor"); + else + Firebug.Debugger.monitorScript(fn, script, "monitor"); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "function", + + supportsObject: function(object, type) + { + return isFunction(object); + }, + + inspectObject: function(fn, context) + { + var sourceLink = findSourceForFunction(fn, context); + if (sourceLink) + Firebug.chrome.select(sourceLink); + if (FBTrace.DBG_FUNCTION_NAME) + FBTrace.sysout("reps.function.inspectObject selected sourceLink is ", sourceLink); + }, + + getTooltip: function(fn, context) + { + var script = findScriptForFunctionInContext(context, fn); + if (script) + return $STRF("Line", [normalizeURL(script.fileName), script.baseLineNumber]); + else + if (fn.toString) + return fn.toString(); + }, + + getTitle: function(fn, context) + { + var name = fn.name ? fn.name : "function"; + return name + "()"; + }, + + getContextMenuItems: function(fn, target, context, script) + { + if (!script) + script = findScriptForFunctionInContext(context, fn); + if (!script) + return; + + var scriptInfo = getSourceFileAndLineByScript(context, script); + var monitored = scriptInfo ? fbs.isMonitored(scriptInfo.sourceFile.href, scriptInfo.lineNo) : false; + + var name = script ? getFunctionName(script, context) : fn.name; + return [ + {label: "CopySource", command: bindFixed(this.copySource, this, fn) }, + "-", + {label: $STRF("ShowCallsInConsole", [name]), nol10n: true, + type: "checkbox", checked: monitored, + command: bindFixed(this.monitor, this, fn, script, monitored) } + ]; + } +}); + +// ************************************************************************************************ +/* +this.jsdScript = domplate(Firebug.Rep, +{ + copySource: function(script) + { + var fn = script.functionObject.getWrappedValue(); + return FirebugReps.Func.copySource(fn); + }, + + monitor: function(fn, script, monitored) + { + fn = script.functionObject.getWrappedValue(); + return FirebugReps.Func.monitor(fn, script, monitored); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "jsdScript", + inspectable: false, + + supportsObject: function(object, type) + { + return object instanceof jsdIScript; + }, + + inspectObject: function(script, context) + { + var sourceLink = getSourceLinkForScript(script, context); + if (sourceLink) + Firebug.chrome.select(sourceLink); + }, + + getRealObject: function(script, context) + { + return script; + }, + + getTooltip: function(script) + { + return $STRF("jsdIScript", [script.tag]); + }, + + getTitle: function(script, context) + { + var fn = script.functionObject.getWrappedValue(); + return FirebugReps.Func.getTitle(fn, context); + }, + + getContextMenuItems: function(script, target, context) + { + var fn = script.functionObject.getWrappedValue(); + + var scriptInfo = getSourceFileAndLineByScript(context, script); + var monitored = scriptInfo ? fbs.isMonitored(scriptInfo.sourceFile.href, scriptInfo.lineNo) : false; + + var name = getFunctionName(script, context); + + return [ + {label: "CopySource", command: bindFixed(this.copySource, this, script) }, + "-", + {label: $STRF("ShowCallsInConsole", [name]), nol10n: true, + type: "checkbox", checked: monitored, + command: bindFixed(this.monitor, this, fn, script, monitored) } + ]; + } +}); +/**/ +//************************************************************************************************ + +this.Obj = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK( + SPAN({"class": "objectTitle"}, "$object|getTitle "), + + SPAN({"class": "objectProps"}, + SPAN({"class": "objectLeftBrace", role: "presentation"}, "{"), + FOR("prop", "$object|propIterator", + SPAN({"class": "objectPropName", role: "presentation"}, "$prop.name"), + SPAN({"class": "objectEqual", role: "presentation"}, "$prop.equal"), + TAG("$prop.tag", {object: "$prop.object"}), + SPAN({"class": "objectComma", role: "presentation"}, "$prop.delim") + ), + SPAN({"class": "objectRightBrace"}, "}") + ) + ), + + propNumberTag: + SPAN({"class": "objectProp-number"}, "$object"), + + propStringTag: + SPAN({"class": "objectProp-string"}, ""$object""), + + propObjectTag: + SPAN({"class": "objectProp-object"}, "$object"), + + propIterator: function (object) + { + ///Firebug.ObjectShortIteratorMax; + var maxLength = 55; // default max length for long representation + + if (!object) + return []; + + var props = []; + var length = 0; + + var numProperties = 0; + var numPropertiesShown = 0; + var maxLengthReached = false; + + var lib = this; + + var propRepsMap = + { + "boolean": this.propNumberTag, + "number": this.propNumberTag, + "string": this.propStringTag, + "object": this.propObjectTag + }; + + try + { + var title = Firebug.Rep.getTitle(object); + length += title.length; + + for (var name in object) + { + var value; + try + { + value = object[name]; + } + catch (exc) + { + continue; + } + + var type = typeof(value); + if (type == "boolean" || + type == "number" || + (type == "string" && value) || + (type == "object" && value && value.toString)) + { + var tag = propRepsMap[type]; + + var value = (type == "object") ? + Firebug.getRep(value).getTitle(value) : + value + ""; + + length += name.length + value.length + 4; + + if (length <= maxLength) + { + props.push({ + tag: tag, + name: name, + object: value, + equal: "=", + delim: ", " + }); + + numPropertiesShown++; + } + else + maxLengthReached = true; + + } + + numProperties++; + + if (maxLengthReached && numProperties > numPropertiesShown) + break; + } + + if (numProperties > numPropertiesShown) + { + props.push({ + object: "...", //xxxHonza localization + tag: FirebugReps.Caption.tag, + name: "", + equal:"", + delim:"" + }); + } + else if (props.length > 0) + { + props[props.length-1].delim = ''; + } + } + catch (exc) + { + // Sometimes we get exceptions when trying to read from certain objects, like + // StorageList, but don't let that gum up the works + // XXXjjb also History.previous fails because object is a web-page object which does not have + // permission to read the history + } + return props; + }, + + fb_1_6_propIterator: function (object, max) + { + max = max || 3; + if (!object) + return []; + + var props = []; + var len = 0, count = 0; + + try + { + for (var name in object) + { + var value; + try + { + value = object[name]; + } + catch (exc) + { + continue; + } + + var t = typeof(value); + if (t == "boolean" || t == "number" || (t == "string" && value) + || (t == "object" && value && value.toString)) + { + var rep = Firebug.getRep(value); + var tag = rep.shortTag || rep.tag; + if (t == "object") + { + value = rep.getTitle(value); + tag = rep.titleTag; + } + count++; + if (count <= max) + props.push({tag: tag, name: name, object: value, equal: "=", delim: ", "}); + else + break; + } + } + if (count > max) + { + props[Math.max(1,max-1)] = { + object: "more...", //xxxHonza localization + tag: FirebugReps.Caption.tag, + name: "", + equal:"", + delim:"" + }; + } + else if (props.length > 0) + { + props[props.length-1].delim = ''; + } + } + catch (exc) + { + // Sometimes we get exceptions when trying to read from certain objects, like + // StorageList, but don't let that gum up the works + // XXXjjb also History.previous fails because object is a web-page object which does not have + // permission to read the history + } + return props; + }, + + /* + propIterator: function (object) + { + if (!object) + return []; + + var props = []; + var len = 0; + + try + { + for (var name in object) + { + var val; + try + { + val = object[name]; + } + catch (exc) + { + continue; + } + + var t = typeof val; + if (t == "boolean" || t == "number" || (t == "string" && val) + || (t == "object" && !isFunction(val) && val && val.toString)) + { + var title = (t == "object") + ? Firebug.getRep(val).getTitle(val) + : val+""; + + len += name.length + title.length + 1; + if (len < 50) + props.push({name: name, value: title}); + else + break; + } + } + } + catch (exc) + { + // Sometimes we get exceptions when trying to read from certain objects, like + // StorageList, but don't let that gum up the works + // XXXjjb also History.previous fails because object is a web-page object which does not have + // permission to read the history + } + + return props; + }, + /**/ + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "object", + + supportsObject: function(object, type) + { + return true; + } +}); + + +// ************************************************************************************************ + +this.Arr = domplate(Firebug.Rep, +{ + tag: + OBJECTBOX({_repObject: "$object"}, + SPAN({"class": "arrayLeftBracket", role : "presentation"}, "["), + FOR("item", "$object|arrayIterator", + TAG("$item.tag", {object: "$item.object"}), + SPAN({"class": "arrayComma", role : "presentation"}, "$item.delim") + ), + SPAN({"class": "arrayRightBracket", role : "presentation"}, "]") + ), + + shortTag: + OBJECTBOX({_repObject: "$object"}, + SPAN({"class": "arrayLeftBracket", role : "presentation"}, "["), + FOR("item", "$object|shortArrayIterator", + TAG("$item.tag", {object: "$item.object"}), + SPAN({"class": "arrayComma", role : "presentation"}, "$item.delim") + ), + // TODO: xxxpedro - confirm this on Firebug + //FOR("prop", "$object|shortPropIterator", + // " $prop.name=", + // SPAN({"class": "objectPropValue"}, "$prop.value|cropString") + //), + SPAN({"class": "arrayRightBracket"}, "]") + ), + + arrayIterator: function(array) + { + var items = []; + for (var i = 0; i < array.length; ++i) + { + var value = array[i]; + var rep = Firebug.getRep(value); + var tag = rep.shortTag ? rep.shortTag : rep.tag; + var delim = (i == array.length-1 ? "" : ", "); + + items.push({object: value, tag: tag, delim: delim}); + } + + return items; + }, + + shortArrayIterator: function(array) + { + var items = []; + for (var i = 0; i < array.length && i < 3; ++i) + { + var value = array[i]; + var rep = Firebug.getRep(value); + var tag = rep.shortTag ? rep.shortTag : rep.tag; + var delim = (i == array.length-1 ? "" : ", "); + + items.push({object: value, tag: tag, delim: delim}); + } + + if (array.length > 3) + items.push({object: (array.length-3) + " more...", tag: FirebugReps.Caption.tag, delim: ""}); + + return items; + }, + + shortPropIterator: this.Obj.propIterator, + + getItemIndex: function(child) + { + var arrayIndex = 0; + for (child = child.previousSibling; child; child = child.previousSibling) + { + if (child.repObject) + ++arrayIndex; + } + return arrayIndex; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "array", + + supportsObject: function(object) + { + return this.isArray(object); + }, + + // http://code.google.com/p/fbug/issues/detail?id=874 + // BEGIN Yahoo BSD Source (modified here) YAHOO.lang.isArray, YUI 2.2.2 June 2007 + isArray: function(obj) { + try { + if (!obj) + return false; + else if (isIE && !isFunction(obj) && typeof obj == "object" && isFinite(obj.length) && obj.nodeType != 8) + return true; + else if (isFinite(obj.length) && isFunction(obj.splice)) + return true; + else if (isFinite(obj.length) && isFunction(obj.callee)) // arguments + return true; + else if (instanceOf(obj, "HTMLCollection")) + return true; + else if (instanceOf(obj, "NodeList")) + return true; + else + return false; + } + catch(exc) + { + if (FBTrace.DBG_ERRORS) + { + FBTrace.sysout("isArray FAILS:", exc); /* Something weird: without the try/catch, OOM, with no exception?? */ + FBTrace.sysout("isArray Fails on obj", obj); + } + } + + return false; + }, + // END Yahoo BSD SOURCE See license below. + + getTitle: function(object, context) + { + return "[" + object.length + "]"; + } +}); + +// ************************************************************************************************ + +this.Property = domplate(Firebug.Rep, +{ + supportsObject: function(object) + { + return object instanceof Property; + }, + + getRealObject: function(prop, context) + { + return prop.object[prop.name]; + }, + + getTitle: function(prop, context) + { + return prop.name; + } +}); + +// ************************************************************************************************ + +this.NetFile = domplate(this.Obj, +{ + supportsObject: function(object) + { + return object instanceof Firebug.NetFile; + }, + + browseObject: function(file, context) + { + openNewTab(file.href); + return true; + }, + + getRealObject: function(file, context) + { + return null; + } +}); + +// ************************************************************************************************ + +this.Except = domplate(Firebug.Rep, +{ + tag: + OBJECTBOX({_repObject: "$object"}, "$object.message"), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "exception", + + supportsObject: function(object) + { + return object instanceof ErrorCopy; + } +}); + + +// ************************************************************************************************ + +this.Element = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK( + "<", + SPAN({"class": "nodeTag"}, "$object.nodeName|toLowerCase"), + FOR("attr", "$object|attrIterator", + " $attr.nodeName="", SPAN({"class": "nodeValue"}, "$attr.nodeValue"), """ + ), + ">" + ), + + shortTag: + OBJECTLINK( + SPAN({"class": "$object|getVisible"}, + SPAN({"class": "selectorTag"}, "$object|getSelectorTag"), + SPAN({"class": "selectorId"}, "$object|getSelectorId"), + SPAN({"class": "selectorClass"}, "$object|getSelectorClass"), + SPAN({"class": "selectorValue"}, "$object|getValue") + ) + ), + + getVisible: function(elt) + { + return isVisible(elt) ? "" : "selectorHidden"; + }, + + getSelectorTag: function(elt) + { + return elt.nodeName.toLowerCase(); + }, + + getSelectorId: function(elt) + { + return elt.id ? "#" + elt.id : ""; + }, + + getSelectorClass: function(elt) + { + return elt.className ? "." + elt.className.split(" ")[0] : ""; + }, + + getValue: function(elt) + { + // TODO: xxxpedro + return ""; + var value; + if (elt instanceof HTMLImageElement) + value = getFileName(elt.src); + else if (elt instanceof HTMLAnchorElement) + value = getFileName(elt.href); + else if (elt instanceof HTMLInputElement) + value = elt.value; + else if (elt instanceof HTMLFormElement) + value = getFileName(elt.action); + else if (elt instanceof HTMLScriptElement) + value = getFileName(elt.src); + + return value ? " " + cropString(value, 20) : ""; + }, + + attrIterator: function(elt) + { + var attrs = []; + var idAttr, classAttr; + if (elt.attributes) + { + for (var i = 0; i < elt.attributes.length; ++i) + { + var attr = elt.attributes[i]; + if (attr.nodeName && attr.nodeName.indexOf("firebug-") != -1) + continue; + else if (attr.nodeName == "id") + idAttr = attr; + else if (attr.nodeName == "class") + classAttr = attr; + else + attrs.push(attr); + } + } + if (classAttr) + attrs.splice(0, 0, classAttr); + if (idAttr) + attrs.splice(0, 0, idAttr); + + return attrs; + }, + + shortAttrIterator: function(elt) + { + var attrs = []; + if (elt.attributes) + { + for (var i = 0; i < elt.attributes.length; ++i) + { + var attr = elt.attributes[i]; + if (attr.nodeName == "id" || attr.nodeName == "class") + attrs.push(attr); + } + } + + return attrs; + }, + + getHidden: function(elt) + { + return isVisible(elt) ? "" : "nodeHidden"; + }, + + getXPath: function(elt) + { + return getElementTreeXPath(elt); + }, + + // TODO: xxxpedro remove this? + getNodeText: function(element) + { + var text = element.textContent; + if (Firebug.showFullTextNodes) + return text; + else + return cropString(text, 50); + }, + /**/ + + getNodeTextGroups: function(element) + { + var text = element.textContent; + if (!Firebug.showFullTextNodes) + { + text=cropString(text,50); + } + + var escapeGroups=[]; + + if (Firebug.showTextNodesWithWhitespace) + escapeGroups.push({ + 'group': 'whitespace', + 'class': 'nodeWhiteSpace', + 'extra': { + '\t': '_Tab', + '\n': '_Para', + ' ' : '_Space' + } + }); + if (Firebug.showTextNodesWithEntities) + escapeGroups.push({ + 'group':'text', + 'class':'nodeTextEntity', + 'extra':{} + }); + + if (escapeGroups.length) + return escapeGroupsForEntities(text, escapeGroups); + else + return [{str:text,'class':'',extra:''}]; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + copyHTML: function(elt) + { + var html = getElementXML(elt); + copyToClipboard(html); + }, + + copyInnerHTML: function(elt) + { + copyToClipboard(elt.innerHTML); + }, + + copyXPath: function(elt) + { + var xpath = getElementXPath(elt); + copyToClipboard(xpath); + }, + + persistor: function(context, xpath) + { + var elts = xpath + ? getElementsByXPath(context.window.document, xpath) + : null; + + return elts && elts.length ? elts[0] : null; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "element", + + supportsObject: function(object) + { + //return object instanceof Element || object.nodeType == 1 && typeof object.nodeName == "string"; + return instanceOf(object, "Element"); + }, + + browseObject: function(elt, context) + { + var tag = elt.nodeName.toLowerCase(); + if (tag == "script") + openNewTab(elt.src); + else if (tag == "link") + openNewTab(elt.href); + else if (tag == "a") + openNewTab(elt.href); + else if (tag == "img") + openNewTab(elt.src); + + return true; + }, + + persistObject: function(elt, context) + { + var xpath = getElementXPath(elt); + + return bind(this.persistor, top, xpath); + }, + + getTitle: function(element, context) + { + return getElementCSSSelector(element); + }, + + getTooltip: function(elt) + { + return this.getXPath(elt); + }, + + getContextMenuItems: function(elt, target, context) + { + var monitored = areEventsMonitored(elt, null, context); + + return [ + {label: "CopyHTML", command: bindFixed(this.copyHTML, this, elt) }, + {label: "CopyInnerHTML", command: bindFixed(this.copyInnerHTML, this, elt) }, + {label: "CopyXPath", command: bindFixed(this.copyXPath, this, elt) }, + "-", + {label: "ShowEventsInConsole", type: "checkbox", checked: monitored, + command: bindFixed(toggleMonitorEvents, FBL, elt, null, monitored, context) }, + "-", + {label: "ScrollIntoView", command: bindFixed(elt.scrollIntoView, elt) } + ]; + } +}); + +// ************************************************************************************************ + +this.TextNode = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK( + "<", + SPAN({"class": "nodeTag"}, "TextNode"), + " textContent="", SPAN({"class": "nodeValue"}, "$object.textContent|cropString"), """, + ">" + ), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "textNode", + + supportsObject: function(object) + { + return object instanceof Text; + } +}); + +// ************************************************************************************************ + +this.Document = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK("Document ", SPAN({"class": "objectPropValue"}, "$object|getLocation")), + + getLocation: function(doc) + { + return doc.location ? getFileName(doc.location.href) : ""; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "object", + + supportsObject: function(object) + { + //return object instanceof Document || object instanceof XMLDocument; + return instanceOf(object, "Document"); + }, + + browseObject: function(doc, context) + { + openNewTab(doc.location.href); + return true; + }, + + persistObject: function(doc, context) + { + return this.persistor; + }, + + persistor: function(context) + { + return context.window.document; + }, + + getTitle: function(win, context) + { + return "document"; + }, + + getTooltip: function(doc) + { + return doc.location.href; + } +}); + +// ************************************************************************************************ + +this.StyleSheet = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK("StyleSheet ", SPAN({"class": "objectPropValue"}, "$object|getLocation")), + + getLocation: function(styleSheet) + { + return getFileName(styleSheet.href); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + copyURL: function(styleSheet) + { + copyToClipboard(styleSheet.href); + }, + + openInTab: function(styleSheet) + { + openNewTab(styleSheet.href); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "object", + + supportsObject: function(object) + { + //return object instanceof CSSStyleSheet; + return instanceOf(object, "CSSStyleSheet"); + }, + + browseObject: function(styleSheet, context) + { + openNewTab(styleSheet.href); + return true; + }, + + persistObject: function(styleSheet, context) + { + return bind(this.persistor, top, styleSheet.href); + }, + + getTooltip: function(styleSheet) + { + return styleSheet.href; + }, + + getContextMenuItems: function(styleSheet, target, context) + { + return [ + {label: "CopyLocation", command: bindFixed(this.copyURL, this, styleSheet) }, + "-", + {label: "OpenInTab", command: bindFixed(this.openInTab, this, styleSheet) } + ]; + }, + + persistor: function(context, href) + { + return getStyleSheetByHref(href, context); + } +}); + +// ************************************************************************************************ + +this.Window = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK("Window ", SPAN({"class": "objectPropValue"}, "$object|getLocation")), + + getLocation: function(win) + { + try + { + return (win && win.location && !win.closed) ? getFileName(win.location.href) : ""; + } + catch (exc) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("reps.Window window closed?"); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "object", + + supportsObject: function(object) + { + return instanceOf(object, "Window"); + }, + + browseObject: function(win, context) + { + openNewTab(win.location.href); + return true; + }, + + persistObject: function(win, context) + { + return this.persistor; + }, + + persistor: function(context) + { + return context.window; + }, + + getTitle: function(win, context) + { + return "window"; + }, + + getTooltip: function(win) + { + if (win && !win.closed) + return win.location.href; + } +}); + +// ************************************************************************************************ + +this.Event = domplate(Firebug.Rep, +{ + tag: TAG("$copyEventTag", {object: "$object|copyEvent"}), + + copyEventTag: + OBJECTLINK("$object|summarizeEvent"), + + summarizeEvent: function(event) + { + var info = [event.type, ' ']; + + var eventFamily = getEventFamily(event.type); + if (eventFamily == "mouse") + info.push("clientX=", event.clientX, ", clientY=", event.clientY); + else if (eventFamily == "key") + info.push("charCode=", event.charCode, ", keyCode=", event.keyCode); + + return info.join(""); + }, + + copyEvent: function(event) + { + return new EventCopy(event); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "object", + + supportsObject: function(object) + { + //return object instanceof Event || object instanceof EventCopy; + return instanceOf(object, "Event") || instanceOf(object, "EventCopy"); + }, + + getTitle: function(event, context) + { + return "Event " + event.type; + } +}); + +// ************************************************************************************************ + +this.SourceLink = domplate(Firebug.Rep, +{ + tag: + OBJECTLINK({$collapsed: "$object|hideSourceLink"}, "$object|getSourceLinkTitle"), + + hideSourceLink: function(sourceLink) + { + return sourceLink ? sourceLink.href.indexOf("XPCSafeJSObjectWrapper") != -1 : true; + }, + + getSourceLinkTitle: function(sourceLink) + { + if (!sourceLink) + return ""; + + try + { + var fileName = getFileName(sourceLink.href); + fileName = decodeURIComponent(fileName); + fileName = cropString(fileName, 17); + } + catch(exc) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("reps.getSourceLinkTitle decodeURIComponent fails for \'"+fileName+"\': "+exc, exc); + } + + return typeof sourceLink.line == "number" ? + fileName + " (line " + sourceLink.line + ")" : + fileName; + + // TODO: xxxpedro + //return $STRF("Line", [fileName, sourceLink.line]); + }, + + copyLink: function(sourceLink) + { + copyToClipboard(sourceLink.href); + }, + + openInTab: function(sourceLink) + { + openNewTab(sourceLink.href); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "sourceLink", + + supportsObject: function(object) + { + return object instanceof SourceLink; + }, + + getTooltip: function(sourceLink) + { + return decodeURI(sourceLink.href); + }, + + inspectObject: function(sourceLink, context) + { + if (sourceLink.type == "js") + { + var scriptFile = getSourceFileByHref(sourceLink.href, context); + if (scriptFile) + return Firebug.chrome.select(sourceLink); + } + else if (sourceLink.type == "css") + { + // If an object is defined, treat it as the highest priority for + // inspect actions + if (sourceLink.object) { + Firebug.chrome.select(sourceLink.object); + return; + } + + var stylesheet = getStyleSheetByHref(sourceLink.href, context); + if (stylesheet) + { + var ownerNode = stylesheet.ownerNode; + if (ownerNode) + { + Firebug.chrome.select(sourceLink, "html"); + return; + } + + var panel = context.getPanel("stylesheet"); + if (panel && panel.getRuleByLine(stylesheet, sourceLink.line)) + return Firebug.chrome.select(sourceLink); + } + } + + // Fallback is to just open the view-source window on the file + viewSource(sourceLink.href, sourceLink.line); + }, + + browseObject: function(sourceLink, context) + { + openNewTab(sourceLink.href); + return true; + }, + + getContextMenuItems: function(sourceLink, target, context) + { + return [ + {label: "CopyLocation", command: bindFixed(this.copyLink, this, sourceLink) }, + "-", + {label: "OpenInTab", command: bindFixed(this.openInTab, this, sourceLink) } + ]; + } +}); + +// ************************************************************************************************ + +this.SourceFile = domplate(this.SourceLink, +{ + tag: + OBJECTLINK({$collapsed: "$object|hideSourceLink"}, "$object|getSourceLinkTitle"), + + persistor: function(context, href) + { + return getSourceFileByHref(href, context); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "sourceFile", + + supportsObject: function(object) + { + return object instanceof SourceFile; + }, + + persistObject: function(sourceFile) + { + return bind(this.persistor, top, sourceFile.href); + }, + + browseObject: function(sourceLink, context) + { + }, + + getTooltip: function(sourceFile) + { + return sourceFile.href; + } +}); + +// ************************************************************************************************ + +this.StackFrame = domplate(Firebug.Rep, // XXXjjb Since the repObject is fn the stack does not have correct line numbers +{ + tag: + OBJECTBLOCK( + A({"class": "objectLink objectLink-function focusRow a11yFocus", _repObject: "$object.fn"}, "$object|getCallName"), + " ( ", + FOR("arg", "$object|argIterator", + TAG("$arg.tag", {object: "$arg.value"}), + SPAN({"class": "arrayComma"}, "$arg.delim") + ), + " )", + SPAN({"class": "objectLink-sourceLink objectLink"}, "$object|getSourceLinkTitle") + ), + + getCallName: function(frame) + { + //TODO: xxxpedro reps StackFrame + return frame.name || "anonymous"; + + //return getFunctionName(frame.script, frame.context); + }, + + getSourceLinkTitle: function(frame) + { + //TODO: xxxpedro reps StackFrame + var fileName = cropString(getFileName(frame.href), 20); + return fileName + (frame.lineNo ? " (line " + frame.lineNo + ")" : ""); + + var fileName = cropString(getFileName(frame.href), 17); + return $STRF("Line", [fileName, frame.lineNo]); + }, + + argIterator: function(frame) + { + if (!frame.args) + return []; + + var items = []; + + for (var i = 0; i < frame.args.length; ++i) + { + var arg = frame.args[i]; + + if (!arg) + break; + + var rep = Firebug.getRep(arg.value); + var tag = rep.shortTag ? rep.shortTag : rep.tag; + + var delim = (i == frame.args.length-1 ? "" : ", "); + + items.push({name: arg.name, value: arg.value, tag: tag, delim: delim}); + } + + return items; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "stackFrame", + + supportsObject: function(object) + { + return object instanceof StackFrame; + }, + + inspectObject: function(stackFrame, context) + { + var sourceLink = new SourceLink(stackFrame.href, stackFrame.lineNo, "js"); + Firebug.chrome.select(sourceLink); + }, + + getTooltip: function(stackFrame, context) + { + return $STRF("Line", [stackFrame.href, stackFrame.lineNo]); + } + +}); + +// ************************************************************************************************ + +this.StackTrace = domplate(Firebug.Rep, +{ + tag: + FOR("frame", "$object.frames focusRow", + TAG(this.StackFrame.tag, {object: "$frame"}) + ), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "stackTrace", + + supportsObject: function(object) + { + return object instanceof StackTrace; + } +}); + +// ************************************************************************************************ + +this.jsdStackFrame = domplate(Firebug.Rep, +{ + inspectable: false, + + supportsObject: function(object) + { + return (object instanceof jsdIStackFrame) && (object.isValid); + }, + + getTitle: function(frame, context) + { + if (!frame.isValid) return "(invalid frame)"; // XXXjjb avoid frame.script == null + return getFunctionName(frame.script, context); + }, + + getTooltip: function(frame, context) + { + if (!frame.isValid) return "(invalid frame)"; // XXXjjb avoid frame.script == null + var sourceInfo = FBL.getSourceFileAndLineByScript(context, frame.script, frame); + if (sourceInfo) + return $STRF("Line", [sourceInfo.sourceFile.href, sourceInfo.lineNo]); + else + return $STRF("Line", [frame.script.fileName, frame.line]); + }, + + getContextMenuItems: function(frame, target, context) + { + var fn = frame.script.functionObject.getWrappedValue(); + return FirebugReps.Func.getContextMenuItems(fn, target, context, frame.script); + } +}); + +// ************************************************************************************************ + +this.ErrorMessage = domplate(Firebug.Rep, +{ + tag: + OBJECTBOX({ + $hasTwisty: "$object|hasStackTrace", + $hasBreakSwitch: "$object|hasBreakSwitch", + $breakForError: "$object|hasErrorBreak", + _repObject: "$object", + _stackTrace: "$object|getLastErrorStackTrace", + onclick: "$onToggleError"}, + + DIV({"class": "errorTitle a11yFocus", role : 'checkbox', 'aria-checked' : 'false'}, + "$object.message|getMessage" + ), + DIV({"class": "errorTrace"}), + DIV({"class": "errorSourceBox errorSource-$object|getSourceType"}, + IMG({"class": "errorBreak a11yFocus", src:"blank.gif", role : 'checkbox', 'aria-checked':'false', title: "Break on this error"}), + A({"class": "errorSource a11yFocus"}, "$object|getLine") + ), + TAG(this.SourceLink.tag, {object: "$object|getSourceLink"}) + ), + + getLastErrorStackTrace: function(error) + { + return error.trace; + }, + + hasStackTrace: function(error) + { + var url = error.href.toString(); + var fromCommandLine = (url.indexOf("XPCSafeJSObjectWrapper") != -1); + return !fromCommandLine && error.trace; + }, + + hasBreakSwitch: function(error) + { + return error.href && error.lineNo > 0; + }, + + hasErrorBreak: function(error) + { + return fbs.hasErrorBreakpoint(error.href, error.lineNo); + }, + + getMessage: function(message) + { + var re = /\[Exception... "(.*?)" nsresult:/; + var m = re.exec(message); + return m ? m[1] : message; + }, + + getLine: function(error) + { + if (error.category == "js") + { + if (error.source) + return cropString(error.source, 80); + else if (error.href && error.href.indexOf("XPCSafeJSObjectWrapper") == -1) + return cropString(error.getSourceLine(), 80); + } + }, + + getSourceLink: function(error) + { + var ext = error.category == "css" ? "css" : "js"; + return error.lineNo ? new SourceLink(error.href, error.lineNo, ext) : null; + }, + + getSourceType: function(error) + { + // Errors occurring inside of HTML event handlers look like "foo.html (line 1)" + // so let's try to skip those + if (error.source) + return "syntax"; + else if (error.lineNo == 1 && getFileExtension(error.href) != "js") + return "none"; + else if (error.category == "css") + return "none"; + else if (!error.href || !error.lineNo) + return "none"; + else + return "exec"; + }, + + onToggleError: function(event) + { + var target = event.currentTarget; + if (hasClass(event.target, "errorBreak")) + { + this.breakOnThisError(target.repObject); + } + else if (hasClass(event.target, "errorSource")) + { + var panel = Firebug.getElementPanel(event.target); + this.inspectObject(target.repObject, panel.context); + } + else if (hasClass(event.target, "errorTitle")) + { + var traceBox = target.childNodes[1]; + toggleClass(target, "opened"); + event.target.setAttribute('aria-checked', hasClass(target, "opened")); + if (hasClass(target, "opened")) + { + if (target.stackTrace) + var node = FirebugReps.StackTrace.tag.append({object: target.stackTrace}, traceBox); + if (Firebug.A11yModel.enabled) + { + var panel = Firebug.getElementPanel(event.target); + dispatch([Firebug.A11yModel], "onLogRowContentCreated", [panel , traceBox]); + } + } + else + clearNode(traceBox); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + copyError: function(error) + { + var message = [ + this.getMessage(error.message), + error.href, + "Line " + error.lineNo + ]; + copyToClipboard(message.join("\n")); + }, + + breakOnThisError: function(error) + { + if (this.hasErrorBreak(error)) + Firebug.Debugger.clearErrorBreakpoint(error.href, error.lineNo); + else + Firebug.Debugger.setErrorBreakpoint(error.href, error.lineNo); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "errorMessage", + inspectable: false, + + supportsObject: function(object) + { + return object instanceof ErrorMessage; + }, + + inspectObject: function(error, context) + { + var sourceLink = this.getSourceLink(error); + FirebugReps.SourceLink.inspectObject(sourceLink, context); + }, + + getContextMenuItems: function(error, target, context) + { + var breakOnThisError = this.hasErrorBreak(error); + + var items = [ + {label: "CopyError", command: bindFixed(this.copyError, this, error) } + ]; + + if (error.category == "css") + { + items.push( + "-", + {label: "BreakOnThisError", type: "checkbox", checked: breakOnThisError, + command: bindFixed(this.breakOnThisError, this, error) }, + + optionMenu("BreakOnAllErrors", "breakOnErrors") + ); + } + + return items; + } +}); + +// ************************************************************************************************ + +this.Assert = domplate(Firebug.Rep, +{ + tag: + DIV( + DIV({"class": "errorTitle"}), + DIV({"class": "assertDescription"}) + ), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "assert", + + inspectObject: function(error, context) + { + var sourceLink = this.getSourceLink(error); + Firebug.chrome.select(sourceLink); + }, + + getContextMenuItems: function(error, target, context) + { + var breakOnThisError = this.hasErrorBreak(error); + + return [ + {label: "CopyError", command: bindFixed(this.copyError, this, error) }, + "-", + {label: "BreakOnThisError", type: "checkbox", checked: breakOnThisError, + command: bindFixed(this.breakOnThisError, this, error) }, + {label: "BreakOnAllErrors", type: "checkbox", checked: Firebug.breakOnErrors, + command: bindFixed(this.breakOnAllErrors, this, error) } + ]; + } +}); + +// ************************************************************************************************ + +this.SourceText = domplate(Firebug.Rep, +{ + tag: + DIV( + FOR("line", "$object|lineIterator", + DIV({"class": "sourceRow", role : "presentation"}, + SPAN({"class": "sourceLine", role : "presentation"}, "$line.lineNo"), + SPAN({"class": "sourceRowText", role : "presentation"}, "$line.text") + ) + ) + ), + + lineIterator: function(sourceText) + { + var maxLineNoChars = (sourceText.lines.length + "").length; + var list = []; + + for (var i = 0; i < sourceText.lines.length; ++i) + { + // Make sure all line numbers are the same width (with a fixed-width font) + var lineNo = (i+1) + ""; + while (lineNo.length < maxLineNoChars) + lineNo = " " + lineNo; + + list.push({lineNo: lineNo, text: sourceText.lines[i]}); + } + + return list; + }, + + getHTML: function(sourceText) + { + return getSourceLineRange(sourceText, 1, sourceText.lines.length); + } +}); + +//************************************************************************************************ +this.nsIDOMHistory = domplate(Firebug.Rep, +{ + tag:OBJECTBOX({onclick: "$showHistory"}, + OBJECTLINK("$object|summarizeHistory") + ), + + className: "nsIDOMHistory", + + summarizeHistory: function(history) + { + try + { + var items = history.length; + return items + " history entries"; + } + catch(exc) + { + return "object does not support history (nsIDOMHistory)"; + } + }, + + showHistory: function(history) + { + try + { + var items = history.length; // if this throws, then unsupported + Firebug.chrome.select(history); + } + catch (exc) + { + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + supportsObject: function(object, type) + { + return (object instanceof Ci.nsIDOMHistory); + } +}); + +// ************************************************************************************************ +this.ApplicationCache = domplate(Firebug.Rep, +{ + tag:OBJECTBOX({onclick: "$showApplicationCache"}, + OBJECTLINK("$object|summarizeCache") + ), + + summarizeCache: function(applicationCache) + { + try + { + return applicationCache.length + " items in offline cache"; + } + catch(exc) + { + return "https://bugzilla.mozilla.org/show_bug.cgi?id=422264"; + } + }, + + showApplicationCache: function(event) + { + openNewTab("https://bugzilla.mozilla.org/show_bug.cgi?id=422264"); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "applicationCache", + + supportsObject: function(object, type) + { + if (Ci.nsIDOMOfflineResourceList) + return (object instanceof Ci.nsIDOMOfflineResourceList); + } + +}); + +this.Storage = domplate(Firebug.Rep, +{ + tag: OBJECTBOX({onclick: "$show"}, OBJECTLINK("$object|summarize")), + + summarize: function(storage) + { + return storage.length +" items in Storage"; + }, + show: function(storage) + { + openNewTab("http://dev.w3.org/html5/webstorage/#storage-0"); + }, + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + className: "Storage", + + supportsObject: function(object, type) + { + return (object instanceof Storage); + } + +}); + +// ************************************************************************************************ +Firebug.registerRep( + //this.nsIDOMHistory, // make this early to avoid exceptions + this.Undefined, + this.Null, + this.Number, + this.String, + this.Window, + //this.ApplicationCache, // must come before Arr (array) else exceptions. + //this.ErrorMessage, + this.Element, + //this.TextNode, + this.Document, + this.StyleSheet, + this.Event, + //this.SourceLink, + //this.SourceFile, + //this.StackTrace, + //this.StackFrame, + //this.jsdStackFrame, + //this.jsdScript, + //this.NetFile, + this.Property, + this.Except, + this.Arr +); + +Firebug.setDefaultReps(this.Func, this.Obj); + +}}); + +// ************************************************************************************************ +/* + * The following is http://developer.yahoo.com/yui/license.txt and applies to only code labeled "Yahoo BSD Source" + * in only this file reps.js. John J. Barton June 2007. + * +Software License Agreement (BSD License) + +Copyright (c) 2006, Yahoo! Inc. +All rights reserved. + +Redistribution and use of this software in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of Yahoo! Inc. nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of Yahoo! Inc. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * / + */ + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// Constants + +var saveTimeout = 400; +var pageAmount = 10; + +// ************************************************************************************************ +// Globals + +var currentTarget = null; +var currentGroup = null; +var currentPanel = null; +var currentEditor = null; + +var defaultEditor = null; + +var originalClassName = null; + +var originalValue = null; +var defaultValue = null; +var previousValue = null; + +var invalidEditor = false; +var ignoreNextInput = false; + +// ************************************************************************************************ + +Firebug.Editor = extend(Firebug.Module, +{ + supportsStopEvent: true, + + dispatchName: "editor", + tabCharacter: " ", + + startEditing: function(target, value, editor) + { + this.stopEditing(); + + if (hasClass(target, "insertBefore") || hasClass(target, "insertAfter")) + return; + + var panel = Firebug.getElementPanel(target); + if (!panel.editable) + return; + + if (FBTrace.DBG_EDITOR) + FBTrace.sysout("editor.startEditing " + value, target); + + defaultValue = target.getAttribute("defaultValue"); + if (value == undefined) + { + var textContent = isIE ? "innerText" : "textContent"; + value = target[textContent]; + if (value == defaultValue) + value = ""; + } + + originalValue = previousValue = value; + + invalidEditor = false; + currentTarget = target; + currentPanel = panel; + currentGroup = getAncestorByClass(target, "editGroup"); + + currentPanel.editing = true; + + var panelEditor = currentPanel.getEditor(target, value); + currentEditor = editor ? editor : panelEditor; + if (!currentEditor) + currentEditor = getDefaultEditor(currentPanel); + + var inlineParent = getInlineParent(target); + var targetSize = getOffsetSize(inlineParent); + + setClass(panel.panelNode, "editing"); + setClass(target, "editing"); + if (currentGroup) + setClass(currentGroup, "editing"); + + currentEditor.show(target, currentPanel, value, targetSize); + //dispatch(this.fbListeners, "onBeginEditing", [currentPanel, currentEditor, target, value]); + currentEditor.beginEditing(target, value); + if (FBTrace.DBG_EDITOR) + FBTrace.sysout("Editor start panel "+currentPanel.name); + this.attachListeners(currentEditor, panel.context); + }, + + stopEditing: function(cancel) + { + if (!currentTarget) + return; + + if (FBTrace.DBG_EDITOR) + FBTrace.sysout("editor.stopEditing cancel:" + cancel+" saveTimeout: "+this.saveTimeout); + + clearTimeout(this.saveTimeout); + delete this.saveTimeout; + + this.detachListeners(currentEditor, currentPanel.context); + + removeClass(currentPanel.panelNode, "editing"); + removeClass(currentTarget, "editing"); + if (currentGroup) + removeClass(currentGroup, "editing"); + + var value = currentEditor.getValue(); + if (value == defaultValue) + value = ""; + + var removeGroup = currentEditor.endEditing(currentTarget, value, cancel); + + try + { + if (cancel) + { + //dispatch([Firebug.A11yModel], 'onInlineEditorClose', [currentPanel, currentTarget, removeGroup && !originalValue]); + if (value != originalValue) + this.saveEditAndNotifyListeners(currentTarget, originalValue, previousValue); + + if (removeGroup && !originalValue && currentGroup) + currentGroup.parentNode.removeChild(currentGroup); + } + else if (!value) + { + this.saveEditAndNotifyListeners(currentTarget, null, previousValue); + + if (removeGroup && currentGroup) + currentGroup.parentNode.removeChild(currentGroup); + } + else + this.save(value); + } + catch (exc) + { + //throw exc.message; + //ERROR(exc); + } + + currentEditor.hide(); + currentPanel.editing = false; + + //dispatch(this.fbListeners, "onStopEdit", [currentPanel, currentEditor, currentTarget]); + //if (FBTrace.DBG_EDITOR) + // FBTrace.sysout("Editor stop panel "+currentPanel.name); + + currentTarget = null; + currentGroup = null; + currentPanel = null; + currentEditor = null; + originalValue = null; + invalidEditor = false; + + return value; + }, + + cancelEditing: function() + { + return this.stopEditing(true); + }, + + update: function(saveNow) + { + if (this.saveTimeout) + clearTimeout(this.saveTimeout); + + invalidEditor = true; + + currentEditor.layout(); + + if (saveNow) + this.save(); + else + { + var context = currentPanel.context; + this.saveTimeout = context.setTimeout(bindFixed(this.save, this), saveTimeout); + if (FBTrace.DBG_EDITOR) + FBTrace.sysout("editor.update saveTimeout: "+this.saveTimeout); + } + }, + + save: function(value) + { + if (!invalidEditor) + return; + + if (value == undefined) + value = currentEditor.getValue(); + if (FBTrace.DBG_EDITOR) + FBTrace.sysout("editor.save saveTimeout: "+this.saveTimeout+" currentPanel: "+(currentPanel?currentPanel.name:"null")); + try + { + this.saveEditAndNotifyListeners(currentTarget, value, previousValue); + + previousValue = value; + invalidEditor = false; + } + catch (exc) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("editor.save FAILS "+exc, exc); + } + }, + + saveEditAndNotifyListeners: function(currentTarget, value, previousValue) + { + currentEditor.saveEdit(currentTarget, value, previousValue); + //dispatch(this.fbListeners, "onSaveEdit", [currentPanel, currentEditor, currentTarget, value, previousValue]); + }, + + setEditTarget: function(element) + { + if (!element) + { + dispatch([Firebug.A11yModel], 'onInlineEditorClose', [currentPanel, currentTarget, true]); + this.stopEditing(); + } + else if (hasClass(element, "insertBefore")) + this.insertRow(element, "before"); + else if (hasClass(element, "insertAfter")) + this.insertRow(element, "after"); + else + this.startEditing(element); + }, + + tabNextEditor: function() + { + if (!currentTarget) + return; + + var value = currentEditor.getValue(); + var nextEditable = currentTarget; + do + { + nextEditable = !value && currentGroup + ? getNextOutsider(nextEditable, currentGroup) + : getNextByClass(nextEditable, "editable"); + } + while (nextEditable && !nextEditable.offsetHeight); + + this.setEditTarget(nextEditable); + }, + + tabPreviousEditor: function() + { + if (!currentTarget) + return; + + var value = currentEditor.getValue(); + var prevEditable = currentTarget; + do + { + prevEditable = !value && currentGroup + ? getPreviousOutsider(prevEditable, currentGroup) + : getPreviousByClass(prevEditable, "editable"); + } + while (prevEditable && !prevEditable.offsetHeight); + + this.setEditTarget(prevEditable); + }, + + insertRow: function(relative, insertWhere) + { + var group = + relative || getAncestorByClass(currentTarget, "editGroup") || currentTarget; + var value = this.stopEditing(); + + currentPanel = Firebug.getElementPanel(group); + + currentEditor = currentPanel.getEditor(group, value); + if (!currentEditor) + currentEditor = getDefaultEditor(currentPanel); + + currentGroup = currentEditor.insertNewRow(group, insertWhere); + if (!currentGroup) + return; + + var editable = hasClass(currentGroup, "editable") + ? currentGroup + : getNextByClass(currentGroup, "editable"); + + if (editable) + this.setEditTarget(editable); + }, + + insertRowForObject: function(relative) + { + var container = getAncestorByClass(relative, "insertInto"); + if (container) + { + relative = getChildByClass(container, "insertBefore"); + if (relative) + this.insertRow(relative, "before"); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + attachListeners: function(editor, context) + { + var win = isIE ? + currentTarget.ownerDocument.parentWindow : + currentTarget.ownerDocument.defaultView; + + addEvent(win, "resize", this.onResize); + addEvent(win, "blur", this.onBlur); + + var chrome = Firebug.chrome; + + this.listeners = [ + chrome.keyCodeListen("ESCAPE", null, bind(this.cancelEditing, this)) + ]; + + if (editor.arrowCompletion) + { + this.listeners.push( + chrome.keyCodeListen("UP", null, bindFixed(editor.completeValue, editor, -1)), + chrome.keyCodeListen("DOWN", null, bindFixed(editor.completeValue, editor, 1)), + chrome.keyCodeListen("PAGE_UP", null, bindFixed(editor.completeValue, editor, -pageAmount)), + chrome.keyCodeListen("PAGE_DOWN", null, bindFixed(editor.completeValue, editor, pageAmount)) + ); + } + + if (currentEditor.tabNavigation) + { + this.listeners.push( + chrome.keyCodeListen("RETURN", null, bind(this.tabNextEditor, this)), + chrome.keyCodeListen("RETURN", isControl, bind(this.insertRow, this, null, "after")), + chrome.keyCodeListen("TAB", null, bind(this.tabNextEditor, this)), + chrome.keyCodeListen("TAB", isShift, bind(this.tabPreviousEditor, this)) + ); + } + else if (currentEditor.multiLine) + { + this.listeners.push( + chrome.keyCodeListen("TAB", null, insertTab) + ); + } + else + { + this.listeners.push( + chrome.keyCodeListen("RETURN", null, bindFixed(this.stopEditing, this)) + ); + + if (currentEditor.tabCompletion) + { + this.listeners.push( + chrome.keyCodeListen("TAB", null, bind(editor.completeValue, editor, 1)), + chrome.keyCodeListen("TAB", isShift, bind(editor.completeValue, editor, -1)) + ); + } + } + }, + + detachListeners: function(editor, context) + { + if (!this.listeners) + return; + + var win = isIE ? + currentTarget.ownerDocument.parentWindow : + currentTarget.ownerDocument.defaultView; + + removeEvent(win, "resize", this.onResize); + removeEvent(win, "blur", this.onBlur); + + var chrome = Firebug.chrome; + if (chrome) + { + for (var i = 0; i < this.listeners.length; ++i) + chrome.keyIgnore(this.listeners[i]); + } + + delete this.listeners; + }, + + onResize: function(event) + { + currentEditor.layout(true); + }, + + onBlur: function(event) + { + if (currentEditor.enterOnBlur && isAncestor(event.target, currentEditor.box)) + this.stopEditing(); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Module + + initialize: function() + { + Firebug.Module.initialize.apply(this, arguments); + + this.onResize = bindFixed(this.onResize, this); + this.onBlur = bind(this.onBlur, this); + }, + + disable: function() + { + this.stopEditing(); + }, + + showContext: function(browser, context) + { + this.stopEditing(); + }, + + showPanel: function(browser, panel) + { + this.stopEditing(); + } +}); + +// ************************************************************************************************ +// BaseEditor + +Firebug.BaseEditor = extend(Firebug.MeasureBox, +{ + getValue: function() + { + }, + + setValue: function(value) + { + }, + + show: function(target, panel, value, textSize, targetSize) + { + }, + + hide: function() + { + }, + + layout: function(forceAll) + { + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Support for context menus within inline editors. + + getContextMenuItems: function(target) + { + var items = []; + items.push({label: "Cut", commandID: "cmd_cut"}); + items.push({label: "Copy", commandID: "cmd_copy"}); + items.push({label: "Paste", commandID: "cmd_paste"}); + return items; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Editor Module listeners will get "onBeginEditing" just before this call + + beginEditing: function(target, value) + { + }, + + // Editor Module listeners will get "onSaveEdit" just after this call + saveEdit: function(target, value, previousValue) + { + }, + + endEditing: function(target, value, cancel) + { + // Remove empty groups by default + return true; + }, + + insertNewRow: function(target, insertWhere) + { + } +}); + +// ************************************************************************************************ +// InlineEditor + +// basic inline editor attributes +var inlineEditorAttributes = { + "class": "textEditorInner", + + type: "text", + spellcheck: "false", + + onkeypress: "$onKeyPress", + + onoverflow: "$onOverflow", + oncontextmenu: "$onContextMenu" +}; + +// IE does not support the oninput event, so we're using the onkeydown to signalize +// the relevant keyboard events, and the onpropertychange to actually handle the +// input event, which should happen after the onkeydown event is fired and after the +// value of the input is updated, but before the onkeyup and before the input (with the +// new value) is rendered +if (isIE) +{ + inlineEditorAttributes.onpropertychange = "$onInput"; + inlineEditorAttributes.onkeydown = "$onKeyDown"; +} +// for other browsers we use the oninput event +else +{ + inlineEditorAttributes.oninput = "$onInput"; +} + +Firebug.InlineEditor = function(doc) +{ + this.initializeInline(doc); +}; + +Firebug.InlineEditor.prototype = domplate(Firebug.BaseEditor, +{ + enterOnBlur: true, + outerMargin: 8, + shadowExpand: 7, + + tag: + DIV({"class": "inlineEditor"}, + DIV({"class": "textEditorTop1"}, + DIV({"class": "textEditorTop2"}) + ), + DIV({"class": "textEditorInner1"}, + DIV({"class": "textEditorInner2"}, + INPUT( + inlineEditorAttributes + ) + ) + ), + DIV({"class": "textEditorBottom1"}, + DIV({"class": "textEditorBottom2"}) + ) + ), + + inputTag : + INPUT({"class": "textEditorInner", type: "text", + /*oninput: "$onInput",*/ onkeypress: "$onKeyPress", onoverflow: "$onOverflow"} + ), + + expanderTag: + IMG({"class": "inlineExpander", src: "blank.gif"}), + + initialize: function() + { + this.fixedWidth = false; + this.completeAsYouType = true; + this.tabNavigation = true; + this.multiLine = false; + this.tabCompletion = false; + this.arrowCompletion = true; + this.noWrap = true; + this.numeric = false; + }, + + destroy: function() + { + this.destroyInput(); + }, + + initializeInline: function(doc) + { + if (FBTrace.DBG_EDITOR) + FBTrace.sysout("Firebug.InlineEditor initializeInline()"); + + //this.box = this.tag.replace({}, doc, this); + this.box = this.tag.append({}, doc.body, this); + + //this.input = this.box.childNodes[1].firstChild.firstChild; // XXXjjb childNode[1] required + this.input = this.box.getElementsByTagName("input")[0]; + + if (isIElt8) + { + this.input.style.top = "-8px"; + } + + this.expander = this.expanderTag.replace({}, doc, this); + this.initialize(); + }, + + destroyInput: function() + { + // XXXjoe Need to remove input/keypress handlers to avoid leaks + }, + + getValue: function() + { + return this.input.value; + }, + + setValue: function(value) + { + // It's only a one-line editor, so new lines shouldn't be allowed + return this.input.value = stripNewLines(value); + }, + + show: function(target, panel, value, targetSize) + { + //dispatch([Firebug.A11yModel], "onInlineEditorShow", [panel, this]); + this.target = target; + this.panel = panel; + + this.targetSize = targetSize; + + // TODO: xxxpedro editor + //this.targetOffset = getClientOffset(target); + + // Some browsers (IE, Google Chrome and Safari) will have problem trying to get the + // offset values of invisible elements, or empty elements. So, in order to get the + // correct values, we temporary inject a character in the innerHTML of the empty element, + // then we get the offset values, and next, we restore the original innerHTML value. + var innerHTML = target.innerHTML; + var isEmptyElement = !innerHTML; + if (isEmptyElement) + target.innerHTML = "."; + + // Get the position of the target element (that is about to be edited) + this.targetOffset = + { + x: target.offsetLeft, + y: target.offsetTop + }; + + // Restore the original innerHTML value of the empty element + if (isEmptyElement) + target.innerHTML = innerHTML; + + this.originalClassName = this.box.className; + + var classNames = target.className.split(" "); + for (var i = 0; i < classNames.length; ++i) + setClass(this.box, "editor-" + classNames[i]); + + // Make the editor match the target's font style + copyTextStyles(target, this.box); + + this.setValue(value); + + if (this.fixedWidth) + this.updateLayout(true); + else + { + this.startMeasuring(target); + this.textSize = this.measureInputText(value); + + // Correct the height of the box to make the funky CSS drop-shadow line up + var parent = this.input.parentNode; + if (hasClass(parent, "textEditorInner2")) + { + var yDiff = this.textSize.height - this.shadowExpand; + + // IE6 height offset + if (isIE6) + yDiff -= 2; + + parent.style.height = yDiff + "px"; + parent.parentNode.style.height = yDiff + "px"; + } + + this.updateLayout(true); + } + + this.getAutoCompleter().reset(); + + if (isIElt8) + panel.panelNode.appendChild(this.box); + else + target.offsetParent.appendChild(this.box); + + //console.log(target); + //this.input.select(); // it's called bellow, with setTimeout + + if (isIE) + { + // reset input style + this.input.style.fontFamily = "Monospace"; + this.input.style.fontSize = "11px"; + } + + // Insert the "expander" to cover the target element with white space + if (!this.fixedWidth) + { + copyBoxStyles(target, this.expander); + + target.parentNode.replaceChild(this.expander, target); + collapse(target, true); + this.expander.parentNode.insertBefore(target, this.expander); + } + + //TODO: xxxpedro + //scrollIntoCenterView(this.box, null, true); + + // Display the editor after change its size and position to avoid flickering + this.box.style.display = "block"; + + // we need to call input.focus() and input.select() with a timeout, + // otherwise it won't work on all browsers due to timing issues + var self = this; + setTimeout(function(){ + self.input.focus(); + self.input.select(); + },0); + }, + + hide: function() + { + this.box.className = this.originalClassName; + + if (!this.fixedWidth) + { + this.stopMeasuring(); + + collapse(this.target, false); + + if (this.expander.parentNode) + this.expander.parentNode.removeChild(this.expander); + } + + if (this.box.parentNode) + { + ///setSelectionRange(this.input, 0, 0); + this.input.blur(); + + this.box.parentNode.removeChild(this.box); + } + + delete this.target; + delete this.panel; + }, + + layout: function(forceAll) + { + if (!this.fixedWidth) + this.textSize = this.measureInputText(this.input.value); + + if (forceAll) + this.targetOffset = getClientOffset(this.expander); + + this.updateLayout(false, forceAll); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + beginEditing: function(target, value) + { + }, + + saveEdit: function(target, value, previousValue) + { + }, + + endEditing: function(target, value, cancel) + { + // Remove empty groups by default + return true; + }, + + insertNewRow: function(target, insertWhere) + { + }, + + advanceToNext: function(target, charCode) + { + return false; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getAutoCompleteRange: function(value, offset) + { + }, + + getAutoCompleteList: function(preExpr, expr, postExpr) + { + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getAutoCompleter: function() + { + if (!this.autoCompleter) + { + this.autoCompleter = new Firebug.AutoCompleter(null, + bind(this.getAutoCompleteRange, this), bind(this.getAutoCompleteList, this), + true, false); + } + + return this.autoCompleter; + }, + + completeValue: function(amt) + { + //console.log("completeValue"); + + var selectRangeCallback = this.getAutoCompleter().complete(currentPanel.context, this.input, true, amt < 0); + + if (selectRangeCallback) + { + Firebug.Editor.update(true); + + // We need to select the editor text after calling update in Safari/Chrome, + // otherwise the text won't be selected + if (isSafari) + setTimeout(selectRangeCallback,0); + else + selectRangeCallback(); + } + else + this.incrementValue(amt); + }, + + incrementValue: function(amt) + { + var value = this.input.value; + + // TODO: xxxpedro editor + if (isIE) + var start = getInputSelectionStart(this.input), end = start; + else + var start = this.input.selectionStart, end = this.input.selectionEnd; + + //debugger; + var range = this.getAutoCompleteRange(value, start); + if (!range || range.type != "int") + range = {start: 0, end: value.length-1}; + + var expr = value.substr(range.start, range.end-range.start+1); + preExpr = value.substr(0, range.start); + postExpr = value.substr(range.end+1); + + // See if the value is an integer, and if so increment it + var intValue = parseInt(expr); + if (!!intValue || intValue == 0) + { + var m = /\d+/.exec(expr); + var digitPost = expr.substr(m.index+m[0].length); + + var completion = intValue-amt; + this.input.value = preExpr + completion + digitPost + postExpr; + + setSelectionRange(this.input, start, end); + + Firebug.Editor.update(true); + + return true; + } + else + return false; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + onKeyPress: function(event) + { + //console.log("onKeyPress", event); + if (event.keyCode == 27 && !this.completeAsYouType) + { + var reverted = this.getAutoCompleter().revert(this.input); + if (reverted) + cancelEvent(event); + } + else if (event.charCode && this.advanceToNext(this.target, event.charCode)) + { + Firebug.Editor.tabNextEditor(); + cancelEvent(event); + } + else + { + if (this.numeric && event.charCode && (event.charCode < 48 || event.charCode > 57) + && event.charCode != 45 && event.charCode != 46) + FBL.cancelEvent(event); + else + { + // If the user backspaces, don't autocomplete after the upcoming input event + this.ignoreNextInput = event.keyCode == 8; + } + } + }, + + onOverflow: function() + { + this.updateLayout(false, false, 3); + }, + + onKeyDown: function(event) + { + //console.log("onKeyDown", event.keyCode); + if (event.keyCode > 46 || event.keyCode == 32 || event.keyCode == 8) + { + this.keyDownPressed = true; + } + }, + + onInput: function(event) + { + //debugger; + + // skip not relevant onpropertychange calls on IE + if (isIE) + { + if (event.propertyName != "value" || !isVisible(this.input) || !this.keyDownPressed) + return; + + this.keyDownPressed = false; + } + + //console.log("onInput", event); + //console.trace(); + + var selectRangeCallback; + + if (this.ignoreNextInput) + { + this.ignoreNextInput = false; + this.getAutoCompleter().reset(); + } + else if (this.completeAsYouType) + selectRangeCallback = this.getAutoCompleter().complete(currentPanel.context, this.input, false); + else + this.getAutoCompleter().reset(); + + Firebug.Editor.update(); + + if (selectRangeCallback) + { + // We need to select the editor text after calling update in Safari/Chrome, + // otherwise the text won't be selected + if (isSafari) + setTimeout(selectRangeCallback,0); + else + selectRangeCallback(); + } + }, + + onContextMenu: function(event) + { + cancelEvent(event); + + var popup = $("fbInlineEditorPopup"); + FBL.eraseNode(popup); + + var target = event.target || event.srcElement; + var menu = this.getContextMenuItems(target); + if (menu) + { + for (var i = 0; i < menu.length; ++i) + FBL.createMenuItem(popup, menu[i]); + } + + if (!popup.firstChild) + return false; + + popup.openPopupAtScreen(event.screenX, event.screenY, true); + return true; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + updateLayout: function(initial, forceAll, extraWidth) + { + if (this.fixedWidth) + { + this.box.style.left = (this.targetOffset.x) + "px"; + this.box.style.top = (this.targetOffset.y) + "px"; + + var w = this.target.offsetWidth; + var h = this.target.offsetHeight; + this.input.style.width = w + "px"; + this.input.style.height = (h-3) + "px"; + } + else + { + if (initial || forceAll) + { + this.box.style.left = this.targetOffset.x + "px"; + this.box.style.top = this.targetOffset.y + "px"; + } + + var approxTextWidth = this.textSize.width; + var maxWidth = (currentPanel.panelNode.scrollWidth - this.targetOffset.x) + - this.outerMargin; + + var wrapped = initial + ? this.noWrap && this.targetSize.height > this.textSize.height+3 + : this.noWrap && approxTextWidth > maxWidth; + + if (wrapped) + { + var style = isIE ? + this.target.currentStyle : + this.target.ownerDocument.defaultView.getComputedStyle(this.target, ""); + + targetMargin = parseInt(style.marginLeft) + parseInt(style.marginRight); + + // Make the width fit the remaining x-space from the offset to the far right + approxTextWidth = maxWidth - targetMargin; + + this.input.style.width = "100%"; + this.box.style.width = approxTextWidth + "px"; + } + else + { + // Make the input one character wider than the text value so that + // typing does not ever cause the textbox to scroll + var charWidth = this.measureInputText('m').width; + + // Sometimes we need to make the editor a little wider, specifically when + // an overflow happens, otherwise it will scroll off some text on the left + if (extraWidth) + charWidth *= extraWidth; + + var inputWidth = approxTextWidth + charWidth; + + if (initial) + { + if (isIE) + { + // TODO: xxxpedro + var xDiff = 13; + this.box.style.width = (inputWidth + xDiff) + "px"; + } + else + this.box.style.width = "auto"; + } + else + { + // TODO: xxxpedro + var xDiff = isIE ? 13: this.box.scrollWidth - this.input.offsetWidth; + this.box.style.width = (inputWidth + xDiff) + "px"; + } + + this.input.style.width = inputWidth + "px"; + } + + this.expander.style.width = approxTextWidth + "px"; + this.expander.style.height = Math.max(this.textSize.height-3,0) + "px"; + } + + if (forceAll) + scrollIntoCenterView(this.box, null, true); + } +}); + +// ************************************************************************************************ +// Autocompletion + +Firebug.AutoCompleter = function(getExprOffset, getRange, evaluator, selectMode, caseSensitive) +{ + var candidates = null; + var originalValue = null; + var originalOffset = -1; + var lastExpr = null; + var lastOffset = -1; + var exprOffset = 0; + var lastIndex = 0; + var preParsed = null; + var preExpr = null; + var postExpr = null; + + this.revert = function(textBox) + { + if (originalOffset != -1) + { + textBox.value = originalValue; + + setSelectionRange(textBox, originalOffset, originalOffset); + + this.reset(); + return true; + } + else + { + this.reset(); + return false; + } + }; + + this.reset = function() + { + candidates = null; + originalValue = null; + originalOffset = -1; + lastExpr = null; + lastOffset = 0; + exprOffset = 0; + }; + + this.complete = function(context, textBox, cycle, reverse) + { + //console.log("complete", context, textBox, cycle, reverse); + // TODO: xxxpedro important port to firebug (variable leak) + //var value = lastValue = textBox.value; + var value = textBox.value; + + //var offset = textBox.selectionStart; + var offset = getInputSelectionStart(textBox); + + // The result of selectionStart() in Safari/Chrome is 1 unit less than the result + // in Firefox. Therefore, we need to manually adjust the value here. + if (isSafari && !cycle && offset >= 0) offset++; + + if (!selectMode && originalOffset != -1) + offset = originalOffset; + + if (!candidates || !cycle || offset != lastOffset) + { + originalOffset = offset; + originalValue = value; + + // Find the part of the string that will be parsed + var parseStart = getExprOffset ? getExprOffset(value, offset, context) : 0; + preParsed = value.substr(0, parseStart); + var parsed = value.substr(parseStart); + + // Find the part of the string that is being completed + var range = getRange ? getRange(parsed, offset-parseStart, context) : null; + if (!range) + range = {start: 0, end: parsed.length-1 }; + + var expr = parsed.substr(range.start, range.end-range.start+1); + preExpr = parsed.substr(0, range.start); + postExpr = parsed.substr(range.end+1); + exprOffset = parseStart + range.start; + + if (!cycle) + { + if (!expr) + return; + else if (lastExpr && lastExpr.indexOf(expr) != 0) + { + candidates = null; + } + else if (lastExpr && lastExpr.length >= expr.length) + { + candidates = null; + lastExpr = expr; + return; + } + } + + lastExpr = expr; + lastOffset = offset; + + var searchExpr; + + // Check if the cursor is at the very right edge of the expression, or + // somewhere in the middle of it + if (expr && offset != parseStart+range.end+1) + { + if (cycle) + { + // We are in the middle of the expression, but we can + // complete by cycling to the next item in the values + // list after the expression + offset = range.start; + searchExpr = expr; + expr = ""; + } + else + { + // We can't complete unless we are at the ridge edge + return; + } + } + + var values = evaluator(preExpr, expr, postExpr, context); + if (!values) + return; + + if (expr) + { + // Filter the list of values to those which begin with expr. We + // will then go on to complete the first value in the resulting list + candidates = []; + + if (caseSensitive) + { + for (var i = 0; i < values.length; ++i) + { + var name = values[i]; + if (name.indexOf && name.indexOf(expr) == 0) + candidates.push(name); + } + } + else + { + var lowerExpr = caseSensitive ? expr : expr.toLowerCase(); + for (var i = 0; i < values.length; ++i) + { + var name = values[i]; + if (name.indexOf && name.toLowerCase().indexOf(lowerExpr) == 0) + candidates.push(name); + } + } + + lastIndex = reverse ? candidates.length-1 : 0; + } + else if (searchExpr) + { + var searchIndex = -1; + + // Find the first instance of searchExpr in the values list. We + // will then complete the string that is found + if (caseSensitive) + { + searchIndex = values.indexOf(expr); + } + else + { + var lowerExpr = searchExpr.toLowerCase(); + for (var i = 0; i < values.length; ++i) + { + var name = values[i]; + if (name && name.toLowerCase().indexOf(lowerExpr) == 0) + { + searchIndex = i; + break; + } + } + } + + // Nothing found, so there's nothing to complete to + if (searchIndex == -1) + return this.reset(); + + expr = searchExpr; + candidates = cloneArray(values); + lastIndex = searchIndex; + } + else + { + expr = ""; + candidates = []; + for (var i = 0; i < values.length; ++i) + { + if (values[i].substr) + candidates.push(values[i]); + } + lastIndex = -1; + } + } + + if (cycle) + { + expr = lastExpr; + lastIndex += reverse ? -1 : 1; + } + + if (!candidates.length) + return; + + if (lastIndex >= candidates.length) + lastIndex = 0; + else if (lastIndex < 0) + lastIndex = candidates.length-1; + + var completion = candidates[lastIndex]; + var preCompletion = expr.substr(0, offset-exprOffset); + var postCompletion = completion.substr(offset-exprOffset); + + textBox.value = preParsed + preExpr + preCompletion + postCompletion + postExpr; + var offsetEnd = preParsed.length + preExpr.length + completion.length; + + // TODO: xxxpedro remove the following commented code, if the lib.setSelectionRange() + // is working well. + /* + if (textBox.setSelectionRange) + { + // we must select the range with a timeout, otherwise the text won't + // be properly selected (because after this function executes, the editor's + // input will be resized to fit the whole text) + setTimeout(function(){ + if (selectMode) + textBox.setSelectionRange(offset, offsetEnd); + else + textBox.setSelectionRange(offsetEnd, offsetEnd); + },0); + } + /**/ + + // we must select the range with a timeout, otherwise the text won't + // be properly selected (because after this function executes, the editor's + // input will be resized to fit the whole text) + /* + setTimeout(function(){ + if (selectMode) + setSelectionRange(textBox, offset, offsetEnd); + else + setSelectionRange(textBox, offsetEnd, offsetEnd); + },0); + + return true; + /**/ + + // The editor text should be selected only after calling the editor.update() + // in Safari/Chrome, otherwise the text won't be selected. So, we're returning + // a function to be called later (in the proper time for all browsers). + // + // TODO: xxxpedro see if we can move the editor.update() calls to here, and avoid + // returning a closure. the complete() function seems to be called only twice in + // editor.js. See if this function is called anywhere else (like css.js for example). + return function(){ + //console.log("autocomplete ", textBox, offset, offsetEnd); + + if (selectMode) + setSelectionRange(textBox, offset, offsetEnd); + else + setSelectionRange(textBox, offsetEnd, offsetEnd); + }; + /**/ + }; +}; + +// ************************************************************************************************ +// Local Helpers + +var getDefaultEditor = function getDefaultEditor(panel) +{ + if (!defaultEditor) + { + var doc = panel.document; + defaultEditor = new Firebug.InlineEditor(doc); + } + + return defaultEditor; +} + +/** + * An outsider is the first element matching the stepper element that + * is not an child of group. Elements tagged with insertBefore or insertAfter + * classes are also excluded from these results unless they are the sibling + * of group, relative to group's parent editGroup. This allows for the proper insertion + * rows when groups are nested. + */ +var getOutsider = function getOutsider(element, group, stepper) +{ + var parentGroup = getAncestorByClass(group.parentNode, "editGroup"); + var next; + do + { + next = stepper(next || element); + } + while (isAncestor(next, group) || isGroupInsert(next, parentGroup)); + + return next; +} + +var isGroupInsert = function isGroupInsert(next, group) +{ + return (!group || isAncestor(next, group)) + && (hasClass(next, "insertBefore") || hasClass(next, "insertAfter")); +} + +var getNextOutsider = function getNextOutsider(element, group) +{ + return getOutsider(element, group, bind(getNextByClass, FBL, "editable")); +} + +var getPreviousOutsider = function getPreviousOutsider(element, group) +{ + return getOutsider(element, group, bind(getPreviousByClass, FBL, "editable")); +} + +var getInlineParent = function getInlineParent(element) +{ + var lastInline = element; + for (; element; element = element.parentNode) + { + //var s = element.ownerDocument.defaultView.getComputedStyle(element, ""); + var s = isIE ? + element.currentStyle : + element.ownerDocument.defaultView.getComputedStyle(element, ""); + + if (s.display != "inline") + return lastInline; + else + lastInline = element; + } + return null; +} + +var insertTab = function insertTab() +{ + insertTextIntoElement(currentEditor.input, Firebug.Editor.tabCharacter); +} + +// ************************************************************************************************ + +Firebug.registerModule(Firebug.Editor); + +// ************************************************************************************************ + +}}); + + +/* 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(); + + 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" ? FirebugChrome.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 + + + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +// next-generation Console Panel (will override consoje.js) +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +// Constants + +/* +const Cc = Components.classes; +const Ci = Components.interfaces; +const nsIPrefBranch2 = Ci.nsIPrefBranch2; +const PrefService = Cc["@mozilla.org/preferences-service;1"]; +const prefs = PrefService.getService(nsIPrefBranch2); +/**/ +/* + +// new offline message handler +o = {x:1,y:2}; + +r = Firebug.getRep(o); + +r.tag.tag.compile(); + +outputs = []; +html = r.tag.renderHTML({object:o}, outputs); + + +// finish rendering the template (the DOM part) +target = $("build"); +target.innerHTML = html; +root = target.firstChild; + +domArgs = [root, r.tag.context, 0]; +domArgs.push.apply(domArgs, r.tag.domArgs); +domArgs.push.apply(domArgs, outputs); +r.tag.tag.renderDOM.apply(self ? self : r.tag.subject, domArgs); + + + */ +var consoleQueue = []; +var lastHighlightedObject; +var FirebugContext = Env.browser; + +// ************************************************************************************************ + +var maxQueueRequests = 500; + +// ************************************************************************************************ + +Firebug.ConsoleBase = +{ + log: function(object, context, className, rep, noThrottle, sourceLink) + { + //dispatch(this.fbListeners,"log",[context, object, className, sourceLink]); + return this.logRow(appendObject, object, context, className, rep, sourceLink, noThrottle); + }, + + logFormatted: function(objects, context, className, noThrottle, sourceLink) + { + //dispatch(this.fbListeners,"logFormatted",[context, objects, className, sourceLink]); + return this.logRow(appendFormatted, objects, context, className, null, sourceLink, noThrottle); + }, + + openGroup: function(objects, context, className, rep, noThrottle, sourceLink, noPush) + { + return this.logRow(appendOpenGroup, objects, context, className, rep, sourceLink, noThrottle); + }, + + closeGroup: function(context, noThrottle) + { + return this.logRow(appendCloseGroup, null, context, null, null, null, noThrottle, true); + }, + + logRow: function(appender, objects, context, className, rep, sourceLink, noThrottle, noRow) + { + // TODO: xxxpedro console console2 + noThrottle = true; // xxxpedro forced because there is no TabContext yet + + if (!context) + context = FirebugContext; + + if (FBTrace.DBG_ERRORS && !context) + FBTrace.sysout("Console.logRow has no context, skipping objects", objects); + + if (!context) + return; + + if (noThrottle || !context) + { + var panel = this.getPanel(context); + if (panel) + { + var row = panel.append(appender, objects, className, rep, sourceLink, noRow); + var container = panel.panelNode; + + // TODO: xxxpedro what is this? console console2 + /* + var template = Firebug.NetMonitor.NetLimit; + + while (container.childNodes.length > maxQueueRequests + 1) + { + clearDomplate(container.firstChild.nextSibling); + container.removeChild(container.firstChild.nextSibling); + panel.limit.limitInfo.totalCount++; + template.updateCounter(panel.limit); + } + dispatch([Firebug.A11yModel], "onLogRowCreated", [panel , row]); + /**/ + return row; + } + else + { + consoleQueue.push([appender, objects, context, className, rep, sourceLink, noThrottle, noRow]); + } + } + else + { + if (!context.throttle) + { + //FBTrace.sysout("console.logRow has not context.throttle! "); + return; + } + var args = [appender, objects, context, className, rep, sourceLink, true, noRow]; + context.throttle(this.logRow, this, args); + } + }, + + appendFormatted: function(args, row, context) + { + if (!context) + context = FirebugContext; + + var panel = this.getPanel(context); + panel.appendFormatted(args, row); + }, + + clear: function(context) + { + if (!context) + //context = FirebugContext; + context = Firebug.context; + + /* + if (context) + Firebug.Errors.clear(context); + /**/ + + var panel = this.getPanel(context, true); + if (panel) + { + panel.clear(); + } + }, + + // Override to direct output to your panel + getPanel: function(context, noCreate) + { + //return context.getPanel("console", noCreate); + // TODO: xxxpedro console console2 + return Firebug.chrome ? Firebug.chrome.getPanel("Console") : null; + } + +}; + +// ************************************************************************************************ + +//TODO: xxxpedro +//var ActivableConsole = extend(Firebug.ActivableModule, Firebug.ConsoleBase); +var ActivableConsole = extend(Firebug.ConsoleBase, +{ + isAlwaysEnabled: function() + { + return true; + } +}); + +Firebug.Console = Firebug.Console = extend(ActivableConsole, +//Firebug.Console = extend(ActivableConsole, +{ + dispatchName: "console", + + error: function() + { + Firebug.Console.logFormatted(arguments, Firebug.browser, "error"); + }, + + flush: function() + { + dispatch(this.fbListeners,"flush",[]); + + for (var i=0, length=consoleQueue.length; i objects.length) // then too few parameters for format, assume unformatted. + { + format = ""; + objIndex = -1; + parts.length = 0; + break; + } + } + + } + for (var i = 0; i < parts.length; ++i) + { + var part = parts[i]; + if (part && typeof(part) == "object") + { + var object = objects[++objIndex]; + if (typeof(object) != "undefined") + this.appendObject(object, row, part.rep); + else + this.appendObject(part.type, row, FirebugReps.Text); + } + else + FirebugReps.Text.tag.append({object: part}, row); + } + + for (var i = objIndex+1; i < objects.length; ++i) + { + logText(" ", row); + var object = objects[i]; + if (typeof(object) == "string") + FirebugReps.Text.tag.append({object: object}, row); + else + this.appendObject(object, row); + } + }, + + appendOpenGroup: function(objects, row, rep) + { + if (!this.groups) + this.groups = []; + + setClass(row, "logGroup"); + setClass(row, "opened"); + + var innerRow = this.createRow("logRow"); + setClass(innerRow, "logGroupLabel"); + if (rep) + rep.tag.replace({"objects": objects}, innerRow); + else + this.appendFormatted(objects, innerRow, rep); + row.appendChild(innerRow); + //dispatch([Firebug.A11yModel], 'onLogRowCreated', [this, innerRow]); + var groupBody = this.createRow("logGroupBody"); + row.appendChild(groupBody); + groupBody.setAttribute('role', 'group'); + this.groups.push(groupBody); + + addEvent(innerRow, "mousedown", function(event) + { + if (isLeftClick(event)) + { + //console.log(event.currentTarget == event.target); + + var target = event.target || event.srcElement; + + target = getAncestorByClass(target, "logGroupLabel"); + + var groupRow = target.parentNode; + + if (hasClass(groupRow, "opened")) + { + removeClass(groupRow, "opened"); + target.setAttribute('aria-expanded', 'false'); + } + else + { + setClass(groupRow, "opened"); + target.setAttribute('aria-expanded', 'true'); + } + } + }); + }, + + appendCloseGroup: function(object, row, rep) + { + if (this.groups) + this.groups.pop(); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // TODO: xxxpedro console2 + onMouseMove: function(event) + { + var target = event.srcElement || event.target; + + var object = getAncestorByClass(target, "objectLink-element"); + object = object ? object.repObject : null; + + if(object && instanceOf(object, "Element") && object.nodeType == 1) + { + if(object != lastHighlightedObject) + { + Firebug.Inspector.drawBoxModel(object); + object = lastHighlightedObject; + } + } + else + Firebug.Inspector.hideBoxModel(); + + }, + + onMouseDown: function(event) + { + var target = event.srcElement || event.target; + + var object = getAncestorByClass(target, "objectLink"); + var repObject = object ? object.repObject : null; + + if (!repObject) + { + return; + } + + if (hasClass(object, "objectLink-object")) + { + Firebug.chrome.selectPanel("DOM"); + Firebug.chrome.getPanel("DOM").select(repObject, true); + } + else if (hasClass(object, "objectLink-element")) + { + Firebug.chrome.selectPanel("HTML"); + Firebug.chrome.getPanel("HTML").select(repObject, true); + } + + /* + if(object && instanceOf(object, "Element") && object.nodeType == 1) + { + if(object != lastHighlightedObject) + { + Firebug.Inspector.drawBoxModel(object); + object = lastHighlightedObject; + } + } + else + Firebug.Inspector.hideBoxModel(); + /**/ + + }, + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "Console", + title: "Console", + //searchable: true, + //breakable: true, + //editable: false, + + options: + { + hasCommandLine: true, + hasToolButtons: true, + isPreRendered: true + }, + + create: function() + { + Firebug.Panel.create.apply(this, arguments); + + this.context = Firebug.browser.window; + this.document = Firebug.chrome.document; + this.onMouseMove = bind(this.onMouseMove, this); + this.onMouseDown = bind(this.onMouseDown, this); + + this.clearButton = new Button({ + element: $("fbConsole_btClear"), + owner: Firebug.Console, + onClick: Firebug.Console.clear + }); + }, + + initialize: function() + { + Firebug.Panel.initialize.apply(this, arguments); // loads persisted content + //Firebug.ActivablePanel.initialize.apply(this, arguments); // loads persisted content + + if (!this.persistedContent && Firebug.Console.isAlwaysEnabled()) + { + this.insertLogLimit(this.context); + + // Initialize log limit and listen for changes. + this.updateMaxLimit(); + + if (this.context.consoleReloadWarning) // we have not yet injected the console + this.insertReloadWarning(); + } + + //Firebug.Console.injector.install(Firebug.browser.window); + + addEvent(this.panelNode, "mouseover", this.onMouseMove); + addEvent(this.panelNode, "mousedown", this.onMouseDown); + + this.clearButton.initialize(); + + //consolex.trace(); + //TODO: xxxpedro remove this + /* + Firebug.Console.openGroup(["asd"], null, "group", null, false); + Firebug.Console.log("asd"); + Firebug.Console.log("asd"); + Firebug.Console.log("asd"); + /**/ + + //TODO: xxxpedro preferences prefs + //prefs.addObserver(Firebug.prefDomain, this, false); + }, + + initializeNode : function() + { + //dispatch([Firebug.A11yModel], 'onInitializeNode', [this]); + if (FBTrace.DBG_CONSOLE) + { + this.onScroller = bind(this.onScroll, this); + addEvent(this.panelNode, "scroll", this.onScroller); + } + + this.onResizer = bind(this.onResize, this); + this.resizeEventTarget = Firebug.chrome.$('fbContentBox'); + addEvent(this.resizeEventTarget, "resize", this.onResizer); + }, + + destroyNode : function() + { + //dispatch([Firebug.A11yModel], 'onDestroyNode', [this]); + if (this.onScroller) + removeEvent(this.panelNode, "scroll", this.onScroller); + + //removeEvent(this.resizeEventTarget, "resize", this.onResizer); + }, + + shutdown: function() + { + //TODO: xxxpedro console console2 + this.clearButton.shutdown(); + + removeEvent(this.panelNode, "mousemove", this.onMouseMove); + removeEvent(this.panelNode, "mousedown", this.onMouseDown); + + this.destroyNode(); + + Firebug.Panel.shutdown.apply(this, arguments); + + //TODO: xxxpedro preferences prefs + //prefs.removeObserver(Firebug.prefDomain, this, false); + }, + + ishow: function(state) + { + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("Console.panel show; " + this.context.getName(), state); + + var enabled = Firebug.Console.isAlwaysEnabled(); + if (enabled) + { + Firebug.Console.disabledPanelPage.hide(this); + this.showCommandLine(true); + this.showToolbarButtons("fbConsoleButtons", true); + Firebug.chrome.setGlobalAttribute("cmd_togglePersistConsole", "checked", this.persistContent); + + if (state && state.wasScrolledToBottom) + { + this.wasScrolledToBottom = state.wasScrolledToBottom; + delete state.wasScrolledToBottom; + } + + if (this.wasScrolledToBottom) + scrollToBottom(this.panelNode); + + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.show ------------------ wasScrolledToBottom: " + + this.wasScrolledToBottom + ", " + this.context.getName()); + } + else + { + this.hide(state); + Firebug.Console.disabledPanelPage.show(this); + } + }, + + ihide: function(state) + { + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("Console.panel hide; " + this.context.getName(), state); + + this.showToolbarButtons("fbConsoleButtons", false); + this.showCommandLine(false); + + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.hide ------------------ wasScrolledToBottom: " + + this.wasScrolledToBottom + ", " + this.context.getName()); + }, + + destroy: function(state) + { + if (this.panelNode.offsetHeight) + this.wasScrolledToBottom = isScrolledToBottom(this.panelNode); + + if (state) + state.wasScrolledToBottom = this.wasScrolledToBottom; + + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.destroy ------------------ wasScrolledToBottom: " + + this.wasScrolledToBottom + ", " + this.context.getName()); + }, + + shouldBreakOnNext: function() + { + // xxxHonza: shouldn't the breakOnErrors be context related? + // xxxJJB, yes, but we can't support it because we can't yet tell + // which window the error is on. + return Firebug.getPref(Firebug.servicePrefDomain, "breakOnErrors"); + }, + + getBreakOnNextTooltip: function(enabled) + { + return (enabled ? $STR("console.Disable Break On All Errors") : + $STR("console.Break On All Errors")); + }, + + enablePanel: function(module) + { + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.ConsolePanel.enablePanel; " + this.context.getName()); + + Firebug.ActivablePanel.enablePanel.apply(this, arguments); + + this.showCommandLine(true); + + if (this.wasScrolledToBottom) + scrollToBottom(this.panelNode); + }, + + disablePanel: function(module) + { + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.ConsolePanel.disablePanel; " + this.context.getName()); + + Firebug.ActivablePanel.disablePanel.apply(this, arguments); + + this.showCommandLine(false); + }, + + getOptionsMenuItems: function() + { + return [ + optionMenu("ShowJavaScriptErrors", "showJSErrors"), + optionMenu("ShowJavaScriptWarnings", "showJSWarnings"), + optionMenu("ShowCSSErrors", "showCSSErrors"), + optionMenu("ShowXMLErrors", "showXMLErrors"), + optionMenu("ShowXMLHttpRequests", "showXMLHttpRequests"), + optionMenu("ShowChromeErrors", "showChromeErrors"), + optionMenu("ShowChromeMessages", "showChromeMessages"), + optionMenu("ShowExternalErrors", "showExternalErrors"), + optionMenu("ShowNetworkErrors", "showNetworkErrors"), + this.getShowStackTraceMenuItem(), + this.getStrictOptionMenuItem(), + "-", + optionMenu("LargeCommandLine", "largeCommandLine") + ]; + }, + + getShowStackTraceMenuItem: function() + { + var menuItem = serviceOptionMenu("ShowStackTrace", "showStackTrace"); + if (FirebugContext && !Firebug.Debugger.isAlwaysEnabled()) + menuItem.disabled = true; + return menuItem; + }, + + getStrictOptionMenuItem: function() + { + var strictDomain = "javascript.options"; + var strictName = "strict"; + var strictValue = prefs.getBoolPref(strictDomain+"."+strictName); + return {label: "JavascriptOptionsStrict", type: "checkbox", checked: strictValue, + command: bindFixed(Firebug.setPref, Firebug, strictDomain, strictName, !strictValue) }; + }, + + getBreakOnMenuItems: function() + { + //xxxHonza: no BON options for now. + /*return [ + optionMenu("console.option.Persist Break On Error", "persistBreakOnError") + ];*/ + return []; + }, + + search: function(text) + { + if (!text) + return; + + // Make previously visible nodes invisible again + if (this.matchSet) + { + for (var i in this.matchSet) + removeClass(this.matchSet[i], "matched"); + } + + this.matchSet = []; + + function findRow(node) { return getAncestorByClass(node, "logRow"); } + var search = new TextSearch(this.panelNode, findRow); + + var logRow = search.find(text); + if (!logRow) + { + dispatch([Firebug.A11yModel], 'onConsoleSearchMatchFound', [this, text, []]); + return false; + } + for (; logRow; logRow = search.findNext()) + { + setClass(logRow, "matched"); + this.matchSet.push(logRow); + } + dispatch([Firebug.A11yModel], 'onConsoleSearchMatchFound', [this, text, this.matchSet]); + return true; + }, + + breakOnNext: function(breaking) + { + Firebug.setPref(Firebug.servicePrefDomain, "breakOnErrors", breaking); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // private + + createRow: function(rowName, className) + { + var elt = this.document.createElement("div"); + elt.className = rowName + (className ? " " + rowName + "-" + className : ""); + return elt; + }, + + getTopContainer: function() + { + if (this.groups && this.groups.length) + return this.groups[this.groups.length-1]; + else + return this.panelNode; + }, + + filterLogRow: function(logRow, scrolledToBottom) + { + if (this.searchText) + { + setClass(logRow, "matching"); + setClass(logRow, "matched"); + + // Search after a delay because we must wait for a frame to be created for + // the new logRow so that the finder will be able to locate it + setTimeout(bindFixed(function() + { + if (this.searchFilter(this.searchText, logRow)) + this.matchSet.push(logRow); + else + removeClass(logRow, "matched"); + + removeClass(logRow, "matching"); + + if (scrolledToBottom) + scrollToBottom(this.panelNode); + }, this), 100); + } + }, + + searchFilter: function(text, logRow) + { + var count = this.panelNode.childNodes.length; + var searchRange = this.document.createRange(); + searchRange.setStart(this.panelNode, 0); + searchRange.setEnd(this.panelNode, count); + + var startPt = this.document.createRange(); + startPt.setStartBefore(logRow); + + var endPt = this.document.createRange(); + endPt.setStartAfter(logRow); + + return finder.Find(text, searchRange, startPt, endPt) != null; + }, + + // nsIPrefObserver + observe: function(subject, topic, data) + { + // We're observing preferences only. + if (topic != "nsPref:changed") + return; + + // xxxHonza check this out. + var prefDomain = "Firebug.extension."; + var prefName = data.substr(prefDomain.length); + if (prefName == "console.logLimit") + this.updateMaxLimit(); + }, + + updateMaxLimit: function() + { + var value = 1000; + //TODO: xxxpedro preferences log limit? + //var value = Firebug.getPref(Firebug.prefDomain, "console.logLimit"); + maxQueueRequests = value ? value : maxQueueRequests; + }, + + showCommandLine: function(shouldShow) + { + //TODO: xxxpedro show command line important + return; + + if (shouldShow) + { + collapse(Firebug.chrome.$("fbCommandBox"), false); + Firebug.CommandLine.setMultiLine(Firebug.largeCommandLine, Firebug.chrome); + } + else + { + // Make sure that entire content of the Console panel is hidden when + // the panel is disabled. + Firebug.CommandLine.setMultiLine(false, Firebug.chrome, Firebug.largeCommandLine); + collapse(Firebug.chrome.$("fbCommandBox"), true); + } + }, + + onScroll: function(event) + { + // Update the scroll position flag if the position changes. + this.wasScrolledToBottom = FBL.isScrolledToBottom(this.panelNode); + + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.onScroll ------------------ wasScrolledToBottom: " + + this.wasScrolledToBottom + ", wasScrolledToBottom: " + + this.context.getName(), event); + }, + + onResize: function(event) + { + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("console.onResize ------------------ wasScrolledToBottom: " + + this.wasScrolledToBottom + ", offsetHeight: " + this.panelNode.offsetHeight + + ", scrollTop: " + this.panelNode.scrollTop + ", scrollHeight: " + + this.panelNode.scrollHeight + ", " + this.context.getName(), event); + + if (this.wasScrolledToBottom) + scrollToBottom(this.panelNode); + } +}); + +// ************************************************************************************************ + +function parseFormat(format) +{ + var parts = []; + if (format.length <= 0) + return parts; + + var reg = /((^%|.%)(\d+)?(\.)([a-zA-Z]))|((^%|.%)([a-zA-Z]))/; + for (var m = reg.exec(format); m; m = reg.exec(format)) + { + if (m[0].substr(0, 2) == "%%") + { + parts.push(format.substr(0, m.index)); + parts.push(m[0].substr(1)); + } + else + { + var type = m[8] ? m[8] : m[5]; + var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0); + + var rep = null; + switch (type) + { + case "s": + rep = FirebugReps.Text; + break; + case "f": + case "i": + case "d": + rep = FirebugReps.Number; + break; + case "o": + rep = null; + break; + } + + parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1)); + parts.push({rep: rep, precision: precision, type: ("%" + type)}); + } + + format = format.substr(m.index+m[0].length); + } + + parts.push(format); + return parts; +} + +// ************************************************************************************************ + +var appendObject = Firebug.ConsolePanel.prototype.appendObject; +var appendFormatted = Firebug.ConsolePanel.prototype.appendFormatted; +var appendOpenGroup = Firebug.ConsolePanel.prototype.appendOpenGroup; +var appendCloseGroup = Firebug.ConsolePanel.prototype.appendCloseGroup; + +// ************************************************************************************************ + +//Firebug.registerActivableModule(Firebug.Console); +Firebug.registerModule(Firebug.Console); +Firebug.registerPanel(Firebug.ConsolePanel); + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// Constants + +//const Cc = Components.classes; +//const Ci = Components.interfaces; + +var frameCounters = {}; +var traceRecursion = 0; + +Firebug.Console.injector = +{ + install: function(context) + { + var win = context.window; + + var consoleHandler = new FirebugConsoleHandler(context, win); + + var properties = + [ + "log", + "debug", + "info", + "warn", + "error", + "assert", + "dir", + "dirxml", + "group", + "groupCollapsed", + "groupEnd", + "time", + "timeEnd", + "count", + "trace", + "profile", + "profileEnd", + "clear", + "open", + "close" + ]; + + var Handler = function(name) + { + var c = consoleHandler; + var f = consoleHandler[name]; + return function(){return f.apply(c,arguments)}; + }; + + var installer = function(c) + { + for (var i=0, l=properties.length; i 1) + { + traceRecursion--; + return; + } + + var frames = []; + + for (var fn = arguments.callee.caller.caller; fn; fn = fn.caller) + { + if (wasVisited(fn)) break; + + var args = []; + + for (var i = 0, l = fn.arguments.length; i < l; ++i) + { + args.push({value: fn.arguments[i]}); + } + + frames.push({fn: fn, name: getFuncName(fn), args: args}); + } + + + // **************************************************************************************** + + try + { + (0)(); + } + catch(e) + { + var result = e; + + var stack = + result.stack || // Firefox / Google Chrome + result.stacktrace || // Opera + ""; + + stack = stack.replace(/\n\r|\r\n/g, "\n"); // normalize line breaks + var items = stack.split(/[\n\r]/); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Google Chrome + if (FBL.isSafari) + { + //var reChromeStackItem = /^\s+at\s+([^\(]+)\s\((.*)\)$/; + //var reChromeStackItem = /^\s+at\s+(.*)((?:http|https|ftp|file):\/\/.*)$/; + var reChromeStackItem = /^\s+at\s+(.*)((?:http|https|ftp|file):\/\/.*)$/; + + var reChromeStackItemName = /\s*\($/; + var reChromeStackItemValue = /^(.+)\:(\d+\:\d+)\)?$/; + + var framePos = 0; + for (var i=4, length=items.length; i 1) + { + objects = [errorObject]; + for (var i = 1; i < args.length; i++) + objects.push(args[i]); + } + + var row = Firebug.Console.log(objects, context, "errorMessage", null, true); // noThrottle + row.scrollIntoView(); + } + + function getComponentsStackDump() + { + // Starting with our stack, walk back to the user-level code + var frame = Components.stack; + var userURL = win.location.href.toString(); + + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("consoleInjector.getComponentsStackDump initial stack for userURL "+userURL, frame); + + // Drop frames until we get into user code. + while (frame && FBL.isSystemURL(frame.filename) ) + frame = frame.caller; + + // Drop two more frames, the injected console function and firebugAppendConsole() + if (frame) + frame = frame.caller; + if (frame) + frame = frame.caller; + + if (FBTrace.DBG_CONSOLE) + FBTrace.sysout("consoleInjector.getComponentsStackDump final stack for userURL "+userURL, frame); + + return frame; + } + + function getStackLink() + { + // TODO: xxxpedro console2 + return; + //return FBL.getFrameSourceLink(getComponentsStackDump()); + } + + function getJSDUserStack() + { + var trace = FBL.getCurrentStackTrace(context); + + var frames = trace ? trace.frames : null; + if (frames && (frames.length > 0) ) + { + var oldest = frames.length - 1; // 6 - 1 = 5 + for (var i = 0; i < frames.length; i++) + { + if (frames[oldest - i].href.indexOf("chrome:") == 0) break; + var fn = frames[oldest - i].fn + ""; + if (fn && (fn.indexOf("_firebugEvalEvent") != -1) ) break; // command line + } + FBTrace.sysout("consoleInjector getJSDUserStack: "+frames.length+" oldest: "+oldest+" i: "+i+" i - oldest + 2: "+(i - oldest + 2), trace); + trace.frames = trace.frames.slice(2 - i); // take the oldest frames, leave 2 behind they are injection code + + return trace; + } + else + return "Firebug failed to get stack trace with any frames"; + } +} + +// ************************************************************************************************ +// Register console namespace + +FBL.registerConsole = function() +{ + //TODO: xxxpedro console options override + //if (Env.Options.overrideConsole) + var win = Env.browser.window; + Firebug.Console.injector.install(win); +}; + +registerConsole(); + +}}); + + +/* 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) +{ + commandHistory.push(command); + commandPointer = 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(); + + 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 (commandPointer > 0 && commandHistory.length > 0) + this.element.value = commandHistory[--commandPointer]; + }, + + nextCommand: function() + { + var element = this.element; + + var limit = commandHistory.length -1; + var i = commandPointer; + + if (i < limit) + element.value = commandHistory[++commandPointer]; + + else if (i == limit) + { + ++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; + + // TODO: xxxpedro html3 + ///Firebug.Console.log(o, Firebug.context, "dirxml", Firebug.HTMLPanel.SoloElement); + var div = Firebug.Console.log(o, Firebug.context, "dirxml"); + var html = []; + Firebug.Reps.appendNode(o, html); + div.innerHTML = html.join(""); + + } +}; + +// ************************************************************************************************ + +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]; + } +}; + +// ************************************************************************************************ +}}); + +/* 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(); + }; +} + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var reIgnore = /about:|javascript:|resource:|chrome:|jar:/; +var layoutInterval = 300; +var indentWidth = 18; + +var cacheSession = null; +var contexts = new Array(); +var panelName = "net"; +var maxQueueRequests = 500; +//var panelBar1 = $("fbPanelBar1"); // chrome not available at startup +var activeRequests = []; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var mimeExtensionMap = +{ + "txt": "text/plain", + "html": "text/html", + "htm": "text/html", + "xhtml": "text/html", + "xml": "text/xml", + "css": "text/css", + "js": "application/x-javascript", + "jss": "application/x-javascript", + "jpg": "image/jpg", + "jpeg": "image/jpeg", + "gif": "image/gif", + "png": "image/png", + "bmp": "image/bmp", + "swf": "application/x-shockwave-flash", + "flv": "video/x-flv" +}; + +var fileCategories = +{ + "undefined": 1, + "html": 1, + "css": 1, + "js": 1, + "xhr": 1, + "image": 1, + "flash": 1, + "txt": 1, + "bin": 1 +}; + +var textFileCategories = +{ + "txt": 1, + "html": 1, + "xhr": 1, + "css": 1, + "js": 1 +}; + +var binaryFileCategories = +{ + "bin": 1, + "flash": 1 +}; + +var mimeCategoryMap = +{ + "text/plain": "txt", + "application/octet-stream": "bin", + "text/html": "html", + "text/xml": "html", + "text/css": "css", + "application/x-javascript": "js", + "text/javascript": "js", + "application/javascript" : "js", + "image/jpeg": "image", + "image/jpg": "image", + "image/gif": "image", + "image/png": "image", + "image/bmp": "image", + "application/x-shockwave-flash": "flash", + "video/x-flv": "flash" +}; + +var binaryCategoryMap = +{ + "image": 1, + "flash" : 1 +}; + +// ************************************************************************************************ + +/** + * @module Represents a module object for the Net panel. This object is derived + * from Firebug.ActivableModule in order to support activation (enable/disable). + * This allows to avoid (performance) expensive features if the functionality is not necessary + * for the user. + */ +Firebug.NetMonitor = extend(Firebug.ActivableModule, +{ + dispatchName: "netMonitor", + + clear: function(context) + { + // The user pressed a Clear button so, remove content of the panel... + var panel = context.getPanel(panelName, true); + if (panel) + panel.clear(); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Module + + initialize: function() + { + return; + + this.panelName = panelName; + + Firebug.ActivableModule.initialize.apply(this, arguments); + + if (Firebug.TraceModule) + Firebug.TraceModule.addListener(this.TraceListener); + + // HTTP observer must be registered now (and not in monitorContext, since if a + // page is opened in a new tab the top document request would be missed otherwise. + NetHttpObserver.registerObserver(); + NetHttpActivityObserver.registerObserver(); + + Firebug.Debugger.addListener(this.DebuggerListener); + }, + + shutdown: function() + { + return; + + prefs.removeObserver(Firebug.prefDomain, this, false); + if (Firebug.TraceModule) + Firebug.TraceModule.removeListener(this.TraceListener); + + NetHttpObserver.unregisterObserver(); + NetHttpActivityObserver.unregisterObserver(); + + Firebug.Debugger.removeListener(this.DebuggerListener); + } +}); + + +/** + * @domplate Represents a template that is used to reneder detailed info about a request. + * This template is rendered when a request is expanded. + */ +Firebug.NetMonitor.NetInfoBody = domplate(Firebug.Rep, new Firebug.Listener(), +{ + tag: + DIV({"class": "netInfoBody", _repObject: "$file"}, + TAG("$infoTabs", {file: "$file"}), + TAG("$infoBodies", {file: "$file"}) + ), + + infoTabs: + DIV({"class": "netInfoTabs focusRow subFocusRow", "role": "tablist"}, + A({"class": "netInfoParamsTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Params", + $collapsed: "$file|hideParams"}, + $STR("URLParameters") + ), + A({"class": "netInfoHeadersTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Headers"}, + $STR("Headers") + ), + A({"class": "netInfoPostTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Post", + $collapsed: "$file|hidePost"}, + $STR("Post") + ), + A({"class": "netInfoPutTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Put", + $collapsed: "$file|hidePut"}, + $STR("Put") + ), + A({"class": "netInfoResponseTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Response", + $collapsed: "$file|hideResponse"}, + $STR("Response") + ), + A({"class": "netInfoCacheTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Cache", + $collapsed: "$file|hideCache"}, + $STR("Cache") + ), + A({"class": "netInfoHtmlTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab", + view: "Html", + $collapsed: "$file|hideHtml"}, + $STR("HTML") + ) + ), + + infoBodies: + DIV({"class": "netInfoBodies outerFocusRow"}, + TABLE({"class": "netInfoParamsText netInfoText netInfoParamsTable", "role": "tabpanel", + cellpadding: 0, cellspacing: 0}, TBODY()), + DIV({"class": "netInfoHeadersText netInfoText", "role": "tabpanel"}), + DIV({"class": "netInfoPostText netInfoText", "role": "tabpanel"}), + DIV({"class": "netInfoPutText netInfoText", "role": "tabpanel"}), + PRE({"class": "netInfoResponseText netInfoText", "role": "tabpanel"}), + DIV({"class": "netInfoCacheText netInfoText", "role": "tabpanel"}, + TABLE({"class": "netInfoCacheTable", cellpadding: 0, cellspacing: 0, "role": "presentation"}, + TBODY({"role": "list", "aria-label": $STR("Cache")}) + ) + ), + DIV({"class": "netInfoHtmlText netInfoText", "role": "tabpanel"}, + IFRAME({"class": "netInfoHtmlPreview", "role": "document"}) + ) + ), + + headerDataTag: + FOR("param", "$headers", + TR({"role": "listitem"}, + TD({"class": "netInfoParamName", "role": "presentation"}, + TAG("$param|getNameTag", {param: "$param"}) + ), + TD({"class": "netInfoParamValue", "role": "list", "aria-label": "$param.name"}, + FOR("line", "$param|getParamValueIterator", + CODE({"class": "focusRow subFocusRow", "role": "listitem"}, "$line") + ) + ) + ) + ), + + customTab: + A({"class": "netInfo$tabId\\Tab netInfoTab", onclick: "$onClickTab", view: "$tabId", "role": "tab"}, + "$tabTitle" + ), + + customBody: + DIV({"class": "netInfo$tabId\\Text netInfoText", "role": "tabpanel"}), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + nameTag: + SPAN("$param|getParamName"), + + nameWithTooltipTag: + SPAN({title: "$param.name"}, "$param|getParamName"), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getNameTag: function(param) + { + return (this.getParamName(param) == param.name) ? this.nameTag : this.nameWithTooltipTag; + }, + + getParamName: function(param) + { + var limit = 25; + var name = param.name; + if (name.length > limit) + name = name.substr(0, limit) + "..."; + return name; + }, + + getParamTitle: function(param) + { + var limit = 25; + var name = param.name; + if (name.length > limit) + return name; + return ""; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + hideParams: function(file) + { + return !file.urlParams || !file.urlParams.length; + }, + + hidePost: function(file) + { + return file.method.toUpperCase() != "POST"; + }, + + hidePut: function(file) + { + return file.method.toUpperCase() != "PUT"; + }, + + hideResponse: function(file) + { + return false; + //return file.category in binaryFileCategories; + }, + + hideCache: function(file) + { + return true; + //xxxHonza: I don't see any reason why not to display the cache also info for images. + return !file.cacheEntry; // || file.category=="image"; + }, + + hideHtml: function(file) + { + return (file.mimeType != "text/html") && (file.mimeType != "application/xhtml+xml"); + }, + + onClickTab: function(event) + { + this.selectTab(event.currentTarget || event.srcElement); + }, + + getParamValueIterator: function(param) + { + // TODO: xxxpedro console2 + return param.value; + + // This value is inserted into CODE element and so, make sure the HTML isn't escaped (1210). + // This is why the second parameter is true. + // The CODE (with style white-space:pre) element preserves whitespaces so they are + // displayed the same, as they come from the server (1194). + // In case of a long header values of post parameters the value must be wrapped (2105). + return wrapText(param.value, true); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + appendTab: function(netInfoBox, tabId, tabTitle) + { + // Create new tab and body. + var args = {tabId: tabId, tabTitle: tabTitle}; + ///this.customTab.append(args, netInfoBox.getElementsByClassName("netInfoTabs").item(0)); + ///this.customBody.append(args, netInfoBox.getElementsByClassName("netInfoBodies").item(0)); + this.customTab.append(args, $$(".netInfoTabs", netInfoBox)[0]); + this.customBody.append(args, $$(".netInfoBodies", netInfoBox)[0]); + }, + + selectTabByName: function(netInfoBox, tabName) + { + var tab = getChildByClass(netInfoBox, "netInfoTabs", "netInfo"+tabName+"Tab"); + if (tab) + this.selectTab(tab); + }, + + selectTab: function(tab) + { + var view = tab.getAttribute("view"); + + var netInfoBox = getAncestorByClass(tab, "netInfoBody"); + + var selectedTab = netInfoBox.selectedTab; + + if (selectedTab) + { + //netInfoBox.selectedText.removeAttribute("selected"); + removeClass(netInfoBox.selectedText, "netInfoTextSelected"); + + removeClass(selectedTab, "netInfoTabSelected"); + //selectedTab.removeAttribute("selected"); + selectedTab.setAttribute("aria-selected", "false"); + } + + var textBodyName = "netInfo" + view + "Text"; + + selectedTab = netInfoBox.selectedTab = tab; + + netInfoBox.selectedText = $$("."+textBodyName, netInfoBox)[0]; + //netInfoBox.selectedText = netInfoBox.getElementsByClassName(textBodyName).item(0); + + //netInfoBox.selectedText.setAttribute("selected", "true"); + setClass(netInfoBox.selectedText, "netInfoTextSelected"); + + setClass(selectedTab, "netInfoTabSelected"); + selectedTab.setAttribute("selected", "true"); + selectedTab.setAttribute("aria-selected", "true"); + + var file = Firebug.getRepObject(netInfoBox); + + //var context = Firebug.getElementPanel(netInfoBox).context; + var context = Firebug.chrome; + + this.updateInfo(netInfoBox, file, context); + }, + + updateInfo: function(netInfoBox, file, context) + { + if (FBTrace.DBG_NET) + FBTrace.sysout("net.updateInfo; file", file); + + if (!netInfoBox) + { + if (FBTrace.DBG_NET || FBTrace.DBG_ERRORS) + FBTrace.sysout("net.updateInfo; ERROR netInfo == null " + file.href, file); + return; + } + + var tab = netInfoBox.selectedTab; + + if (hasClass(tab, "netInfoParamsTab")) + { + if (file.urlParams && !netInfoBox.urlParamsPresented) + { + netInfoBox.urlParamsPresented = true; + this.insertHeaderRows(netInfoBox, file.urlParams, "Params"); + } + } + + else if (hasClass(tab, "netInfoHeadersTab")) + { + var headersText = $$(".netInfoHeadersText", netInfoBox)[0]; + //var headersText = netInfoBox.getElementsByClassName("netInfoHeadersText").item(0); + + if (file.responseHeaders && !netInfoBox.responseHeadersPresented) + { + netInfoBox.responseHeadersPresented = true; + NetInfoHeaders.renderHeaders(headersText, file.responseHeaders, "ResponseHeaders"); + } + + if (file.requestHeaders && !netInfoBox.requestHeadersPresented) + { + netInfoBox.requestHeadersPresented = true; + NetInfoHeaders.renderHeaders(headersText, file.requestHeaders, "RequestHeaders"); + } + } + + else if (hasClass(tab, "netInfoPostTab")) + { + if (!netInfoBox.postPresented) + { + netInfoBox.postPresented = true; + //var postText = netInfoBox.getElementsByClassName("netInfoPostText").item(0); + var postText = $$(".netInfoPostText", netInfoBox)[0]; + NetInfoPostData.render(context, postText, file); + } + } + + else if (hasClass(tab, "netInfoPutTab")) + { + if (!netInfoBox.putPresented) + { + netInfoBox.putPresented = true; + //var putText = netInfoBox.getElementsByClassName("netInfoPutText").item(0); + var putText = $$(".netInfoPutText", netInfoBox)[0]; + NetInfoPostData.render(context, putText, file); + } + } + + else if (hasClass(tab, "netInfoResponseTab") && file.loaded && !netInfoBox.responsePresented) + { + ///var responseTextBox = netInfoBox.getElementsByClassName("netInfoResponseText").item(0); + var responseTextBox = $$(".netInfoResponseText", netInfoBox)[0]; + if (file.category == "image") + { + netInfoBox.responsePresented = true; + + var responseImage = netInfoBox.ownerDocument.createElement("img"); + responseImage.src = file.href; + + clearNode(responseTextBox); + responseTextBox.appendChild(responseImage, responseTextBox); + } + else ///if (!(binaryCategoryMap.hasOwnProperty(file.category))) + { + this.setResponseText(file, netInfoBox, responseTextBox, context); + } + } + + else if (hasClass(tab, "netInfoCacheTab") && file.loaded && !netInfoBox.cachePresented) + { + var responseTextBox = netInfoBox.getElementsByClassName("netInfoCacheText").item(0); + if (file.cacheEntry) { + netInfoBox.cachePresented = true; + this.insertHeaderRows(netInfoBox, file.cacheEntry, "Cache"); + } + } + + else if (hasClass(tab, "netInfoHtmlTab") && file.loaded && !netInfoBox.htmlPresented) + { + netInfoBox.htmlPresented = true; + + var text = Utils.getResponseText(file, context); + + ///var iframe = netInfoBox.getElementsByClassName("netInfoHtmlPreview").item(0); + var iframe = $$(".netInfoHtmlPreview", netInfoBox)[0]; + + ///iframe.contentWindow.document.body.innerHTML = text; + + // TODO: xxxpedro net - remove scripts + var reScript = //gi; + + text = text.replace(reScript, ""); + + iframe.contentWindow.document.write(text); + iframe.contentWindow.document.close(); + } + + // Notify listeners about update so, content of custom tabs can be updated. + dispatch(NetInfoBody.fbListeners, "updateTabBody", [netInfoBox, file, context]); + }, + + setResponseText: function(file, netInfoBox, responseTextBox, context) + { + //********************************************** + //********************************************** + //********************************************** + netInfoBox.responsePresented = true; + // line breaks somehow are different in IE + // make this only once in the initialization? we don't have net panels and modules yet. + if (isIE) + responseTextBox.style.whiteSpace = "nowrap"; + + responseTextBox[ + typeof responseTextBox.textContent != "undefined" ? + "textContent" : + "innerText" + ] = file.responseText; + + return; + //********************************************** + //********************************************** + //********************************************** + + // Get response text and make sure it doesn't exceed the max limit. + var text = Utils.getResponseText(file, context); + var limit = Firebug.netDisplayedResponseLimit + 15; + var limitReached = text ? (text.length > limit) : false; + if (limitReached) + text = text.substr(0, limit) + "..."; + + // Insert the response into the UI. + if (text) + insertWrappedText(text, responseTextBox); + else + insertWrappedText("", responseTextBox); + + // Append a message informing the user that the response isn't fully displayed. + if (limitReached) + { + var object = { + text: $STR("net.responseSizeLimitMessage"), + onClickLink: function() { + var panel = context.getPanel("net", true); + panel.openResponseInTab(file); + } + }; + Firebug.NetMonitor.ResponseSizeLimit.append(object, responseTextBox); + } + + netInfoBox.responsePresented = true; + + if (FBTrace.DBG_NET) + FBTrace.sysout("net.setResponseText; response text updated"); + }, + + insertHeaderRows: function(netInfoBox, headers, tableName, rowName) + { + if (!headers.length) + return; + + var headersTable = $$(".netInfo"+tableName+"Table", netInfoBox)[0]; + //var headersTable = netInfoBox.getElementsByClassName("netInfo"+tableName+"Table").item(0); + var tbody = getChildByClass(headersTable, "netInfo" + rowName + "Body"); + if (!tbody) + tbody = headersTable.firstChild; + var titleRow = getChildByClass(tbody, "netInfo" + rowName + "Title"); + + this.headerDataTag.insertRows({headers: headers}, titleRow ? titleRow : tbody); + removeClass(titleRow, "collapsed"); + } +}); + +var NetInfoBody = Firebug.NetMonitor.NetInfoBody; + +// ************************************************************************************************ + +/** + * @domplate Used within the Net panel to display raw source of request and response headers + * as well as pretty-formatted summary of these headers. + */ +Firebug.NetMonitor.NetInfoHeaders = domplate(Firebug.Rep, //new Firebug.Listener(), +{ + tag: + DIV({"class": "netInfoHeadersTable", "role": "tabpanel"}, + DIV({"class": "netInfoHeadersGroup netInfoResponseHeadersTitle"}, + SPAN($STR("ResponseHeaders")), + SPAN({"class": "netHeadersViewSource response collapsed", onclick: "$onViewSource", + _sourceDisplayed: false, _rowName: "ResponseHeaders"}, + $STR("net.headers.view source") + ) + ), + TABLE({cellpadding: 0, cellspacing: 0}, + TBODY({"class": "netInfoResponseHeadersBody", "role": "list", + "aria-label": $STR("ResponseHeaders")}) + ), + DIV({"class": "netInfoHeadersGroup netInfoRequestHeadersTitle"}, + SPAN($STR("RequestHeaders")), + SPAN({"class": "netHeadersViewSource request collapsed", onclick: "$onViewSource", + _sourceDisplayed: false, _rowName: "RequestHeaders"}, + $STR("net.headers.view source") + ) + ), + TABLE({cellpadding: 0, cellspacing: 0}, + TBODY({"class": "netInfoRequestHeadersBody", "role": "list", + "aria-label": $STR("RequestHeaders")}) + ) + ), + + sourceTag: + TR({"role": "presentation"}, + TD({colspan: 2, "role": "presentation"}, + PRE({"class": "source"}) + ) + ), + + onViewSource: function(event) + { + var target = event.target; + var requestHeaders = (target.rowName == "RequestHeaders"); + + var netInfoBox = getAncestorByClass(target, "netInfoBody"); + var file = netInfoBox.repObject; + + if (target.sourceDisplayed) + { + var headers = requestHeaders ? file.requestHeaders : file.responseHeaders; + this.insertHeaderRows(netInfoBox, headers, target.rowName); + target.innerHTML = $STR("net.headers.view source"); + } + else + { + var source = requestHeaders ? file.requestHeadersText : file.responseHeadersText; + this.insertSource(netInfoBox, source, target.rowName); + target.innerHTML = $STR("net.headers.pretty print"); + } + + target.sourceDisplayed = !target.sourceDisplayed; + + cancelEvent(event); + }, + + insertSource: function(netInfoBox, source, rowName) + { + // This breaks copy to clipboard. + //if (source) + // source = source.replace(/\r\n/gm, "\\r\\n\r\n"); + + ///var tbody = netInfoBox.getElementsByClassName("netInfo" + rowName + "Body").item(0); + var tbody = $$(".netInfo" + rowName + "Body", netInfoBox)[0]; + var node = this.sourceTag.replace({}, tbody); + ///var sourceNode = node.getElementsByClassName("source").item(0); + var sourceNode = $$(".source", node)[0]; + sourceNode.innerHTML = source; + }, + + insertHeaderRows: function(netInfoBox, headers, rowName) + { + var headersTable = $$(".netInfoHeadersTable", netInfoBox)[0]; + var tbody = $$(".netInfo" + rowName + "Body", headersTable)[0]; + + //var headersTable = netInfoBox.getElementsByClassName("netInfoHeadersTable").item(0); + //var tbody = headersTable.getElementsByClassName("netInfo" + rowName + "Body").item(0); + + clearNode(tbody); + + if (!headers.length) + return; + + NetInfoBody.headerDataTag.insertRows({headers: headers}, tbody); + + var titleRow = getChildByClass(headersTable, "netInfo" + rowName + "Title"); + removeClass(titleRow, "collapsed"); + }, + + init: function(parent) + { + var rootNode = this.tag.append({}, parent); + + var netInfoBox = getAncestorByClass(parent, "netInfoBody"); + var file = netInfoBox.repObject; + + var viewSource; + + viewSource = $$(".request", rootNode)[0]; + //viewSource = rootNode.getElementsByClassName("netHeadersViewSource request").item(0); + if (file.requestHeadersText) + removeClass(viewSource, "collapsed"); + + viewSource = $$(".response", rootNode)[0]; + //viewSource = rootNode.getElementsByClassName("netHeadersViewSource response").item(0); + if (file.responseHeadersText) + removeClass(viewSource, "collapsed"); + }, + + renderHeaders: function(parent, headers, rowName) + { + if (!parent.firstChild) + this.init(parent); + + this.insertHeaderRows(parent, headers, rowName); + } +}); + +var NetInfoHeaders = Firebug.NetMonitor.NetInfoHeaders; + +// ************************************************************************************************ + +/** + * @domplate Represents posted data within request info (the info, which is visible when + * a request entry is expanded. This template renders content of the Post tab. + */ +Firebug.NetMonitor.NetInfoPostData = domplate(Firebug.Rep, /*new Firebug.Listener(),*/ +{ + // application/x-www-form-urlencoded + paramsTable: + TABLE({"class": "netInfoPostParamsTable", cellpadding: 0, cellspacing: 0, "role": "presentation"}, + TBODY({"role": "list", "aria-label": $STR("net.label.Parameters")}, + TR({"class": "netInfoPostParamsTitle", "role": "presentation"}, + TD({colspan: 3, "role": "presentation"}, + DIV({"class": "netInfoPostParams"}, + $STR("net.label.Parameters"), + SPAN({"class": "netInfoPostContentType"}, + "application/x-www-form-urlencoded" + ) + ) + ) + ) + ) + ), + + // multipart/form-data + partsTable: + TABLE({"class": "netInfoPostPartsTable", cellpadding: 0, cellspacing: 0, "role": "presentation"}, + TBODY({"role": "list", "aria-label": $STR("net.label.Parts")}, + TR({"class": "netInfoPostPartsTitle", "role": "presentation"}, + TD({colspan: 2, "role":"presentation" }, + DIV({"class": "netInfoPostParams"}, + $STR("net.label.Parts"), + SPAN({"class": "netInfoPostContentType"}, + "multipart/form-data" + ) + ) + ) + ) + ) + ), + + // application/json + jsonTable: + TABLE({"class": "netInfoPostJSONTable", cellpadding: 0, cellspacing: 0, "role": "presentation"}, + ///TBODY({"role": "list", "aria-label": $STR("jsonviewer.tab.JSON")}, + TBODY({"role": "list", "aria-label": $STR("JSON")}, + TR({"class": "netInfoPostJSONTitle", "role": "presentation"}, + TD({"role": "presentation" }, + DIV({"class": "netInfoPostParams"}, + ///$STR("jsonviewer.tab.JSON") + $STR("JSON") + ) + ) + ), + TR( + TD({"class": "netInfoPostJSONBody"}) + ) + ) + ), + + // application/xml + xmlTable: + TABLE({"class": "netInfoPostXMLTable", cellpadding: 0, cellspacing: 0, "role": "presentation"}, + TBODY({"role": "list", "aria-label": $STR("xmlviewer.tab.XML")}, + TR({"class": "netInfoPostXMLTitle", "role": "presentation"}, + TD({"role": "presentation" }, + DIV({"class": "netInfoPostParams"}, + $STR("xmlviewer.tab.XML") + ) + ) + ), + TR( + TD({"class": "netInfoPostXMLBody"}) + ) + ) + ), + + sourceTable: + TABLE({"class": "netInfoPostSourceTable", cellpadding: 0, cellspacing: 0, "role": "presentation"}, + TBODY({"role": "list", "aria-label": $STR("net.label.Source")}, + TR({"class": "netInfoPostSourceTitle", "role": "presentation"}, + TD({colspan: 2, "role": "presentation"}, + DIV({"class": "netInfoPostSource"}, + $STR("net.label.Source") + ) + ) + ) + ) + ), + + sourceBodyTag: + TR({"role": "presentation"}, + TD({colspan: 2, "role": "presentation"}, + FOR("line", "$param|getParamValueIterator", + CODE({"class":"focusRow subFocusRow" , "role": "listitem"},"$line") + ) + ) + ), + + getParamValueIterator: function(param) + { + return NetInfoBody.getParamValueIterator(param); + }, + + render: function(context, parentNode, file) + { + //debugger; + var spy = getAncestorByClass(parentNode, "spyHead"); + var spyObject = spy.repObject; + var data = spyObject.data; + + ///var contentType = Utils.findHeader(file.requestHeaders, "content-type"); + var contentType = file.mimeType; + + ///var text = Utils.getPostText(file, context, true); + ///if (text == undefined) + /// return; + + ///if (Utils.isURLEncodedRequest(file, context)) + // fake Utils.isURLEncodedRequest identification + if (contentType && contentType == "application/x-www-form-urlencoded" || + data && data.indexOf("=") != -1) + { + ///var lines = text.split("\n"); + ///var params = parseURLEncodedText(lines[lines.length-1]); + var params = parseURLEncodedTextArray(data); + if (params) + this.insertParameters(parentNode, params); + } + + ///if (Utils.isMultiPartRequest(file, context)) + ///{ + /// var data = this.parseMultiPartText(file, context); + /// if (data) + /// this.insertParts(parentNode, data); + ///} + + // moved to the top + ///var contentType = Utils.findHeader(file.requestHeaders, "content-type"); + + ///if (Firebug.JSONViewerModel.isJSON(contentType)) + var jsonData = { + responseText: data + }; + + if (Firebug.JSONViewerModel.isJSON(contentType, data)) + ///this.insertJSON(parentNode, file, context); + this.insertJSON(parentNode, jsonData, context); + + ///if (Firebug.XMLViewerModel.isXML(contentType)) + /// this.insertXML(parentNode, file, context); + + ///var postText = Utils.getPostText(file, context); + ///postText = Utils.formatPostText(postText); + var postText = data; + if (postText) + this.insertSource(parentNode, postText); + }, + + insertParameters: function(parentNode, params) + { + if (!params || !params.length) + return; + + var paramTable = this.paramsTable.append({object:{}}, parentNode); + var row = $$(".netInfoPostParamsTitle", paramTable)[0]; + //var paramTable = this.paramsTable.append(null, parentNode); + //var row = paramTable.getElementsByClassName("netInfoPostParamsTitle").item(0); + + var tbody = paramTable.getElementsByTagName("tbody")[0]; + + NetInfoBody.headerDataTag.insertRows({headers: params}, row); + }, + + insertParts: function(parentNode, data) + { + if (!data.params || !data.params.length) + return; + + var partsTable = this.partsTable.append({object:{}}, parentNode); + var row = $$(".netInfoPostPartsTitle", paramTable)[0]; + //var partsTable = this.partsTable.append(null, parentNode); + //var row = partsTable.getElementsByClassName("netInfoPostPartsTitle").item(0); + + NetInfoBody.headerDataTag.insertRows({headers: data.params}, row); + }, + + insertJSON: function(parentNode, file, context) + { + ///var text = Utils.getPostText(file, context); + var text = file.responseText; + ///var data = parseJSONString(text, "http://" + file.request.originalURI.host); + var data = parseJSONString(text); + if (!data) + return; + + ///var jsonTable = this.jsonTable.append(null, parentNode); + var jsonTable = this.jsonTable.append({}, parentNode); + ///var jsonBody = jsonTable.getElementsByClassName("netInfoPostJSONBody").item(0); + var jsonBody = $$(".netInfoPostJSONBody", jsonTable)[0]; + + if (!this.toggles) + this.toggles = {}; + + Firebug.DOMPanel.DirTable.tag.replace( + {object: data, toggles: this.toggles}, jsonBody); + }, + + insertXML: function(parentNode, file, context) + { + var text = Utils.getPostText(file, context); + + var jsonTable = this.xmlTable.append(null, parentNode); + ///var jsonBody = jsonTable.getElementsByClassName("netInfoPostXMLBody").item(0); + var jsonBody = $$(".netInfoPostXMLBody", jsonTable)[0]; + + Firebug.XMLViewerModel.insertXML(jsonBody, text); + }, + + insertSource: function(parentNode, text) + { + var sourceTable = this.sourceTable.append({object:{}}, parentNode); + var row = $$(".netInfoPostSourceTitle", sourceTable)[0]; + //var sourceTable = this.sourceTable.append(null, parentNode); + //var row = sourceTable.getElementsByClassName("netInfoPostSourceTitle").item(0); + + var param = {value: [text]}; + this.sourceBodyTag.insertRows({param: param}, row); + }, + + parseMultiPartText: function(file, context) + { + var text = Utils.getPostText(file, context); + if (text == undefined) + return null; + + FBTrace.sysout("net.parseMultiPartText; boundary: ", text); + + var boundary = text.match(/\s*boundary=\s*(.*)/)[1]; + + var divider = "\r\n\r\n"; + var bodyStart = text.indexOf(divider); + var body = text.substr(bodyStart + divider.length); + + var postData = {}; + postData.mimeType = "multipart/form-data"; + postData.params = []; + + var parts = body.split("--" + boundary); + for (var i=0; i 1) ? m[1] : "", + value: trim(part[1]) + }); + } + + return postData; + } +}); + +var NetInfoPostData = Firebug.NetMonitor.NetInfoPostData; + +// ************************************************************************************************ + + +// TODO: xxxpedro net i18n +var $STRP = function(a){return a;}; + +Firebug.NetMonitor.NetLimit = domplate(Firebug.Rep, +{ + collapsed: true, + + tableTag: + DIV( + TABLE({width: "100%", cellpadding: 0, cellspacing: 0}, + TBODY() + ) + ), + + limitTag: + TR({"class": "netRow netLimitRow", $collapsed: "$isCollapsed"}, + TD({"class": "netCol netLimitCol", colspan: 6}, + TABLE({cellpadding: 0, cellspacing: 0}, + TBODY( + TR( + TD( + SPAN({"class": "netLimitLabel"}, + $STRP("plural.Limit_Exceeded", [0]) + ) + ), + TD({style: "width:100%"}), + TD( + BUTTON({"class": "netLimitButton", title: "$limitPrefsTitle", + onclick: "$onPreferences"}, + $STR("LimitPrefs") + ) + ), + TD(" ") + ) + ) + ) + ) + ), + + isCollapsed: function() + { + return this.collapsed; + }, + + onPreferences: function(event) + { + openNewTab("about:config"); + }, + + updateCounter: function(row) + { + removeClass(row, "collapsed"); + + // Update info within the limit row. + var limitLabel = row.getElementsByClassName("netLimitLabel").item(0); + limitLabel.firstChild.nodeValue = $STRP("plural.Limit_Exceeded", [row.limitInfo.totalCount]); + }, + + createTable: function(parent, limitInfo) + { + var table = this.tableTag.replace({}, parent); + var row = this.createRow(table.firstChild.firstChild, limitInfo); + return [table, row]; + }, + + createRow: function(parent, limitInfo) + { + var row = this.limitTag.insertRows(limitInfo, parent, this)[0]; + row.limitInfo = limitInfo; + return row; + }, + + // nsIPrefObserver + observe: function(subject, topic, data) + { + // We're observing preferences only. + if (topic != "nsPref:changed") + return; + + if (data.indexOf("net.logLimit") != -1) + this.updateMaxLimit(); + }, + + updateMaxLimit: function() + { + var value = Firebug.getPref(Firebug.prefDomain, "net.logLimit"); + maxQueueRequests = value ? value : maxQueueRequests; + } +}); + +var NetLimit = Firebug.NetMonitor.NetLimit; + +// ************************************************************************************************ + +Firebug.NetMonitor.ResponseSizeLimit = domplate(Firebug.Rep, +{ + tag: + DIV({"class": "netInfoResponseSizeLimit"}, + SPAN("$object.beforeLink"), + A({"class": "objectLink", onclick: "$onClickLink"}, + "$object.linkText" + ), + SPAN("$object.afterLink") + ), + + reLink: /^(.*)(.*)<\/a>(.*$)/, + append: function(obj, parent) + { + var m = obj.text.match(this.reLink); + return this.tag.append({onClickLink: obj.onClickLink, + object: { + beforeLink: m[1], + linkText: m[2], + afterLink: m[3] + }}, parent, this); + } +}); + +// ************************************************************************************************ +// ************************************************************************************************ + +Firebug.NetMonitor.Utils = +{ + findHeader: function(headers, name) + { + if (!headers) + return null; + + name = name.toLowerCase(); + for (var i = 0; i < headers.length; ++i) + { + var headerName = headers[i].name.toLowerCase(); + if (headerName == name) + return headers[i].value; + } + }, + + formatPostText: function(text) + { + if (text instanceof XMLDocument) + return getElementXML(text.documentElement); + else + return text; + }, + + getPostText: function(file, context, noLimit) + { + if (!file.postText) + { + file.postText = readPostTextFromRequest(file.request, context); + + if (!file.postText && context) + file.postText = readPostTextFromPage(file.href, context); + } + + if (!file.postText) + return file.postText; + + var limit = Firebug.netDisplayedPostBodyLimit; + if (file.postText.length > limit && !noLimit) + { + return cropString(file.postText, limit, + "\n\n... " + $STR("net.postDataSizeLimitMessage") + " ...\n\n"); + } + + return file.postText; + }, + + getResponseText: function(file, context) + { + // The response can be also empty string so, check agains "undefined". + return (typeof(file.responseText) != "undefined")? file.responseText : + context.sourceCache.loadText(file.href, file.method, file); + }, + + isURLEncodedRequest: function(file, context) + { + var text = Utils.getPostText(file, context); + if (text && text.toLowerCase().indexOf("content-type: application/x-www-form-urlencoded") == 0) + return true; + + // The header value doesn't have to be always exactly "application/x-www-form-urlencoded", + // there can be even charset specified. So, use indexOf rather than just "==". + var headerValue = Utils.findHeader(file.requestHeaders, "content-type"); + if (headerValue && headerValue.indexOf("application/x-www-form-urlencoded") == 0) + return true; + + return false; + }, + + isMultiPartRequest: function(file, context) + { + var text = Utils.getPostText(file, context); + if (text && text.toLowerCase().indexOf("content-type: multipart/form-data") == 0) + return true; + return false; + }, + + getMimeType: function(mimeType, uri) + { + if (!mimeType || !(mimeCategoryMap.hasOwnProperty(mimeType))) + { + var ext = getFileExtension(uri); + if (!ext) + return mimeType; + else + { + var extMimeType = mimeExtensionMap[ext.toLowerCase()]; + return extMimeType ? extMimeType : mimeType; + } + } + else + return mimeType; + }, + + getDateFromSeconds: function(s) + { + var d = new Date(); + d.setTime(s*1000); + return d; + }, + + getHttpHeaders: function(request, file) + { + try + { + var http = QI(request, Ci.nsIHttpChannel); + file.status = request.responseStatus; + + // xxxHonza: is there any problem to do this in requestedFile method? + file.method = http.requestMethod; + file.urlParams = parseURLParams(file.href); + file.mimeType = Utils.getMimeType(request.contentType, request.name); + + if (!file.responseHeaders && Firebug.collectHttpHeaders) + { + var requestHeaders = [], responseHeaders = []; + + http.visitRequestHeaders({ + visitHeader: function(name, value) + { + requestHeaders.push({name: name, value: value}); + } + }); + http.visitResponseHeaders({ + visitHeader: function(name, value) + { + responseHeaders.push({name: name, value: value}); + } + }); + + file.requestHeaders = requestHeaders; + file.responseHeaders = responseHeaders; + } + } + catch (exc) + { + // An exception can be throwed e.g. when the request is aborted and + // request.responseStatus is accessed. + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("net.getHttpHeaders FAILS " + file.href, exc); + } + }, + + isXHR: function(request) + { + try + { + var callbacks = request.notificationCallbacks; + var xhrRequest = callbacks ? callbacks.getInterface(Ci.nsIXMLHttpRequest) : null; + if (FBTrace.DBG_NET) + FBTrace.sysout("net.isXHR; " + (xhrRequest != null) + ", " + safeGetName(request)); + + return (xhrRequest != null); + } + catch (exc) + { + } + + return false; + }, + + getFileCategory: function(file) + { + if (file.category) + { + if (FBTrace.DBG_NET) + FBTrace.sysout("net.getFileCategory; current: " + file.category + " for: " + file.href, file); + return file.category; + } + + if (file.isXHR) + { + if (FBTrace.DBG_NET) + FBTrace.sysout("net.getFileCategory; XHR for: " + file.href, file); + return file.category = "xhr"; + } + + if (!file.mimeType) + { + var ext = getFileExtension(file.href); + if (ext) + file.mimeType = mimeExtensionMap[ext.toLowerCase()]; + } + + /*if (FBTrace.DBG_NET) + FBTrace.sysout("net.getFileCategory; " + mimeCategoryMap[file.mimeType] + + ", mimeType: " + file.mimeType + " for: " + file.href, file);*/ + + if (!file.mimeType) + return ""; + + // Solve cases when charset is also specified, eg "text/html; charset=UTF-8". + var mimeType = file.mimeType; + if (mimeType) + mimeType = mimeType.split(";")[0]; + + return (file.category = mimeCategoryMap[mimeType]); + } +}; + +var Utils = Firebug.NetMonitor.Utils; + +// ************************************************************************************************ + +//Firebug.registerRep(Firebug.NetMonitor.NetRequestTable); +//Firebug.registerActivableModule(Firebug.NetMonitor); +//Firebug.registerPanel(NetPanel); + +Firebug.registerModule(Firebug.NetMonitor); +//Firebug.registerRep(Firebug.NetMonitor.BreakpointRep); + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// Constants + +//const Cc = Components.classes; +//const Ci = Components.interfaces; + +// List of contexts with XHR spy attached. +var contexts = []; + +// ************************************************************************************************ +// Spy Module + +/** + * @module Represents a XHR Spy module. The main purpose of the XHR Spy feature is to monitor + * XHR activity of the current page and create appropriate log into the Console panel. + * This feature can be controlled by an option Show XMLHttpRequests (from within the + * console panel). + * + * The module is responsible for attaching/detaching a HTTP Observers when Firebug is + * activated/deactivated for a site. + */ +Firebug.Spy = extend(Firebug.Module, +/** @lends Firebug.Spy */ +{ + dispatchName: "spy", + + initialize: function() + { + if (Firebug.TraceModule) + Firebug.TraceModule.addListener(this.TraceListener); + + Firebug.Module.initialize.apply(this, arguments); + }, + + shutdown: function() + { + Firebug.Module.shutdown.apply(this, arguments); + + if (Firebug.TraceModule) + Firebug.TraceModule.removeListener(this.TraceListener); + }, + + initContext: function(context) + { + context.spies = []; + + if (Firebug.showXMLHttpRequests && Firebug.Console.isAlwaysEnabled()) + this.attachObserver(context, context.window); + + if (FBTrace.DBG_SPY) + FBTrace.sysout("spy.initContext " + contexts.length + " ", context.getName()); + }, + + destroyContext: function(context) + { + // For any spies that are in progress, remove our listeners so that they don't leak + this.detachObserver(context, null); + + if (FBTrace.DBG_SPY && context.spies.length) + FBTrace.sysout("spy.destroyContext; ERROR There are leaking Spies (" + + context.spies.length + ") " + context.getName()); + + delete context.spies; + + if (FBTrace.DBG_SPY) + FBTrace.sysout("spy.destroyContext " + contexts.length + " ", context.getName()); + }, + + watchWindow: function(context, win) + { + if (Firebug.showXMLHttpRequests && Firebug.Console.isAlwaysEnabled()) + this.attachObserver(context, win); + }, + + unwatchWindow: function(context, win) + { + try + { + // This make sure that the existing context is properly removed from "contexts" array. + this.detachObserver(context, win); + } + catch (ex) + { + // Get exceptions here sometimes, so let's just ignore them + // since the window is going away anyhow + ERROR(ex); + } + }, + + updateOption: function(name, value) + { + // XXXjjb Honza, if Console.isEnabled(context) false, then this can't be called, + // but somehow seems not correct + if (name == "showXMLHttpRequests") + { + var tach = value ? this.attachObserver : this.detachObserver; + for (var i = 0; i < TabWatcher.contexts.length; ++i) + { + var context = TabWatcher.contexts[i]; + iterateWindows(context.window, function(win) + { + tach.apply(this, [context, win]); + }); + } + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // Attaching Spy to XHR requests. + + /** + * Returns false if Spy should not be attached to XHRs executed by the specified window. + */ + skipSpy: function(win) + { + if (!win) + return true; + + // Don't attach spy to chrome. + var uri = safeGetWindowLocation(win); + if (uri && (uri.indexOf("about:") == 0 || uri.indexOf("chrome:") == 0)) + return true; + }, + + attachObserver: function(context, win) + { + if (Firebug.Spy.skipSpy(win)) + return; + + for (var i=0; insIHttpChannel. + * Returns null if the request doesn't represent XHR. + */ + getXHR: function(request) + { + // Does also query-interface for nsIHttpChannel. + if (!(request instanceof Ci.nsIHttpChannel)) + return null; + + try + { + var callbacks = request.notificationCallbacks; + return (callbacks ? callbacks.getInterface(Ci.nsIXMLHttpRequest) : null); + } + catch (exc) + { + if (exc.name == "NS_NOINTERFACE") + { + if (FBTrace.DBG_SPY) + FBTrace.sysout("spy.getXHR; Request is not nsIXMLHttpRequest: " + + safeGetRequestName(request)); + } + } + + return null; + } +}); + + + + + +// ************************************************************************************************ + +/* +function getSpyForXHR(request, xhrRequest, context, noCreate) +{ + var spy = null; + + // Iterate all existing spy objects in this context and look for one that is + // already created for this request. + var length = context.spies.length; + for (var i=0; i= 3) + { + var netInfoBox = getChildByClass(spy.logRow, "spyHead", "netInfoBody"); + if (netInfoBox) + { + netInfoBox.htmlPresented = false; + netInfoBox.responsePresented = false; + } + } + + // If the request is loading update the end time. + if (spy.xhrRequest.readyState == 3) + { + spy.responseTime = spy.endTime - spy.sendTime; + updateTime(spy); + } + + // Request loaded. Get all the info from the request now, just in case the + // XHR would be aborted in the original onReadyStateChange handler. + if (spy.xhrRequest.readyState == 4) + { + // Cumulate response so, multipart response content is properly displayed. + if (SpyHttpActivityObserver.getActivityDistributor()) + spy.responseText += spy.xhrRequest.responseText; + else + { + // xxxHonza: remove from FB 1.6 + if (!spy.responseText) + spy.responseText = spy.xhrRequest.responseText; + } + + // The XHR is loaded now (used also by the activity observer). + spy.loaded = true; + + // Update UI. + updateHttpSpyInfo(spy); + + // Notify Net pane about a request beeing loaded. + // xxxHonza: I don't think this is necessary. + var netProgress = spy.context.netProgress; + if (netProgress) + netProgress.post(netProgress.stopFile, [spy.request, spy.endTime, spy.postText, spy.responseText]); + + // Notify registered listeners about finish of the XHR. + dispatch(Firebug.Spy.fbListeners, "onLoad", [spy.context, spy]); + } + + // Pass the event to the original page handler. + callPageHandler(spy, event, originalHandler); +} + +function onHTTPSpyLoad(spy) +{ + if (FBTrace.DBG_SPY) + FBTrace.sysout("spy.onHTTPSpyLoad: " + spy.href, spy); + + // Detach must be done in onLoad (not in onreadystatechange) otherwise + // onAbort would not be handled. + spy.detach(); + + // xxxHonza: Still needed for Fx 3.5 (#502959) + if (!SpyHttpActivityObserver.getActivityDistributor()) + onHTTPSpyReadyStateChange(spy, null); +} + +function onHTTPSpyError(spy) +{ + if (FBTrace.DBG_SPY) + FBTrace.sysout("spy.onHTTPSpyError; " + spy.href, spy); + + spy.detach(); + spy.loaded = true; + + if (spy.logRow) + { + removeClass(spy.logRow, "loading"); + setClass(spy.logRow, "error"); + } +} + +function onHTTPSpyAbort(spy) +{ + if (FBTrace.DBG_SPY) + FBTrace.sysout("spy.onHTTPSpyAbort: " + spy.href, spy); + + spy.detach(); + spy.loaded = true; + + if (spy.logRow) + { + removeClass(spy.logRow, "loading"); + setClass(spy.logRow, "error"); + } + + spy.statusText = "Aborted"; + updateLogRow(spy); + + // Notify Net pane about a request beeing aborted. + // xxxHonza: the net panel shoud find out this itself. + var netProgress = spy.context.netProgress; + if (netProgress) + netProgress.post(netProgress.abortFile, [spy.request, spy.endTime, spy.postText, spy.responseText]); +} +/**/ + +// ************************************************************************************************ + +/** + * @domplate Represents a template for XHRs logged in the Console panel. The body of the + * log (displayed when expanded) is rendered using {@link Firebug.NetMonitor.NetInfoBody}. + */ + +Firebug.Spy.XHR = domplate(Firebug.Rep, +/** @lends Firebug.Spy.XHR */ + +{ + tag: + DIV({"class": "spyHead", _repObject: "$object"}, + TABLE({"class": "spyHeadTable focusRow outerFocusRow", cellpadding: 0, cellspacing: 0, + "role": "listitem", "aria-expanded": "false"}, + TBODY({"role": "presentation"}, + TR({"class": "spyRow"}, + TD({"class": "spyTitleCol spyCol", onclick: "$onToggleBody"}, + DIV({"class": "spyTitle"}, + "$object|getCaption" + ), + DIV({"class": "spyFullTitle spyTitle"}, + "$object|getFullUri" + ) + ), + TD({"class": "spyCol"}, + DIV({"class": "spyStatus"}, "$object|getStatus") + ), + TD({"class": "spyCol"}, + SPAN({"class": "spyIcon"}) + ), + TD({"class": "spyCol"}, + SPAN({"class": "spyTime"}) + ), + TD({"class": "spyCol"}, + TAG(FirebugReps.SourceLink.tag, {object: "$object.sourceLink"}) + ) + ) + ) + ) + ), + + getCaption: function(spy) + { + return spy.method.toUpperCase() + " " + cropString(spy.getURL(), 100); + }, + + getFullUri: function(spy) + { + return spy.method.toUpperCase() + " " + spy.getURL(); + }, + + getStatus: function(spy) + { + var text = ""; + if (spy.statusCode) + text += spy.statusCode + " "; + + if (spy.statusText) + return text += spy.statusText; + + return text; + }, + + onToggleBody: function(event) + { + var target = event.currentTarget || event.srcElement; + var logRow = getAncestorByClass(target, "logRow-spy"); + + if (isLeftClick(event)) + { + toggleClass(logRow, "opened"); + + var spy = getChildByClass(logRow, "spyHead").repObject; + var spyHeadTable = getAncestorByClass(target, "spyHeadTable"); + + if (hasClass(logRow, "opened")) + { + updateHttpSpyInfo(spy, logRow); + if (spyHeadTable) + spyHeadTable.setAttribute('aria-expanded', 'true'); + } + else + { + //var netInfoBox = getChildByClass(spy.logRow, "spyHead", "netInfoBody"); + //dispatch(Firebug.NetMonitor.NetInfoBody.fbListeners, "destroyTabBody", [netInfoBox, spy]); + //if (spyHeadTable) + // spyHeadTable.setAttribute('aria-expanded', 'false'); + } + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + copyURL: function(spy) + { + copyToClipboard(spy.getURL()); + }, + + copyParams: function(spy) + { + var text = spy.postText; + if (!text) + return; + + var url = reEncodeURL(spy, text, true); + copyToClipboard(url); + }, + + copyResponse: function(spy) + { + copyToClipboard(spy.responseText); + }, + + openInTab: function(spy) + { + openNewTab(spy.getURL(), spy.postText); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + supportsObject: function(object) + { + // TODO: xxxpedro spy xhr + return false; + + return object instanceof Firebug.Spy.XMLHttpRequestSpy; + }, + + browseObject: function(spy, context) + { + var url = spy.getURL(); + openNewTab(url); + return true; + }, + + getRealObject: function(spy, context) + { + return spy.xhrRequest; + }, + + getContextMenuItems: function(spy) + { + var items = [ + {label: "CopyLocation", command: bindFixed(this.copyURL, this, spy) } + ]; + + if (spy.postText) + { + items.push( + {label: "CopyLocationParameters", command: bindFixed(this.copyParams, this, spy) } + ); + } + + items.push( + {label: "CopyResponse", command: bindFixed(this.copyResponse, this, spy) }, + "-", + {label: "OpenInTab", command: bindFixed(this.openInTab, this, spy) } + ); + + return items; + } +}); + +// ************************************************************************************************ + +function updateTime(spy) +{ + var timeBox = spy.logRow.getElementsByClassName("spyTime").item(0); + if (spy.responseTime) + timeBox.textContent = " " + formatTime(spy.responseTime); +} + +function updateLogRow(spy) +{ + updateTime(spy); + + var statusBox = spy.logRow.getElementsByClassName("spyStatus").item(0); + statusBox.textContent = Firebug.Spy.XHR.getStatus(spy); + + removeClass(spy.logRow, "loading"); + setClass(spy.logRow, "loaded"); + + try + { + var errorRange = Math.floor(spy.xhrRequest.status/100); + if (errorRange == 4 || errorRange == 5) + setClass(spy.logRow, "error"); + } + catch (exc) + { + } +} + +var updateHttpSpyInfo = function updateHttpSpyInfo(spy, logRow) +{ + if (!spy.logRow && logRow) + spy.logRow = logRow; + + if (!spy.logRow || !hasClass(spy.logRow, "opened")) + return; + + if (!spy.params) + //spy.params = parseURLParams(spy.href+""); + spy.params = parseURLParams(spy.href+""); + + if (!spy.requestHeaders) + spy.requestHeaders = getRequestHeaders(spy); + + if (!spy.responseHeaders && spy.loaded) + spy.responseHeaders = getResponseHeaders(spy); + + var template = Firebug.NetMonitor.NetInfoBody; + var netInfoBox = getChildByClass(spy.logRow, "spyHead", "netInfoBody"); + if (!netInfoBox) + { + var head = getChildByClass(spy.logRow, "spyHead"); + netInfoBox = template.tag.append({"file": spy}, head); + dispatch(template.fbListeners, "initTabBody", [netInfoBox, spy]); + template.selectTabByName(netInfoBox, "Response"); + } + else + { + template.updateInfo(netInfoBox, spy, spy.context); + } +}; + + + +// ************************************************************************************************ + +function getRequestHeaders(spy) +{ + var headers = []; + + var channel = spy.xhrRequest.channel; + if (channel instanceof Ci.nsIHttpChannel) + { + channel.visitRequestHeaders({ + visitHeader: function(name, value) + { + headers.push({name: name, value: value}); + } + }); + } + + return headers; +} + +function getResponseHeaders(spy) +{ + var headers = []; + + try + { + var channel = spy.xhrRequest.channel; + if (channel instanceof Ci.nsIHttpChannel) + { + channel.visitResponseHeaders({ + visitHeader: function(name, value) + { + headers.push({name: name, value: value}); + } + }); + } + } + catch (exc) + { + if (FBTrace.DBG_SPY || FBTrace.DBG_ERRORS) + FBTrace.sysout("spy.getResponseHeaders; EXCEPTION " + + safeGetRequestName(spy.request), exc); + } + + return headers; +} + +// ************************************************************************************************ +// Registration + +Firebug.registerModule(Firebug.Spy); +//Firebug.registerRep(Firebug.Spy.XHR); + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ + +// List of JSON content types. +var contentTypes = +{ + "text/plain": 1, + "text/javascript": 1, + "text/x-javascript": 1, + "text/json": 1, + "text/x-json": 1, + "application/json": 1, + "application/x-json": 1, + "application/javascript": 1, + "application/x-javascript": 1, + "application/json-rpc": 1 +}; + +// ************************************************************************************************ +// Model implementation + +Firebug.JSONViewerModel = extend(Firebug.Module, +{ + dispatchName: "jsonViewer", + initialize: function() + { + Firebug.NetMonitor.NetInfoBody.addListener(this); + + // Used by Firebug.DOMPanel.DirTable domplate. + this.toggles = {}; + }, + + shutdown: function() + { + Firebug.NetMonitor.NetInfoBody.removeListener(this); + }, + + initTabBody: function(infoBox, file) + { + if (FBTrace.DBG_JSONVIEWER) + FBTrace.sysout("jsonviewer.initTabBody", infoBox); + + // Let listeners to parse the JSON. + dispatch(this.fbListeners, "onParseJSON", [file]); + + // The JSON is still no there, try to parse most common cases. + if (!file.jsonObject) + { + ///if (this.isJSON(safeGetContentType(file.request), file.responseText)) + if (this.isJSON(file.mimeType, file.responseText)) + file.jsonObject = this.parseJSON(file); + } + + // The jsonObject is created so, the JSON tab can be displayed. + if (file.jsonObject && hasProperties(file.jsonObject)) + { + Firebug.NetMonitor.NetInfoBody.appendTab(infoBox, "JSON", + ///$STR("jsonviewer.tab.JSON")); + $STR("JSON")); + + if (FBTrace.DBG_JSONVIEWER) + FBTrace.sysout("jsonviewer.initTabBody; JSON object available " + + (typeof(file.jsonObject) != "undefined"), file.jsonObject); + } + }, + + isJSON: function(contentType, data) + { + // Workaround for JSON responses without proper content type + // Let's consider all responses starting with "{" as JSON. In the worst + // case there will be an exception when parsing. This means that no-JSON + // responses (and post data) (with "{") can be parsed unnecessarily, + // which represents a little overhead, but this happens only if the request + // is actually expanded by the user in the UI (Net & Console panels). + + ///var responseText = data ? trimLeft(data) : null; + ///if (responseText && responseText.indexOf("{") == 0) + /// return true; + var responseText = data ? trim(data) : null; + if (responseText && responseText.indexOf("{") == 0) + return true; + + if (!contentType) + return false; + + contentType = contentType.split(";")[0]; + contentType = trim(contentType); + return contentTypes[contentType]; + }, + + // Update listener for TabView + updateTabBody: function(infoBox, file, context) + { + var tab = infoBox.selectedTab; + ///var tabBody = infoBox.getElementsByClassName("netInfoJSONText").item(0); + var tabBody = $$(".netInfoJSONText", infoBox)[0]; + if (!hasClass(tab, "netInfoJSONTab") || tabBody.updated) + return; + + tabBody.updated = true; + + if (file.jsonObject) { + Firebug.DOMPanel.DirTable.tag.replace( + {object: file.jsonObject, toggles: this.toggles}, tabBody); + } + }, + + parseJSON: function(file) + { + var jsonString = new String(file.responseText); + ///return parseJSONString(jsonString, "http://" + file.request.originalURI.host); + return parseJSONString(jsonString); + } +}); + +// ************************************************************************************************ +// Registration + +Firebug.registerModule(Firebug.JSONViewerModel); + +// ************************************************************************************************ +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// Constants + +// List of XML related content types. +var xmlContentTypes = +[ + "text/xml", + "application/xml", + "application/xhtml+xml", + "application/rss+xml", + "application/atom+xml",, + "application/vnd.mozilla.maybe.feed", + "application/rdf+xml", + "application/vnd.mozilla.xul+xml" +]; + +// ************************************************************************************************ +// Model implementation + +/** + * @module Implements viewer for XML based network responses. In order to create a new + * tab wihin network request detail, a listener is registered into + * Firebug.NetMonitor.NetInfoBody object. + */ +Firebug.XMLViewerModel = extend(Firebug.Module, +{ + dispatchName: "xmlViewer", + + initialize: function() + { + ///Firebug.ActivableModule.initialize.apply(this, arguments); + Firebug.Module.initialize.apply(this, arguments); + Firebug.NetMonitor.NetInfoBody.addListener(this); + }, + + shutdown: function() + { + ///Firebug.ActivableModule.shutdown.apply(this, arguments); + Firebug.Module.shutdown.apply(this, arguments); + Firebug.NetMonitor.NetInfoBody.removeListener(this); + }, + + /** + * Check response's content-type and if it's a XML, create a new tab with XML preview. + */ + initTabBody: function(infoBox, file) + { + if (FBTrace.DBG_XMLVIEWER) + FBTrace.sysout("xmlviewer.initTabBody", infoBox); + + // If the response is XML let's display a pretty preview. + ///if (this.isXML(safeGetContentType(file.request))) + if (this.isXML(file.mimeType, file.responseText)) + { + Firebug.NetMonitor.NetInfoBody.appendTab(infoBox, "XML", + ///$STR("xmlviewer.tab.XML")); + $STR("XML")); + + if (FBTrace.DBG_XMLVIEWER) + FBTrace.sysout("xmlviewer.initTabBody; XML response available"); + } + }, + + isXML: function(contentType) + { + if (!contentType) + return false; + + // Look if the response is XML based. + for (var i=0; i\s*/, ""); + + var div = parentNode.ownerDocument.createElement("div"); + div.innerHTML = xmlText; + + var root = div.getElementsByTagName("*")[0]; + + /*** + var parser = CCIN("@mozilla.org/xmlextras/domparser;1", "nsIDOMParser"); + var doc = parser.parseFromString(text, "text/xml"); + var root = doc.documentElement; + + // Error handling + var nsURI = "http://www.mozilla.org/newlayout/xml/parsererror.xml"; + if (root.namespaceURI == nsURI && root.nodeName == "parsererror") + { + this.ParseError.tag.replace({error: { + message: root.firstChild.nodeValue, + source: root.lastChild.textContent + }}, parentNode); + return; + } + /**/ + + if (FBTrace.DBG_XMLVIEWER) + FBTrace.sysout("xmlviewer.updateTabBody; XML response parsed", doc); + + // Override getHidden in these templates. The parsed XML documen is + // hidden, but we want to display it using 'visible' styling. + /* + var templates = [ + Firebug.HTMLPanel.CompleteElement, + Firebug.HTMLPanel.Element, + Firebug.HTMLPanel.TextElement, + Firebug.HTMLPanel.EmptyElement, + Firebug.HTMLPanel.XEmptyElement, + ]; + + var originals = []; + for (var i=0; iFirebug.XMLViewerModel. + */ +Firebug.XMLViewerModel.ParseError = domplate(Firebug.Rep, +{ + tag: + DIV({"class": "xmlInfoError"}, + DIV({"class": "xmlInfoErrorMsg"}, "$error.message"), + PRE({"class": "xmlInfoErrorSource"}, "$error|getSource") + ), + + getSource: function(error) + { + var parts = error.source.split("\n"); + if (parts.length != 2) + return error.source; + + var limit = 50; + var column = parts[1].length; + if (column >= limit) { + parts[0] = "..." + parts[0].substr(column - limit); + parts[1] = "..." + parts[1].substr(column - limit); + } + + if (parts[0].length > 80) + parts[0] = parts[0].substr(0, 80) + "..."; + + return parts.join("\n"); + } +}); + +// ************************************************************************************************ +// Registration + +Firebug.registerModule(Firebug.XMLViewerModel); + +}}); + + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +// ************************************************************************************************ +// Globals + +var ElementCache = Firebug.Lite.Cache.Element; +var cacheID = Firebug.Lite.Cache.ID; + +var ignoreHTMLProps = +{ + // ignores the attributes injected by Sizzle, otherwise it will + // be visible on IE (when enumerating element.attributes) + sizcache: 1, + sizset: 1 +}; + +// ignores also the cache property injected by firebug +ignoreHTMLProps[cacheID] = 1; + + +// ************************************************************************************************ +// HTML Module + +Firebug.HTML = extend(Firebug.Module, +{ + appendTreeNode: function(nodeArray, html) + { + var reTrim = /^\s+|\s+$/g; + + if (!nodeArray.length) nodeArray = [nodeArray]; + + for (var n=0, node; node=nodeArray[n]; n++) + { + if (node.nodeType == 1) + { + if (Firebug.ignoreFirebugElements && node.firebugIgnore) continue; + + var uid = ElementCache(node); + var child = node.childNodes; + var childLength = child.length; + + var nodeName = node.nodeName.toLowerCase(); + + var nodeVisible = isVisible(node); + + var hasSingleTextChild = childLength == 1 && node.firstChild.nodeType == 3 && + nodeName != "script" && nodeName != "style"; + + var nodeControl = !hasSingleTextChild && childLength > 0 ? + ('
                  ') : ''; + + 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 || 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; + + 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; + + 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: true, + 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.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.HTML.selectTreeNode(ElementCache(Firebug.browser.document.body)); + } + + // 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(FirebugChrome.selectedHTMLElementId) + Firebug.HTML.selectTreeNode(FirebugChrome.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"; + + selectedElement = e; + + FirebugChrome.selectedHTMLElementId = e.id; + + var target = ElementCache.get(e.id); + var selectedSidePanel = Firebug.chrome.getPanel("HTML").sidePanelBar.selectedPanel; + + var stack = FirebugChrome.htmlSelectionStack; + + stack.unshift(target); + + if (stack.length > 2) + stack.pop(); + + var lazySelect = function() + { + selectedSidePanelTS = new Date().getTime(); + + 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') + { + 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(' ]'); + } + +}; + + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +/* + +Hack: +Firebug.chrome.currentPanel = Firebug.chrome.selectedPanel; +Firebug.showInfoTips = true; +Firebug.InfoTip.initializeBrowser(Firebug.chrome); + +/**/ + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// Constants + +var maxWidth = 100, maxHeight = 80; +var infoTipMargin = 10; +var infoTipWindowPadding = 25; + +// ************************************************************************************************ + +Firebug.InfoTip = extend(Firebug.Module, +{ + dispatchName: "infoTip", + tags: domplate( + { + infoTipTag: DIV({"class": "infoTip"}), + + colorTag: + DIV({style: "background: $rgbValue; width: 100px; height: 40px"}, " "), + + imgTag: + DIV({"class": "infoTipImageBox infoTipLoading"}, + IMG({"class": "infoTipImage", src: "$urlValue", repeat: "$repeat", + onload: "$onLoadImage"}), + IMG({"class": "infoTipBgImage", collapsed: true, src: "blank.gif"}), + DIV({"class": "infoTipCaption"}) + ), + + onLoadImage: function(event) + { + var img = event.currentTarget || event.srcElement; + ///var bgImg = img.nextSibling; + ///if (!bgImg) + /// return; // Sometimes gets called after element is dead + + ///var caption = bgImg.nextSibling; + var innerBox = img.parentNode; + + /// TODO: xxxpedro infoTip hack + var caption = getElementByClass(innerBox, "infoTipCaption"); + var bgImg = getElementByClass(innerBox, "infoTipBgImage"); + if (!bgImg) + return; // Sometimes gets called after element is dead + + // TODO: xxxpedro infoTip IE and timing issue + // TODO: use offline document to avoid flickering + if (isIE) + removeClass(innerBox, "infoTipLoading"); + + var updateInfoTip = function(){ + + var w = img.naturalWidth || img.width || 10, + h = img.naturalHeight || img.height || 10; + + var repeat = img.getAttribute("repeat"); + + if (repeat == "repeat-x" || (w == 1 && h > 1)) + { + collapse(img, true); + collapse(bgImg, false); + bgImg.style.background = "url(" + img.src + ") repeat-x"; + bgImg.style.width = maxWidth + "px"; + if (h > maxHeight) + bgImg.style.height = maxHeight + "px"; + else + bgImg.style.height = h + "px"; + } + else if (repeat == "repeat-y" || (h == 1 && w > 1)) + { + collapse(img, true); + collapse(bgImg, false); + bgImg.style.background = "url(" + img.src + ") repeat-y"; + bgImg.style.height = maxHeight + "px"; + if (w > maxWidth) + bgImg.style.width = maxWidth + "px"; + else + bgImg.style.width = w + "px"; + } + else if (repeat == "repeat" || (w == 1 && h == 1)) + { + collapse(img, true); + collapse(bgImg, false); + bgImg.style.background = "url(" + img.src + ") repeat"; + bgImg.style.width = maxWidth + "px"; + bgImg.style.height = maxHeight + "px"; + } + else + { + if (w > maxWidth || h > maxHeight) + { + if (w > h) + { + img.style.width = maxWidth + "px"; + img.style.height = Math.round((h / w) * maxWidth) + "px"; + } + else + { + img.style.width = Math.round((w / h) * maxHeight) + "px"; + img.style.height = maxHeight + "px"; + } + } + } + + //caption.innerHTML = $STRF("Dimensions", [w, h]); + caption.innerHTML = $STRF(w + " x " + h); + + + }; + + if (isIE) + setTimeout(updateInfoTip, 0); + else + { + updateInfoTip(); + removeClass(innerBox, "infoTipLoading"); + } + + /// + } + + /* + /// onLoadImage original + onLoadImage: function(event) + { + var img = event.currentTarget; + var bgImg = img.nextSibling; + if (!bgImg) + return; // Sometimes gets called after element is dead + + var caption = bgImg.nextSibling; + var innerBox = img.parentNode; + + var w = img.naturalWidth, h = img.naturalHeight; + var repeat = img.getAttribute("repeat"); + + if (repeat == "repeat-x" || (w == 1 && h > 1)) + { + collapse(img, true); + collapse(bgImg, false); + bgImg.style.background = "url(" + img.src + ") repeat-x"; + bgImg.style.width = maxWidth + "px"; + if (h > maxHeight) + bgImg.style.height = maxHeight + "px"; + else + bgImg.style.height = h + "px"; + } + else if (repeat == "repeat-y" || (h == 1 && w > 1)) + { + collapse(img, true); + collapse(bgImg, false); + bgImg.style.background = "url(" + img.src + ") repeat-y"; + bgImg.style.height = maxHeight + "px"; + if (w > maxWidth) + bgImg.style.width = maxWidth + "px"; + else + bgImg.style.width = w + "px"; + } + else if (repeat == "repeat" || (w == 1 && h == 1)) + { + collapse(img, true); + collapse(bgImg, false); + bgImg.style.background = "url(" + img.src + ") repeat"; + bgImg.style.width = maxWidth + "px"; + bgImg.style.height = maxHeight + "px"; + } + else + { + if (w > maxWidth || h > maxHeight) + { + if (w > h) + { + img.style.width = maxWidth + "px"; + img.style.height = Math.round((h / w) * maxWidth) + "px"; + } + else + { + img.style.width = Math.round((w / h) * maxHeight) + "px"; + img.style.height = maxHeight + "px"; + } + } + } + + caption.innerHTML = $STRF("Dimensions", [w, h]); + + removeClass(innerBox, "infoTipLoading"); + } + /**/ + + }), + + initializeBrowser: function(browser) + { + browser.onInfoTipMouseOut = bind(this.onMouseOut, this, browser); + browser.onInfoTipMouseMove = bind(this.onMouseMove, this, browser); + + ///var doc = browser.contentDocument; + var doc = browser.document; + if (!doc) + return; + + ///doc.addEventListener("mouseover", browser.onInfoTipMouseMove, true); + ///doc.addEventListener("mouseout", browser.onInfoTipMouseOut, true); + ///doc.addEventListener("mousemove", browser.onInfoTipMouseMove, true); + addEvent(doc, "mouseover", browser.onInfoTipMouseMove); + addEvent(doc, "mouseout", browser.onInfoTipMouseOut); + addEvent(doc, "mousemove", browser.onInfoTipMouseMove); + + return browser.infoTip = this.tags.infoTipTag.append({}, getBody(doc)); + }, + + uninitializeBrowser: function(browser) + { + if (browser.infoTip) + { + ///var doc = browser.contentDocument; + var doc = browser.document; + ///doc.removeEventListener("mouseover", browser.onInfoTipMouseMove, true); + ///doc.removeEventListener("mouseout", browser.onInfoTipMouseOut, true); + ///doc.removeEventListener("mousemove", browser.onInfoTipMouseMove, true); + removeEvent(doc, "mouseover", browser.onInfoTipMouseMove); + removeEvent(doc, "mouseout", browser.onInfoTipMouseOut); + removeEvent(doc, "mousemove", browser.onInfoTipMouseMove); + + browser.infoTip.parentNode.removeChild(browser.infoTip); + delete browser.infoTip; + delete browser.onInfoTipMouseMove; + } + }, + + showInfoTip: function(infoTip, panel, target, x, y, rangeParent, rangeOffset) + { + if (!Firebug.showInfoTips) + return; + + var scrollParent = getOverflowParent(target); + var scrollX = x + (scrollParent ? scrollParent.scrollLeft : 0); + + if (panel.showInfoTip(infoTip, target, scrollX, y, rangeParent, rangeOffset)) + { + var htmlElt = infoTip.ownerDocument.documentElement; + var panelWidth = htmlElt.clientWidth; + var panelHeight = htmlElt.clientHeight; + + if (x+infoTip.offsetWidth+infoTipMargin > panelWidth) + { + infoTip.style.left = Math.max(0, panelWidth-(infoTip.offsetWidth+infoTipMargin)) + "px"; + infoTip.style.right = "auto"; + } + else + { + infoTip.style.left = (x+infoTipMargin) + "px"; + infoTip.style.right = "auto"; + } + + if (y+infoTip.offsetHeight+infoTipMargin > panelHeight) + { + infoTip.style.top = Math.max(0, panelHeight-(infoTip.offsetHeight+infoTipMargin)) + "px"; + infoTip.style.bottom = "auto"; + } + else + { + infoTip.style.top = (y+infoTipMargin) + "px"; + infoTip.style.bottom = "auto"; + } + + if (FBTrace.DBG_INFOTIP) + FBTrace.sysout("infotip.showInfoTip; top: " + infoTip.style.top + + ", left: " + infoTip.style.left + ", bottom: " + infoTip.style.bottom + + ", right:" + infoTip.style.right + ", offsetHeight: " + infoTip.offsetHeight + + ", offsetWidth: " + infoTip.offsetWidth + + ", x: " + x + ", panelWidth: " + panelWidth + + ", y: " + y + ", panelHeight: " + panelHeight); + + infoTip.setAttribute("active", "true"); + } + else + this.hideInfoTip(infoTip); + }, + + hideInfoTip: function(infoTip) + { + if (infoTip) + infoTip.removeAttribute("active"); + }, + + onMouseOut: function(event, browser) + { + if (!event.relatedTarget) + this.hideInfoTip(browser.infoTip); + }, + + onMouseMove: function(event, browser) + { + // Ignore if the mouse is moving over the existing info tip. + if (getAncestorByClass(event.target, "infoTip")) + return; + + if (browser.currentPanel) + { + var x = event.clientX, y = event.clientY, target = event.target || event.srcElement; + this.showInfoTip(browser.infoTip, browser.currentPanel, target, x, y, event.rangeParent, event.rangeOffset); + } + else + this.hideInfoTip(browser.infoTip); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + populateColorInfoTip: function(infoTip, color) + { + this.tags.colorTag.replace({rgbValue: color}, infoTip); + return true; + }, + + populateImageInfoTip: function(infoTip, url, repeat) + { + if (!repeat) + repeat = "no-repeat"; + + this.tags.imgTag.replace({urlValue: url, repeat: repeat}, infoTip); + + return true; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Module + + disable: function() + { + // XXXjoe For each browser, call uninitializeBrowser + }, + + showPanel: function(browser, panel) + { + if (panel) + { + var infoTip = panel.panelBrowser.infoTip; + if (!infoTip) + infoTip = this.initializeBrowser(panel.panelBrowser); + this.hideInfoTip(infoTip); + } + + }, + + showSidePanel: function(browser, panel) + { + this.showPanel(browser, panel); + } +}); + +// ************************************************************************************************ + +Firebug.registerModule(Firebug.InfoTip); + +// ************************************************************************************************ + +}}); + + +/* See license.txt for terms of usage */ + +// move to FBL +(function() { + +// ************************************************************************************************ +// XPath + +/** + * Gets an XPath for an element which describes its hierarchical location. + */ +this.getElementXPath = function(element) +{ + if (element && element.id) + return '//*[@id="' + element.id + '"]'; + else + return this.getElementTreeXPath(element); +}; + +this.getElementTreeXPath = function(element) +{ + var paths = []; + + for (; element && element.nodeType == 1; element = element.parentNode) + { + var index = 0; + for (var sibling = element.previousSibling; sibling; sibling = sibling.previousSibling) + { + if (sibling.nodeName == element.nodeName) + ++index; + } + + var tagName = element.nodeName.toLowerCase(); + var pathIndex = (index ? "[" + (index+1) + "]" : ""); + paths.splice(0, 0, tagName + pathIndex); + } + + return paths.length ? "/" + paths.join("/") : null; +}; + +this.getElementsByXPath = function(doc, xpath) +{ + var nodes = []; + + try { + var result = doc.evaluate(xpath, doc, null, XPathResult.ANY_TYPE, null); + for (var item = result.iterateNext(); item; item = result.iterateNext()) + nodes.push(item); + } + catch (exc) + { + // Invalid xpath expressions make their way here sometimes. If that happens, + // we still want to return an empty set without an exception. + } + + return nodes; +}; + +this.getRuleMatchingElements = function(rule, doc) +{ + var css = rule.selectorText; + var xpath = this.cssToXPath(css); + return this.getElementsByXPath(doc, xpath); +}; + + +}).call(FBL); + + + + +FBL.ns(function() { with (FBL) { + +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ + +var toCamelCase = function toCamelCase(s) +{ + return s.replace(reSelectorCase, toCamelCaseReplaceFn); +}; + +var toSelectorCase = function toSelectorCase(s) +{ + return s.replace(reCamelCase, "-$1").toLowerCase(); + +}; + +var reCamelCase = /([A-Z])/g; +var reSelectorCase = /\-(.)/g; +var toCamelCaseReplaceFn = function toCamelCaseReplaceFn(m,g) +{ + return g.toUpperCase(); +}; + + + + + +// ************************************************************************************************ + +var ElementCache = Firebug.Lite.Cache.Element; +var StyleSheetCache = Firebug.Lite.Cache.StyleSheet; + +var globalCSSRuleIndex; + +var externalStyleSheetURLs = []; +var 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") + ) +}); + + +var processAllStyleSheetsTimeout = null; +var loadExternalStylesheet = function(doc, styleSheetIterator, styleSheet) +{ + var url = styleSheet.href; + styleSheet.firebugIgnore = true; + + var source = Firebug.Lite.Proxy.load(url); + + // TODO: check for null and error responses + + + // remove comments + //var reMultiComment = /(\/\*([^\*]|\*(?!\/))*\*\/)/g; + //source = source.replace(reMultiComment, ""); + + // convert relative addresses to absolute ones + source = source.replace(/url\(([^\)]+)\)/g, function(a,name){ + + var hasDomain = /\w+:\/\/./.test(name); + + if (!hasDomain) + { + name = name.replace(/^(["'])(.+)\1$/, "$2"); + var first = name.charAt(0); + + // relative path, based on root + if (first == "/") + { + // TODO: xxxpedro move to lib or Firebug.Lite.something + // getURLRoot + var m = /^([^:]+:\/{1,3}[^\/]+)/.exec(url); + + return m ? + "url(" + m[1] + name + ")" : + "url(" + name + ")"; + } + // relative path, based on current location + else + { + // TODO: xxxpedro move to lib or Firebug.Lite.something + // getURLPath + var path = url.replace(/[^\/]+\.[\w\d]+(\?.+|#.+)?$/g, ""); + + path = path + name; + + var reBack = /[^\/]+\/\.\.\//; + while(reBack.test(path)) + { + path = path.replace(reBack, ""); + } + + //console.log("url(" + path + ")"); + + return "url(" + path + ")"; + } + } + + // if it is an absolute path, there is nothing to do + return a; + }); + + var oldStyle = styleSheet.ownerNode; + + if (!oldStyle) return; + + if (!oldStyle.parentNode) return; + + var style = createGlobalElement("style"); + style.setAttribute("charset","utf-8"); + style.setAttribute("type", "text/css"); + style.innerHTML = source; + + //debugger; + oldStyle.parentNode.insertBefore(style, oldStyle.nextSibling); + oldStyle.parentNode.removeChild(oldStyle); + + + //doc.getElementsByTagName("head")[0].appendChild(style); + + doc.styleSheets[doc.styleSheets.length-1].externalURL = url; + + console.log(url, "call " + externalStyleSheetURLs.length, source); + + externalStyleSheetURLs.pop(); + + if (processAllStyleSheetsTimeout) + { + clearTimeout(processAllStyleSheetsTimeout); + } + + processAllStyleSheetsTimeout = setTimeout(function(){ + console.log("processing"); + FBL.processAllStyleSheets(doc, styleSheetIterator); + processAllStyleSheetsTimeout = null; + },200); + +}; + + +FBL.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 maxSpecificity) + { + maxSpecificity = spec; + mostSpecificSelector = sel; + } + } + } + + rule.specificity = maxSpecificity; + } + } + + rules.sort(sortElementRules); + //rules.sort(solveRulesTied); + + return rules; +}; + +var sortElementRules = function(a, b) +{ + var ruleA = CSSRuleMap[a]; + var ruleB = CSSRuleMap[b]; + + var specificityA = ruleA.specificity; + var specificityB = ruleB.specificity; + + if (specificityA > specificityB) + return 1; + + else if (specificityA < specificityB) + return -1; + + else + return ruleA.order > ruleB.order ? 1 : -1; +}; + +var solveRulesTied = function(a, b) +{ + var ruleA = CSSRuleMap[a]; + var ruleB = CSSRuleMap[b]; + + if (ruleA.specificity == ruleB.specificity) + return ruleA.order > ruleB.order ? 1 : -1; + + return null; +}; + +var reSelectorTag = /(^|\s)(?:\w+)/g; +var reSelectorClass = /\.[\w\d_-]+/g; +var reSelectorId = /#[\w\d_-]+/g; + +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; +}; + +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ +// ************************************************************************************************ + + +// ************************************************************************************************ +// Constants + +//const Cc = Components.classes; +//const Ci = Components.interfaces; +//const nsIDOMCSSStyleRule = Ci.nsIDOMCSSStyleRule; +//const nsIInterfaceRequestor = Ci.nsIInterfaceRequestor; +//const nsISelectionDisplay = Ci.nsISelectionDisplay; +//const nsISelectionController = Ci.nsISelectionController; + +// See: http://mxr.mozilla.org/mozilla1.9.2/source/content/events/public/nsIEventStateManager.h#153 +//const STATE_ACTIVE = 0x01; +//const STATE_FOCUS = 0x02; +//const STATE_HOVER = 0x04; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +Firebug.SourceBoxPanel = Firebug.Panel; + +var domUtils = null; + +var textContent = isIE ? "innerText" : "textContent"; +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var CSSDomplateBase = { + isEditable: function(rule) + { + return !rule.isSystemSheet; + }, + isSelectorEditable: function(rule) + { + return rule.isSelectorEditable && this.isEditable(rule); + } +}; + +var CSSPropTag = domplate(CSSDomplateBase, { + tag: DIV({"class": "cssProp focusRow", $disabledStyle: "$prop.disabled", + $editGroup: "$rule|isEditable", + $cssOverridden: "$prop.overridden", role : "option"}, + A({"class": "cssPropDisable"}, "  "), + SPAN({"class": "cssPropName", $editable: "$rule|isEditable"}, "$prop.name"), + SPAN({"class": "cssColon"}, ":"), + SPAN({"class": "cssPropValue", $editable: "$rule|isEditable"}, "$prop.value$prop.important"), + SPAN({"class": "cssSemi"}, ";") + ) +}); + +var CSSRuleTag = + TAG("$rule.tag", {rule: "$rule"}); + +var CSSImportRuleTag = domplate({ + tag: DIV({"class": "cssRule insertInto focusRow importRule", _repObject: "$rule.rule"}, + "@import "", + A({"class": "objectLink", _repObject: "$rule.rule.styleSheet"}, "$rule.rule.href"), + "";" + ) +}); + +var CSSStyleRuleTag = domplate(CSSDomplateBase, { + tag: DIV({"class": "cssRule insertInto", + $cssEditableRule: "$rule|isEditable", + $editGroup: "$rule|isSelectorEditable", + _repObject: "$rule.rule", + "ruleId": "$rule.id", role : 'presentation'}, + DIV({"class": "cssHead focusRow", role : 'listitem'}, + SPAN({"class": "cssSelector", $editable: "$rule|isSelectorEditable"}, "$rule.selector"), " {" + ), + DIV({role : 'group'}, + DIV({"class": "cssPropertyListBox", role : 'listbox'}, + FOR("prop", "$rule.props", + TAG(CSSPropTag.tag, {rule: "$rule", prop: "$prop"}) + ) + ) + ), + DIV({"class": "editable insertBefore", role:"presentation"}, "}") + ) +}); + +var reSplitCSS = /(url\("?[^"\)]+?"?\))|(rgb\(.*?\))|(#[\dA-Fa-f]+)|(-?\d+(\.\d+)?(%|[a-z]{1,2})?)|([^,\s]+)|"(.*?)"/; + +var reURL = /url\("?([^"\)]+)?"?\)/; + +var reRepeat = /no-repeat|repeat-x|repeat-y|repeat/; + +//const sothinkInstalled = !!$("swfcatcherKey_sidebar"); +var sothinkInstalled = false; +var styleGroups = +{ + text: [ + "font-family", + "font-size", + "font-weight", + "font-style", + "color", + "text-transform", + "text-decoration", + "letter-spacing", + "word-spacing", + "line-height", + "text-align", + "vertical-align", + "direction", + "column-count", + "column-gap", + "column-width" + ], + + background: [ + "background-color", + "background-image", + "background-repeat", + "background-position", + "background-attachment", + "opacity" + ], + + box: [ + "width", + "height", + "top", + "right", + "bottom", + "left", + "margin-top", + "margin-right", + "margin-bottom", + "margin-left", + "padding-top", + "padding-right", + "padding-bottom", + "padding-left", + "border-top-width", + "border-right-width", + "border-bottom-width", + "border-left-width", + "border-top-color", + "border-right-color", + "border-bottom-color", + "border-left-color", + "border-top-style", + "border-right-style", + "border-bottom-style", + "border-left-style", + "-moz-border-top-radius", + "-moz-border-right-radius", + "-moz-border-bottom-radius", + "-moz-border-left-radius", + "outline-top-width", + "outline-right-width", + "outline-bottom-width", + "outline-left-width", + "outline-top-color", + "outline-right-color", + "outline-bottom-color", + "outline-left-color", + "outline-top-style", + "outline-right-style", + "outline-bottom-style", + "outline-left-style" + ], + + layout: [ + "position", + "display", + "visibility", + "z-index", + "overflow-x", // http://www.w3.org/TR/2002/WD-css3-box-20021024/#overflow + "overflow-y", + "overflow-clip", + "white-space", + "clip", + "float", + "clear", + "-moz-box-sizing" + ], + + other: [ + "cursor", + "list-style-image", + "list-style-position", + "list-style-type", + "marker-offset", + "user-focus", + "user-select", + "user-modify", + "user-input" + ] +}; + +var styleGroupTitles = +{ + text: "Text", + background: "Background", + box: "Box Model", + layout: "Layout", + other: "Other" +}; + +Firebug.CSSModule = extend(Firebug.Module, +{ + freeEdit: function(styleSheet, value) + { + if (!styleSheet.editStyleSheet) + { + var ownerNode = getStyleSheetOwnerNode(styleSheet); + styleSheet.disabled = true; + + var url = CCSV("@mozilla.org/network/standard-url;1", Components.interfaces.nsIURL); + url.spec = styleSheet.href; + + var editStyleSheet = ownerNode.ownerDocument.createElementNS( + "http://www.w3.org/1999/xhtml", + "style"); + unwrapObject(editStyleSheet).firebugIgnore = true; + editStyleSheet.setAttribute("type", "text/css"); + editStyleSheet.setAttributeNS( + "http://www.w3.org/XML/1998/namespace", + "base", + url.directory); + if (ownerNode.hasAttribute("media")) + { + editStyleSheet.setAttribute("media", ownerNode.getAttribute("media")); + } + + // Insert the edited stylesheet directly after the old one to ensure the styles + // cascade properly. + ownerNode.parentNode.insertBefore(editStyleSheet, ownerNode.nextSibling); + + styleSheet.editStyleSheet = editStyleSheet; + } + + styleSheet.editStyleSheet.innerHTML = value; + if (FBTrace.DBG_CSS) + FBTrace.sysout("css.saveEdit styleSheet.href:"+styleSheet.href+" got innerHTML:"+value+"\n"); + + dispatch(this.fbListeners, "onCSSFreeEdit", [styleSheet, value]); + }, + + insertRule: function(styleSheet, cssText, ruleIndex) + { + if (FBTrace.DBG_CSS) FBTrace.sysout("Insert: " + ruleIndex + " " + cssText); + var insertIndex = styleSheet.insertRule(cssText, ruleIndex); + + dispatch(this.fbListeners, "onCSSInsertRule", [styleSheet, cssText, ruleIndex]); + + return insertIndex; + }, + + deleteRule: function(styleSheet, ruleIndex) + { + if (FBTrace.DBG_CSS) FBTrace.sysout("deleteRule: " + ruleIndex + " " + styleSheet.cssRules.length, styleSheet.cssRules); + dispatch(this.fbListeners, "onCSSDeleteRule", [styleSheet, ruleIndex]); + + styleSheet.deleteRule(ruleIndex); + }, + + setProperty: function(rule, propName, propValue, propPriority) + { + var style = rule.style || rule; + + // Record the original CSS text for the inline case so we can reconstruct at a later + // point for diffing purposes + var baseText = style.cssText; + + // good browsers + if (style.getPropertyValue) + { + var prevValue = style.getPropertyValue(propName); + var prevPriority = style.getPropertyPriority(propName); + + // XXXjoe Gecko bug workaround: Just changing priority doesn't have any effect + // unless we remove the property first + style.removeProperty(propName); + + style.setProperty(propName, propValue, propPriority); + } + // sad browsers + else + { + // TODO: xxxpedro parse CSS rule to find property priority in IE? + //console.log(propName, propValue); + style[toCamelCase(propName)] = propValue; + } + + if (propName) { + dispatch(this.fbListeners, "onCSSSetProperty", [style, propName, propValue, propPriority, prevValue, prevPriority, rule, baseText]); + } + }, + + removeProperty: function(rule, propName, parent) + { + var style = rule.style || rule; + + // Record the original CSS text for the inline case so we can reconstruct at a later + // point for diffing purposes + var baseText = style.cssText; + + if (style.getPropertyValue) + { + + var prevValue = style.getPropertyValue(propName); + var prevPriority = style.getPropertyPriority(propName); + + style.removeProperty(propName); + } + else + { + style[toCamelCase(propName)] = ""; + } + + if (propName) { + dispatch(this.fbListeners, "onCSSRemoveProperty", [style, propName, prevValue, prevPriority, rule, baseText]); + } + }/*, + + cleanupSheets: function(doc, context) + { + // Due to the manner in which the layout engine handles multiple + // references to the same sheet we need to kick it a little bit. + // The injecting a simple stylesheet then removing it will force + // Firefox to regenerate it's CSS hierarchy. + // + // WARN: This behavior was determined anecdotally. + // See http://code.google.com/p/fbug/issues/detail?id=2440 + var style = doc.createElementNS("http://www.w3.org/1999/xhtml", "style"); + style.setAttribute("charset","utf-8"); + unwrapObject(style).firebugIgnore = true; + style.setAttribute("type", "text/css"); + style.innerHTML = "#fbIgnoreStyleDO_NOT_USE {}"; + addStyleSheet(doc, style); + style.parentNode.removeChild(style); + + // https://bugzilla.mozilla.org/show_bug.cgi?id=500365 + // This voodoo touches each style sheet to force some Firefox internal change to allow edits. + var styleSheets = getAllStyleSheets(context); + for(var i = 0; i < styleSheets.length; i++) + { + try + { + var rules = styleSheets[i].cssRules; + if (rules.length > 0) + var touch = rules[0]; + if (FBTrace.DBG_CSS && touch) + FBTrace.sysout("css.show() touch "+typeof(touch)+" in "+(styleSheets[i].href?styleSheets[i].href:context.getName())); + } + catch(e) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("css.show: sheet.cssRules FAILS for "+(styleSheets[i]?styleSheets[i].href:"null sheet")+e, e); + } + } + }, + cleanupSheetHandler: function(event, context) + { + var target = event.target || event.srcElement, + tagName = (target.tagName || "").toLowerCase(); + if (tagName == "link") + { + this.cleanupSheets(target.ownerDocument, context); + } + }, + watchWindow: function(context, win) + { + var cleanupSheets = bind(this.cleanupSheets, this), + cleanupSheetHandler = bind(this.cleanupSheetHandler, this, context), + doc = win.document; + + //doc.addEventListener("DOMAttrModified", cleanupSheetHandler, false); + //doc.addEventListener("DOMNodeInserted", cleanupSheetHandler, false); + }, + loadedContext: function(context) + { + var self = this; + iterateWindows(context.browser.contentWindow, function(subwin) + { + self.cleanupSheets(subwin.document, context); + }); + } + /**/ +}); + +// ************************************************************************************************ + +Firebug.CSSStyleSheetPanel = function() {}; + +Firebug.CSSStyleSheetPanel.prototype = extend(Firebug.SourceBoxPanel, +{ + template: domplate( + { + tag: + DIV({"class": "cssSheet insertInto a11yCSSView"}, + FOR("rule", "$rules", + CSSRuleTag + ), + DIV({"class": "cssSheet editable insertBefore"}, "") + ) + }), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + refresh: function() + { + if (this.location) + this.updateLocation(this.location); + else if (this.selection) + this.updateSelection(this.selection); + }, + + toggleEditing: function() + { + if (!this.stylesheetEditor) + this.stylesheetEditor = new StyleSheetEditor(this.document); + + if (this.editing) + Firebug.Editor.stopEditing(); + else + { + if (!this.location) + return; + + var styleSheet = this.location.editStyleSheet + ? this.location.editStyleSheet.sheet + : this.location; + + var css = getStyleSheetCSS(styleSheet, this.context); + //var topmost = getTopmostRuleLine(this.panelNode); + + this.stylesheetEditor.styleSheet = this.location; + Firebug.Editor.startEditing(this.panelNode, css, this.stylesheetEditor); + //this.stylesheetEditor.scrollToLine(topmost.line, topmost.offset); + } + }, + + getStylesheetURL: function(rule) + { + if (this.location.href) + return this.location.href; + else + return this.context.window.location.href; + }, + + getRuleByLine: function(styleSheet, line) + { + if (!domUtils) + return null; + + var cssRules = styleSheet.cssRules; + for (var i = 0; i < cssRules.length; ++i) + { + var rule = cssRules[i]; + if (rule instanceof CSSStyleRule) + { + var ruleLine = domUtils.getRuleLine(rule); + if (ruleLine >= line) + return rule; + } + } + }, + + highlightRule: function(rule) + { + var ruleElement = Firebug.getElementByRepObject(this.panelNode.firstChild, rule); + if (ruleElement) + { + scrollIntoCenterView(ruleElement, this.panelNode); + setClassTimed(ruleElement, "jumpHighlight", this.context); + } + }, + + getStyleSheetRules: function(context, styleSheet) + { + var isSystemSheet = isSystemStyleSheet(styleSheet); + + function appendRules(cssRules) + { + for (var i = 0; i < cssRules.length; ++i) + { + var rule = cssRules[i]; + + // TODO: xxxpedro opera instanceof stylesheet remove the following comments when + // the issue with opera and style sheet Classes has been solved. + + //if (rule instanceof CSSStyleRule) + if (instanceOf(rule, "CSSStyleRule")) + { + var props = this.getRuleProperties(context, rule); + //var line = domUtils.getRuleLine(rule); + var line = null; + + var selector = rule.selectorText; + + if (isIE) + { + selector = selector.replace(reSelectorTag, + function(s){return s.toLowerCase();}); + } + + var ruleId = rule.selectorText+"/"+line; + rules.push({tag: CSSStyleRuleTag.tag, rule: rule, id: ruleId, + selector: selector, props: props, + isSystemSheet: isSystemSheet, + isSelectorEditable: true}); + } + //else if (rule instanceof CSSImportRule) + else if (instanceOf(rule, "CSSImportRule")) + rules.push({tag: CSSImportRuleTag.tag, rule: rule}); + //else if (rule instanceof CSSMediaRule) + else if (instanceOf(rule, "CSSMediaRule")) + appendRules.apply(this, [rule.cssRules]); + else + { + if (FBTrace.DBG_ERRORS || FBTrace.DBG_CSS) + FBTrace.sysout("css getStyleSheetRules failed to classify a rule ", rule); + } + } + } + + var rules = []; + appendRules.apply(this, [styleSheet.cssRules || styleSheet.rules]); + return rules; + }, + + parseCSSProps: function(style, inheritMode) + { + var props = []; + + if (Firebug.expandShorthandProps) + { + var count = style.length-1, + index = style.length; + while (index--) + { + var propName = style.item(count - index); + this.addProperty(propName, style.getPropertyValue(propName), !!style.getPropertyPriority(propName), false, inheritMode, props); + } + } + else + { + var lines = style.cssText.match(/(?:[^;\(]*(?:\([^\)]*?\))?[^;\(]*)*;?/g); + var propRE = /\s*([^:\s]*)\s*:\s*(.*?)\s*(! important)?;?$/; + var line,i=0; + // TODO: xxxpedro port to firebug: variable leaked into global namespace + var m; + + while(line=lines[i++]){ + m = propRE.exec(line); + if(!m) + continue; + //var name = m[1], value = m[2], important = !!m[3]; + if (m[2]) + this.addProperty(m[1], m[2], !!m[3], false, inheritMode, props); + }; + } + + return props; + }, + + getRuleProperties: function(context, rule, inheritMode) + { + var props = this.parseCSSProps(rule.style, inheritMode); + + // TODO: xxxpedro port to firebug: variable leaked into global namespace + //var line = domUtils.getRuleLine(rule); + var line; + var ruleId = rule.selectorText+"/"+line; + this.addOldProperties(context, ruleId, inheritMode, props); + sortProperties(props); + + return props; + }, + + addOldProperties: function(context, ruleId, inheritMode, props) + { + if (context.selectorMap && context.selectorMap.hasOwnProperty(ruleId) ) + { + var moreProps = context.selectorMap[ruleId]; + for (var i = 0; i < moreProps.length; ++i) + { + var prop = moreProps[i]; + this.addProperty(prop.name, prop.value, prop.important, true, inheritMode, props); + } + } + }, + + addProperty: function(name, value, important, disabled, inheritMode, props) + { + name = name.toLowerCase(); + + if (inheritMode && !inheritedStyleNames[name]) + return; + + name = this.translateName(name, value); + if (name) + { + value = stripUnits(rgbToHex(value)); + important = important ? " !important" : ""; + + var prop = {name: name, value: value, important: important, disabled: disabled}; + props.push(prop); + } + }, + + translateName: function(name, value) + { + // Don't show these proprietary Mozilla properties + if ((value == "-moz-initial" + && (name == "-moz-background-clip" || name == "-moz-background-origin" + || name == "-moz-background-inline-policy")) + || (value == "physical" + && (name == "margin-left-ltr-source" || name == "margin-left-rtl-source" + || name == "margin-right-ltr-source" || name == "margin-right-rtl-source")) + || (value == "physical" + && (name == "padding-left-ltr-source" || name == "padding-left-rtl-source" + || name == "padding-right-ltr-source" || name == "padding-right-rtl-source"))) + return null; + + // Translate these back to the form the user probably expects + if (name == "margin-left-value") + return "margin-left"; + else if (name == "margin-right-value") + return "margin-right"; + else if (name == "margin-top-value") + return "margin-top"; + else if (name == "margin-bottom-value") + return "margin-bottom"; + else if (name == "padding-left-value") + return "padding-left"; + else if (name == "padding-right-value") + return "padding-right"; + else if (name == "padding-top-value") + return "padding-top"; + else if (name == "padding-bottom-value") + return "padding-bottom"; + // XXXjoe What about border! + else + return name; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + editElementStyle: function() + { + ///var rulesBox = this.panelNode.getElementsByClassName("cssElementRuleContainer")[0]; + var rulesBox = $$(".cssElementRuleContainer", this.panelNode)[0]; + var styleRuleBox = rulesBox && Firebug.getElementByRepObject(rulesBox, this.selection); + if (!styleRuleBox) + { + var rule = {rule: this.selection, inherited: false, selector: "element.style", props: []}; + if (!rulesBox) + { + // The element did not have any displayed styles. We need to create the whole tree and remove + // the no styles message + styleRuleBox = this.template.cascadedTag.replace({ + rules: [rule], inherited: [], inheritLabel: "Inherited from" // $STR("InheritedFrom") + }, this.panelNode); + + ///styleRuleBox = styleRuleBox.getElementsByClassName("cssElementRuleContainer")[0]; + styleRuleBox = $$(".cssElementRuleContainer", styleRuleBox)[0]; + } + else + styleRuleBox = this.template.ruleTag.insertBefore({rule: rule}, rulesBox); + + ///styleRuleBox = styleRuleBox.getElementsByClassName("insertInto")[0]; + styleRuleBox = $$(".insertInto", styleRuleBox)[0]; + } + + Firebug.Editor.insertRowForObject(styleRuleBox); + }, + + insertPropertyRow: function(row) + { + Firebug.Editor.insertRowForObject(row); + }, + + insertRule: function(row) + { + var location = getAncestorByClass(row, "cssRule"); + if (!location) + { + location = getChildByClass(this.panelNode, "cssSheet"); + Firebug.Editor.insertRowForObject(location); + } + else + { + Firebug.Editor.insertRow(location, "before"); + } + }, + + editPropertyRow: function(row) + { + var propValueBox = getChildByClass(row, "cssPropValue"); + Firebug.Editor.startEditing(propValueBox); + }, + + deletePropertyRow: function(row) + { + var rule = Firebug.getRepObject(row); + var propName = getChildByClass(row, "cssPropName")[textContent]; + Firebug.CSSModule.removeProperty(rule, propName); + + // Remove the property from the selector map, if it was disabled + var ruleId = Firebug.getRepNode(row).getAttribute("ruleId"); + if ( this.context.selectorMap && this.context.selectorMap.hasOwnProperty(ruleId) ) + { + var map = this.context.selectorMap[ruleId]; + for (var i = 0; i < map.length; ++i) + { + if (map[i].name == propName) + { + map.splice(i, 1); + break; + } + } + } + if (this.name == "stylesheet") + dispatch([Firebug.A11yModel], 'onInlineEditorClose', [this, row.firstChild, true]); + row.parentNode.removeChild(row); + + this.markChange(this.name == "stylesheet"); + }, + + disablePropertyRow: function(row) + { + toggleClass(row, "disabledStyle"); + + var rule = Firebug.getRepObject(row); + var propName = getChildByClass(row, "cssPropName")[textContent]; + + if (!this.context.selectorMap) + this.context.selectorMap = {}; + + // XXXjoe Generate unique key for elements too + var ruleId = Firebug.getRepNode(row).getAttribute("ruleId"); + if (!(this.context.selectorMap.hasOwnProperty(ruleId))) + this.context.selectorMap[ruleId] = []; + + var map = this.context.selectorMap[ruleId]; + var propValue = getChildByClass(row, "cssPropValue")[textContent]; + var parsedValue = parsePriority(propValue); + if (hasClass(row, "disabledStyle")) + { + Firebug.CSSModule.removeProperty(rule, propName); + + map.push({"name": propName, "value": parsedValue.value, + "important": parsedValue.priority}); + } + else + { + Firebug.CSSModule.setProperty(rule, propName, parsedValue.value, parsedValue.priority); + + var index = findPropByName(map, propName); + map.splice(index, 1); + } + + this.markChange(this.name == "stylesheet"); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + onMouseDown: function(event) + { + //console.log("onMouseDown", event.target || event.srcElement, event); + + // xxxpedro adjusting coordinates because the panel isn't a window yet + var offset = event.clientX - this.panelNode.parentNode.offsetLeft; + + // XXjoe Hack to only allow clicking on the checkbox + if (!isLeftClick(event) || offset > 20) + return; + + var target = event.target || event.srcElement; + if (hasClass(target, "textEditor")) + return; + + var row = getAncestorByClass(target, "cssProp"); + if (row && hasClass(row, "editGroup")) + { + this.disablePropertyRow(row); + cancelEvent(event); + } + }, + + onDoubleClick: function(event) + { + //console.log("onDoubleClick", event.target || event.srcElement, event); + + // xxxpedro adjusting coordinates because the panel isn't a window yet + var offset = event.clientX - this.panelNode.parentNode.offsetLeft; + + if (!isLeftClick(event) || offset <= 20) + return; + + var target = event.target || event.srcElement; + + //console.log("ok", target, hasClass(target, "textEditorInner"), !isLeftClick(event), offset <= 20); + + // if the inline editor was clicked, don't insert a new rule + if (hasClass(target, "textEditorInner")) + return; + + var row = getAncestorByClass(target, "cssRule"); + if (row && !getAncestorByClass(target, "cssPropName") + && !getAncestorByClass(target, "cssPropValue")) + { + this.insertPropertyRow(row); + cancelEvent(event); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "stylesheet", + title: "CSS", + parentPanel: null, + searchable: true, + dependents: ["css", "stylesheet", "dom", "domSide", "layout"], + + options: + { + hasToolButtons: true + }, + + create: function() + { + Firebug.Panel.create.apply(this, arguments); + + this.onMouseDown = bind(this.onMouseDown, this); + this.onDoubleClick = bind(this.onDoubleClick, this); + + if (this.name == "stylesheet") + { + this.onChangeSelect = bind(this.onChangeSelect, this); + + var doc = Firebug.browser.document; + var selectNode = this.selectNode = createElement("select"); + + processAllStyleSheets(doc, function(doc, styleSheet) + { + var key = StyleSheetCache.key(styleSheet); + var fileName = getFileName(styleSheet.href) || getFileName(doc.location.href); + var option = createElement("option", {value: key}); + + option.appendChild(Firebug.chrome.document.createTextNode(fileName)); + selectNode.appendChild(option); + }); + + this.toolButtonsNode.appendChild(selectNode); + } + /**/ + }, + + onChangeSelect: function(event) + { + event = event || window.event; + var target = event.srcElement || event.currentTarget; + var key = target.value; + var styleSheet = StyleSheetCache.get(key); + + this.updateLocation(styleSheet); + }, + + initialize: function() + { + Firebug.Panel.initialize.apply(this, arguments); + + //if (!domUtils) + //{ + // try { + // domUtils = CCSV("@mozilla.org/inspector/dom-utils;1", "inIDOMUtils"); + // } catch (exc) { + // if (FBTrace.DBG_ERRORS) + // FBTrace.sysout("@mozilla.org/inspector/dom-utils;1 FAILED to load: "+exc, exc); + // } + //} + + //TODO: xxxpedro + this.context = Firebug.chrome; // TODO: xxxpedro css2 + this.document = Firebug.chrome.document; // TODO: xxxpedro css2 + + this.initializeNode(); + + if (this.name == "stylesheet") + { + var styleSheets = Firebug.browser.document.styleSheets; + + if (styleSheets.length > 0) + { + addEvent(this.selectNode, "change", this.onChangeSelect); + + this.updateLocation(styleSheets[0]); + } + } + + //Firebug.SourceBoxPanel.initialize.apply(this, arguments); + }, + + shutdown: function() + { + // must destroy the editor when we leave the panel to avoid problems (Issue 2981) + Firebug.Editor.stopEditing(); + + if (this.name == "stylesheet") + { + removeEvent(this.selectNode, "change", this.onChangeSelect); + } + + this.destroyNode(); + + Firebug.Panel.shutdown.apply(this, arguments); + }, + + destroy: function(state) + { + //state.scrollTop = this.panelNode.scrollTop ? this.panelNode.scrollTop : this.lastScrollTop; + + //persistObjects(this, state); + + // xxxpedro we are stopping the editor in the shutdown method already + //Firebug.Editor.stopEditing(); + Firebug.Panel.destroy.apply(this, arguments); + }, + + initializeNode: function(oldPanelNode) + { + addEvent(this.panelNode, "mousedown", this.onMouseDown); + addEvent(this.panelNode, "dblclick", this.onDoubleClick); + //Firebug.SourceBoxPanel.initializeNode.apply(this, arguments); + //dispatch([Firebug.A11yModel], 'onInitializeNode', [this, 'css']); + }, + + destroyNode: function() + { + removeEvent(this.panelNode, "mousedown", this.onMouseDown); + removeEvent(this.panelNode, "dblclick", this.onDoubleClick); + //Firebug.SourceBoxPanel.destroyNode.apply(this, arguments); + //dispatch([Firebug.A11yModel], 'onDestroyNode', [this, 'css']); + }, + + ishow: function(state) + { + Firebug.Inspector.stopInspecting(true); + + this.showToolbarButtons("fbCSSButtons", true); + + if (this.context.loaded && !this.location) // wait for loadedContext to restore the panel + { + restoreObjects(this, state); + + if (!this.location) + this.location = this.getDefaultLocation(); + + if (state && state.scrollTop) + this.panelNode.scrollTop = state.scrollTop; + } + }, + + ihide: function() + { + this.showToolbarButtons("fbCSSButtons", false); + + this.lastScrollTop = this.panelNode.scrollTop; + }, + + supportsObject: function(object) + { + if (object instanceof CSSStyleSheet) + return 1; + else if (object instanceof CSSStyleRule) + return 2; + else if (object instanceof CSSStyleDeclaration) + return 2; + else if (object instanceof SourceLink && object.type == "css" && reCSS.test(object.href)) + return 2; + else + return 0; + }, + + updateLocation: function(styleSheet) + { + if (!styleSheet) + return; + if (styleSheet.editStyleSheet) + styleSheet = styleSheet.editStyleSheet.sheet; + + // if it is a restricted stylesheet, show the warning message and abort the update process + if (styleSheet.restricted) + { + FirebugReps.Warning.tag.replace({object: "AccessRestricted"}, this.panelNode); + + // TODO: xxxpedro remove when there the external resource problem is fixed + externalStyleSheetWarning.tag.append({ + object: "The stylesheet could not be loaded due to access restrictions. ", + link: "more...", + href: "http://getfirebug.com/wiki/index.php/Firebug_Lite_FAQ#I_keep_seeing_.22Access_to_restricted_URI_denied.22" + }, this.panelNode); + + return; + } + + var rules = this.getStyleSheetRules(this.context, styleSheet); + + var result; + if (rules.length) + result = this.template.tag.replace({rules: rules}, this.panelNode); + else + result = FirebugReps.Warning.tag.replace({object: "EmptyStyleSheet"}, this.panelNode); + + // TODO: xxxpedro need to fix showToolbarButtons function + //this.showToolbarButtons("fbCSSButtons", !isSystemStyleSheet(this.location)); + + //dispatch([Firebug.A11yModel], 'onCSSRulesAdded', [this, this.panelNode]); + }, + + updateSelection: function(object) + { + this.selection = null; + + if (object instanceof CSSStyleDeclaration) { + object = object.parentRule; + } + + if (object instanceof CSSStyleRule) + { + this.navigate(object.parentStyleSheet); + this.highlightRule(object); + } + else if (object instanceof CSSStyleSheet) + { + this.navigate(object); + } + else if (object instanceof SourceLink) + { + try + { + var sourceLink = object; + + var sourceFile = getSourceFileByHref(sourceLink.href, this.context); + if (sourceFile) + { + clearNode(this.panelNode); // replace rendered stylesheets + this.showSourceFile(sourceFile); + + var lineNo = object.line; + if (lineNo) + this.scrollToLine(lineNo, this.jumpHighlightFactory(lineNo, this.context)); + } + else // XXXjjb we should not be taking this path + { + var stylesheet = getStyleSheetByHref(sourceLink.href, this.context); + if (stylesheet) + this.navigate(stylesheet); + else + { + if (FBTrace.DBG_CSS) + FBTrace.sysout("css.updateSelection no sourceFile for "+sourceLink.href, sourceLink); + } + } + } + catch(exc) { + if (FBTrace.DBG_CSS) + FBTrace.sysout("css.upDateSelection FAILS "+exc, exc); + } + } + }, + + updateOption: function(name, value) + { + if (name == "expandShorthandProps") + this.refresh(); + }, + + getLocationList: function() + { + var styleSheets = getAllStyleSheets(this.context); + return styleSheets; + }, + + getOptionsMenuItems: function() + { + return [ + {label: "Expand Shorthand Properties", type: "checkbox", checked: Firebug.expandShorthandProps, + command: bindFixed(Firebug.togglePref, Firebug, "expandShorthandProps") }, + "-", + {label: "Refresh", command: bind(this.refresh, this) } + ]; + }, + + getContextMenuItems: function(style, target) + { + var items = []; + + if (this.infoTipType == "color") + { + items.push( + {label: "CopyColor", + command: bindFixed(copyToClipboard, FBL, this.infoTipObject) } + ); + } + else if (this.infoTipType == "image") + { + items.push( + {label: "CopyImageLocation", + command: bindFixed(copyToClipboard, FBL, this.infoTipObject) }, + {label: "OpenImageInNewTab", + command: bindFixed(openNewTab, FBL, this.infoTipObject) } + ); + } + + ///if (this.selection instanceof Element) + if (isElement(this.selection)) + { + items.push( + //"-", + {label: "EditStyle", + command: bindFixed(this.editElementStyle, this) } + ); + } + else if (!isSystemStyleSheet(this.selection)) + { + items.push( + //"-", + {label: "NewRule", + command: bindFixed(this.insertRule, this, target) } + ); + } + + var cssRule = getAncestorByClass(target, "cssRule"); + if (cssRule && hasClass(cssRule, "cssEditableRule")) + { + items.push( + "-", + {label: "NewProp", + command: bindFixed(this.insertPropertyRow, this, target) } + ); + + var propRow = getAncestorByClass(target, "cssProp"); + if (propRow) + { + var propName = getChildByClass(propRow, "cssPropName")[textContent]; + var isDisabled = hasClass(propRow, "disabledStyle"); + + items.push( + {label: $STRF("EditProp", [propName]), nol10n: true, + command: bindFixed(this.editPropertyRow, this, propRow) }, + {label: $STRF("DeleteProp", [propName]), nol10n: true, + command: bindFixed(this.deletePropertyRow, this, propRow) }, + {label: $STRF("DisableProp", [propName]), nol10n: true, + type: "checkbox", checked: isDisabled, + command: bindFixed(this.disablePropertyRow, this, propRow) } + ); + } + } + + items.push( + "-", + {label: "Refresh", command: bind(this.refresh, this) } + ); + + return items; + }, + + browseObject: function(object) + { + if (this.infoTipType == "image") + { + openNewTab(this.infoTipObject); + return true; + } + }, + + showInfoTip: function(infoTip, target, x, y) + { + var propValue = getAncestorByClass(target, "cssPropValue"); + if (propValue) + { + var offset = getClientOffset(propValue); + var offsetX = x-offset.x; + + var text = propValue[textContent]; + var charWidth = propValue.offsetWidth/text.length; + var charOffset = Math.floor(offsetX/charWidth); + + var cssValue = parseCSSValue(text, charOffset); + if (cssValue) + { + if (cssValue.value == this.infoTipValue) + return true; + + this.infoTipValue = cssValue.value; + + if (cssValue.type == "rgb" || (!cssValue.type && isColorKeyword(cssValue.value))) + { + this.infoTipType = "color"; + this.infoTipObject = cssValue.value; + + return Firebug.InfoTip.populateColorInfoTip(infoTip, cssValue.value); + } + else if (cssValue.type == "url") + { + ///var propNameNode = target.parentNode.getElementsByClassName("cssPropName").item(0); + var propNameNode = getElementByClass(target.parentNode, "cssPropName"); + if (propNameNode && isImageRule(propNameNode[textContent])) + { + var rule = Firebug.getRepObject(target); + var baseURL = this.getStylesheetURL(rule); + var relURL = parseURLValue(cssValue.value); + var absURL = isDataURL(relURL) ? relURL:absoluteURL(relURL, baseURL); + var repeat = parseRepeatValue(text); + + this.infoTipType = "image"; + this.infoTipObject = absURL; + + return Firebug.InfoTip.populateImageInfoTip(infoTip, absURL, repeat); + } + } + } + } + + delete this.infoTipType; + delete this.infoTipValue; + delete this.infoTipObject; + }, + + getEditor: function(target, value) + { + if (target == this.panelNode + || hasClass(target, "cssSelector") || hasClass(target, "cssRule") + || hasClass(target, "cssSheet")) + { + if (!this.ruleEditor) + this.ruleEditor = new CSSRuleEditor(this.document); + + return this.ruleEditor; + } + else + { + if (!this.editor) + this.editor = new CSSEditor(this.document); + + return this.editor; + } + }, + + getDefaultLocation: function() + { + try + { + var styleSheets = this.context.window.document.styleSheets; + if (styleSheets.length) + { + var sheet = styleSheets[0]; + return (Firebug.filterSystemURLs && isSystemURL(getURLForStyleSheet(sheet))) ? null : sheet; + } + } + catch (exc) + { + if (FBTrace.DBG_LOCATIONS) + FBTrace.sysout("css.getDefaultLocation FAILS "+exc, exc); + } + }, + + getObjectDescription: function(styleSheet) + { + var url = getURLForStyleSheet(styleSheet); + var instance = getInstanceForStyleSheet(styleSheet); + + var baseDescription = splitURLBase(url); + if (instance) { + baseDescription.name = baseDescription.name + " #" + (instance + 1); + } + return baseDescription; + }, + + search: function(text, reverse) + { + var curDoc = this.searchCurrentDoc(!Firebug.searchGlobal, text, reverse); + if (!curDoc && Firebug.searchGlobal) + { + return this.searchOtherDocs(text, reverse); + } + return curDoc; + }, + + searchOtherDocs: function(text, reverse) + { + var scanRE = Firebug.Search.getTestingRegex(text); + function scanDoc(styleSheet) { + // we don't care about reverse here as we are just looking for existence, + // if we do have a result we will handle the reverse logic on display + for (var i = 0; i < styleSheet.cssRules.length; i++) + { + if (scanRE.test(styleSheet.cssRules[i].cssText)) + { + return true; + } + } + } + + if (this.navigateToNextDocument(scanDoc, reverse)) + { + return this.searchCurrentDoc(true, text, reverse); + } + }, + + searchCurrentDoc: function(wrapSearch, text, reverse) + { + if (!text) + { + delete this.currentSearch; + return false; + } + + var row; + if (this.currentSearch && text == this.currentSearch.text) + { + row = this.currentSearch.findNext(wrapSearch, false, reverse, Firebug.Search.isCaseSensitive(text)); + } + else + { + if (this.editing) + { + this.currentSearch = new TextSearch(this.stylesheetEditor.box); + row = this.currentSearch.find(text, reverse, Firebug.Search.isCaseSensitive(text)); + + if (row) + { + var sel = this.document.defaultView.getSelection(); + sel.removeAllRanges(); + sel.addRange(this.currentSearch.range); + scrollSelectionIntoView(this); + return true; + } + else + return false; + } + else + { + function findRow(node) { return node.nodeType == 1 ? node : node.parentNode; } + this.currentSearch = new TextSearch(this.panelNode, findRow); + row = this.currentSearch.find(text, reverse, Firebug.Search.isCaseSensitive(text)); + } + } + + if (row) + { + this.document.defaultView.getSelection().selectAllChildren(row); + scrollIntoCenterView(row, this.panelNode); + dispatch([Firebug.A11yModel], 'onCSSSearchMatchFound', [this, text, row]); + return true; + } + else + { + dispatch([Firebug.A11yModel], 'onCSSSearchMatchFound', [this, text, null]); + return false; + } + }, + + getSearchOptionsMenuItems: function() + { + return [ + Firebug.Search.searchOptionMenu("search.Case_Sensitive", "searchCaseSensitive"), + Firebug.Search.searchOptionMenu("search.Multiple_Files", "searchGlobal") + ]; + } +}); +/**/ +// ************************************************************************************************ + +function CSSElementPanel() {} + +CSSElementPanel.prototype = extend(Firebug.CSSStyleSheetPanel.prototype, +{ + template: domplate( + { + cascadedTag: + DIV({"class": "a11yCSSView", role : 'presentation'}, + DIV({role : 'list', 'aria-label' : $STR('aria.labels.style rules') }, + FOR("rule", "$rules", + TAG("$ruleTag", {rule: "$rule"}) + ) + ), + DIV({role : "list", 'aria-label' :$STR('aria.labels.inherited style rules')}, + FOR("section", "$inherited", + H1({"class": "cssInheritHeader groupHeader focusRow", role : 'listitem' }, + SPAN({"class": "cssInheritLabel"}, "$inheritLabel"), + TAG(FirebugReps.Element.shortTag, {object: "$section.element"}) + ), + DIV({role : 'group'}, + FOR("rule", "$section.rules", + TAG("$ruleTag", {rule: "$rule"}) + ) + ) + ) + ) + ), + + ruleTag: + isIE ? + // IE needs the sourceLink first, otherwise it will be rendered outside the panel + DIV({"class": "cssElementRuleContainer"}, + TAG(FirebugReps.SourceLink.tag, {object: "$rule.sourceLink"}), + TAG(CSSStyleRuleTag.tag, {rule: "$rule"}) + ) + : + // other browsers need the sourceLink last, otherwise it will cause an extra space + // before the rule representation + DIV({"class": "cssElementRuleContainer"}, + TAG(CSSStyleRuleTag.tag, {rule: "$rule"}), + TAG(FirebugReps.SourceLink.tag, {object: "$rule.sourceLink"}) + ) + }), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + updateCascadeView: function(element) + { + //dispatch([Firebug.A11yModel], 'onBeforeCSSRulesAdded', [this]); + var rules = [], sections = [], usedProps = {}; + this.getInheritedRules(element, sections, usedProps); + this.getElementRules(element, rules, usedProps); + + if (rules.length || sections.length) + { + var inheritLabel = "Inherited from"; // $STR("InheritedFrom"); + var result = this.template.cascadedTag.replace({rules: rules, inherited: sections, + inheritLabel: inheritLabel}, this.panelNode); + //dispatch([Firebug.A11yModel], 'onCSSRulesAdded', [this, result]); + } + else + { + var result = FirebugReps.Warning.tag.replace({object: "EmptyElementCSS"}, this.panelNode); + //dispatch([Firebug.A11yModel], 'onCSSRulesAdded', [this, result]); + } + + // TODO: xxxpedro remove when there the external resource problem is fixed + if (externalStyleSheetURLs.length > 0) + externalStyleSheetWarning.tag.append({ + object: "The results here may be inaccurate because some " + + "stylesheets could not be loaded due to access restrictions. ", + link: "more...", + href: "http://getfirebug.com/wiki/index.php/Firebug_Lite_FAQ#I_keep_seeing_.22This_element_has_no_style_rules.22" + }, this.panelNode); + }, + + getStylesheetURL: function(rule) + { + // if the parentStyleSheet.href is null, CSS std says its inline style. + // TODO: xxxpedro IE doesn't have rule.parentStyleSheet so we must fall back to the doc.location + if (rule && rule.parentStyleSheet && rule.parentStyleSheet.href) + return rule.parentStyleSheet.href; + else + return this.selection.ownerDocument.location.href; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getInheritedRules: function(element, sections, usedProps) + { + var parent = element.parentNode; + if (parent && parent.nodeType == 1) + { + this.getInheritedRules(parent, sections, usedProps); + + var rules = []; + this.getElementRules(parent, rules, usedProps, true); + + if (rules.length) + sections.splice(0, 0, {element: parent, rules: rules}); + } + }, + + getElementRules: function(element, rules, usedProps, inheritMode) + { + var inspectedRules, displayedRules = {}; + + // TODO: xxxpedro remove document specificity issue + //var eid = ElementCache(element); + //inspectedRules = ElementCSSRulesMap[eid]; + + inspectedRules = getElementCSSRules(element); + + if (inspectedRules) + { + for (var i = 0, length=inspectedRules.length; i < length; ++i) + { + var ruleId = inspectedRules[i]; + var ruleData = CSSRuleMap[ruleId]; + var rule = ruleData.rule; + + var ssid = ruleData.styleSheetId; + var parentStyleSheet = StyleSheetCache.get(ssid); + + var href = parentStyleSheet.externalURL ? parentStyleSheet.externalURL : parentStyleSheet.href; // Null means inline + + var instance = null; + //var instance = getInstanceForStyleSheet(rule.parentStyleSheet, element.ownerDocument); + + var isSystemSheet = false; + //var isSystemSheet = isSystemStyleSheet(rule.parentStyleSheet); + + if (!Firebug.showUserAgentCSS && isSystemSheet) // This removes user agent rules + continue; + + if (!href) + href = element.ownerDocument.location.href; // http://code.google.com/p/fbug/issues/detail?id=452 + + var props = this.getRuleProperties(this.context, rule, inheritMode); + if (inheritMode && !props.length) + continue; + + // + //var line = domUtils.getRuleLine(rule); + var line; + + var ruleId = rule.selectorText+"/"+line; + var sourceLink = new SourceLink(href, line, "css", rule, instance); + + this.markOverridenProps(props, usedProps, inheritMode); + + rules.splice(0, 0, {rule: rule, id: ruleId, + selector: ruleData.selector, sourceLink: sourceLink, + props: props, inherited: inheritMode, + isSystemSheet: isSystemSheet}); + } + } + + if (element.style) + this.getStyleProperties(element, rules, usedProps, inheritMode); + + if (FBTrace.DBG_CSS) + FBTrace.sysout("getElementRules "+rules.length+" rules for "+getElementXPath(element), rules); + }, + /* + getElementRules: function(element, rules, usedProps, inheritMode) + { + var inspectedRules, displayedRules = {}; + try + { + inspectedRules = domUtils ? domUtils.getCSSStyleRules(element) : null; + } catch (exc) {} + + if (inspectedRules) + { + for (var i = 0; i < inspectedRules.Count(); ++i) + { + var rule = QI(inspectedRules.GetElementAt(i), nsIDOMCSSStyleRule); + + var href = rule.parentStyleSheet.href; // Null means inline + + var instance = getInstanceForStyleSheet(rule.parentStyleSheet, element.ownerDocument); + + var isSystemSheet = isSystemStyleSheet(rule.parentStyleSheet); + if (!Firebug.showUserAgentCSS && isSystemSheet) // This removes user agent rules + continue; + if (!href) + href = element.ownerDocument.location.href; // http://code.google.com/p/fbug/issues/detail?id=452 + + var props = this.getRuleProperties(this.context, rule, inheritMode); + if (inheritMode && !props.length) + continue; + + var line = domUtils.getRuleLine(rule); + var ruleId = rule.selectorText+"/"+line; + var sourceLink = new SourceLink(href, line, "css", rule, instance); + + this.markOverridenProps(props, usedProps, inheritMode); + + rules.splice(0, 0, {rule: rule, id: ruleId, + selector: rule.selectorText, sourceLink: sourceLink, + props: props, inherited: inheritMode, + isSystemSheet: isSystemSheet}); + } + } + + if (element.style) + this.getStyleProperties(element, rules, usedProps, inheritMode); + + if (FBTrace.DBG_CSS) + FBTrace.sysout("getElementRules "+rules.length+" rules for "+getElementXPath(element), rules); + }, + /**/ + markOverridenProps: function(props, usedProps, inheritMode) + { + for (var i = 0; i < props.length; ++i) + { + var prop = props[i]; + if ( usedProps.hasOwnProperty(prop.name) ) + { + var deadProps = usedProps[prop.name]; // all previous occurrences of this property + for (var j = 0; j < deadProps.length; ++j) + { + var deadProp = deadProps[j]; + if (!deadProp.disabled && !deadProp.wasInherited && deadProp.important && !prop.important) + prop.overridden = true; // new occurrence overridden + else if (!prop.disabled) + deadProp.overridden = true; // previous occurrences overridden + } + } + else + usedProps[prop.name] = []; + + prop.wasInherited = inheritMode ? true : false; + usedProps[prop.name].push(prop); // all occurrences of a property seen so far, by name + } + }, + + getStyleProperties: function(element, rules, usedProps, inheritMode) + { + var props = this.parseCSSProps(element.style, inheritMode); + this.addOldProperties(this.context, getElementXPath(element), inheritMode, props); + + sortProperties(props); + this.markOverridenProps(props, usedProps, inheritMode); + + if (props.length) + rules.splice(0, 0, + {rule: element, id: getElementXPath(element), + selector: "element.style", props: props, inherited: inheritMode}); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "css", + title: "Style", + parentPanel: "HTML", + order: 0, + + initialize: function() + { + this.context = Firebug.chrome; // TODO: xxxpedro css2 + this.document = Firebug.chrome.document; // TODO: xxxpedro css2 + + Firebug.CSSStyleSheetPanel.prototype.initialize.apply(this, arguments); + + // TODO: xxxpedro css2 + var selection = ElementCache.get(FirebugChrome.selectedHTMLElementId); + if (selection) + this.select(selection, true); + + //this.updateCascadeView(document.getElementsByTagName("h1")[0]); + //this.updateCascadeView(document.getElementById("build")); + + /* + this.onStateChange = bindFixed(this.contentStateCheck, this); + this.onHoverChange = bindFixed(this.contentStateCheck, this, STATE_HOVER); + this.onActiveChange = bindFixed(this.contentStateCheck, this, STATE_ACTIVE); + /**/ + }, + + ishow: function(state) + { + }, + + watchWindow: function(win) + { + if (domUtils) + { + // Normally these would not be required, but in order to update after the state is set + // using the options menu we need to monitor these global events as well + var doc = win.document; + ///addEvent(doc, "mouseover", this.onHoverChange); + ///addEvent(doc, "mousedown", this.onActiveChange); + } + }, + unwatchWindow: function(win) + { + var doc = win.document; + ///removeEvent(doc, "mouseover", this.onHoverChange); + ///removeEvent(doc, "mousedown", this.onActiveChange); + + if (isAncestor(this.stateChangeEl, doc)) + { + this.removeStateChangeHandlers(); + } + }, + + supportsObject: function(object) + { + return object instanceof Element ? 1 : 0; + }, + + updateView: function(element) + { + this.updateCascadeView(element); + if (domUtils) + { + this.contentState = safeGetContentState(element); + this.addStateChangeHandlers(element); + } + }, + + updateSelection: function(element) + { + if ( !instanceOf(element , "Element") ) // html supports SourceLink + return; + + if (sothinkInstalled) + { + FirebugReps.Warning.tag.replace({object: "SothinkWarning"}, this.panelNode); + return; + } + + /* + if (!domUtils) + { + FirebugReps.Warning.tag.replace({object: "DOMInspectorWarning"}, this.panelNode); + return; + } + /**/ + + if (!element) + return; + + this.updateView(element); + }, + + updateOption: function(name, value) + { + if (name == "showUserAgentCSS" || name == "expandShorthandProps") + this.refresh(); + }, + + getOptionsMenuItems: function() + { + var ret = [ + {label: "Show User Agent CSS", type: "checkbox", checked: Firebug.showUserAgentCSS, + command: bindFixed(Firebug.togglePref, Firebug, "showUserAgentCSS") }, + {label: "Expand Shorthand Properties", type: "checkbox", checked: Firebug.expandShorthandProps, + command: bindFixed(Firebug.togglePref, Firebug, "expandShorthandProps") } + ]; + if (domUtils && this.selection) + { + var state = safeGetContentState(this.selection); + + ret.push("-"); + ret.push({label: ":active", type: "checkbox", checked: state & STATE_ACTIVE, + command: bindFixed(this.updateContentState, this, STATE_ACTIVE, state & STATE_ACTIVE)}); + ret.push({label: ":hover", type: "checkbox", checked: state & STATE_HOVER, + command: bindFixed(this.updateContentState, this, STATE_HOVER, state & STATE_HOVER)}); + } + return ret; + }, + + updateContentState: function(state, remove) + { + domUtils.setContentState(remove ? this.selection.ownerDocument.documentElement : this.selection, state); + this.refresh(); + }, + + addStateChangeHandlers: function(el) + { + this.removeStateChangeHandlers(); + + /* + addEvent(el, "focus", this.onStateChange); + addEvent(el, "blur", this.onStateChange); + addEvent(el, "mouseup", this.onStateChange); + addEvent(el, "mousedown", this.onStateChange); + addEvent(el, "mouseover", this.onStateChange); + addEvent(el, "mouseout", this.onStateChange); + /**/ + + this.stateChangeEl = el; + }, + + removeStateChangeHandlers: function() + { + var sel = this.stateChangeEl; + if (sel) + { + /* + removeEvent(sel, "focus", this.onStateChange); + removeEvent(sel, "blur", this.onStateChange); + removeEvent(sel, "mouseup", this.onStateChange); + removeEvent(sel, "mousedown", this.onStateChange); + removeEvent(sel, "mouseover", this.onStateChange); + removeEvent(sel, "mouseout", this.onStateChange); + /**/ + } + }, + + contentStateCheck: function(state) + { + if (!state || this.contentState & state) + { + var timeoutRunner = bindFixed(function() + { + var newState = safeGetContentState(this.selection); + if (newState != this.contentState) + { + this.context.invalidatePanels(this.name); + } + }, this); + + // Delay exec until after the event has processed and the state has been updated + setTimeout(timeoutRunner, 0); + } + } +}); + +function safeGetContentState(selection) +{ + try + { + return domUtils.getContentState(selection); + } + catch (e) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("css.safeGetContentState; EXCEPTION", e); + } +} + +// ************************************************************************************************ + +function CSSComputedElementPanel() {} + +CSSComputedElementPanel.prototype = extend(CSSElementPanel.prototype, +{ + template: domplate( + { + computedTag: + DIV({"class": "a11yCSSView", role : "list", "aria-label" : $STR('aria.labels.computed styles')}, + FOR("group", "$groups", + H1({"class": "cssInheritHeader groupHeader focusRow", role : "listitem"}, + SPAN({"class": "cssInheritLabel"}, "$group.title") + ), + TABLE({width: "100%", role : 'group'}, + TBODY({role : 'presentation'}, + FOR("prop", "$group.props", + TR({"class": 'focusRow computedStyleRow', role : 'listitem'}, + TD({"class": "stylePropName", role : 'presentation'}, "$prop.name"), + TD({"class": "stylePropValue", role : 'presentation'}, "$prop.value") + ) + ) + ) + ) + ) + ) + }), + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + updateComputedView: function(element) + { + var win = isIE ? + element.ownerDocument.parentWindow : + element.ownerDocument.defaultView; + + var style = isIE ? + element.currentStyle : + win.getComputedStyle(element, ""); + + var groups = []; + + for (var groupName in styleGroups) + { + // TODO: xxxpedro i18n $STR + //var title = $STR("StyleGroup-" + groupName); + var title = styleGroupTitles[groupName]; + var group = {title: title, props: []}; + groups.push(group); + + var props = styleGroups[groupName]; + for (var i = 0; i < props.length; ++i) + { + var propName = props[i]; + var propValue = style.getPropertyValue ? + style.getPropertyValue(propName) : + ""+style[toCamelCase(propName)]; + + if (propValue === undefined || propValue === null) + continue; + + propValue = stripUnits(rgbToHex(propValue)); + if (propValue) + group.props.push({name: propName, value: propValue}); + } + } + + var result = this.template.computedTag.replace({groups: groups}, this.panelNode); + //dispatch([Firebug.A11yModel], 'onCSSRulesAdded', [this, result]); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "computed", + title: "Computed", + parentPanel: "HTML", + order: 1, + + updateView: function(element) + { + this.updateComputedView(element); + }, + + getOptionsMenuItems: function() + { + return [ + {label: "Refresh", command: bind(this.refresh, this) } + ]; + } +}); + +// ************************************************************************************************ +// CSSEditor + +function CSSEditor(doc) +{ + this.initializeInline(doc); +} + +CSSEditor.prototype = domplate(Firebug.InlineEditor.prototype, +{ + insertNewRow: function(target, insertWhere) + { + var rule = Firebug.getRepObject(target); + var emptyProp = + { + // TODO: xxxpedro - uses charCode(255) to force the element being rendered, + // allowing webkit to get the correct position of the property name "span", + // when inserting a new CSS rule? + name: "", + value: "", + important: "" + }; + + if (insertWhere == "before") + return CSSPropTag.tag.insertBefore({prop: emptyProp, rule: rule}, target); + else + return CSSPropTag.tag.insertAfter({prop: emptyProp, rule: rule}, target); + }, + + saveEdit: function(target, value, previousValue) + { + // We need to check the value first in order to avoid a problem in IE8 + // See Issue 3038: Empty (null) styles when adding CSS styles in Firebug Lite + if (!value) return; + + target.innerHTML = escapeForCss(value); + + var row = getAncestorByClass(target, "cssProp"); + if (hasClass(row, "disabledStyle")) + toggleClass(row, "disabledStyle"); + + var rule = Firebug.getRepObject(target); + + if (hasClass(target, "cssPropName")) + { + if (value && previousValue != value) // name of property has changed. + { + var propValue = getChildByClass(row, "cssPropValue")[textContent]; + var parsedValue = parsePriority(propValue); + + if (propValue && propValue != "undefined") { + if (FBTrace.DBG_CSS) + FBTrace.sysout("CSSEditor.saveEdit : "+previousValue+"->"+value+" = "+propValue+"\n"); + if (previousValue) + Firebug.CSSModule.removeProperty(rule, previousValue); + Firebug.CSSModule.setProperty(rule, value, parsedValue.value, parsedValue.priority); + } + } + else if (!value) // name of the property has been deleted, so remove the property. + Firebug.CSSModule.removeProperty(rule, previousValue); + } + else if (getAncestorByClass(target, "cssPropValue")) + { + var propName = getChildByClass(row, "cssPropName")[textContent]; + var propValue = getChildByClass(row, "cssPropValue")[textContent]; + + if (FBTrace.DBG_CSS) + { + FBTrace.sysout("CSSEditor.saveEdit propName=propValue: "+propName +" = "+propValue+"\n"); + // FBTrace.sysout("CSSEditor.saveEdit BEFORE style:",style); + } + + if (value && value != "null") + { + var parsedValue = parsePriority(value); + Firebug.CSSModule.setProperty(rule, propName, parsedValue.value, parsedValue.priority); + } + else if (previousValue && previousValue != "null") + Firebug.CSSModule.removeProperty(rule, propName); + } + + this.panel.markChange(this.panel.name == "stylesheet"); + }, + + advanceToNext: function(target, charCode) + { + if (charCode == 58 /*":"*/ && hasClass(target, "cssPropName")) + return true; + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + getAutoCompleteRange: function(value, offset) + { + if (hasClass(this.target, "cssPropName")) + return {start: 0, end: value.length-1}; + else + return parseCSSValue(value, offset); + }, + + getAutoCompleteList: function(preExpr, expr, postExpr) + { + if (hasClass(this.target, "cssPropName")) + { + return getCSSPropertyNames(); + } + else + { + var row = getAncestorByClass(this.target, "cssProp"); + var propName = getChildByClass(row, "cssPropName")[textContent]; + return getCSSKeywordsByProperty(propName); + } + } +}); + +//************************************************************************************************ +//CSSRuleEditor + +function CSSRuleEditor(doc) +{ + this.initializeInline(doc); + this.completeAsYouType = false; +} +CSSRuleEditor.uniquifier = 0; +CSSRuleEditor.prototype = domplate(Firebug.InlineEditor.prototype, +{ + insertNewRow: function(target, insertWhere) + { + var emptyRule = { + selector: "", + id: "", + props: [], + isSelectorEditable: true + }; + + if (insertWhere == "before") + return CSSStyleRuleTag.tag.insertBefore({rule: emptyRule}, target); + else + return CSSStyleRuleTag.tag.insertAfter({rule: emptyRule}, target); + }, + + saveEdit: function(target, value, previousValue) + { + if (FBTrace.DBG_CSS) + FBTrace.sysout("CSSRuleEditor.saveEdit: '" + value + "' '" + previousValue + "'", target); + + target.innerHTML = escapeForCss(value); + + if (value === previousValue) return; + + var row = getAncestorByClass(target, "cssRule"); + var styleSheet = this.panel.location; + styleSheet = styleSheet.editStyleSheet ? styleSheet.editStyleSheet.sheet : styleSheet; + + var cssRules = styleSheet.cssRules; + var rule = Firebug.getRepObject(target), oldRule = rule; + var ruleIndex = cssRules.length; + if (rule || Firebug.getRepObject(row.nextSibling)) + { + var searchRule = rule || Firebug.getRepObject(row.nextSibling); + for (ruleIndex=0; ruleIndex b.name ? 1 : -1; + }); +} + +function getTopmostRuleLine(panelNode) +{ + for (var child = panelNode.firstChild; child; child = child.nextSibling) + { + if (child.offsetTop+child.offsetHeight > panelNode.scrollTop) + { + var rule = child.repObject; + if (rule) + return { + line: domUtils.getRuleLine(rule), + offset: panelNode.scrollTop-child.offsetTop + }; + } + } + return 0; +} + +function getStyleSheetCSS(sheet, context) +{ + if (sheet.ownerNode instanceof HTMLStyleElement) + return sheet.ownerNode.innerHTML; + else + return context.sourceCache.load(sheet.href).join(""); +} + +function getStyleSheetOwnerNode(sheet) { + for (; sheet && !sheet.ownerNode; sheet = sheet.parentStyleSheet); + + return sheet.ownerNode; +} + +function scrollSelectionIntoView(panel) +{ + var selCon = getSelectionController(panel); + selCon.scrollSelectionIntoView( + nsISelectionController.SELECTION_NORMAL, + nsISelectionController.SELECTION_FOCUS_REGION, true); +} + +function getSelectionController(panel) +{ + var browser = Firebug.chrome.getPanelBrowser(panel); + return browser.docShell.QueryInterface(nsIInterfaceRequestor) + .getInterface(nsISelectionDisplay) + .QueryInterface(nsISelectionController); +} + +// ************************************************************************************************ + +Firebug.registerModule(Firebug.CSSModule); +Firebug.registerPanel(Firebug.CSSStyleSheetPanel); +Firebug.registerPanel(CSSElementPanel); +Firebug.registerPanel(CSSComputedElementPanel); + +// ************************************************************************************************ + +}}); + + +/* 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 (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; +}; + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var ElementCache = Firebug.Lite.Cache.Element; + +var insertSliceSize = 18; +var insertInterval = 40; + +var ignoreVars = +{ + "__firebug__": 1, + "eval": 1, + + // We are forced to ignore Java-related variables, because + // trying to access them causes browser freeze + "java": 1, + "sun": 1, + "Packages": 1, + "JavaArray": 1, + "JavaMember": 1, + "JavaObject": 1, + "JavaClass": 1, + "JavaPackage": 1, + "_firebug": 1, + "_FirebugConsole": 1, + "_FirebugCommandLine": 1 +}; + +if (Firebug.ignoreFirebugElements) + ignoreVars[Firebug.Lite.Cache.ID] = 1; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +var memberPanelRep = + isIE6 ? + {"class": "memberLabel $member.type\\Label", href: "javacript:void(0)"} + : + {"class": "memberLabel $member.type\\Label"}; + +var RowTag = + TR({"class": "memberRow $member.open $member.type\\Row", $hasChildren: "$member.hasChildren", role : 'presentation', + level: "$member.level"}, + TD({"class": "memberLabelCell", style: "padding-left: $member.indent\\px", role : 'presentation'}, + A(memberPanelRep, + SPAN({}, "$member.name") + ) + ), + TD({"class": "memberValueCell", role : 'presentation'}, + TAG("$member.tag", {object: "$member.value"}) + ) + ); + +var WatchRowTag = + TR({"class": "watchNewRow", level: 0}, + TD({"class": "watchEditCell", colspan: 2}, + DIV({"class": "watchEditBox a11yFocusNoTab", role: "button", 'tabindex' : '0', + 'aria-label' : $STR('press enter to add new watch expression')}, + $STR("NewWatch") + ) + ) + ); + +var SizerRow = + TR({role : 'presentation'}, + TD({width: "30%"}), + TD({width: "70%"}) + ); + +var domTableClass = isIElt8 ? "domTable domTableIE" : "domTable"; +var DirTablePlate = domplate(Firebug.Rep, +{ + tag: + TABLE({"class": domTableClass, cellpadding: 0, cellspacing: 0, onclick: "$onClick", role :"tree"}, + TBODY({role: 'presentation'}, + SizerRow, + FOR("member", "$object|memberIterator", RowTag) + ) + ), + + watchTag: + TABLE({"class": domTableClass, cellpadding: 0, cellspacing: 0, + _toggles: "$toggles", _domPanel: "$domPanel", onclick: "$onClick", role : 'tree'}, + TBODY({role : 'presentation'}, + SizerRow, + WatchRowTag + ) + ), + + tableTag: + TABLE({"class": domTableClass, cellpadding: 0, cellspacing: 0, + _toggles: "$toggles", _domPanel: "$domPanel", onclick: "$onClick", role : 'tree'}, + TBODY({role : 'presentation'}, + SizerRow + ) + ), + + rowTag: + FOR("member", "$members", RowTag), + + memberIterator: function(object, level) + { + return getMembers(object, level); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + onClick: function(event) + { + if (!isLeftClick(event)) + return; + + var target = event.target || event.srcElement; + + var row = getAncestorByClass(target, "memberRow"); + var label = getAncestorByClass(target, "memberLabel"); + if (label && hasClass(row, "hasChildren")) + { + var row = label.parentNode.parentNode; + this.toggleRow(row); + } + else + { + var object = Firebug.getRepObject(target); + if (typeof(object) == "function") + { + Firebug.chrome.select(object, "script"); + cancelEvent(event); + } + else if (event.detail == 2 && !object) + { + var panel = row.parentNode.parentNode.domPanel; + if (panel) + { + var rowValue = panel.getRowPropertyValue(row); + if (typeof(rowValue) == "boolean") + panel.setPropertyValue(row, !rowValue); + else + panel.editProperty(row); + + cancelEvent(event); + } + } + } + + return false; + }, + + toggleRow: function(row) + { + var level = parseInt(row.getAttribute("level")); + var toggles = row.parentNode.parentNode.toggles; + + if (hasClass(row, "opened")) + { + removeClass(row, "opened"); + + if (toggles) + { + var path = getPath(row); + + // Remove the path from the toggle tree + for (var i = 0; i < path.length; ++i) + { + if (i == path.length-1) + delete toggles[path[i]]; + else + toggles = toggles[path[i]]; + } + } + + var rowTag = this.rowTag; + var tbody = row.parentNode; + + setTimeout(function() + { + for (var firstRow = row.nextSibling; firstRow; firstRow = row.nextSibling) + { + if (parseInt(firstRow.getAttribute("level")) <= level) + break; + + tbody.removeChild(firstRow); + } + }, row.insertTimeout ? row.insertTimeout : 0); + } + else + { + setClass(row, "opened"); + + if (toggles) + { + var path = getPath(row); + + // Mark the path in the toggle tree + for (var i = 0; i < path.length; ++i) + { + var name = path[i]; + if (toggles.hasOwnProperty(name)) + toggles = toggles[name]; + else + toggles = toggles[name] = {}; + } + } + + var value = row.lastChild.firstChild.repObject; + var members = getMembers(value, level+1); + + var rowTag = this.rowTag; + var lastRow = row; + + var delay = 0; + //var setSize = members.length; + //var rowCount = 1; + while (members.length) + { + with({slice: members.splice(0, insertSliceSize), isLast: !members.length}) + { + setTimeout(function() + { + if (lastRow.parentNode) + { + var result = rowTag.insertRows({members: slice}, lastRow); + lastRow = result[1]; + //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [null, result, rowCount, setSize]); + //rowCount += insertSliceSize; + } + if (isLast) + row.removeAttribute("insertTimeout"); + }, delay); + } + + delay += insertInterval; + } + + row.insertTimeout = delay; + } + } +}); + + + +// ************************************************************************************************ + +Firebug.DOMBasePanel = function() {} + +Firebug.DOMBasePanel.prototype = extend(Firebug.Panel, +{ + tag: DirTablePlate.tableTag, + + getRealObject: function(object) + { + // TODO: Move this to some global location + // TODO: Unwrapping should be centralized rather than sprinkling it around ad hoc. + // TODO: We might be able to make this check more authoritative with QueryInterface. + if (!object) return object; + if (object.wrappedJSObject) return object.wrappedJSObject; + return object; + }, + + rebuild: function(update, scrollTop) + { + //dispatch([Firebug.A11yModel], 'onBeforeDomUpdateSelection', [this]); + var members = getMembers(this.selection); + expandMembers(members, this.toggles, 0, 0); + + this.showMembers(members, update, scrollTop); + + //TODO: xxxpedro statusbar + if (!this.parentPanel) + updateStatusBar(this); + }, + + showMembers: function(members, update, scrollTop) + { + // If we are still in the midst of inserting rows, cancel all pending + // insertions here - this is a big speedup when stepping in the debugger + if (this.timeouts) + { + for (var i = 0; i < this.timeouts.length; ++i) + this.context.clearTimeout(this.timeouts[i]); + delete this.timeouts; + } + + if (!members.length) + return this.showEmptyMembers(); + + var panelNode = this.panelNode; + var priorScrollTop = scrollTop == undefined ? panelNode.scrollTop : scrollTop; + + // If we are asked to "update" the current view, then build the new table + // offscreen and swap it in when it's done + var offscreen = update && panelNode.firstChild; + var dest = offscreen ? panelNode.ownerDocument : panelNode; + + var table = this.tag.replace({domPanel: this, toggles: this.toggles}, dest); + var tbody = table.lastChild; + var rowTag = DirTablePlate.rowTag; + + // Insert the first slice immediately + //var slice = members.splice(0, insertSliceSize); + //var result = rowTag.insertRows({members: slice}, tbody.lastChild); + + //var setSize = members.length; + //var rowCount = 1; + + var panel = this; + var result; + + //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [panel, result, rowCount, setSize]); + var timeouts = []; + + var delay = 0; + + // enable to measure rendering performance + var renderStart = new Date().getTime(); + while (members.length) + { + with({slice: members.splice(0, insertSliceSize), isLast: !members.length}) + { + timeouts.push(this.context.setTimeout(function() + { + // TODO: xxxpedro can this be a timing error related to the + // "iteration number" approach insted of "duration time"? + // avoid error in IE8 + if (!tbody.lastChild) return; + + result = rowTag.insertRows({members: slice}, tbody.lastChild); + + //rowCount += insertSliceSize; + //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [panel, result, rowCount, setSize]); + + if ((panelNode.scrollHeight+panelNode.offsetHeight) >= priorScrollTop) + panelNode.scrollTop = priorScrollTop; + + + // enable to measure rendering performance + //if (isLast) alert(new Date().getTime() - renderStart + "ms"); + + + }, delay)); + + delay += insertInterval; + } + } + + if (offscreen) + { + timeouts.push(this.context.setTimeout(function() + { + if (panelNode.firstChild) + panelNode.replaceChild(table, panelNode.firstChild); + else + panelNode.appendChild(table); + + // Scroll back to where we were before + panelNode.scrollTop = priorScrollTop; + }, delay)); + } + else + { + timeouts.push(this.context.setTimeout(function() + { + panelNode.scrollTop = scrollTop == undefined ? 0 : scrollTop; + }, delay)); + } + this.timeouts = timeouts; + }, + + /* + // new + showMembers: function(members, update, scrollTop) + { + // If we are still in the midst of inserting rows, cancel all pending + // insertions here - this is a big speedup when stepping in the debugger + if (this.timeouts) + { + for (var i = 0; i < this.timeouts.length; ++i) + this.context.clearTimeout(this.timeouts[i]); + delete this.timeouts; + } + + if (!members.length) + return this.showEmptyMembers(); + + var panelNode = this.panelNode; + var priorScrollTop = scrollTop == undefined ? panelNode.scrollTop : scrollTop; + + // If we are asked to "update" the current view, then build the new table + // offscreen and swap it in when it's done + var offscreen = update && panelNode.firstChild; + var dest = offscreen ? panelNode.ownerDocument : panelNode; + + var table = this.tag.replace({domPanel: this, toggles: this.toggles}, dest); + var tbody = table.lastChild; + var rowTag = DirTablePlate.rowTag; + + // Insert the first slice immediately + //var slice = members.splice(0, insertSliceSize); + //var result = rowTag.insertRows({members: slice}, tbody.lastChild); + + //var setSize = members.length; + //var rowCount = 1; + + var panel = this; + var result; + + //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [panel, result, rowCount, setSize]); + var timeouts = []; + + var delay = 0; + var _insertSliceSize = insertSliceSize; + var _insertInterval = insertInterval; + + // enable to measure rendering performance + var renderStart = new Date().getTime(); + var lastSkip = renderStart, now; + + while (members.length) + { + with({slice: members.splice(0, _insertSliceSize), isLast: !members.length}) + { + var _tbody = tbody; + var _rowTag = rowTag; + var _panelNode = panelNode; + var _priorScrollTop = priorScrollTop; + + timeouts.push(this.context.setTimeout(function() + { + // TODO: xxxpedro can this be a timing error related to the + // "iteration number" approach insted of "duration time"? + // avoid error in IE8 + if (!_tbody.lastChild) return; + + result = _rowTag.insertRows({members: slice}, _tbody.lastChild); + + //rowCount += _insertSliceSize; + //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [panel, result, rowCount, setSize]); + + if ((_panelNode.scrollHeight + _panelNode.offsetHeight) >= _priorScrollTop) + _panelNode.scrollTop = _priorScrollTop; + + + // enable to measure rendering performance + //alert("gap: " + (new Date().getTime() - lastSkip)); + //lastSkip = new Date().getTime(); + + //if (isLast) alert("new: " + (new Date().getTime() - renderStart) + "ms"); + + }, delay)); + + delay += _insertInterval; + } + } + + if (offscreen) + { + timeouts.push(this.context.setTimeout(function() + { + if (panelNode.firstChild) + panelNode.replaceChild(table, panelNode.firstChild); + else + panelNode.appendChild(table); + + // Scroll back to where we were before + panelNode.scrollTop = priorScrollTop; + }, delay)); + } + else + { + timeouts.push(this.context.setTimeout(function() + { + panelNode.scrollTop = scrollTop == undefined ? 0 : scrollTop; + }, delay)); + } + this.timeouts = timeouts; + }, + /**/ + + showEmptyMembers: function() + { + FirebugReps.Warning.tag.replace({object: "NoMembersWarning"}, this.panelNode); + }, + + findPathObject: function(object) + { + var pathIndex = -1; + for (var i = 0; i < this.objectPath.length; ++i) + { + // IE needs === instead of == or otherwise some objects will + // be considered equal to different objects, returning the + // wrong index of the objectPath array + if (this.getPathObject(i) === object) + return i; + } + + return -1; + }, + + getPathObject: function(index) + { + var object = this.objectPath[index]; + + if (object instanceof Property) + return object.getObject(); + else + return object; + }, + + getRowObject: function(row) + { + var object = getRowOwnerObject(row); + return object ? object : this.selection; + }, + + getRowPropertyValue: function(row) + { + var object = this.getRowObject(row); + object = this.getRealObject(object); + if (object) + { + var propName = getRowName(row); + + if (object instanceof jsdIStackFrame) + return Firebug.Debugger.evaluate(propName, this.context); + else + return object[propName]; + } + }, + /* + copyProperty: function(row) + { + var value = this.getRowPropertyValue(row); + copyToClipboard(value); + }, + + editProperty: function(row, editValue) + { + if (hasClass(row, "watchNewRow")) + { + if (this.context.stopped) + Firebug.Editor.startEditing(row, ""); + else if (Firebug.Console.isAlwaysEnabled()) // not stopped in debugger, need command line + { + if (Firebug.CommandLine.onCommandLineFocus()) + Firebug.Editor.startEditing(row, ""); + else + row.innerHTML = $STR("warning.Command line blocked?"); + } + else + row.innerHTML = $STR("warning.Console must be enabled"); + } + else if (hasClass(row, "watchRow")) + Firebug.Editor.startEditing(row, getRowName(row)); + else + { + var object = this.getRowObject(row); + this.context.thisValue = object; + + if (!editValue) + { + var propValue = this.getRowPropertyValue(row); + + var type = typeof(propValue); + if (type == "undefined" || type == "number" || type == "boolean") + editValue = propValue; + else if (type == "string") + editValue = "\"" + escapeJS(propValue) + "\""; + else if (propValue == null) + editValue = "null"; + else if (object instanceof Window || object instanceof jsdIStackFrame) + editValue = getRowName(row); + else + editValue = "this." + getRowName(row); + } + + + Firebug.Editor.startEditing(row, editValue); + } + }, + + deleteProperty: function(row) + { + if (hasClass(row, "watchRow")) + this.deleteWatch(row); + else + { + var object = getRowOwnerObject(row); + if (!object) + object = this.selection; + object = this.getRealObject(object); + + if (object) + { + var name = getRowName(row); + try + { + delete object[name]; + } + catch (exc) + { + return; + } + + this.rebuild(true); + this.markChange(); + } + } + }, + + setPropertyValue: function(row, value) // value must be string + { + if(FBTrace.DBG_DOM) + { + FBTrace.sysout("row: "+row); + FBTrace.sysout("value: "+value+" type "+typeof(value), value); + } + + var name = getRowName(row); + if (name == "this") + return; + + var object = this.getRowObject(row); + object = this.getRealObject(object); + if (object && !(object instanceof jsdIStackFrame)) + { + // unwrappedJSObject.property = unwrappedJSObject + Firebug.CommandLine.evaluate(value, this.context, object, this.context.getGlobalScope(), + function success(result, context) + { + if (FBTrace.DBG_DOM) + FBTrace.sysout("setPropertyValue evaluate success object["+name+"]="+result+" type "+typeof(result), result); + object[name] = result; + }, + function failed(exc, context) + { + try + { + if (FBTrace.DBG_DOM) + FBTrace.sysout("setPropertyValue evaluate failed with exc:"+exc+" object["+name+"]="+value+" type "+typeof(value), exc); + // If the value doesn't parse, then just store it as a string. Some users will + // not realize they're supposed to enter a JavaScript expression and just type + // literal text + object[name] = String(value); // unwrappedJSobject.property = string + } + catch (exc) + { + return; + } + } + ); + } + else if (this.context.stopped) + { + try + { + Firebug.CommandLine.evaluate(name+"="+value, this.context); + } + catch (exc) + { + try + { + // See catch block above... + object[name] = String(value); // unwrappedJSobject.property = string + } + catch (exc) + { + return; + } + } + } + + this.rebuild(true); + this.markChange(); + }, + + highlightRow: function(row) + { + if (this.highlightedRow) + cancelClassTimed(this.highlightedRow, "jumpHighlight", this.context); + + this.highlightedRow = row; + + if (row) + setClassTimed(row, "jumpHighlight", this.context); + },/**/ + + onMouseMove: function(event) + { + var target = event.srcElement || event.target; + + var object = getAncestorByClass(target, "objectLink-element"); + object = object ? object.repObject : null; + + if(object && instanceOf(object, "Element") && object.nodeType == 1) + { + if(object != lastHighlightedObject) + { + Firebug.Inspector.drawBoxModel(object); + object = lastHighlightedObject; + } + } + else + Firebug.Inspector.hideBoxModel(); + + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + create: function() + { + // TODO: xxxpedro + this.context = Firebug.browser; + + this.objectPath = []; + this.propertyPath = []; + this.viewPath = []; + this.pathIndex = -1; + this.toggles = {}; + + Firebug.Panel.create.apply(this, arguments); + + this.panelNode.style.padding = "0 1px"; + }, + + initialize: function(){ + Firebug.Panel.initialize.apply(this, arguments); + + addEvent(this.panelNode, "mousemove", this.onMouseMove); + }, + + shutdown: function() + { + removeEvent(this.panelNode, "mousemove", this.onMouseMove); + + Firebug.Panel.shutdown.apply(this, arguments); + }, + + /* + destroy: function(state) + { + var view = this.viewPath[this.pathIndex]; + if (view && this.panelNode.scrollTop) + view.scrollTop = this.panelNode.scrollTop; + + if (this.pathIndex) + state.pathIndex = this.pathIndex; + if (this.viewPath) + state.viewPath = this.viewPath; + if (this.propertyPath) + state.propertyPath = this.propertyPath; + + if (this.propertyPath.length > 0 && !this.propertyPath[1]) + state.firstSelection = persistObject(this.getPathObject(1), this.context); + + Firebug.Panel.destroy.apply(this, arguments); + }, + /**/ + + ishow: function(state) + { + if (this.context.loaded && !this.selection) + { + if (!state) + { + this.select(null); + return; + } + if (state.viewPath) + this.viewPath = state.viewPath; + if (state.propertyPath) + this.propertyPath = state.propertyPath; + + var defaultObject = this.getDefaultSelection(this.context); + var selectObject = defaultObject; + + if (state.firstSelection) + { + var restored = state.firstSelection(this.context); + if (restored) + { + selectObject = restored; + this.objectPath = [defaultObject, restored]; + } + else + this.objectPath = [defaultObject]; + } + else + this.objectPath = [defaultObject]; + + if (this.propertyPath.length > 1) + { + for (var i = 1; i < this.propertyPath.length; ++i) + { + var name = this.propertyPath[i]; + if (!name) + continue; + + var object = selectObject; + try + { + selectObject = object[name]; + } + catch (exc) + { + selectObject = null; + } + + if (selectObject) + { + this.objectPath.push(new Property(object, name)); + } + else + { + // If we can't access a property, just stop + this.viewPath.splice(i); + this.propertyPath.splice(i); + this.objectPath.splice(i); + selectObject = this.getPathObject(this.objectPath.length-1); + break; + } + } + } + + var selection = state.pathIndex <= this.objectPath.length-1 + ? this.getPathObject(state.pathIndex) + : this.getPathObject(this.objectPath.length-1); + + this.select(selection); + } + }, + /* + hide: function() + { + var view = this.viewPath[this.pathIndex]; + if (view && this.panelNode.scrollTop) + view.scrollTop = this.panelNode.scrollTop; + }, + /**/ + + supportsObject: function(object) + { + if (object == null) + return 1000; + + if (typeof(object) == "undefined") + return 1000; + else if (object instanceof SourceLink) + return 0; + else + return 1; // just agree to support everything but not agressively. + }, + + refresh: function() + { + this.rebuild(true); + }, + + updateSelection: function(object) + { + var previousIndex = this.pathIndex; + var previousView = previousIndex == -1 ? null : this.viewPath[previousIndex]; + + var newPath = this.pathToAppend; + delete this.pathToAppend; + + var pathIndex = this.findPathObject(object); + if (newPath || pathIndex == -1) + { + this.toggles = {}; + + if (newPath) + { + // Remove everything after the point where we are inserting, so we + // essentially replace it with the new path + if (previousView) + { + if (this.panelNode.scrollTop) + previousView.scrollTop = this.panelNode.scrollTop; + + var start = previousIndex + 1, + // Opera needs the length argument in splice(), otherwise + // it will consider that only one element should be removed + length = this.objectPath.length - start; + + this.objectPath.splice(start, length); + this.propertyPath.splice(start, length); + this.viewPath.splice(start, length); + } + + var value = this.getPathObject(previousIndex); + if (!value) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("dom.updateSelection no pathObject for "+previousIndex+"\n"); + return; + } + + for (var i = 0, length = newPath.length; i < length; ++i) + { + var name = newPath[i]; + var object = value; + try + { + value = value[name]; + } + catch(exc) + { + if (FBTrace.DBG_ERRORS) + FBTrace.sysout("dom.updateSelection FAILS at path_i="+i+" for name:"+name+"\n"); + return; + } + + ++this.pathIndex; + this.objectPath.push(new Property(object, name)); + this.propertyPath.push(name); + this.viewPath.push({toggles: this.toggles, scrollTop: 0}); + } + } + else + { + this.toggles = {}; + + var win = Firebug.browser.window; + //var win = this.context.getGlobalScope(); + if (object === win) + { + this.pathIndex = 0; + this.objectPath = [win]; + this.propertyPath = [null]; + this.viewPath = [{toggles: this.toggles, scrollTop: 0}]; + } + else + { + this.pathIndex = 1; + this.objectPath = [win, object]; + this.propertyPath = [null, null]; + this.viewPath = [ + {toggles: {}, scrollTop: 0}, + {toggles: this.toggles, scrollTop: 0} + ]; + } + } + + this.panelNode.scrollTop = 0; + this.rebuild(); + } + else + { + this.pathIndex = pathIndex; + + var view = this.viewPath[pathIndex]; + this.toggles = view.toggles; + + // Persist the current scroll location + if (previousView && this.panelNode.scrollTop) + previousView.scrollTop = this.panelNode.scrollTop; + + this.rebuild(false, view.scrollTop); + } + }, + + getObjectPath: function(object) + { + return this.objectPath; + }, + + getDefaultSelection: function() + { + return Firebug.browser.window; + //return this.context.getGlobalScope(); + }/*, + + updateOption: function(name, value) + { + const optionMap = {showUserProps: 1, showUserFuncs: 1, showDOMProps: 1, + showDOMFuncs: 1, showDOMConstants: 1}; + if ( optionMap.hasOwnProperty(name) ) + this.rebuild(true); + }, + + getOptionsMenuItems: function() + { + return [ + optionMenu("ShowUserProps", "showUserProps"), + optionMenu("ShowUserFuncs", "showUserFuncs"), + optionMenu("ShowDOMProps", "showDOMProps"), + optionMenu("ShowDOMFuncs", "showDOMFuncs"), + optionMenu("ShowDOMConstants", "showDOMConstants"), + "-", + {label: "Refresh", command: bindFixed(this.rebuild, this, true) } + ]; + }, + + getContextMenuItems: function(object, target) + { + var row = getAncestorByClass(target, "memberRow"); + + var items = []; + + if (row) + { + var rowName = getRowName(row); + var rowObject = this.getRowObject(row); + var rowValue = this.getRowPropertyValue(row); + + var isWatch = hasClass(row, "watchRow"); + var isStackFrame = rowObject instanceof jsdIStackFrame; + + if (typeof(rowValue) == "string" || typeof(rowValue) == "number") + { + // Functions already have a copy item in their context menu + items.push( + "-", + {label: "CopyValue", + command: bindFixed(this.copyProperty, this, row) } + ); + } + + items.push( + "-", + {label: isWatch ? "EditWatch" : (isStackFrame ? "EditVariable" : "EditProperty"), + command: bindFixed(this.editProperty, this, row) } + ); + + if (isWatch || (!isStackFrame && !isDOMMember(rowObject, rowName))) + { + items.push( + {label: isWatch ? "DeleteWatch" : "DeleteProperty", + command: bindFixed(this.deleteProperty, this, row) } + ); + } + } + + items.push( + "-", + {label: "Refresh", command: bindFixed(this.rebuild, this, true) } + ); + + return items; + }, + + getEditor: function(target, value) + { + if (!this.editor) + this.editor = new DOMEditor(this.document); + + return this.editor; + }/**/ +}); + +// ************************************************************************************************ + +// TODO: xxxpedro statusbar +var updateStatusBar = function(panel) +{ + var path = panel.propertyPath; + var index = panel.pathIndex; + + var r = []; + + for (var i=0, l=path.length; i'); + r.push(i==0 ? "window" : path[i] || "Object"); + r.push('
                  '); + + if(i < l-1) + r.push('>'); + } + panel.statusBarNode.innerHTML = r.join(""); +}; + + +var DOMMainPanel = Firebug.DOMPanel = function () {}; + +Firebug.DOMPanel.DirTable = DirTablePlate; + +DOMMainPanel.prototype = extend(Firebug.DOMBasePanel.prototype, +{ + onClickStatusBar: function(event) + { + var target = event.srcElement || event.target; + var element = getAncestorByClass(target, "fbHover"); + + if(element) + { + var pathIndex = element.getAttribute("pathIndex"); + + if(pathIndex) + { + this.select(this.getPathObject(pathIndex)); + } + } + }, + + selectRow: function(row, target) + { + if (!target) + target = row.lastChild.firstChild; + + if (!target || !target.repObject) + return; + + this.pathToAppend = getPath(row); + + // If the object is inside an array, look up its index + var valueBox = row.lastChild.firstChild; + if (hasClass(valueBox, "objectBox-array")) + { + var arrayIndex = FirebugReps.Arr.getItemIndex(target); + this.pathToAppend.push(arrayIndex); + } + + // Make sure we get a fresh status path for the object, since otherwise + // it might find the object in the existing path and not refresh it + //Firebug.chrome.clearStatusPath(); + + this.select(target.repObject, true); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + onClick: function(event) + { + var target = event.srcElement || event.target; + var repNode = Firebug.getRepNode(target); + if (repNode) + { + var row = getAncestorByClass(target, "memberRow"); + if (row) + { + this.selectRow(row, repNode); + cancelEvent(event); + } + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "DOM", + title: "DOM", + searchable: true, + statusSeparator: ">", + + options: { + hasToolButtons: true, + hasStatusBar: true + }, + + create: function() + { + Firebug.DOMBasePanel.prototype.create.apply(this, arguments); + + this.onClick = bind(this.onClick, this); + + //TODO: xxxpedro + this.onClickStatusBar = bind(this.onClickStatusBar, this); + + this.panelNode.style.padding = "0 1px"; + }, + + initialize: function(oldPanelNode) + { + //this.panelNode.addEventListener("click", this.onClick, false); + //dispatch([Firebug.A11yModel], 'onInitializeNode', [this, 'console']); + + Firebug.DOMBasePanel.prototype.initialize.apply(this, arguments); + + addEvent(this.panelNode, "click", this.onClick); + + // TODO: xxxpedro dom + this.ishow(); + + //TODO: xxxpedro + addEvent(this.statusBarNode, "click", this.onClickStatusBar); + }, + + shutdown: function() + { + //this.panelNode.removeEventListener("click", this.onClick, false); + //dispatch([Firebug.A11yModel], 'onDestroyNode', [this, 'console']); + + removeEvent(this.panelNode, "click", this.onClick); + + Firebug.DOMBasePanel.prototype.shutdown.apply(this, arguments); + }/*, + + search: function(text, reverse) + { + if (!text) + { + delete this.currentSearch; + this.highlightRow(null); + return false; + } + + var row; + if (this.currentSearch && text == this.currentSearch.text) + row = this.currentSearch.findNext(true, undefined, reverse, Firebug.searchCaseSensitive); + else + { + function findRow(node) { return getAncestorByClass(node, "memberRow"); } + this.currentSearch = new TextSearch(this.panelNode, findRow); + row = this.currentSearch.find(text, reverse, Firebug.searchCaseSensitive); + } + + if (row) + { + var sel = this.document.defaultView.getSelection(); + sel.removeAllRanges(); + sel.addRange(this.currentSearch.range); + + scrollIntoCenterView(row, this.panelNode); + + this.highlightRow(row); + dispatch([Firebug.A11yModel], 'onDomSearchMatchFound', [this, text, row]); + return true; + } + else + { + dispatch([Firebug.A11yModel], 'onDomSearchMatchFound', [this, text, null]); + return false; + } + }/**/ +}); + +Firebug.registerPanel(DOMMainPanel); + + +// ************************************************************************************************ + + + +// ************************************************************************************************ +// Local Helpers + +var getMembers = function getMembers(object, level) // we expect object to be user-level object wrapped in security blanket +{ + if (!level) + level = 0; + + var ordinals = [], userProps = [], userClasses = [], userFuncs = [], + domProps = [], domFuncs = [], domConstants = []; + + try + { + var domMembers = getDOMMembers(object); + //var domMembers = {}; // TODO: xxxpedro + //var domConstantMap = {}; // TODO: xxxpedro + + if (object.wrappedJSObject) + var insecureObject = object.wrappedJSObject; + else + var insecureObject = object; + + // IE function prototype is not listed in (for..in) + if (isIE && isFunction(object)) + addMember("user", userProps, "prototype", object.prototype, level); + + for (var name in insecureObject) // enumeration is safe + { + if (ignoreVars[name] == 1) // javascript.options.strict says ignoreVars is undefined. + continue; + + var val; + try + { + val = insecureObject[name]; // getter is safe + } + catch (exc) + { + // Sometimes we get exceptions trying to access certain members + if (FBTrace.DBG_ERRORS && FBTrace.DBG_DOM) + FBTrace.sysout("dom.getMembers cannot access "+name, exc); + } + + var ordinal = parseInt(name); + if (ordinal || ordinal == 0) + { + addMember("ordinal", ordinals, name, val, level); + } + else if (isFunction(val)) + { + if (isClassFunction(val) && !(name in domMembers)) + addMember("userClass", userClasses, name, val, level); + else if (name in domMembers) + addMember("domFunction", domFuncs, name, val, level, domMembers[name]); + else + addMember("userFunction", userFuncs, name, val, level); + } + else + { + //TODO: xxxpedro + /* + var getterFunction = insecureObject.__lookupGetter__(name), + setterFunction = insecureObject.__lookupSetter__(name), + prefix = ""; + + if(getterFunction && !setterFunction) + prefix = "get "; + /**/ + + var prefix = ""; + + if (name in domMembers && !(name in domConstantMap)) + addMember("dom", domProps, (prefix+name), val, level, domMembers[name]); + else if (name in domConstantMap) + addMember("dom", domConstants, (prefix+name), val, level); + else + addMember("user", userProps, (prefix+name), val, level); + } + } + } + catch (exc) + { + // Sometimes we get exceptions just from trying to iterate the members + // of certain objects, like StorageList, but don't let that gum up the works + throw exc; + if (FBTrace.DBG_ERRORS && FBTrace.DBG_DOM) + FBTrace.sysout("dom.getMembers FAILS: ", exc); + //throw exc; + } + + function sortName(a, b) { return a.name > b.name ? 1 : -1; } + function sortOrder(a, b) { return a.order > b.order ? 1 : -1; } + + var members = []; + + members.push.apply(members, ordinals); + + Firebug.showUserProps = true; // TODO: xxxpedro + Firebug.showUserFuncs = true; // TODO: xxxpedro + Firebug.showDOMProps = true; + Firebug.showDOMFuncs = true; + Firebug.showDOMConstants = true; + + if (Firebug.showUserProps) + { + userProps.sort(sortName); + members.push.apply(members, userProps); + } + + if (Firebug.showUserFuncs) + { + userClasses.sort(sortName); + members.push.apply(members, userClasses); + + userFuncs.sort(sortName); + members.push.apply(members, userFuncs); + } + + if (Firebug.showDOMProps) + { + domProps.sort(sortName); + members.push.apply(members, domProps); + } + + if (Firebug.showDOMFuncs) + { + domFuncs.sort(sortName); + members.push.apply(members, domFuncs); + } + + if (Firebug.showDOMConstants) + members.push.apply(members, domConstants); + + return members; +} + +function expandMembers(members, toggles, offset, level) // recursion starts with offset=0, level=0 +{ + var expanded = 0; + for (var i = offset; i < members.length; ++i) + { + var member = members[i]; + if (member.level > level) + break; + + if ( toggles.hasOwnProperty(member.name) ) + { + member.open = "opened"; // member.level <= level && member.name in toggles. + + var newMembers = getMembers(member.value, level+1); // sets newMembers.level to level+1 + + var args = [i+1, 0]; + args.push.apply(args, newMembers); + members.splice.apply(members, args); + + /* + if (FBTrace.DBG_DOM) + { + FBTrace.sysout("expandMembers member.name", member.name); + FBTrace.sysout("expandMembers toggles", toggles); + FBTrace.sysout("expandMembers toggles[member.name]", toggles[member.name]); + FBTrace.sysout("dom.expandedMembers level: "+level+" member", member); + } + /**/ + + expanded += newMembers.length; + i += newMembers.length + expandMembers(members, toggles[member.name], i+1, level+1); + } + } + + return expanded; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + +function isClassFunction(fn) +{ + try + { + for (var name in fn.prototype) + return true; + } catch (exc) {} + return false; +} + +var hasProperties = function hasProperties(ob) +{ + try + { + for (var name in ob) + return true; + } catch (exc) {} + + // IE function prototype is not listed in (for..in) + if (isFunction(ob)) return true; + + return false; +} + +FBL.ErrorCopy = function(message) +{ + this.message = message; +}; + +var addMember = function addMember(type, props, name, value, level, order) +{ + var rep = Firebug.getRep(value); // do this first in case a call to instanceof reveals contents + var tag = rep.shortTag ? rep.shortTag : rep.tag; + + var ErrorCopy = function(){}; //TODO: xxxpedro + + var valueType = typeof(value); + var hasChildren = hasProperties(value) && !(value instanceof ErrorCopy) && + (isFunction(value) || (valueType == "object" && value != null) + || (valueType == "string" && value.length > Firebug.stringCropLength)); + + props.push({ + name: name, + value: value, + type: type, + rowClass: "memberRow-"+type, + open: "", + order: order, + level: level, + indent: level*16, + hasChildren: hasChildren, + tag: tag + }); +} + +var getWatchRowIndex = function getWatchRowIndex(row) +{ + var index = -1; + for (; row && hasClass(row, "watchRow"); row = row.previousSibling) + ++index; + return index; +} + +var getRowName = function getRowName(row) +{ + var node = row.firstChild; + return node.textContent ? node.textContent : node.innerText; +} + +var getRowValue = function getRowValue(row) +{ + return row.lastChild.firstChild.repObject; +} + +var getRowOwnerObject = function getRowOwnerObject(row) +{ + var parentRow = getParentRow(row); + if (parentRow) + return getRowValue(parentRow); +} + +var getParentRow = function getParentRow(row) +{ + var level = parseInt(row.getAttribute("level"))-1; + for (row = row.previousSibling; row; row = row.previousSibling) + { + if (parseInt(row.getAttribute("level")) == level) + return row; + } +} + +var getPath = function getPath(row) +{ + var name = getRowName(row); + var path = [name]; + + var level = parseInt(row.getAttribute("level"))-1; + for (row = row.previousSibling; row; row = row.previousSibling) + { + if (parseInt(row.getAttribute("level")) == level) + { + var name = getRowName(row); + path.splice(0, 0, name); + + --level; + } + } + + return path; +} + +// ************************************************************************************************ + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + +// ************************************************************************************************ +// DOM Module + +Firebug.DOM = extend(Firebug.Module, +{ + getPanel: function() + { + return Firebug.chrome ? Firebug.chrome.getPanel("DOM") : null; + } +}); + +Firebug.registerModule(Firebug.DOM); + + +// ************************************************************************************************ +// DOM Panel + +var lastHighlightedObject; + +function DOMSidePanel(){}; + +DOMSidePanel.prototype = extend(Firebug.DOMBasePanel.prototype, +{ + selectRow: function(row, target) + { + if (!target) + target = row.lastChild.firstChild; + + if (!target || !target.repObject) + return; + + this.pathToAppend = getPath(row); + + // If the object is inside an array, look up its index + var valueBox = row.lastChild.firstChild; + if (hasClass(valueBox, "objectBox-array")) + { + var arrayIndex = FirebugReps.Arr.getItemIndex(target); + this.pathToAppend.push(arrayIndex); + } + + // Make sure we get a fresh status path for the object, since otherwise + // it might find the object in the existing path and not refresh it + //Firebug.chrome.clearStatusPath(); + + var object = target.repObject; + + if (instanceOf(object, "Element")) + { + Firebug.HTML.selectTreeNode(ElementCache(object)); + } + else + { + Firebug.chrome.selectPanel("DOM"); + Firebug.chrome.getPanel("DOM").select(object, true); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + onClick: function(event) + { + /* + var target = event.srcElement || event.target; + + var object = getAncestorByClass(target, "objectLink"); + object = object ? object.repObject : null; + + if(!object) return; + + if (instanceOf(object, "Element")) + { + Firebug.HTML.selectTreeNode(ElementCache(object)); + } + else + { + Firebug.chrome.selectPanel("DOM"); + Firebug.chrome.getPanel("DOM").select(object, true); + } + /**/ + + + var target = event.srcElement || event.target; + var repNode = Firebug.getRepNode(target); + if (repNode) + { + var row = getAncestorByClass(target, "memberRow"); + if (row) + { + this.selectRow(row, repNode); + cancelEvent(event); + } + } + /**/ + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // extends Panel + + name: "DOMSidePanel", + parentPanel: "HTML", + title: "DOM", + + options: { + hasToolButtons: true + }, + + isInitialized: false, + + create: function() + { + Firebug.DOMBasePanel.prototype.create.apply(this, arguments); + + this.onClick = bind(this.onClick, this); + }, + + initialize: function(){ + Firebug.DOMBasePanel.prototype.initialize.apply(this, arguments); + + addEvent(this.panelNode, "click", this.onClick); + + // TODO: xxxpedro css2 + var selection = ElementCache.get(FirebugChrome.selectedHTMLElementId); + if (selection) + this.select(selection, true); + }, + + shutdown: function() + { + removeEvent(this.panelNode, "click", this.onClick); + + Firebug.DOMBasePanel.prototype.shutdown.apply(this, arguments); + }, + + reattach: function(oldChrome) + { + //this.isInitialized = oldChrome.getPanel("DOM").isInitialized; + this.toggles = oldChrome.getPanel("DOMSidePanel").toggles; + } + +}); + +Firebug.registerPanel(DOMSidePanel); + + +// ************************************************************************************************ +}}); + +/* See license.txt for terms of usage */ + +FBL.FBTrace = {}; + +(function() { +// ************************************************************************************************ + +var traceOptions = { + DBG_TIMESTAMP: 1, + DBG_INITIALIZE: 1, + DBG_CHROME: 1, + DBG_ERRORS: 1, + DBG_DISPATCH: 1, + DBG_CSS: 1 +}; + +this.module = null; + +this.initialize = function() +{ + if (!this.messageQueue) + this.messageQueue = []; + + for (var name in traceOptions) + this[name] = traceOptions[name]; +}; + +// ************************************************************************************************ +// FBTrace API + +this.sysout = function() +{ + return this.logFormatted(arguments, ""); +}; + +this.dumpProperties = function(title, object) +{ + return this.logFormatted("dumpProperties() not supported.", "warning"); +}; + +this.dumpStack = function() +{ + return this.logFormatted("dumpStack() not supported.", "warning"); +}; + +this.flush = function(module) +{ + this.module = module; + + var queue = this.messageQueue; + this.messageQueue = []; + + for (var i = 0; i < queue.length; ++i) + this.writeMessage(queue[i][0], queue[i][1], queue[i][2]); +}; + +this.getPanel = function() +{ + return this.module ? this.module.getPanel() : null; +}; + +//************************************************************************************************* + +this.logFormatted = function(objects, className) +{ + var html = this.DBG_TIMESTAMP ? [getTimestamp(), " | "] : []; + var length = objects.length; + + for (var i = 0; i < length; ++i) + { + appendText(" ", html); + + var object = objects[i]; + + if (i == 0) + { + html.push(""); + 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); + +/* 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(); + } + +}); + +Firebug.registerPanel(TracePanel); + +// ************************************************************************************************ +}}); + +/* 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); + } + +}); + + + + +// ************************************************************************************************ +}}); + +FBL.ns(function() { with (FBL) { +// ************************************************************************************************ + +FirebugChrome.Skin = +{ + CSS: '.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;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;}#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;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 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;}', + HTML: '
                   
                   
                  >>>
                  2 errors' +}; + +// ************************************************************************************************ +}}); + +// ************************************************************************************************ +FBL.initialize(); +// ************************************************************************************************ + +})(); \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/firebug-lite.js b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/firebug-lite.js new file mode 100755 index 0000000..f9f8484 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/firebug-lite/build/firebug-lite.js @@ -0,0 +1,7886 @@ +(function(){ +/************************************************************** + * + * Firebug Lite 1.3.2 + * + * Copyright (c) 2007, Parakey Inc. + * Released under BSD license. + * More information: http://getfirebug.com/firebuglite + * + **************************************************************/ +/* + * CSS selectors powered by: + * + * Sizzle CSS Selector Engine - v1.0 + * Copyright 2009, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +var FBL={}; +(function(){var productionDir="http://getfirebug.com/releases/lite/"; +var bookmarkletVersion=4; +var reNotWhitespace=/[^\s]/; +var reSplitFile=/:\/{1,3}(.*?)\/([^\/]*?)\/?($|\?.*)/; +this.reJavascript=/\s*javascript:\s*(.*)/; +this.reChrome=/chrome:\/\/([^\/]*)\//; +this.reFile=/file:\/\/([^\/]*)\//; +var userAgent=navigator.userAgent.toLowerCase(); +this.isFirefox=/firefox/.test(userAgent); +this.isOpera=/opera/.test(userAgent); +this.isSafari=/webkit/.test(userAgent); +this.isIE=/msie/.test(userAgent)&&!/opera/.test(userAgent); +this.isIE6=/msie 6/i.test(navigator.appVersion); +this.browserVersion=(userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[0,"0"])[1]; +this.isIElt8=this.isIE&&(this.browserVersion-0<8); +this.NS=null; +this.pixelsPerInch=null; +var namespaces=[]; +this.ns=function(fn){var ns={}; +namespaces.push(fn,ns); +return ns +}; +var FBTrace=null; +this.initialize=function(){if(window.firebug&&firebug.firebuglite||window.console&&console.firebuglite){return +}if(FBL.FBTrace){FBTrace=FBL.FBTrace +}else{FBTrace=FBL.FBTrace={} +}FBL.Ajax.initialize(); +var isChromeContext=window.Firebug&&typeof window.Firebug.SharedEnv=="object"; +if(isChromeContext){sharedEnv=window.Firebug.SharedEnv; +delete window.Firebug.SharedEnv; +FBL.Env=sharedEnv; +FBL.Env.isChromeContext=true; +FBTrace.messageQueue=FBL.Env.traceMessageQueue +}else{FBL.NS=document.documentElement.namespaceURI; +FBL.Env.browser=window; +FBL.Env.destroy=destroyEnvironment; +if(document.documentElement.getAttribute("debug")=="true"){FBL.Env.Options.startOpened=true +}findLocation(); +var prefs=eval("("+FBL.readCookie("FirebugLite")+")"); +if(prefs){FBL.Env.Options.startOpened=prefs.startOpened; +FBL.Env.Options.enableTrace=prefs.enableTrace; +FBL.Env.Options.enablePersistent=prefs.enablePersistent; +FBL.Env.Options.disableXHRListener=prefs.disableXHRListener +}if(FBL.isFirefox&&typeof FBL.Env.browser.console=="object"&&FBL.Env.browser.console.firebug&&FBL.Env.Options.disableWhenFirebugActive){return +}}if(FBL.Env.isDebugMode){FBL.Env.browser.FBL=FBL +}this.isQuiksMode=FBL.Env.browser.document.compatMode=="BackCompat"; +this.isIEQuiksMode=this.isIE&&this.isQuiksMode; +this.isIEStantandMode=this.isIE&&!this.isQuiksMode; +this.noFixedPosition=this.isIE6||this.isIEQuiksMode; +if(FBL.Env.Options.enableTrace){FBTrace.initialize() +}if(FBTrace.DBG_INITIALIZE&&isChromeContext){FBTrace.sysout("FBL.initialize - persistent application","initialize chrome context") +}if(FBTrace.DBG_INITIALIZE){FBTrace.sysout("FBL.initialize",namespaces.length/2+" namespaces BEGIN") +}for(var i=0; +i0){path=reLastDir.exec(path)[1] +}path+=backDir[2] +}else{if(src.indexOf("/")!=-1){if(/^\.\/./.test(src)){path+=src.substring(2) +}else{if(/^\/./.test(src)){var domain=/^(\w+:\/\/[^\/]+)/.exec(path); +path=domain[1]+src +}else{path+=src +}}}}}}FBL.Env.isChromeExtension=script&&script.getAttribute("extension")=="Chrome"; +if(FBL.Env.isChromeExtension){path=productionDir; +FBL.Env.bookmarkletOutdated=false; +script={innerHTML:"{showIconWhenHidden:false}"} +}var m=path&&path.match(/([^\/]+)\/$/)||null; +if(path&&m){var Env=FBL.Env; +Env.useLocalSkin=path.indexOf(location.protocol+"//"+location.host+"/")==0; +if(fileName=="firebug-lite-dev.js"){Env.isDevelopmentMode=true; +Env.isDebugMode=true +}else{if(fileName=="firebug-lite-debug.js"){Env.isDebugMode=true +}}if(Env.browser.document.documentElement.getAttribute("debug")=="true"){Env.Options.startOpened=true +}if(fileOptions){var options=fileOptions.split(","); +for(var i=0,length=options.length; +i1){for(var i=0; +i":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){return ob+"" +}try{if(ob&&"toString" in ob&&typeof ob.toString=="function"){return ob.toString() +}}catch(exc){return ob+"" +}}; +this.hasProperties=function(ob){try{for(var name in ob){return true +}}catch(exc){}return false +}; +var reTrim=/^\s+|\s+$/g; +this.trim=function(s){return s.replace(reTrim,"") +}; +this.emptyFn=function(){}; +this.isVisible=function(elt){return this.getStyle(elt,"visibility")!="hidden"&&(elt.offsetWidth>0||elt.offsetHeight>0||elt.tagName in invisibleTags||elt.namespaceURI=="http://www.w3.org/2000/svg"||elt.namespaceURI=="http://www.w3.org/1998/Math/MathML") +}; +this.collapse=function(elt,collapsed){if(this.isIElt8){if(collapsed){this.setClass(elt,"collapsed") +}else{this.removeClass(elt,"collapsed") +}}else{elt.setAttribute("collapsed",collapsed?"true":"false") +}}; +this.obscure=function(elt,obscured){if(obscured){this.setClass(elt,"obscured") +}else{this.removeClass(elt,"obscured") +}}; +this.hide=function(elt,hidden){elt.style.visibility=hidden?"hidden":"visible" +}; +this.clearNode=function(node){var nodeName=" "+node.nodeName.toLowerCase()+" "; +var ignoreTags=" table tbody thead tfoot th tr td "; +if(this.isIE&&ignoreTags.indexOf(nodeName)!=-1){this.eraseNode(node) +}else{node.innerHTML="" +}}; +this.eraseNode=function(node){while(node.lastChild){node.removeChild(node.lastChild) +}}; +this.iterateWindows=function(win,handler){if(!win||!win.document){return +}handler(win); +if(win==top||!win.frames){return +}for(var i=0; +iscrollParent.offsetHeight){return scrollParent +}}}; +this.isScrolledToBottom=function(element){var onBottom=(element.scrollTop+element.offsetHeight)==element.scrollHeight; +if(FBTrace.DBG_CONSOLE){FBTrace.sysout("isScrolledToBottom offsetHeight: "+element.offsetHeight+" onBottom:"+onBottom) +}return onBottom +}; +this.scrollToBottom=function(element){element.scrollTop=element.scrollHeight; +if(FBTrace.DBG_CONSOLE){FBTrace.sysout("scrollToBottom reset scrollTop "+element.scrollTop+" = "+element.scrollHeight); +if(element.scrollHeight==element.offsetHeight){FBTrace.sysout("scrollToBottom attempt to scroll non-scrollable element "+element,element) +}}return(element.scrollTop==element.scrollHeight) +}; +this.move=function(element,x,y){element.style.left=x+"px"; +element.style.top=y+"px" +}; +this.resize=function(element,w,h){element.style.width=w+"px"; +element.style.height=h+"px" +}; +this.linesIntoCenterView=function(element,scrollBox){if(!scrollBox){scrollBox=this.getOverflowParent(element) +}if(!scrollBox){return +}var offset=this.getClientOffset(element); +var topSpace=offset.y-scrollBox.scrollTop; +var bottomSpace=(scrollBox.scrollTop+scrollBox.clientHeight)-(offset.y+element.offsetHeight); +if(topSpace<0||bottomSpace<0){var split=(scrollBox.clientHeight/2); +var centerY=offset.y-split; +scrollBox.scrollTop=centerY; +topSpace=split; +bottomSpace=split-element.offsetHeight +}return{before:Math.round((topSpace/element.offsetHeight)+0.5),after:Math.round((bottomSpace/element.offsetHeight)+0.5)} +}; +this.scrollIntoCenterView=function(element,scrollBox,notX,notY){if(!element){return +}if(!scrollBox){scrollBox=this.getOverflowParent(element) +}if(!scrollBox){return +}var offset=this.getClientOffset(element); +if(!notY){var topSpace=offset.y-scrollBox.scrollTop; +var bottomSpace=(scrollBox.scrollTop+scrollBox.clientHeight)-(offset.y+element.offsetHeight); +if(topSpace<0||bottomSpace<0){var centerY=offset.y-(scrollBox.clientHeight/2); +scrollBox.scrollTop=centerY +}}if(!notX){var leftSpace=offset.x-scrollBox.scrollLeft; +var rightSpace=(scrollBox.scrollLeft+scrollBox.clientWidth)-(offset.x+element.clientWidth); +if(leftSpace<0||rightSpace<0){var centerX=offset.x-(scrollBox.clientWidth/2); +scrollBox.scrollLeft=centerX +}}if(FBTrace.DBG_SOURCEFILES){FBTrace.sysout("lib.scrollIntoCenterView ","Element:"+element.innerHTML) +}}; +var cssKeywordMap=null; +var cssPropNames=null; +var cssColorNames=null; +var imageRules=null; +this.getCSSKeywordsByProperty=function(propName){if(!cssKeywordMap){cssKeywordMap={}; +for(var name in this.cssInfo){var list=[]; +var types=this.cssInfo[name]; +for(var i=0; +i"); +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"); +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("") +}; +this.hasClass=function(node,name){if(arguments.length==2){return(" "+node.className+" ").indexOf(" "+name+" ")!=-1 +}if(!node||node.nodeType!=1){return false +}else{for(var i=1; +i=0){var size=name.length; +node.className=node.className.substr(0,index-1)+node.className.substr(index+size) +}}}; +this.toggleClass=function(elt,name){if((" "+elt.className+" ").indexOf(" "+name+" ")!=-1){this.removeClass(elt,name) +}else{this.setClass(elt,name) +}}; +this.setClassTimed=function(elt,name,context,timeout){if(!timeout){timeout=1300 +}if(elt.__setClassTimeout){context.clearTimeout(elt.__setClassTimeout) +}else{this.setClass(elt,name) +}elt.__setClassTimeout=context.setTimeout(function(){delete elt.__setClassTimeout; +FBL.removeClass(elt,name) +},timeout) +}; +this.cancelClassTimed=function(elt,name,context){if(elt.__setClassTimeout){FBL.removeClass(elt,name); +context.clearTimeout(elt.__setClassTimeout); +delete elt.__setClassTimeout +}}; +this.$=function(id,doc){if(doc){return doc.getElementById(id) +}else{return FBL.Firebug.chrome.document.getElementById(id) +}}; +this.$$=function(selector,doc){if(doc||!FBL.Firebug.chrome){return FBL.Firebug.Selector(selector,doc) +}else{return FBL.Firebug.Selector(selector,FBL.Firebug.chrome.document) +}}; +this.getChildByClass=function(node){for(var i=1; +i1&&doc.styleSheets[1].href=="chrome://browser/skin/feeds/subscribe.css")){return true +}return FBL.isSystemURL(win.location.href) +}catch(exc){ERROR("tabWatcher.isSystemPage document not ready:"+exc); +return false +}}; +this.isSystemStyleSheet=function(sheet){var href=sheet&&sheet.href; +return href&&FBL.isSystemURL(href) +}; +this.getURIHost=function(uri){try{if(uri){return uri.host +}else{return"" +}}catch(exc){return"" +}}; +this.isLocalURL=function(url){if(url.substr(0,5)=="file:"){return true +}else{if(url.substr(0,8)=="wyciwyg:"){return true +}else{return false +}}}; +this.isDataURL=function(url){return(url&&url.substr(0,5)=="data:") +}; +this.getLocalPath=function(url){if(this.isLocalURL(url)){var fileHandler=ioService.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler); +var file=fileHandler.getFileFromURLSpec(url); +return file.path +}}; +this.getURLFromLocalFile=function(file){var fileHandler=ioService.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler); +var URL=fileHandler.getURLSpecFromFile(file); +return URL +}; +this.getDataURLForContent=function(content,url){var uri="data:text/html;"; +uri+="fileName="+encodeURIComponent(url)+","; +uri+=encodeURIComponent(content); +return uri +},this.getDomain=function(url){var m=/[^:]+:\/{1,3}([^\/]+)/.exec(url); +return m?m[1]:"" +}; +this.getURLPath=function(url){var m=/[^:]+:\/{1,3}[^\/]+(\/.*?)$/.exec(url); +return m?m[1]:"" +}; +this.getPrettyDomain=function(url){var m=/[^:]+:\/{1,3}(www\.)?([^\/]+)/.exec(url); +return m?m[2]:"" +}; +this.absoluteURL=function(url,baseURL){return this.absoluteURLWithDots(url,baseURL).replace("/./","/","g") +}; +this.absoluteURLWithDots=function(url,baseURL){if(url[0]=="?"){return baseURL+url +}var reURL=/(([^:]+:)\/{1,2}[^\/]*)(.*?)$/; +var m=reURL.exec(url); +if(m){return url +}var m=reURL.exec(baseURL); +if(!m){return"" +}var head=m[1]; +var tail=m[3]; +if(url.substr(0,2)=="//"){return m[2]+url +}else{if(url[0]=="/"){return head+url +}else{if(tail[tail.length-1]=="/"){return baseURL+url +}else{var parts=tail.split("/"); +return head+parts.slice(0,parts.length-1).join("/")+"/"+url +}}}}; +this.normalizeURL=function(url){if(!url){return"" +}if(url.length<255){url=url.replace(/[^\/]+\/\.\.\//,"","g"); +url=url.replace(/#.*/,""); +url=url.replace(/file:\/([^\/])/g,"file:///$1"); +if(url.indexOf("chrome:")==0){var m=reChromeCase.exec(url); +if(m){url="chrome://"+m[1].toLowerCase()+"/"+m[2] +}}}return url +}; +this.denormalizeURL=function(url){return url.replace(/file:\/\/\//g,"file:/") +}; +this.parseURLParams=function(url){var q=url?url.indexOf("?"):-1; +if(q==-1){return[] +}var search=url.substr(q+1); +var h=search.lastIndexOf("#"); +if(h!=-1){search=search.substr(0,h) +}if(!search){return[] +}return this.parseURLEncodedText(search) +}; +this.parseURLEncodedText=function(text){var maxValueLength=25000; +var params=[]; +text=text.replace(/\+/g," "); +var args=text.split("&"); +for(var i=0; +imaxValueLength){parts[1]=this.$STR("LargeData") +}params.push({name:decodeURIComponent(parts[0]),value:decodeURIComponent(parts[1])}) +}else{params.push({name:decodeURIComponent(parts[0]),value:""}) +}}catch(e){if(FBTrace.DBG_ERRORS){FBTrace.sysout("parseURLEncodedText EXCEPTION ",e); +FBTrace.sysout("parseURLEncodedText EXCEPTION URI",args[i]) +}}}params.sort(function(a,b){return a.name<=b.name?-1:1 +}); +return params +}; +this.parseURLParamsArray=function(url){var q=url?url.indexOf("?"):-1; +if(q==-1){return[] +}var search=url.substr(q+1); +var h=search.lastIndexOf("#"); +if(h!=-1){search=search.substr(0,h) +}if(!search){return[] +}return this.parseURLEncodedTextArray(search) +}; +this.parseURLEncodedTextArray=function(text){var maxValueLength=25000; +var params=[]; +text=text.replace(/\+/g," "); +var args=text.split("&"); +for(var i=0; +imaxValueLength){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; +i0){setTimeout(this.sendRequest,10) +}}},getResponse:function(options){var t=this.transport,type=options.dataType; +if(t.status!=200){return t.statusText +}else{if(type=="text"){return t.responseText +}else{if(type=="html"){return t.responseText +}else{if(type=="xml"){return t.responseXML +}else{if(type=="json"){return eval("("+t.responseText+")") +}}}}}},getState:function(){return this.states[this.transport.readyState] +}}; +this.createCookie=function(name,value,days){if("cookie" in document){if(days){var date=new Date(); +date.setTime(date.getTime()+(days*24*60*60*1000)); +var expires="; expires="+date.toGMTString() +}else{var expires="" +}document.cookie=name+"="+value+expires+"; path=/" +}}; +this.readCookie=function(name){if("cookie" in document){var nameEQ=name+"="; +var ca=document.cookie.split(";"); +for(var i=0; +iobjects.length){format=""; +objIndex=-1; +parts.length=0; +break +}}}var result=[]; +for(var i=0; +i'; +var tabNode=this.tabNode=createElement("a",{id:panelId+"Tab",className:"fbTab fbHover",innerHTML:tabHTML}); +if(isIE6){tabNode.href="javascript:void(0)" +}var panelBarNode=this.parentPanel?Firebug.chrome.getPanel(this.parentPanel).sidePanelBarNode:this.panelBarNode; +panelBarNode.appendChild(tabNode); +tabNode.style.display="block"; +if(options.hasToolButtons){this.toolButtonsNode=createElement("span",{id:panelId+"Buttons",className:"fbToolbarButtons"}); +$("fbToolbarButtons").appendChild(this.toolButtonsNode) +}if(options.hasStatusBar){this.statusBarBox=$("fbStatusBarBox"); +this.statusBarNode=createElement("span",{id:panelId+"StatusBar",className:"fbToolbarButtons fbStatusBar"}); +this.statusBarBox.appendChild(this.statusBarNode) +}}this.containerNode=this.panelNode.parentNode; +if(FBTrace.DBG_INITIALIZE){FBTrace.sysout("Firebug.Panel.create",this.name) +}this.onContextMenu=bind(this.onContextMenu,this) +},destroy:function(state){if(FBTrace.DBG_INITIALIZE){FBTrace.sysout("Firebug.Panel.destroy",this.name) +}if(this.hasSidePanel){this.sidePanelBar.destroy(); +this.sidePanelBar=null +}this.options=null; +this.name=null; +this.parentPanel=null; +this.tabNode=null; +this.panelNode=null; +this.containerNode=null; +this.toolButtonsNode=null; +this.statusBarBox=null; +this.statusBarNode=null +},initialize:function(){if(FBTrace.DBG_INITIALIZE){FBTrace.sysout("Firebug.Panel.initialize",this.name) +}if(this.hasSidePanel){this.sidePanelBar.initialize() +}var options=this.options=extend(Firebug.Panel.options,this.options); +var panelId="fb"+this.name; +this.panelNode=$(panelId); +this.tabNode=$(panelId+"Tab"); +this.tabNode.style.display="block"; +if(options.hasStatusBar){this.statusBarBox=$("fbStatusBarBox"); +this.statusBarNode=$(panelId+"StatusBar") +}if(options.hasToolButtons){this.toolButtonsNode=$(panelId+"Buttons") +}this.containerNode=this.panelNode.parentNode; +this.containerNode.scrollTop=this.lastScrollTop; +addEvent(this.containerNode,"contextmenu",this.onContextMenu); +Firebug.chrome.currentPanel=Firebug.chrome.selectedPanel&&Firebug.chrome.selectedPanel.sidePanelBar?Firebug.chrome.selectedPanel.sidePanelBar.selectedPanel:Firebug.chrome.selectedPanel; +Firebug.showInfoTips=true; +Firebug.InfoTip.initializeBrowser(Firebug.chrome) +},shutdown:function(){if(FBTrace.DBG_INITIALIZE){FBTrace.sysout("Firebug.Panel.shutdown",this.name) +}Firebug.InfoTip.uninitializeBrowser(Firebug.chrome); +if(Firebug.chrome.largeCommandLineVisible){Firebug.chrome.hideLargeCommandLine() +}if(this.hasSidePanel){}this.lastScrollTop=this.containerNode.scrollTop; +removeEvent(this.containerNode,"contextmenu",this.onContextMenu) +},detach:function(oldChrome,newChrome){if(oldChrome.selectedPanel.name==this.name){this.lastScrollTop=oldChrome.selectedPanel.containerNode.scrollTop +}},reattach:function(doc){if(this.options.innerHTMLSync){this.synchronizeUI() +}},synchronizeUI:function(){this.containerNode.scrollTop=this.lastScrollTop||0 +},show:function(state){var options=this.options; +if(options.hasStatusBar){this.statusBarBox.style.display="inline"; +this.statusBarNode.style.display="inline" +}if(options.hasToolButtons){this.toolButtonsNode.style.display="inline" +}this.panelNode.style.display="block"; +this.visible=true; +if(!this.parentPanel){Firebug.chrome.layout(this) +}},hide:function(state){var options=this.options; +if(options.hasStatusBar){this.statusBarBox.style.display="none"; +this.statusBarNode.style.display="none" +}if(options.hasToolButtons){this.toolButtonsNode.style.display="none" +}this.panelNode.style.display="none"; +this.visible=false +},watchWindow:function(win){},unwatchWindow:function(win){},updateOption:function(name,value){},showToolbarButtons:function(buttonsId,show){try{if(!this.context.browser){if(FBTrace.DBG_ERRORS){FBTrace.sysout("firebug.Panel showToolbarButtons this.context has no browser, this:",this) +}return +}var buttons=this.context.browser.chrome.$(buttonsId); +if(buttons){collapse(buttons,show?"false":"true") +}}catch(exc){if(FBTrace.DBG_ERRORS){FBTrace.dumpProperties("firebug.Panel showToolbarButtons FAILS",exc); +if(!this.context.browser){FBTrace.dumpStack("firebug.Panel showToolbarButtons no browser") +}}}},supportsObject:function(object){return 0 +},hasObject:function(object){return false +},select:function(object,forceUpdate){if(!object){object=this.getDefaultSelection(this.context) +}if(FBTrace.DBG_PANELS){FBTrace.sysout("firebug.select "+this.name+" forceUpdate: "+forceUpdate+" "+object+((object==this.selection)?"==":"!=")+this.selection) +}if(forceUpdate||object!=this.selection){this.selection=object; +this.updateSelection(object) +}},updateSelection:function(object){},markChange:function(skipSelf){if(this.dependents){if(skipSelf){for(var i=0; +ilocB.path){return 1 +}if(locA.pathlocB.name){return 1 +}if(locA.namewidth||el.scrollHeight>height)){width=el.scrollWidth; +height=el.scrollHeight +}return{width:width,height:height} +},getWindowScrollPosition:function(){var top=0,left=0,el; +if(typeof this.window.pageYOffset=="number"){top=this.window.pageYOffset; +left=this.window.pageXOffset +}else{if((el=this.document.body)&&(el.scrollTop||el.scrollLeft)){top=el.scrollTop; +left=el.scrollLeft +}else{if((el=this.document.documentElement)&&(el.scrollTop||el.scrollLeft)){top=el.scrollTop; +left=el.scrollLeft +}}}return{top:top,left:left} +},getElementFromPoint:function(x,y){if(shouldFixElementFromPoint){var scroll=this.getWindowScrollPosition(); +return this.document.elementFromPoint(x+scroll.left,y+scroll.top) +}else{return this.document.elementFromPoint(x,y) +}},getElementPosition:function(el){var left=0; +var top=0; +do{left+=el.offsetLeft; +top+=el.offsetTop +}while(el=el.offsetParent); +return{left:left,top:top} +},getElementBox:function(el){var result={}; +if(el.getBoundingClientRect){var rect=el.getBoundingClientRect(); +var offset=isIE?this.document.body.clientTop||this.document.documentElement.clientTop:0; +var scroll=this.getWindowScrollPosition(); +result.top=Math.round(rect.top-offset+scroll.top); +result.left=Math.round(rect.left-offset+scroll.left); +result.height=Math.round(rect.bottom-rect.top); +result.width=Math.round(rect.right-rect.left) +}else{var position=this.getElementPosition(el); +result.top=position.top; +result.left=position.left; +result.height=el.offsetHeight; +result.width=el.offsetWidth +}return result +},getMeasurement:function(el,name){var result={value:0,unit:"px"}; +var cssValue=this.getStyle(el,name); +if(!cssValue){return result +}if(cssValue.toLowerCase()=="auto"){return result +}var reMeasure=/(\d+\.?\d*)(.*)/; +var m=cssValue.match(reMeasure); +if(m){result.value=m[1]-0; +result.unit=m[2].toLowerCase() +}return result +},getMeasurementInPixels:function(el,name){if(!el){return null +}var m=this.getMeasurement(el,name); +var value=m.value; +var unit=m.unit; +if(unit=="px"){return value +}else{if(unit=="pt"){return this.pointsToPixels(name,value) +}}if(unit=="em"){return this.emToPixels(el,value) +}else{if(unit=="%"){return this.percentToPixels(el,value) +}}},getMeasurementBox1:function(el,name){var sufixes=["Top","Left","Bottom","Right"]; +var result=[]; +for(var i=0,sufix; +sufix=sufixes[i]; +i++){result[i]=Math.round(this.getMeasurementInPixels(el,name+sufix)) +}return{top:result[0],left:result[1],bottom:result[2],right:result[3]} +},getMeasurementBox:function(el,name){var result=[]; +var sufixes=name=="border"?["TopWidth","LeftWidth","BottomWidth","RightWidth"]:["Top","Left","Bottom","Right"]; +if(isIE){var propName,cssValue; +var autoMargin=null; +for(var i=0,sufix; +sufix=sufixes[i]; +i++){propName=name+sufix; +cssValue=el.currentStyle[propName]||el.style[propName]; +if(cssValue=="auto"){if(!autoMargin){autoMargin=this.getCSSAutoMarginBox(el) +}result[i]=autoMargin[sufix.toLowerCase()] +}else{result[i]=this.getMeasurementInPixels(el,propName) +}}}else{for(var i=0,sufix; +sufix=sufixes[i]; +i++){result[i]=this.getMeasurementInPixels(el,name+sufix) +}}return{top:result[0],left:result[1],bottom:result[2],right:result[3]} +},getCSSAutoMarginBox:function(el){if(isIE&&" meta title input script link a ".indexOf(" "+el.nodeName.toLowerCase()+" ")!=-1){return{top:0,left:0,bottom:0,right:0} +}if(isIE&&" h1 h2 h3 h4 h5 h6 h7 ul p ".indexOf(" "+el.nodeName.toLowerCase()+" ")==-1){return{top:0,left:0,bottom:0,right:0} +}var offsetTop=0; +if(false&&isIEStantandMode){var scrollSize=Firebug.browser.getWindowScrollSize(); +offsetTop=scrollSize.height +}var box=this.document.createElement("div"); +box.style.cssText="margin:0; padding:1px; border: 0; visibility: hidden;"; +var clone=el.cloneNode(false); +var text=this.document.createTextNode(" "); +clone.appendChild(text); +box.appendChild(clone); +this.document.body.appendChild(box); +var marginTop=clone.offsetTop-box.offsetTop-1; +var marginBottom=box.offsetHeight-clone.offsetHeight-2-marginTop; +var marginLeft=clone.offsetLeft-box.offsetLeft-1; +var marginRight=box.offsetWidth-clone.offsetWidth-2-marginLeft; +this.document.body.removeChild(box); +return{top:marginTop+offsetTop,left:marginLeft,bottom:marginBottom-offsetTop,right:marginRight} +},getFontSizeInPixels:function(el){var size=this.getMeasurement(el,"fontSize"); +if(size.unit=="px"){return size.value +}var computeDirtyFontSize=function(el,calibration){var div=this.document.createElement("div"); +var divStyle=offscreenStyle; +if(calibration){divStyle+=" font-size:"+calibration+"px;" +}div.style.cssText=divStyle; +div.innerHTML="A"; +el.appendChild(div); +var value=div.offsetHeight; +el.removeChild(div); +return value +}; +var rate=200/225; +var value=computeDirtyFontSize(el); +return value*rate +},pointsToPixels:function(name,value,returnFloat){var axis=/Top$|Bottom$/.test(name)?"y":"x"; +var result=value*pixelsPerInch[axis]/72; +return returnFloat?result:Math.round(result) +},emToPixels:function(el,value){if(!el){return null +}var fontSize=this.getFontSizeInPixels(el); +return Math.round(value*fontSize) +},exToPixels:function(el,value){if(!el){return null +}var div=this.document.createElement("div"); +div.style.cssText=offscreenStyle+"width:"+value+"ex;"; +el.appendChild(div); +var value=div.offsetWidth; +el.removeChild(div); +return value +},percentToPixels:function(el,value){if(!el){return null +}var div=this.document.createElement("div"); +div.style.cssText=offscreenStyle+"width:"+value+"%;"; +el.appendChild(div); +var value=div.offsetWidth; +el.removeChild(div); +return value +},getStyle:isIE?function(el,name){return el.currentStyle[name]||el.style[name]||undefined +}:function(el,name){return this.document.defaultView.getComputedStyle(el,null)[name]||el.style[name]||undefined +}} +}}); +FBL.ns(function(){with(FBL){var WindowDefaultOptions={type:"frame",id:"FirebugUI",height:250},commandLine,fbTop,fbContent,fbContentStyle,fbBottom,fbBtnInspect,fbToolbar,fbPanelBox1,fbPanelBox1Style,fbPanelBox2,fbPanelBox2Style,fbPanelBar2Box,fbPanelBar2BoxStyle,fbHSplitter,fbVSplitter,fbVSplitterStyle,fbPanel1,fbPanel1Style,fbPanel2,fbPanel2Style,fbConsole,fbConsoleStyle,fbHTML,fbCommandLine,fbLargeCommandLine,fbLargeCommandButtons,topHeight,topPartialHeight,chromeRedrawSkipRate=isIE?75:isOpera?80:75,lastSelectedPanelName,focusCommandLineState=0,lastFocusedPanelName,lastHSplitterMouseMove=0,onHSplitterMouseMoveBuffer=null,onHSplitterMouseMoveTimer=null,lastVSplitterMouseMove=0; +FBL.FirebugChrome={isOpen:false,height:250,sidePanelWidth:350,selectedPanelName:"Console",selectedHTMLElementId:null,chromeMap:{},htmlSelectionStack:[],consoleMessageQueue:[],create:function(){if(FBTrace.DBG_INITIALIZE){FBTrace.sysout("FirebugChrome.create","creating chrome window") +}createChromeWindow() +},initialize:function(){if(FBTrace.DBG_INITIALIZE){FBTrace.sysout("FirebugChrome.initialize","initializing chrome window") +}if(Env.chrome.type=="frame"||Env.chrome.type=="div"){ChromeMini.create(Env.chrome) +}var chrome=Firebug.chrome=new Chrome(Env.chrome); +FirebugChrome.chromeMap[chrome.type]=chrome; +addGlobalEvent("keydown",onGlobalKeyDown); +if(Env.Options.enablePersistent&&chrome.type=="popup"){var frame=FirebugChrome.chromeMap.frame; +if(frame){frame.close() +}chrome.initialize() +}},clone:function(FBChrome){for(var name in FBChrome){var prop=FBChrome[name]; +if(FBChrome.hasOwnProperty(name)&&!isFunction(prop)){this[name]=prop +}}}}; +var createChromeWindow=function(options){options=extend(WindowDefaultOptions,options||{}); +var chrome={},context=options.context||Env.browser,type=chrome.type=Env.Options.enablePersistent?"popup":options.type,isChromeFrame=type=="frame",useLocalSkin=Env.useLocalSkin,url=useLocalSkin?Env.Location.skin:"about:blank",body=context.document.getElementsByTagName("body")[0],formatNode=function(node){if(!Env.isDebugMode){node.firebugIgnore=true +}node.style.border="0"; +node.style.visibility="hidden"; +node.style.zIndex="2147483647"; +node.style.position=noFixedPosition?"absolute":"fixed"; +node.style.width="100%"; +node.style.left="0"; +node.style.bottom=noFixedPosition?"-1px":"0"; +node.style.height=options.height+"px"; +if(isFirefox){node.style.display="none" +}},createChromeDiv=function(){var node=chrome.node=createGlobalElement("div"),style=createGlobalElement("style"),css=FirebugChrome.Skin.CSS,rules=".fbBody *{margin:0;padding:0;font-size:11px;line-height:13px;color:inherit;}"+css+".fbBody #fbHSplitter{position:absolute !important;} .fbBody #fbHTML span{line-height:14px;} .fbBody .lineNo div{line-height:inherit !important;}"; +style.type="text/css"; +if(style.styleSheet){style.styleSheet.cssText=rules +}else{style.appendChild(context.document.createTextNode(rules)) +}document.getElementsByTagName("head")[0].appendChild(style); +node.className="fbBody"; +node.style.overflow="hidden"; +node.innerHTML=getChromeDivTemplate(); +if(isIE){setTimeout(function(){node.firstChild.style.height="1px"; +node.firstChild.style.position="static" +},0) +}formatNode(node); +body.appendChild(node); +chrome.window=window; +chrome.document=document; +onChromeLoad(chrome) +}; +try{if(type=="div"){createChromeDiv(); +return +}else{if(isChromeFrame){var node=chrome.node=createGlobalElement("iframe"); +node.setAttribute("src",url); +node.setAttribute("frameBorder","0"); +formatNode(node); +body.appendChild(node); +node.id=options.id +}else{var height=FirebugChrome.height||options.height,options=["true,top=",Math.max(screen.availHeight-height-61,0),",left=0,height=",height,",width=",screen.availWidth-10,",resizable"].join(""),node=chrome.node=context.window.open(url,"popup",options); +if(node){try{node.focus() +}catch(E){alert("Firebug Error: Firebug popup was blocked."); +return +}}else{alert("Firebug Error: Firebug popup was blocked."); +return +}}}if(!useLocalSkin){var tpl=getChromeTemplate(!isChromeFrame),doc=isChromeFrame?node.contentWindow.document:node.document; +doc.write(tpl); +doc.close() +}var win,waitDelay=useLocalSkin?isChromeFrame?200:300:100,waitForWindow=function(){if(isChromeFrame&&(win=node.contentWindow)&&node.contentWindow.document.getElementById("fbCommandLine")||!isChromeFrame&&(win=node.window)&&node.document&&node.document.getElementById("fbCommandLine")){chrome.window=win.window; +chrome.document=win.document; +setTimeout(function(){onChromeLoad(chrome) +},0) +}else{setTimeout(waitForWindow,waitDelay) +}}; +waitForWindow() +}catch(e){var msg=e.message||e; +if(/access/i.test(msg)){if(isChromeFrame){body.removeChild(node) +}else{if(type=="popup"){node.close() +}}createChromeDiv() +}else{alert("Firebug Error: Firebug GUI could not be created.") +}}}; +var onChromeLoad=function onChromeLoad(chrome){Env.chrome=chrome; +if(FBTrace.DBG_INITIALIZE){FBTrace.sysout("Chrome onChromeLoad","chrome window loaded") +}if(Env.Options.enablePersistent){Env.FirebugChrome=FirebugChrome; +chrome.window.Firebug=chrome.window.Firebug||{}; +chrome.window.Firebug.SharedEnv=Env; +if(Env.isDevelopmentMode){Env.browser.window.FBDev.loadChromeApplication(chrome) +}else{var doc=chrome.document; +var script=doc.createElement("script"); +script.src=Env.Location.app+"#remote,persist"; +doc.getElementsByTagName("head")[0].appendChild(script) +}}else{if(chrome.type=="frame"||chrome.type=="div"){setTimeout(function(){FBL.Firebug.initialize() +},0) +}else{if(chrome.type=="popup"){var oldChrome=FirebugChrome.chromeMap.frame; +var newChrome=new Chrome(chrome); +dispatch(newChrome.panelMap,"detach",[oldChrome,newChrome]); +if(oldChrome){oldChrome.close() +}newChrome.reattach(oldChrome,newChrome) +}}}}; +var getChromeDivTemplate=function(){return FirebugChrome.Skin.HTML +}; +var getChromeTemplate=function(isPopup){var tpl=FirebugChrome.Skin; +var r=[],i=-1; +r[++i]=''; +r[++i]=""; +r[++i]=Firebug.version; +r[++i]=""; +r[++i]=''; +r[++i]=tpl.HTML; +r[++i]=""; +return r.join("") +}; +var Chrome=function Chrome(chrome){var type=chrome.type; +var Base=type=="frame"||type=="div"?ChromeFrameBase:ChromePopupBase; +append(this,Base); +append(this,chrome); +append(this,new Context(chrome.window)); +FirebugChrome.chromeMap[type]=this; +Firebug.chrome=this; +Env.chrome=chrome.window; +this.commandLineVisible=false; +this.sidePanelVisible=false; +this.create(); +return this +}; +var ChromeBase={}; +append(ChromeBase,Controller); +append(ChromeBase,PanelBar); +append(ChromeBase,{node:null,type:null,document:null,window:null,sidePanelVisible:false,commandLineVisible:false,largeCommandLineVisible:false,inspectButton:null,create:function(){PanelBar.create.call(this); +if(Firebug.Inspector){this.inspectButton=new Button({type:"toggle",element:$("fbChrome_btInspect"),owner:Firebug.Inspector,onPress:Firebug.Inspector.startInspecting,onUnpress:Firebug.Inspector.stopInspecting}) +}},destroy:function(){if(Firebug.Inspector){this.inspectButton.destroy() +}PanelBar.destroy.call(this); +this.shutdown() +},testMenu:function(){var firebugMenu=new Menu({id:"fbFirebugMenu",items:[{label:"Open Firebug",type:"shortcut",key:isFirefox?"Shift+F12":"F12",checked:true,command:"toggleChrome"},{label:"Open Firebug in New Window",type:"shortcut",key:isFirefox?"Ctrl+Shift+F12":"Ctrl+F12",command:"openPopup"},{label:"Inspect Element",type:"shortcut",key:"Ctrl+Shift+C",command:"toggleInspect"},{label:"Command Line",type:"shortcut",key:"Ctrl+Shift+L",command:"focusCommandLine"},"-",{label:"Options",type:"group",child:"fbFirebugOptionsMenu"},"-",{label:"Firebug Lite Website...",command:"visitWebsite"},{label:"Discussion Group...",command:"visitDiscussionGroup"},{label:"Issue Tracker...",command:"visitIssueTracker"}],onHide:function(){iconButton.restore() +},toggleChrome:function(){Firebug.chrome.toggle() +},openPopup:function(){Firebug.chrome.toggle(true,true) +},toggleInspect:function(){Firebug.Inspector.toggleInspect() +},focusCommandLine:function(){Firebug.chrome.focusCommandLine() +},visitWebsite:function(){this.visit("http://getfirebug.com/lite.html") +},visitDiscussionGroup:function(){this.visit("http://groups.google.com/group/firebug") +},visitIssueTracker:function(){this.visit("http://code.google.com/p/fbug/issues/list") +},visit:function(url){window.open(url) +}}); +var firebugOptionsMenu={id:"fbFirebugOptionsMenu",getItems:function(){var cookiesDisabled=!Firebug.saveCookies; +return[{label:"Save Options in Cookies",type:"checkbox",value:"saveCookies",checked:Firebug.saveCookies,command:"saveOptions"},"-",{label:"Start Opened",type:"checkbox",value:"startOpened",checked:Firebug.startOpened,disabled:cookiesDisabled},{label:"Start in New Window",type:"checkbox",value:"startInNewWindow",checked:Firebug.startInNewWindow,disabled:cookiesDisabled},{label:"Show Icon When Hidden",type:"checkbox",value:"showIconWhenHidden",checked:Firebug.showIconWhenHidden,disabled:cookiesDisabled},{label:"Override Console Object",type:"checkbox",value:"overrideConsole",checked:Firebug.overrideConsole,disabled:cookiesDisabled},{label:"Ignore Firebug Elements",type:"checkbox",value:"ignoreFirebugElements",checked:Firebug.ignoreFirebugElements,disabled:cookiesDisabled},{label:"Disable When Firebug Active",type:"checkbox",value:"disableWhenFirebugActive",checked:Firebug.disableWhenFirebugActive,disabled:cookiesDisabled},{label:"Disable XHR Listener",type:"checkbox",value:"disableXHRListener",checked:Firebug.disableXHRListener,disabled:cookiesDisabled},{label:"Enable Trace Mode",type:"checkbox",value:"enableTrace",checked:Firebug.enableTrace,disabled:cookiesDisabled},{label:"Enable Persistent Mode (experimental)",type:"checkbox",value:"enablePersistent",checked:Firebug.enablePersistent,disabled:cookiesDisabled},"-",{label:"Reset All Firebug Options",command:"restorePrefs",disabled:cookiesDisabled}] +},onCheck:function(target,value,checked){Firebug.setPref(value,checked) +},saveOptions:function(target){var saveEnabled=target.getAttribute("checked"); +if(!saveEnabled){this.restorePrefs() +}this.updateMenu(target); +return false +},restorePrefs:function(target){Firebug.restorePrefs(); +if(Firebug.saveCookies){Firebug.savePrefs() +}else{Firebug.erasePrefs() +}if(target){this.updateMenu(target) +}return false +},updateMenu:function(target){var options=getElementsByClass(target.parentNode,"fbMenuOption"); +var firstOption=options[0]; +var enabled=Firebug.saveCookies; +if(enabled){Menu.check(firstOption) +}else{Menu.uncheck(firstOption) +}if(enabled){Menu.check(options[0]) +}else{Menu.uncheck(options[0]) +}for(var i=1,length=options.length; +ichromeRedrawSkipRate){lastHSplitterMouseMove=new Date().getTime(); +handleHSplitterMouseMove() +}else{if(!onHSplitterMouseMoveTimer){onHSplitterMouseMoveTimer=setTimeout(handleHSplitterMouseMove,chromeRedrawSkipRate) +}}cancelEvent(event,true); +return false +}; +var handleHSplitterMouseMove=function(){if(onHSplitterMouseMoveTimer){clearTimeout(onHSplitterMouseMoveTimer); +onHSplitterMouseMoveTimer=null +}var clientY=onHSplitterMouseMoveBuffer; +var windowSize=Firebug.browser.getWindowSize(); +var scrollSize=Firebug.browser.getWindowScrollSize(); +var commandLineHeight=Firebug.chrome.commandLineVisible?fbCommandLine.offsetHeight:0; +var fixedHeight=topHeight+commandLineHeight; +var chromeNode=Firebug.chrome.node; +var scrollbarSize=!isIE&&(scrollSize.width>windowSize.width)?17:0; +var height=windowSize.height; +var chromeHeight=Math.max(height-clientY+5-scrollbarSize,fixedHeight); +chromeHeight=Math.min(chromeHeight,windowSize.height-scrollbarSize); +FirebugChrome.height=chromeHeight; +chromeNode.style.height=chromeHeight+"px"; +if(noFixedPosition){Firebug.chrome.fixIEPosition() +}Firebug.chrome.draw() +}; +var onHSplitterMouseUp=function onHSplitterMouseUp(event){removeGlobalEvent("mousemove",onHSplitterMouseMove); +removeGlobalEvent("mouseup",onHSplitterMouseUp); +if(isIE){removeEvent(Firebug.browser.document.documentElement,"mouseleave",onHSplitterMouseUp) +}fbHSplitter.className=""; +Firebug.chrome.draw(); +return false +}; +var onVSplitterMouseDown=function onVSplitterMouseDown(event){addGlobalEvent("mousemove",onVSplitterMouseMove); +addGlobalEvent("mouseup",onVSplitterMouseUp); +return false +}; +var onVSplitterMouseMove=function onVSplitterMouseMove(event){if(new Date().getTime()-lastVSplitterMouseMove>chromeRedrawSkipRate){var target=event.target||event.srcElement; +if(target&&target.ownerDocument){var clientX=event.clientX; +var win=document.all?event.srcElement.ownerDocument.parentWindow:event.target.ownerDocument.defaultView; +if(win!=win.parent){clientX+=win.frameElement?win.frameElement.offsetLeft:0 +}var size=Firebug.chrome.getSize(); +var x=Math.max(size.width-clientX+3,6); +FirebugChrome.sidePanelWidth=x; +Firebug.chrome.draw() +}lastVSplitterMouseMove=new Date().getTime() +}cancelEvent(event,true); +return false +}; +var onVSplitterMouseUp=function onVSplitterMouseUp(event){removeGlobalEvent("mousemove",onVSplitterMouseMove); +removeGlobalEvent("mouseup",onVSplitterMouseUp); +Firebug.chrome.draw() +} +}}); +FBL.ns(function(){with(FBL){Firebug.Lite={} +}}); +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" +}} +}}); +FBL.ns(function(){with(FBL){Firebug.Lite.Cache={ID:"firebug"+new Date().getTime()}; +var cacheUID=0; +var createCache=function(){var map={}; +var CID=Firebug.Lite.Cache.ID; +var supportsDeleteExpando=!document.all; +var cacheFunction=function(element){return cacheAPI.set(element) +}; +var cacheAPI={get:function(key){return map.hasOwnProperty(key)?map[key]:null +},set:function(element){var id=element[CID]; +if(!id){id=++cacheUID; +element[CID]=id +}if(!map.hasOwnProperty(id)){map[id]=element +}return id +},unset:function(element){var id=element[CID]; +if(supportsDeleteExpando){delete element[CID] +}else{if(element.removeAttribute){element.removeAttribute(CID) +}}delete map[id] +},key:function(element){return element[CID] +},has:function(element){return map.hasOwnProperty(element[CID]) +},clear:function(){for(var id in map){var element=map[id]; +cacheAPI.unset(element) +}}}; +FBL.append(cacheFunction,cacheAPI); +return cacheFunction +}; +Firebug.Lite.Cache.StyleSheet=createCache(); +Firebug.Lite.Cache.Element=createCache() +}}); +FBL.ns(function(){with(FBL){Firebug.Lite.Proxy={_callbacks:{},load:function(url){var resourceDomain=getDomain(url); +var isLocalResource=!resourceDomain||resourceDomain==Firebug.context.window.location.host; +return isLocalResource?fetchResource(url):fetchProxyResource(url) +},loadJSONP:function(url,callback){var script=createGlobalElement("script"),doc=Firebug.context.document,uid=""+new Date().getTime(),callbackName="callback=Firebug.Lite.Proxy._callbacks."+uid,jsonpURL=url.indexOf("?")!=-1?url+"&"+callbackName:url+"?"+callbackName; +Firebug.Lite.Proxy._callbacks[uid]=function(data){if(callback){callback(data) +}script.parentNode.removeChild(script); +delete Firebug.Lite.Proxy._callbacks[uid] +}; +script.src=jsonpURL; +if(doc.documentElement){doc.documentElement.appendChild(script) +}},YQL:function(url,callback){var yql="http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22"+encodeURIComponent(url)+"%22&format=xml"; +this.loadJSONP(yql,function(data){var source=data.results[0]; +var match=/\s+

                  ([\s\S]+)<\/p>\s+<\/body>$/.exec(source); +if(match){source=match[1] +}console.log(source) +}) +}}; +var fetchResource=function(url){var xhr=FBL.Ajax.getXHRObject(); +xhr.open("get",url,false); +xhr.send(); +return xhr.responseText +}; +var fetchProxyResource=function(url){var proxyURL=Env.Location.baseDir+"plugin/proxy/proxy.php?url="+encodeURIComponent(url); +var response=fetchResource(proxyURL); +try{var data=eval("("+response+")") +}catch(E){return"ERROR: Firebug Lite Proxy plugin returned an invalid response." +}return data?data.contents:"" +} +}}); +FBL.ns(function(){with(FBL){Firebug.Lite.Script=function(window){this.fileName=null; +this.isValid=null; +this.baseLineNumber=null; +this.lineExtent=null; +this.tag=null; +this.functionName=null; +this.functionSource=null +}; +Firebug.Lite.Script.prototype={isLineExecutable:function(){},pcToLine:function(){},lineToPc:function(){},toString:function(){return"Firebug.Lite.Script" +}} +}}); +FBL.ns(function(){with(FBL){Firebug.Lite.Style={} +}}); +FBL.ns(function(){with(FBL){var chunker=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,done=0,toString=Object.prototype.toString,hasDuplicate=false,baseHasDuplicate=true; +[0,0].sort(function(){baseHasDuplicate=false; +return 0 +}); +var Sizzle=function(selector,context,results,seed){results=results||[]; +var origContext=context=context||document; +if(context.nodeType!==1&&context.nodeType!==9){return[] +}if(!selector||typeof selector!=="string"){return results +}var parts=[],m,set,checkSet,check,mode,extra,prune=true,contextXML=isXML(context),soFar=selector; +while((chunker.exec(""),m=chunker.exec(soFar))!==null){soFar=m[3]; +parts.push(m[1]); +if(m[2]){extra=m[3]; +break +}}if(parts.length>1&&origPOS.exec(selector)){if(parts.length===2&&Expr.relative[parts[0]]){set=posProcess(parts[0]+parts[1],context) +}else{set=Expr.relative[parts[0]]?[context]:Sizzle(parts.shift(),context); +while(parts.length){selector=parts.shift(); +if(Expr.relative[selector]){selector+=parts.shift() +}set=posProcess(selector,set) +}}}else{if(!seed&&parts.length>1&&context.nodeType===9&&!contextXML&&Expr.match.ID.test(parts[0])&&!Expr.match.ID.test(parts[parts.length-1])){var ret=Sizzle.find(parts.shift(),context,contextXML); +context=ret.expr?Sizzle.filter(ret.expr,ret.set)[0]:ret.set[0] +}if(context){var ret=seed?{expr:parts.pop(),set:makeArray(seed)}:Sizzle.find(parts.pop(),parts.length===1&&(parts[0]==="~"||parts[0]==="+")&&context.parentNode?context.parentNode:context,contextXML); +set=ret.expr?Sizzle.filter(ret.expr,ret.set):ret.set; +if(parts.length>0){checkSet=makeArray(set) +}else{prune=false +}while(parts.length){var cur=parts.pop(),pop=cur; +if(!Expr.relative[cur]){cur="" +}else{pop=parts.pop() +}if(pop==null){pop=context +}Expr.relative[cur](checkSet,pop,contextXML) +}}else{checkSet=parts=[] +}}if(!checkSet){checkSet=set +}if(!checkSet){throw"Syntax error, unrecognized expression: "+(cur||selector) +}if(toString.call(checkSet)==="[object Array]"){if(!prune){results.push.apply(results,checkSet) +}else{if(context&&context.nodeType===1){for(var i=0; +checkSet[i]!=null; +i++){if(checkSet[i]&&(checkSet[i]===true||checkSet[i].nodeType===1&&contains(context,checkSet[i]))){results.push(set[i]) +}}}else{for(var i=0; +checkSet[i]!=null; +i++){if(checkSet[i]&&checkSet[i].nodeType===1){results.push(set[i]) +}}}}}else{makeArray(checkSet,results) +}if(extra){Sizzle(extra,origContext,results,seed); +Sizzle.uniqueSort(results) +}return results +}; +Sizzle.uniqueSort=function(results){if(sortOrder){hasDuplicate=baseHasDuplicate; +results.sort(sortOrder); +if(hasDuplicate){for(var i=1; +i":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=0)){if(!inplace){result.push(elem) +}}else{if(inplace){curLoop[i]=false +}}}}return false +},ID:function(match){return match[1].replace(/\\/g,"") +},TAG:function(match,curLoop){for(var i=0; +curLoop[i]===false; +i++){}return curLoop[i]&&isXML(curLoop[i])?match[1]:match[1].toUpperCase() +},CHILD:function(match){if(match[1]=="nth"){var test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(match[2]=="even"&&"2n"||match[2]=="odd"&&"2n+1"||!/\D/.test(match[2])&&"0n+"+match[2]||match[2]); +match[2]=(test[1]+(test[2]||1))-0; +match[3]=test[3]-0 +}match[0]=done++; +return match +},ATTR:function(match,curLoop,inplace,result,not,isXML){var name=match[1].replace(/\\/g,""); +if(!isXML&&Expr.attrMap[name]){match[1]=Expr.attrMap[name] +}if(match[2]==="~="){match[4]=" "+match[4]+" " +}return match +},PSEUDO:function(match,curLoop,inplace,result,not){if(match[1]==="not"){if((chunker.exec(match[3])||"").length>1||/^\w/.test(match[3])){match[3]=Sizzle(match[3],null,null,curLoop) +}else{var ret=Sizzle.filter(match[3],curLoop,inplace,true^not); +if(!inplace){result.push.apply(result,ret) +}return false +}}else{if(Expr.match.POS.test(match[0])||Expr.match.CHILD.test(match[0])){return true +}}return match +},POS:function(match){match.unshift(true); +return match +}},filters:{enabled:function(elem){return elem.disabled===false&&elem.type!=="hidden" +},disabled:function(elem){return elem.disabled===true +},checked:function(elem){return elem.checked===true +},selected:function(elem){elem.parentNode.selectedIndex; +return elem.selected===true +},parent:function(elem){return !!elem.firstChild +},empty:function(elem){return !elem.firstChild +},has:function(elem,i,match){return !!Sizzle(match[3],elem).length +},header:function(elem){return/h\d/i.test(elem.nodeName) +},text:function(elem){return"text"===elem.type +},radio:function(elem){return"radio"===elem.type +},checkbox:function(elem){return"checkbox"===elem.type +},file:function(elem){return"file"===elem.type +},password:function(elem){return"password"===elem.type +},submit:function(elem){return"submit"===elem.type +},image:function(elem){return"image"===elem.type +},reset:function(elem){return"reset"===elem.type +},button:function(elem){return"button"===elem.type||elem.nodeName.toUpperCase()==="BUTTON" +},input:function(elem){return/input|select|textarea|button/i.test(elem.nodeName) +}},setFilters:{first:function(elem,i){return i===0 +},last:function(elem,i,match,array){return i===array.length-1 +},even:function(elem,i){return i%2===0 +},odd:function(elem,i){return i%2===1 +},lt:function(elem,i,match){return imatch[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=0) +}}},ID:function(elem,match){return elem.nodeType===1&&elem.getAttribute("id")===match +},TAG:function(elem,match){return(match==="*"&&elem.nodeType===1)||elem.nodeName===match +},CLASS:function(elem,match){return(" "+(elem.className||elem.getAttribute("class"))+" ").indexOf(match)>-1 +},ATTR:function(elem,match){var name=match[1],result=Expr.attrHandle[name]?Expr.attrHandle[name](elem):elem[name]!=null?elem[name]:elem.getAttribute(name),value=result+"",type=match[2],check=match[4]; +return result==null?type==="!=":type==="="?value===check:type==="*="?value.indexOf(check)>=0:type==="~="?(" "+value+" ").indexOf(check)>=0:!check?value&&result!==false:type==="!="?value!=check:type==="^="?value.indexOf(check)===0:type==="$="?value.substr(value.length-check.length)===check:type==="|="?value===check||value.substr(0,check.length+1)===check+"-":false +},POS:function(elem,match,i,array){var name=match[2],filter=Expr.setFilters[name]; +if(filter){return filter(elem,i,match,array) +}}}}; +var origPOS=Expr.match.POS; +for(var type in Expr.match){Expr.match[type]=new RegExp(Expr.match[type].source+/(?![^\[]*\])(?![^\(]*\))/.source); +Expr.leftMatch[type]=new RegExp(/(^(?:.|\r|\n)*?)/.source+Expr.match[type].source) +}var makeArray=function(array,results){array=Array.prototype.slice.call(array,0); +if(results){results.push.apply(results,array); +return results +}return array +}; +try{Array.prototype.slice.call(document.documentElement.childNodes,0) +}catch(e){makeArray=function(array,results){var ret=results||[]; +if(toString.call(array)==="[object Array]"){Array.prototype.push.apply(ret,array) +}else{if(typeof array.length==="number"){for(var i=0,l=array.length; +i"; +var root=document.documentElement; +root.insertBefore(form,root.firstChild); +if(!!document.getElementById(id)){Expr.find.ID=function(match,context,isXML){if(typeof context.getElementById!=="undefined"&&!isXML){var m=context.getElementById(match[1]); +return m?m.id===match[1]||typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id").nodeValue===match[1]?[m]:undefined:[] +}}; +Expr.filter.ID=function(elem,match){var node=typeof elem.getAttributeNode!=="undefined"&&elem.getAttributeNode("id"); +return elem.nodeType===1&&node&&node.nodeValue===match +} +}root.removeChild(form); +root=form=null +})(); +(function(){var div=document.createElement("div"); +div.appendChild(document.createComment("")); +if(div.getElementsByTagName("*").length>0){Expr.find.TAG=function(match,context){var results=context.getElementsByTagName(match[1]); +if(match[1]==="*"){var tmp=[]; +for(var i=0; +results[i]; +i++){if(results[i].nodeType===1){tmp.push(results[i]) +}}results=tmp +}return results +} +}div.innerHTML=""; +if(div.firstChild&&typeof div.firstChild.getAttribute!=="undefined"&&div.firstChild.getAttribute("href")!=="#"){Expr.attrHandle.href=function(elem){return elem.getAttribute("href",2) +} +}div=null +})(); +if(document.querySelectorAll){(function(){var oldSizzle=Sizzle,div=document.createElement("div"); +div.innerHTML="

                  "; +if(div.querySelectorAll&&div.querySelectorAll(".TEST").length===0){return +}Sizzle=function(query,context,extra,seed){context=context||document; +if(!seed&&context.nodeType===9&&!isXML(context)){try{return makeArray(context.querySelectorAll(query),extra) +}catch(e){}}return oldSizzle(query,context,extra,seed) +}; +for(var prop in oldSizzle){Sizzle[prop]=oldSizzle[prop] +}div=null +})() +}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var div=document.createElement("div"); +div.innerHTML="
                  "; +if(div.getElementsByClassName("e").length===0){return +}div.lastChild.className="e"; +if(div.getElementsByClassName("e").length===1){return +}Expr.order.splice(1,0,"CLASS"); +Expr.find.CLASS=function(match,context,isXML){if(typeof context.getElementsByClassName!=="undefined"&&!isXML){return context.getElementsByClassName(match[1]) +}}; +div=null +})() +}function dirNodeCheck(dir,cur,doneName,checkSet,nodeCheck,isXML){var sibDir=dir=="previousSibling"&&!isXML; +for(var i=0,l=checkSet.length; +i0){match=elem; +break +}}}elem=elem[dir] +}checkSet[i]=match +}}}var contains=document.compareDocumentPosition?function(a,b){return a.compareDocumentPosition(b)&16 +}:function(a,b){return a!==b&&(a.contains?a.contains(b):true) +}; +var isXML=function(elem){return elem.nodeType===9&&elem.documentElement.nodeName!=="HTML"||!!elem.ownerDocument&&elem.ownerDocument.documentElement.nodeName!=="HTML" +}; +var posProcess=function(selector,context){var tmpSet=[],later="",match,root=context.nodeType?[context]:context; +while((match=Expr.match.PSEUDO.exec(selector))){later+=match[0]; +selector=selector.replace(Expr.match.PSEUDO,"") +}selector=Expr.relative[selector]?selector+"*":selector; +for(var i=0,l=root.length; +i":return">"; +case"&":return"&"; +case"'":return"'"; +case'"':return""" +}return"?" +}return String(value).replace(/[<>&"']/g,replaceChars) +}function __loop__(iter,outputs,fn){var iterOuts=[]; +outputs.push(iterOuts); +if(iter instanceof Array){iter=new ArrayIterator(iter) +}try{while(1){var value=iter.next(); +var itemOuts=[0,0]; +iterOuts.push(itemOuts); +fn.apply(this,[value,itemOuts]) +}}catch(exc){if(exc!=StopIteration){throw exc +}}}var js=fnBlock.join(""); +var r=null; +eval(js); +this.renderMarkup=r +},getVarNames:function(args){if(this.vars){args.push.apply(args,this.vars) +}for(var i=0; +i"'); +this.generateChildMarkup(topBlock,topOuts,blocks,info); +topBlock.push(',""') +},generateChildMarkup:function(topBlock,topOuts,blocks,info){for(var i=0; +i=array.length){throw StopIteration +}return array[index] +} +}function StopIteration(){}FBL.$break=function(){throw StopIteration +}; +var Renderer={renderHTML:function(args,outputs,self){var code=[]; +var markupArgs=[code,this.tag.context,args,outputs]; +markupArgs.push.apply(markupArgs,this.tag.markupArgs); +this.tag.renderMarkup.apply(self?self:this.tag.subject,markupArgs); +return code.join("") +},insertRows:function(args,before,self){this.tag.compile(); +var outputs=[]; +var html=this.renderHTML(args,outputs,self); +var doc=before.ownerDocument; +var div=doc.createElement("div"); +div.innerHTML=""+html+"
                  "; +var tbody=div.firstChild.firstChild; +var parent=before.tagName=="TR"?before.parentNode:before; +var after=before.tagName=="TR"?before.nextSibling:null; +var firstRow=tbody.firstChild,lastRow; +while(tbody.firstChild){lastRow=tbody.firstChild; +if(after){parent.insertBefore(lastRow,after) +}else{parent.appendChild(lastRow) +}}var offset=0; +if(before.tagName=="TR"){var node=firstRow.parentNode.firstChild; +for(; +node&&node!=firstRow; +node=node.nextSibling){++offset +}}var domArgs=[firstRow,this.tag.context,offset]; +domArgs.push.apply(domArgs,this.tag.domArgs); +domArgs.push.apply(domArgs,outputs); +this.tag.renderDOM.apply(self?self:this.tag.subject,domArgs); +return[firstRow,lastRow] +},insertBefore:function(args,before,self){return this.insertNode(args,before.ownerDocument,before,false,self) +},insertAfter:function(args,after,self){return this.insertNode(args,after.ownerDocument,after,true,self) +},insertNode:function(args,doc,element,isAfter,self){if(!args){args={} +}this.tag.compile(); +var outputs=[]; +var html=this.renderHTML(args,outputs,self); +var doc=element.ownerDocument; +if(!womb||womb.ownerDocument!=doc){womb=doc.createElement("div") +}womb.innerHTML=html; +var root=womb.firstChild; +if(isAfter){while(womb.firstChild){if(element.nextSibling){element.parentNode.insertBefore(womb.firstChild,element.nextSibling) +}else{element.parentNode.appendChild(womb.firstChild) +}}}else{while(womb.lastChild){element.parentNode.insertBefore(womb.lastChild,element) +}}var domArgs=[root,this.tag.context,0]; +domArgs.push.apply(domArgs,this.tag.domArgs); +domArgs.push.apply(domArgs,outputs); +this.tag.renderDOM.apply(self?self:this.tag.subject,domArgs); +return root +},replace:function(args,parent,self){this.tag.compile(); +var outputs=[]; +var html=this.renderHTML(args,outputs,self); +var root; +if(parent.nodeType==1){parent.innerHTML=html; +root=parent.firstChild +}else{if(!parent||parent.nodeType!=9){parent=document +}if(!womb||womb.ownerDocument!=parent){womb=parent.createElement("div") +}womb.innerHTML=html; +root=womb.firstChild +}var domArgs=[root,this.tag.context,0]; +domArgs.push.apply(domArgs,this.tag.domArgs); +domArgs.push.apply(domArgs,outputs); +this.tag.renderDOM.apply(self?self:this.tag.subject,domArgs); +return root +},append:function(args,parent,self){this.tag.compile(); +var outputs=[]; +var html=this.renderHTML(args,outputs,self); +if(!womb||womb.ownerDocument!=parent.ownerDocument){womb=parent.ownerDocument.createElement("div") +}womb.innerHTML=html; +var root=womb.firstChild; +while(womb.firstChild){parent.appendChild(womb.firstChild) +}womb=null; +var domArgs=[root,this.tag.context,0]; +domArgs.push.apply(domArgs,this.tag.domArgs); +domArgs.push.apply(domArgs,outputs); +this.tag.renderDOM.apply(self?self:this.tag.subject,domArgs); +return root +}}; +function defineTags(){for(var i=0; +inumPropertiesShown){break +}}if(numProperties>numPropertiesShown){props.push({object:"...",tag:FirebugReps.Caption.tag,name:"",equal:"",delim:""}) +}else{if(props.length>0){props[props.length-1].delim="" +}}}catch(exc){}return props +},fb_1_6_propIterator:function(object,max){max=max||3; +if(!object){return[] +}var props=[]; +var len=0,count=0; +try{for(var name in object){var value; +try{value=object[name] +}catch(exc){continue +}var t=typeof(value); +if(t=="boolean"||t=="number"||(t=="string"&&value)||(t=="object"&&value&&value.toString)){var rep=Firebug.getRep(value); +var tag=rep.shortTag||rep.tag; +if(t=="object"){value=rep.getTitle(value); +tag=rep.titleTag +}count++; +if(count<=max){props.push({tag:tag,name:name,object:value,equal:"=",delim:", "}) +}else{break +}}}if(count>max){props[Math.max(1,max-1)]={object:"more...",tag:FirebugReps.Caption.tag,name:"",equal:"",delim:""} +}else{if(props.length>0){props[props.length-1].delim="" +}}}catch(exc){}return props +},className:"object",supportsObject:function(object,type){return true +}}); +this.Arr=domplate(Firebug.Rep,{tag:OBJECTBOX({_repObject:"$object"},SPAN({"class":"arrayLeftBracket",role:"presentation"},"["),FOR("item","$object|arrayIterator",TAG("$item.tag",{object:"$item.object"}),SPAN({"class":"arrayComma",role:"presentation"},"$item.delim")),SPAN({"class":"arrayRightBracket",role:"presentation"},"]")),shortTag:OBJECTBOX({_repObject:"$object"},SPAN({"class":"arrayLeftBracket",role:"presentation"},"["),FOR("item","$object|shortArrayIterator",TAG("$item.tag",{object:"$item.object"}),SPAN({"class":"arrayComma",role:"presentation"},"$item.delim")),SPAN({"class":"arrayRightBracket"},"]")),arrayIterator:function(array){var items=[]; +for(var i=0; +i3){items.push({object:(array.length-3)+" more...",tag:FirebugReps.Caption.tag,delim:""}) +}return items +},shortPropIterator:this.Obj.propIterator,getItemIndex:function(child){var arrayIndex=0; +for(child=child.previousSibling; +child; +child=child.previousSibling){if(child.repObject){++arrayIndex +}}return arrayIndex +},className:"array",supportsObject:function(object){return this.isArray(object) +},isArray:function(obj){try{if(!obj){return false +}else{if(isIE&&!isFunction(obj)&&typeof obj=="object"&&isFinite(obj.length)&&obj.nodeType!=8){return true +}else{if(isFinite(obj.length)&&isFunction(obj.splice)){return true +}else{if(isFinite(obj.length)&&isFunction(obj.callee)){return true +}else{if(instanceOf(obj,"HTMLCollection")){return true +}else{if(instanceOf(obj,"NodeList")){return true +}else{return false +}}}}}}}catch(exc){if(FBTrace.DBG_ERRORS){FBTrace.sysout("isArray FAILS:",exc); +FBTrace.sysout("isArray Fails on obj",obj) +}}return false +},getTitle:function(object,context){return"["+object.length+"]" +}}); +this.Property=domplate(Firebug.Rep,{supportsObject:function(object){return object instanceof Property +},getRealObject:function(prop,context){return prop.object[prop.name] +},getTitle:function(prop,context){return prop.name +}}); +this.NetFile=domplate(this.Obj,{supportsObject:function(object){return object instanceof Firebug.NetFile +},browseObject:function(file,context){openNewTab(file.href); +return true +},getRealObject:function(file,context){return null +}}); +this.Except=domplate(Firebug.Rep,{tag:OBJECTBOX({_repObject:"$object"},"$object.message"),className:"exception",supportsObject:function(object){return object instanceof ErrorCopy +}}); +this.Element=domplate(Firebug.Rep,{tag:OBJECTLINK("<",SPAN({"class":"nodeTag"},"$object.nodeName|toLowerCase"),FOR("attr","$object|attrIterator"," $attr.nodeName="",SPAN({"class":"nodeValue"},"$attr.nodeValue"),"""),">"),shortTag:OBJECTLINK(SPAN({"class":"$object|getVisible"},SPAN({"class":"selectorTag"},"$object|getSelectorTag"),SPAN({"class":"selectorId"},"$object|getSelectorId"),SPAN({"class":"selectorClass"},"$object|getSelectorClass"),SPAN({"class":"selectorValue"},"$object|getValue"))),getVisible:function(elt){return isVisible(elt)?"":"selectorHidden" +},getSelectorTag:function(elt){return elt.nodeName.toLowerCase() +},getSelectorId:function(elt){return elt.id?"#"+elt.id:"" +},getSelectorClass:function(elt){return elt.className?"."+elt.className.split(" ")[0]:"" +},getValue:function(elt){return""; +var value; +if(elt instanceof HTMLImageElement){value=getFileName(elt.src) +}else{if(elt instanceof HTMLAnchorElement){value=getFileName(elt.href) +}else{if(elt instanceof HTMLInputElement){value=elt.value +}else{if(elt instanceof HTMLFormElement){value=getFileName(elt.action) +}else{if(elt instanceof HTMLScriptElement){value=getFileName(elt.src) +}}}}}return value?" "+cropString(value,20):"" +},attrIterator:function(elt){var attrs=[]; +var idAttr,classAttr; +if(elt.attributes){for(var i=0; +i0 +},hasErrorBreak:function(error){return fbs.hasErrorBreakpoint(error.href,error.lineNo) +},getMessage:function(message){var re=/\[Exception... "(.*?)" nsresult:/; +var m=re.exec(message); +return m?m[1]:message +},getLine:function(error){if(error.category=="js"){if(error.source){return cropString(error.source,80) +}else{if(error.href&&error.href.indexOf("XPCSafeJSObjectWrapper")==-1){return cropString(error.getSourceLine(),80) +}}}},getSourceLink:function(error){var ext=error.category=="css"?"css":"js"; +return error.lineNo?new SourceLink(error.href,error.lineNo,ext):null +},getSourceType:function(error){if(error.source){return"syntax" +}else{if(error.lineNo==1&&getFileExtension(error.href)!="js"){return"none" +}else{if(error.category=="css"){return"none" +}else{if(!error.href||!error.lineNo){return"none" +}else{return"exec" +}}}}},onToggleError:function(event){var target=event.currentTarget; +if(hasClass(event.target,"errorBreak")){this.breakOnThisError(target.repObject) +}else{if(hasClass(event.target,"errorSource")){var panel=Firebug.getElementPanel(event.target); +this.inspectObject(target.repObject,panel.context) +}else{if(hasClass(event.target,"errorTitle")){var traceBox=target.childNodes[1]; +toggleClass(target,"opened"); +event.target.setAttribute("aria-checked",hasClass(target,"opened")); +if(hasClass(target,"opened")){if(target.stackTrace){var node=FirebugReps.StackTrace.tag.append({object:target.stackTrace},traceBox) +}if(Firebug.A11yModel.enabled){var panel=Firebug.getElementPanel(event.target); +dispatch([Firebug.A11yModel],"onLogRowContentCreated",[panel,traceBox]) +}}else{clearNode(traceBox) +}}}}},copyError:function(error){var message=[this.getMessage(error.message),error.href,"Line "+error.lineNo]; +copyToClipboard(message.join("\n")) +},breakOnThisError:function(error){if(this.hasErrorBreak(error)){Firebug.Debugger.clearErrorBreakpoint(error.href,error.lineNo) +}else{Firebug.Debugger.setErrorBreakpoint(error.href,error.lineNo) +}},className:"errorMessage",inspectable:false,supportsObject:function(object){return object instanceof ErrorMessage +},inspectObject:function(error,context){var sourceLink=this.getSourceLink(error); +FirebugReps.SourceLink.inspectObject(sourceLink,context) +},getContextMenuItems:function(error,target,context){var breakOnThisError=this.hasErrorBreak(error); +var items=[{label:"CopyError",command:bindFixed(this.copyError,this,error)}]; +if(error.category=="css"){items.push("-",{label:"BreakOnThisError",type:"checkbox",checked:breakOnThisError,command:bindFixed(this.breakOnThisError,this,error)},optionMenu("BreakOnAllErrors","breakOnErrors")) +}return items +}}); +this.Assert=domplate(Firebug.Rep,{tag:DIV(DIV({"class":"errorTitle"}),DIV({"class":"assertDescription"})),className:"assert",inspectObject:function(error,context){var sourceLink=this.getSourceLink(error); +Firebug.chrome.select(sourceLink) +},getContextMenuItems:function(error,target,context){var breakOnThisError=this.hasErrorBreak(error); +return[{label:"CopyError",command:bindFixed(this.copyError,this,error)},"-",{label:"BreakOnThisError",type:"checkbox",checked:breakOnThisError,command:bindFixed(this.breakOnThisError,this,error)},{label:"BreakOnAllErrors",type:"checkbox",checked:Firebug.breakOnErrors,command:bindFixed(this.breakOnAllErrors,this,error)}] +}}); +this.SourceText=domplate(Firebug.Rep,{tag:DIV(FOR("line","$object|lineIterator",DIV({"class":"sourceRow",role:"presentation"},SPAN({"class":"sourceLine",role:"presentation"},"$line.lineNo"),SPAN({"class":"sourceRowText",role:"presentation"},"$line.text")))),lineIterator:function(sourceText){var maxLineNoChars=(sourceText.lines.length+"").length; +var list=[]; +for(var i=0; +i57)&&event.charCode!=45&&event.charCode!=46){FBL.cancelEvent(event) +}else{this.ignoreNextInput=event.keyCode==8 +}}}},onOverflow:function(){this.updateLayout(false,false,3) +},onKeyDown:function(event){if(event.keyCode>46||event.keyCode==32||event.keyCode==8){this.keyDownPressed=true +}},onInput:function(event){if(isIE){if(event.propertyName!="value"||!isVisible(this.input)||!this.keyDownPressed){return +}this.keyDownPressed=false +}var selectRangeCallback; +if(this.ignoreNextInput){this.ignoreNextInput=false; +this.getAutoCompleter().reset() +}else{if(this.completeAsYouType){selectRangeCallback=this.getAutoCompleter().complete(currentPanel.context,this.input,false) +}else{this.getAutoCompleter().reset() +}}Firebug.Editor.update(); +if(selectRangeCallback){if(isSafari){setTimeout(selectRangeCallback,0) +}else{selectRangeCallback() +}}},onContextMenu:function(event){cancelEvent(event); +var popup=$("fbInlineEditorPopup"); +FBL.eraseNode(popup); +var target=event.target||event.srcElement; +var menu=this.getContextMenuItems(target); +if(menu){for(var i=0; +ithis.textSize.height+3:this.noWrap&&approxTextWidth>maxWidth; +if(wrapped){var style=isIE?this.target.currentStyle:this.target.ownerDocument.defaultView.getComputedStyle(this.target,""); +targetMargin=parseInt(style.marginLeft)+parseInt(style.marginRight); +approxTextWidth=maxWidth-targetMargin; +this.input.style.width="100%"; +this.box.style.width=approxTextWidth+"px" +}else{var charWidth=this.measureInputText("m").width; +if(extraWidth){charWidth*=extraWidth +}var inputWidth=approxTextWidth+charWidth; +if(initial){if(isIE){var xDiff=13; +this.box.style.width=(inputWidth+xDiff)+"px" +}else{this.box.style.width="auto" +}}else{var xDiff=isIE?13:this.box.scrollWidth-this.input.offsetWidth; +this.box.style.width=(inputWidth+xDiff)+"px" +}this.input.style.width=inputWidth+"px" +}this.expander.style.width=approxTextWidth+"px"; +this.expander.style.height=Math.max(this.textSize.height-3,0)+"px" +}if(forceAll){scrollIntoCenterView(this.box,null,true) +}}}); +Firebug.AutoCompleter=function(getExprOffset,getRange,evaluator,selectMode,caseSensitive){var candidates=null; +var originalValue=null; +var originalOffset=-1; +var lastExpr=null; +var lastOffset=-1; +var exprOffset=0; +var lastIndex=0; +var preParsed=null; +var preExpr=null; +var postExpr=null; +this.revert=function(textBox){if(originalOffset!=-1){textBox.value=originalValue; +setSelectionRange(textBox,originalOffset,originalOffset); +this.reset(); +return true +}else{this.reset(); +return false +}}; +this.reset=function(){candidates=null; +originalValue=null; +originalOffset=-1; +lastExpr=null; +lastOffset=0; +exprOffset=0 +}; +this.complete=function(context,textBox,cycle,reverse){var value=textBox.value; +var offset=getInputSelectionStart(textBox); +if(isSafari&&!cycle&&offset>=0){offset++ +}if(!selectMode&&originalOffset!=-1){offset=originalOffset +}if(!candidates||!cycle||offset!=lastOffset){originalOffset=offset; +originalValue=value; +var parseStart=getExprOffset?getExprOffset(value,offset,context):0; +preParsed=value.substr(0,parseStart); +var parsed=value.substr(parseStart); +var range=getRange?getRange(parsed,offset-parseStart,context):null; +if(!range){range={start:0,end:parsed.length-1} +}var expr=parsed.substr(range.start,range.end-range.start+1); +preExpr=parsed.substr(0,range.start); +postExpr=parsed.substr(range.end+1); +exprOffset=parseStart+range.start; +if(!cycle){if(!expr){return +}else{if(lastExpr&&lastExpr.indexOf(expr)!=0){candidates=null +}else{if(lastExpr&&lastExpr.length>=expr.length){candidates=null; +lastExpr=expr; +return +}}}}lastExpr=expr; +lastOffset=offset; +var searchExpr; +if(expr&&offset!=parseStart+range.end+1){if(cycle){offset=range.start; +searchExpr=expr; +expr="" +}else{return +}}var values=evaluator(preExpr,expr,postExpr,context); +if(!values){return +}if(expr){candidates=[]; +if(caseSensitive){for(var i=0; +i=candidates.length){lastIndex=0 +}else{if(lastIndex<0){lastIndex=candidates.length-1 +}}var completion=candidates[lastIndex]; +var preCompletion=expr.substr(0,offset-exprOffset); +var postCompletion=completion.substr(offset-exprOffset); +textBox.value=preParsed+preExpr+preCompletion+postCompletion+postExpr; +var offsetEnd=preParsed.length+preExpr.length+completion.length; +return function(){if(selectMode){setSelectionRange(textBox,offset,offsetEnd) +}else{setSelectionRange(textBox,offsetEnd,offsetEnd) +}} +} +}; +var getDefaultEditor=function getDefaultEditor(panel){if(!defaultEditor){var doc=panel.document; +defaultEditor=new Firebug.InlineEditor(doc) +}return defaultEditor +}; +var getOutsider=function getOutsider(element,group,stepper){var parentGroup=getAncestorByClass(group.parentNode,"editGroup"); +var next; +do{next=stepper(next||element) +}while(isAncestor(next,group)||isGroupInsert(next,parentGroup)); +return next +}; +var isGroupInsert=function isGroupInsert(next,group){return(!group||isAncestor(next,group))&&(hasClass(next,"insertBefore")||hasClass(next,"insertAfter")) +}; +var getNextOutsider=function getNextOutsider(element,group){return getOutsider(element,group,bind(getNextByClass,FBL,"editable")) +}; +var getPreviousOutsider=function getPreviousOutsider(element,group){return getOutsider(element,group,bind(getPreviousByClass,FBL,"editable")) +}; +var getInlineParent=function getInlineParent(element){var lastInline=element; +for(; +element; +element=element.parentNode){var s=isIE?element.currentStyle:element.ownerDocument.defaultView.getComputedStyle(element,""); +if(s.display!="inline"){return lastInline +}else{lastInline=element +}}return null +}; +var insertTab=function insertTab(){insertTextIntoElement(currentEditor.input,Firebug.Editor.tabCharacter) +}; +Firebug.registerModule(Firebug.Editor) +}}); +FBL.ns(function(){with(FBL){var ElementCache=Firebug.Lite.Cache.Element; +var inspectorTS,inspectorTimer,isInspecting; +Firebug.Inspector={create:function(){offlineFragment=Env.browser.document.createDocumentFragment(); +createBoxModelInspector(); +createOutlineInspector() +},destroy:function(){destroyBoxModelInspector(); +destroyOutlineInspector(); +offlineFragment=null +},toggleInspect:function(){if(isInspecting){this.stopInspecting() +}else{Firebug.chrome.inspectButton.changeState("pressed"); +this.startInspecting() +}},startInspecting:function(){isInspecting=true; +Firebug.chrome.selectPanel("HTML"); +createInspectorFrame(); +var size=Firebug.browser.getWindowScrollSize(); +fbInspectFrame.style.width=size.width+"px"; +fbInspectFrame.style.height=size.height+"px"; +addEvent(fbInspectFrame,"mousemove",Firebug.Inspector.onInspecting); +addEvent(fbInspectFrame,"mousedown",Firebug.Inspector.onInspectingClick) +},stopInspecting:function(){isInspecting=false; +if(outlineVisible){this.hideOutline() +}removeEvent(fbInspectFrame,"mousemove",Firebug.Inspector.onInspecting); +removeEvent(fbInspectFrame,"mousedown",Firebug.Inspector.onInspectingClick); +destroyInspectorFrame(); +Firebug.chrome.inspectButton.restore(); +if(Firebug.chrome.type=="popup"){Firebug.chrome.node.focus() +}},onInspectingClick:function(e){fbInspectFrame.style.display="none"; +var targ=Firebug.browser.getElementFromPoint(e.clientX,e.clientY); +fbInspectFrame.style.display="block"; +var id=targ.id; +if(id&&/^fbOutline\w$/.test(id)){return +}if(id=="FirebugUI"){return +}while(targ.nodeType!=1){targ=targ.parentNode +}Firebug.Inspector.stopInspecting() +},onInspecting:function(e){if(new Date().getTime()-lastInspecting>30){fbInspectFrame.style.display="none"; +var targ=Firebug.browser.getElementFromPoint(e.clientX,e.clientY); +fbInspectFrame.style.display="block"; +var id=targ.id; +if(id&&/^fbOutline\w$/.test(id)){return +}if(id=="FirebugUI"){return +}while(targ.nodeType!=1){targ=targ.parentNode +}if(targ.nodeName.toLowerCase()=="body"){return +}Firebug.Inspector.drawOutline(targ); +if(ElementCache(targ)){var target=""+ElementCache.key(targ); +var lazySelect=function(){inspectorTS=new Date().getTime(); +Firebug.HTML.selectTreeNode(""+ElementCache.key(targ)) +}; +if(inspectorTimer){clearTimeout(inspectorTimer); +inspectorTimer=null +}if(new Date().getTime()-inspectorTS>200){setTimeout(lazySelect,0) +}else{inspectorTimer=setTimeout(lazySelect,300) +}}lastInspecting=new Date().getTime() +}},onInspectingBody:function(e){if(new Date().getTime()-lastInspecting>30){var targ=e.target; +var id=targ.id; +if(id&&/^fbOutline\w$/.test(id)){return +}if(id=="FirebugUI"){return +}while(targ.nodeType!=1){targ=targ.parentNode +}if(targ.nodeName.toLowerCase()=="body"){return +}Firebug.Inspector.drawOutline(targ); +if(ElementCache.has(targ)){FBL.Firebug.HTML.selectTreeNode(""+ElementCache.key(targ)) +}lastInspecting=new Date().getTime() +}},drawOutline:function(el){var border=2; +var scrollbarSize=17; +var windowSize=Firebug.browser.getWindowSize(); +var scrollSize=Firebug.browser.getWindowScrollSize(); +var scrollPosition=Firebug.browser.getWindowScrollPosition(); +var box=Firebug.browser.getElementBox(el); +var top=box.top; +var left=box.left; +var height=box.height; +var width=box.width; +var freeHorizontalSpace=scrollPosition.left+windowSize.width-left-width-(!isIE&&scrollSize.height>windowSize.height?scrollbarSize:0); +var freeVerticalSpace=scrollPosition.top+windowSize.height-top-height-(!isIE&&scrollSize.width>windowSize.width?scrollbarSize:0); +var numVerticalBorders=freeVerticalSpace>0?2:1; +var o=outlineElements; +var style; +style=o.fbOutlineT.style; +style.top=top-border+"px"; +style.left=left+"px"; +style.height=border+"px"; +style.width=width+"px"; +style=o.fbOutlineL.style; +style.top=top-border+"px"; +style.left=left-border+"px"; +style.height=height+numVerticalBorders*border+"px"; +style.width=border+"px"; +style=o.fbOutlineB.style; +if(freeVerticalSpace>0){style.top=top+height+"px"; +style.left=left+"px"; +style.width=width+"px" +}else{style.top=-2*border+"px"; +style.left=-2*border+"px"; +style.width=border+"px" +}style=o.fbOutlineR.style; +if(freeHorizontalSpace>0){style.top=top-border+"px"; +style.left=left+width+"px"; +style.height=height+numVerticalBorders*border+"px"; +style.width=(freeHorizontalSpacescrollPosition.top+windowSize.height-offsetHeight||box.left>scrollPosition.left+windowSize.width||scrollPosition.top>box.top+box.height||scrollPosition.left>box.left+box.width){return +}var top=box.top; +var left=box.left; +var height=box.height; +var width=box.width; +var margin=Firebug.browser.getMeasurementBox(el,"margin"); +var padding=Firebug.browser.getMeasurementBox(el,"padding"); +var border=Firebug.browser.getMeasurementBox(el,"border"); +boxModelStyle.top=top-margin.top+"px"; +boxModelStyle.left=left-margin.left+"px"; +boxModelStyle.height=height+margin.top+margin.bottom+"px"; +boxModelStyle.width=width+margin.left+margin.right+"px"; +boxBorderStyle.top=margin.top+"px"; +boxBorderStyle.left=margin.left+"px"; +boxBorderStyle.height=height+"px"; +boxBorderStyle.width=width+"px"; +boxPaddingStyle.top=margin.top+border.top+"px"; +boxPaddingStyle.left=margin.left+border.left+"px"; +boxPaddingStyle.height=height-border.top-border.bottom+"px"; +boxPaddingStyle.width=width-border.left-border.right+"px"; +boxContentStyle.top=margin.top+border.top+padding.top+"px"; +boxContentStyle.left=margin.left+border.left+padding.left+"px"; +boxContentStyle.height=height-border.top-padding.top-padding.bottom-border.bottom+"px"; +boxContentStyle.width=width-border.left-padding.left-padding.right-border.right+"px"; +if(!boxModelVisible){this.showBoxModel() +}},hideBoxModel:function(){if(!boxModelVisible){return +}offlineFragment.appendChild(boxModel); +boxModelVisible=false +},showBoxModel:function(){if(boxModelVisible){return +}if(outlineVisible){this.hideOutline() +}Firebug.browser.document.getElementsByTagName("body")[0].appendChild(boxModel); +boxModelVisible=true +}}; +var offlineFragment=null; +var boxModelVisible=false; +var boxModel,boxModelStyle,boxMargin,boxMarginStyle,boxBorder,boxBorderStyle,boxPadding,boxPaddingStyle,boxContent,boxContentStyle; +var resetStyle="margin:0; padding:0; border:0; position:absolute; overflow:hidden; display:block;"; +var offscreenStyle=resetStyle+"top:-1234px; left:-1234px;"; +var inspectStyle=resetStyle+"z-index: 2147483500;"; +var inspectFrameStyle=resetStyle+"z-index: 2147483550; top:0; left:0; background:url("+Env.Location.skinDir+"pixel_transparent.gif);"; +var inspectModelOpacity=isIE?"filter:alpha(opacity=80);":"opacity:0.8;"; +var inspectModelStyle=inspectStyle+inspectModelOpacity; +var inspectMarginStyle=inspectStyle+"background: #EDFF64; height:100%; width:100%;"; +var inspectBorderStyle=inspectStyle+"background: #666;"; +var inspectPaddingStyle=inspectStyle+"background: SlateBlue;"; +var inspectContentStyle=inspectStyle+"background: SkyBlue;"; +var outlineStyle={fbHorizontalLine:"background: #3875D7;height: 2px;",fbVerticalLine:"background: #3875D7;width: 2px;"}; +var lastInspecting=0; +var fbInspectFrame=null; +var outlineVisible=false; +var outlineElements={}; +var outline={fbOutlineT:"fbHorizontalLine",fbOutlineL:"fbVerticalLine",fbOutlineB:"fbHorizontalLine",fbOutlineR:"fbVerticalLine"}; +var getInspectingTarget=function(){}; +var createInspectorFrame=function createInspectorFrame(){fbInspectFrame=createGlobalElement("div"); +fbInspectFrame.id="fbInspectFrame"; +fbInspectFrame.firebugIgnore=true; +fbInspectFrame.style.cssText=inspectFrameStyle; +Firebug.browser.document.getElementsByTagName("body")[0].appendChild(fbInspectFrame) +}; +var destroyInspectorFrame=function destroyInspectorFrame(){if(fbInspectFrame){Firebug.browser.document.getElementsByTagName("body")[0].removeChild(fbInspectFrame); +fbInspectFrame=null +}}; +var createOutlineInspector=function createOutlineInspector(){for(var name in outline){var el=outlineElements[name]=createGlobalElement("div"); +el.id=name; +el.firebugIgnore=true; +el.style.cssText=inspectStyle+outlineStyle[outline[name]]; +offlineFragment.appendChild(el) +}}; +var destroyOutlineInspector=function destroyOutlineInspector(){for(var name in outline){var el=outlineElements[name]; +el.parentNode.removeChild(el) +}}; +var createBoxModelInspector=function createBoxModelInspector(){boxModel=createGlobalElement("div"); +boxModel.id="fbBoxModel"; +boxModel.firebugIgnore=true; +boxModelStyle=boxModel.style; +boxModelStyle.cssText=inspectModelStyle; +boxMargin=createGlobalElement("div"); +boxMargin.id="fbBoxMargin"; +boxMarginStyle=boxMargin.style; +boxMarginStyle.cssText=inspectMarginStyle; +boxModel.appendChild(boxMargin); +boxBorder=createGlobalElement("div"); +boxBorder.id="fbBoxBorder"; +boxBorderStyle=boxBorder.style; +boxBorderStyle.cssText=inspectBorderStyle; +boxModel.appendChild(boxBorder); +boxPadding=createGlobalElement("div"); +boxPadding.id="fbBoxPadding"; +boxPaddingStyle=boxPadding.style; +boxPaddingStyle.cssText=inspectPaddingStyle; +boxModel.appendChild(boxPadding); +boxContent=createGlobalElement("div"); +boxContent.id="fbBoxContent"; +boxContentStyle=boxContent.style; +boxContentStyle.cssText=inspectContentStyle; +boxModel.appendChild(boxContent); +offlineFragment.appendChild(boxModel) +}; +var destroyBoxModelInspector=function destroyBoxModelInspector(){boxModel.parentNode.removeChild(boxModel) +} +}}); +FBL.ns(function(){with(FBL){var consoleQueue=[]; +var lastHighlightedObject; +var FirebugContext=Env.browser; +var maxQueueRequests=500; +Firebug.ConsoleBase={log:function(object,context,className,rep,noThrottle,sourceLink){return this.logRow(appendObject,object,context,className,rep,sourceLink,noThrottle) +},logFormatted:function(objects,context,className,noThrottle,sourceLink){return this.logRow(appendFormatted,objects,context,className,null,sourceLink,noThrottle) +},openGroup:function(objects,context,className,rep,noThrottle,sourceLink,noPush){return this.logRow(appendOpenGroup,objects,context,className,rep,sourceLink,noThrottle) +},closeGroup:function(context,noThrottle){return this.logRow(appendCloseGroup,null,context,null,null,null,noThrottle,true) +},logRow:function(appender,objects,context,className,rep,sourceLink,noThrottle,noRow){noThrottle=true; +if(!context){context=FirebugContext +}if(FBTrace.DBG_ERRORS&&!context){FBTrace.sysout("Console.logRow has no context, skipping objects",objects) +}if(!context){return +}if(noThrottle||!context){var panel=this.getPanel(context); +if(panel){var row=panel.append(appender,objects,className,rep,sourceLink,noRow); +var container=panel.panelNode; +return row +}else{consoleQueue.push([appender,objects,context,className,rep,sourceLink,noThrottle,noRow]) +}}else{if(!context.throttle){return +}var args=[appender,objects,context,className,rep,sourceLink,true,noRow]; +context.throttle(this.logRow,this,args) +}},appendFormatted:function(args,row,context){if(!context){context=FirebugContext +}var panel=this.getPanel(context); +panel.appendFormatted(args,row) +},clear:function(context){if(!context){context=Firebug.context +}var panel=this.getPanel(context,true); +if(panel){panel.clear() +}},getPanel:function(context,noCreate){return Firebug.chrome?Firebug.chrome.getPanel("Console"):null +}}; +var ActivableConsole=extend(Firebug.ConsoleBase,{isAlwaysEnabled:function(){return true +}}); +Firebug.Console=Firebug.Console=extend(ActivableConsole,{dispatchName:"console",error:function(){Firebug.Console.logFormatted(arguments,Firebug.browser,"error") +},flush:function(){dispatch(this.fbListeners,"flush",[]); +for(var i=0,length=consoleQueue.length; +iobjects.length){format=""; +objIndex=-1; +parts.length=0; +break +}}}for(var i=0; +i1){traceRecursion--; +return +}var frames=[]; +for(var fn=arguments.callee.caller.caller; +fn; +fn=fn.caller){if(wasVisited(fn)){break +}var args=[]; +for(var i=0,l=fn.arguments.length; +i1){objects=[errorObject]; +for(var i=1; +i0)){var oldest=frames.length-1; +for(var i=0; +i0&&commandHistory.length>0){this.element.value=commandHistory[--commandPointer] +}},nextCommand:function(){var element=this.element; +var limit=commandHistory.length-1; +var i=commandPointer; +if(i=0&&i',msg,"",'"] +},onKeyDown:function(e){e=e||event; +var code=e.keyCode; +if(code!=9&&code!=16&&code!=17&&code!=18){isAutoCompleting=false +}if(code==13){this.enter(); +this.clear() +}else{if(code==27){setTimeout(this.clear,0) +}else{if(code==38){this.prevCommand() +}else{if(code==40){this.nextCommand() +}else{if(code==9){this.autocomplete(e.shiftKey) +}else{return +}}}}}cancelEvent(e,true); +return false +},onMultiLineKeyDown:function(e){e=e||event; +var code=e.keyCode; +if(code==13&&e.ctrlKey){this.enter() +}}}); +Firebug.registerModule(Firebug.CommandLine); +function getExpressionOffset(command){var bracketCount=0; +var start=command.length-1; +for(; +start>=0; +--start){var c=command[start]; +if((c==","||c==";"||c==" ")&&!bracketCount){break +}if(reOpenBracket.test(c)){if(bracketCount){--bracketCount +}else{break +}}else{if(reCloseBracket.test(c)){++bracketCount +}}}return start+1 +}var CommandLineAPI={$:function(id){return Firebug.browser.document.getElementById(id) +},$$:function(selector,context){context=context||Firebug.browser.document; +return Firebug.Selector?Firebug.Selector(selector,context):Firebug.Console.error("Firebug.Selector module not loaded.") +},$0:null,$1:null,dir:function(o){Firebug.Console.log(o,Firebug.context,"dir",Firebug.DOMPanel.DirTable) +},dirxml:function(o){if(instanceOf(o,"Window")){o=o.document.documentElement +}else{if(instanceOf(o,"Document")){o=o.documentElement +}}var div=Firebug.Console.log(o,Firebug.context,"dirxml"); +var html=[]; +Firebug.Reps.appendNode(o,html); +div.innerHTML=html.join("") +}}; +var defineCommandLineAPI=function defineCommandLineAPI(){Firebug.CommandLine.API={}; +for(var m in CommandLineAPI){if(!Env.browser.window[m]){Firebug.CommandLine.API[m]=CommandLineAPI[m] +}}var stack=FirebugChrome.htmlSelectionStack; +if(stack){Firebug.CommandLine.API.$0=stack[0]; +Firebug.CommandLine.API.$1=stack[1] +}} +}}); +FBL.ns(function(){with(FBL){if(Env.Options.disableXHRListener){return +}var XHRSpy=function(){this.requestHeaders=[]; +this.responseHeaders=[] +}; +XHRSpy.prototype={method:null,url:null,async:null,xhrRequest:null,href:null,loaded:false,logRow:null,responseText:null,requestHeaders:null,responseHeaders:null,sourceLink:null,getURL:function(){return this.href +}}; +var XMLHttpRequestWrapper=function(activeXObject){var xhrRequest=typeof activeXObject!="undefined"?activeXObject:new _XMLHttpRequest(),spy=new XHRSpy(),self=this,reqType,reqUrl,reqStartTS; +var updateSelfPropertiesIgnore={abort:1,channel:1,getAllResponseHeaders:1,getInterface:1,getResponseHeader:1,mozBackgroundRequest:1,multipart:1,onreadystatechange:1,open:1,send:1,setRequestHeader:1}; +var updateSelfProperties=function(){if(supportsXHRIterator){for(var propName in xhrRequest){if(propName in updateSelfPropertiesIgnore){continue +}try{var propValue=xhrRequest[propName]; +if(propValue&&!isFunction(propValue)){self[propName]=propValue +}}catch(E){}}}else{if(xhrRequest.readyState==4){self.status=xhrRequest.status; +self.statusText=xhrRequest.statusText; +self.responseText=xhrRequest.responseText; +self.responseXML=xhrRequest.responseXML +}}}; +var updateXHRPropertiesIgnore={channel:1,onreadystatechange:1,readyState:1,responseBody:1,responseText:1,responseXML:1,status:1,statusText:1,upload:1}; +var updateXHRProperties=function(){for(var propName in self){if(propName in updateXHRPropertiesIgnore){continue +}try{var propValue=self[propName]; +if(propValue&&!xhrRequest[propName]){xhrRequest[propName]=propValue +}}catch(E){}}}; +var logXHR=function(){var row=Firebug.Console.log(spy,null,"spy",Firebug.Spy.XHR); +if(row){setClass(row,"loading"); +spy.logRow=row +}}; +var finishXHR=function(){var duration=new Date().getTime()-reqStartTS; +var success=xhrRequest.status==200; +var responseHeadersText=xhrRequest.getAllResponseHeaders(); +var responses=responseHeadersText?responseHeadersText.split(/[\n\r]/):[]; +var reHeader=/^(\S+):\s*(.*)/; +for(var i=0,l=responses.length; +i0; +return this +}; +var _ActiveXObject; +var isIE6=/msie 6/i.test(navigator.appVersion); +if(isIE6){_ActiveXObject=window.ActiveXObject; +var xhrObjects=" MSXML2.XMLHTTP.5.0 MSXML2.XMLHTTP.4.0 MSXML2.XMLHTTP.3.0 MSXML2.XMLHTTP Microsoft.XMLHTTP "; +window.ActiveXObject=function(name){var error=null; +try{var activeXObject=new _ActiveXObject(name) +}catch(e){error=e +}finally{if(!error){if(xhrObjects.indexOf(" "+name+" ")!=-1){return new XMLHttpRequestWrapper(activeXObject) +}else{return activeXObject +}}else{throw error.message +}}} +}if(!isIE6){var _XMLHttpRequest=XMLHttpRequest; +window.XMLHttpRequest=function(){return new XMLHttpRequestWrapper() +} +}}}); +FBL.ns(function(){with(FBL){var reIgnore=/about:|javascript:|resource:|chrome:|jar:/; +var layoutInterval=300; +var indentWidth=18; +var cacheSession=null; +var contexts=new Array(); +var panelName="net"; +var maxQueueRequests=500; +var activeRequests=[]; +var mimeExtensionMap={txt:"text/plain",html:"text/html",htm:"text/html",xhtml:"text/html",xml:"text/xml",css:"text/css",js:"application/x-javascript",jss:"application/x-javascript",jpg:"image/jpg",jpeg:"image/jpeg",gif:"image/gif",png:"image/png",bmp:"image/bmp",swf:"application/x-shockwave-flash",flv:"video/x-flv"}; +var fileCategories={"undefined":1,html:1,css:1,js:1,xhr:1,image:1,flash:1,txt:1,bin:1}; +var textFileCategories={txt:1,html:1,xhr:1,css:1,js:1}; +var binaryFileCategories={bin:1,flash:1}; +var mimeCategoryMap={"text/plain":"txt","application/octet-stream":"bin","text/html":"html","text/xml":"html","text/css":"css","application/x-javascript":"js","text/javascript":"js","application/javascript":"js","image/jpeg":"image","image/jpg":"image","image/gif":"image","image/png":"image","image/bmp":"image","application/x-shockwave-flash":"flash","video/x-flv":"flash"}; +var binaryCategoryMap={image:1,flash:1}; +Firebug.NetMonitor=extend(Firebug.ActivableModule,{dispatchName:"netMonitor",clear:function(context){var panel=context.getPanel(panelName,true); +if(panel){panel.clear() +}},initialize:function(){return; +this.panelName=panelName; +Firebug.ActivableModule.initialize.apply(this,arguments); +if(Firebug.TraceModule){Firebug.TraceModule.addListener(this.TraceListener) +}NetHttpObserver.registerObserver(); +NetHttpActivityObserver.registerObserver(); +Firebug.Debugger.addListener(this.DebuggerListener) +},shutdown:function(){return; +prefs.removeObserver(Firebug.prefDomain,this,false); +if(Firebug.TraceModule){Firebug.TraceModule.removeListener(this.TraceListener) +}NetHttpObserver.unregisterObserver(); +NetHttpActivityObserver.unregisterObserver(); +Firebug.Debugger.removeListener(this.DebuggerListener) +}}); +Firebug.NetMonitor.NetInfoBody=domplate(Firebug.Rep,new Firebug.Listener(),{tag:DIV({"class":"netInfoBody",_repObject:"$file"},TAG("$infoTabs",{file:"$file"}),TAG("$infoBodies",{file:"$file"})),infoTabs:DIV({"class":"netInfoTabs focusRow subFocusRow",role:"tablist"},A({"class":"netInfoParamsTab netInfoTab a11yFocus",onclick:"$onClickTab",role:"tab",view:"Params",$collapsed:"$file|hideParams"},$STR("URLParameters")),A({"class":"netInfoHeadersTab netInfoTab a11yFocus",onclick:"$onClickTab",role:"tab",view:"Headers"},$STR("Headers")),A({"class":"netInfoPostTab netInfoTab a11yFocus",onclick:"$onClickTab",role:"tab",view:"Post",$collapsed:"$file|hidePost"},$STR("Post")),A({"class":"netInfoPutTab netInfoTab a11yFocus",onclick:"$onClickTab",role:"tab",view:"Put",$collapsed:"$file|hidePut"},$STR("Put")),A({"class":"netInfoResponseTab netInfoTab a11yFocus",onclick:"$onClickTab",role:"tab",view:"Response",$collapsed:"$file|hideResponse"},$STR("Response")),A({"class":"netInfoCacheTab netInfoTab a11yFocus",onclick:"$onClickTab",role:"tab",view:"Cache",$collapsed:"$file|hideCache"},$STR("Cache")),A({"class":"netInfoHtmlTab netInfoTab a11yFocus",onclick:"$onClickTab",role:"tab",view:"Html",$collapsed:"$file|hideHtml"},$STR("HTML"))),infoBodies:DIV({"class":"netInfoBodies outerFocusRow"},TABLE({"class":"netInfoParamsText netInfoText netInfoParamsTable",role:"tabpanel",cellpadding:0,cellspacing:0},TBODY()),DIV({"class":"netInfoHeadersText netInfoText",role:"tabpanel"}),DIV({"class":"netInfoPostText netInfoText",role:"tabpanel"}),DIV({"class":"netInfoPutText netInfoText",role:"tabpanel"}),PRE({"class":"netInfoResponseText netInfoText",role:"tabpanel"}),DIV({"class":"netInfoCacheText netInfoText",role:"tabpanel"},TABLE({"class":"netInfoCacheTable",cellpadding:0,cellspacing:0,role:"presentation"},TBODY({role:"list","aria-label":$STR("Cache")}))),DIV({"class":"netInfoHtmlText netInfoText",role:"tabpanel"},IFRAME({"class":"netInfoHtmlPreview",role:"document"}))),headerDataTag:FOR("param","$headers",TR({role:"listitem"},TD({"class":"netInfoParamName",role:"presentation"},TAG("$param|getNameTag",{param:"$param"})),TD({"class":"netInfoParamValue",role:"list","aria-label":"$param.name"},FOR("line","$param|getParamValueIterator",CODE({"class":"focusRow subFocusRow",role:"listitem"},"$line"))))),customTab:A({"class":"netInfo$tabId\\Tab netInfoTab",onclick:"$onClickTab",view:"$tabId",role:"tab"},"$tabTitle"),customBody:DIV({"class":"netInfo$tabId\\Text netInfoText",role:"tabpanel"}),nameTag:SPAN("$param|getParamName"),nameWithTooltipTag:SPAN({title:"$param.name"},"$param|getParamName"),getNameTag:function(param){return(this.getParamName(param)==param.name)?this.nameTag:this.nameWithTooltipTag +},getParamName:function(param){var limit=25; +var name=param.name; +if(name.length>limit){name=name.substr(0,limit)+"..." +}return name +},getParamTitle:function(param){var limit=25; +var name=param.name; +if(name.length>limit){return name +}return"" +},hideParams:function(file){return !file.urlParams||!file.urlParams.length +},hidePost:function(file){return file.method.toUpperCase()!="POST" +},hidePut:function(file){return file.method.toUpperCase()!="PUT" +},hideResponse:function(file){return false +},hideCache:function(file){return true; +return !file.cacheEntry +},hideHtml:function(file){return(file.mimeType!="text/html")&&(file.mimeType!="application/xhtml+xml") +},onClickTab:function(event){this.selectTab(event.currentTarget||event.srcElement) +},getParamValueIterator:function(param){return param.value; +return wrapText(param.value,true) +},appendTab:function(netInfoBox,tabId,tabTitle){var args={tabId:tabId,tabTitle:tabTitle}; +this.customTab.append(args,$$(".netInfoTabs",netInfoBox)[0]); +this.customBody.append(args,$$(".netInfoBodies",netInfoBox)[0]) +},selectTabByName:function(netInfoBox,tabName){var tab=getChildByClass(netInfoBox,"netInfoTabs","netInfo"+tabName+"Tab"); +if(tab){this.selectTab(tab) +}},selectTab:function(tab){var view=tab.getAttribute("view"); +var netInfoBox=getAncestorByClass(tab,"netInfoBody"); +var selectedTab=netInfoBox.selectedTab; +if(selectedTab){removeClass(netInfoBox.selectedText,"netInfoTextSelected"); +removeClass(selectedTab,"netInfoTabSelected"); +selectedTab.setAttribute("aria-selected","false") +}var textBodyName="netInfo"+view+"Text"; +selectedTab=netInfoBox.selectedTab=tab; +netInfoBox.selectedText=$$("."+textBodyName,netInfoBox)[0]; +setClass(netInfoBox.selectedText,"netInfoTextSelected"); +setClass(selectedTab,"netInfoTabSelected"); +selectedTab.setAttribute("selected","true"); +selectedTab.setAttribute("aria-selected","true"); +var file=Firebug.getRepObject(netInfoBox); +var context=Firebug.chrome; +this.updateInfo(netInfoBox,file,context) +},updateInfo:function(netInfoBox,file,context){if(FBTrace.DBG_NET){FBTrace.sysout("net.updateInfo; file",file) +}if(!netInfoBox){if(FBTrace.DBG_NET||FBTrace.DBG_ERRORS){FBTrace.sysout("net.updateInfo; ERROR netInfo == null "+file.href,file) +}return +}var tab=netInfoBox.selectedTab; +if(hasClass(tab,"netInfoParamsTab")){if(file.urlParams&&!netInfoBox.urlParamsPresented){netInfoBox.urlParamsPresented=true; +this.insertHeaderRows(netInfoBox,file.urlParams,"Params") +}}else{if(hasClass(tab,"netInfoHeadersTab")){var headersText=$$(".netInfoHeadersText",netInfoBox)[0]; +if(file.responseHeaders&&!netInfoBox.responseHeadersPresented){netInfoBox.responseHeadersPresented=true; +NetInfoHeaders.renderHeaders(headersText,file.responseHeaders,"ResponseHeaders") +}if(file.requestHeaders&&!netInfoBox.requestHeadersPresented){netInfoBox.requestHeadersPresented=true; +NetInfoHeaders.renderHeaders(headersText,file.requestHeaders,"RequestHeaders") +}}else{if(hasClass(tab,"netInfoPostTab")){if(!netInfoBox.postPresented){netInfoBox.postPresented=true; +var postText=$$(".netInfoPostText",netInfoBox)[0]; +NetInfoPostData.render(context,postText,file) +}}else{if(hasClass(tab,"netInfoPutTab")){if(!netInfoBox.putPresented){netInfoBox.putPresented=true; +var putText=$$(".netInfoPutText",netInfoBox)[0]; +NetInfoPostData.render(context,putText,file) +}}else{if(hasClass(tab,"netInfoResponseTab")&&file.loaded&&!netInfoBox.responsePresented){var responseTextBox=$$(".netInfoResponseText",netInfoBox)[0]; +if(file.category=="image"){netInfoBox.responsePresented=true; +var responseImage=netInfoBox.ownerDocument.createElement("img"); +responseImage.src=file.href; +clearNode(responseTextBox); +responseTextBox.appendChild(responseImage,responseTextBox) +}else{this.setResponseText(file,netInfoBox,responseTextBox,context) +}}else{if(hasClass(tab,"netInfoCacheTab")&&file.loaded&&!netInfoBox.cachePresented){var responseTextBox=netInfoBox.getElementsByClassName("netInfoCacheText").item(0); +if(file.cacheEntry){netInfoBox.cachePresented=true; +this.insertHeaderRows(netInfoBox,file.cacheEntry,"Cache") +}}else{if(hasClass(tab,"netInfoHtmlTab")&&file.loaded&&!netInfoBox.htmlPresented){netInfoBox.htmlPresented=true; +var text=Utils.getResponseText(file,context); +var iframe=$$(".netInfoHtmlPreview",netInfoBox)[0]; +var reScript=//gi; +text=text.replace(reScript,""); +iframe.contentWindow.document.write(text); +iframe.contentWindow.document.close() +}}}}}}}dispatch(NetInfoBody.fbListeners,"updateTabBody",[netInfoBox,file,context]) +},setResponseText:function(file,netInfoBox,responseTextBox,context){netInfoBox.responsePresented=true; +if(isIE){responseTextBox.style.whiteSpace="nowrap" +}responseTextBox[typeof responseTextBox.textContent!="undefined"?"textContent":"innerText"]=file.responseText; +return; +var text=Utils.getResponseText(file,context); +var limit=Firebug.netDisplayedResponseLimit+15; +var limitReached=text?(text.length>limit):false; +if(limitReached){text=text.substr(0,limit)+"..." +}if(text){insertWrappedText(text,responseTextBox) +}else{insertWrappedText("",responseTextBox) +}if(limitReached){var object={text:$STR("net.responseSizeLimitMessage"),onClickLink:function(){var panel=context.getPanel("net",true); +panel.openResponseInTab(file) +}}; +Firebug.NetMonitor.ResponseSizeLimit.append(object,responseTextBox) +}netInfoBox.responsePresented=true; +if(FBTrace.DBG_NET){FBTrace.sysout("net.setResponseText; response text updated") +}},insertHeaderRows:function(netInfoBox,headers,tableName,rowName){if(!headers.length){return +}var headersTable=$$(".netInfo"+tableName+"Table",netInfoBox)[0]; +var tbody=getChildByClass(headersTable,"netInfo"+rowName+"Body"); +if(!tbody){tbody=headersTable.firstChild +}var titleRow=getChildByClass(tbody,"netInfo"+rowName+"Title"); +this.headerDataTag.insertRows({headers:headers},titleRow?titleRow:tbody); +removeClass(titleRow,"collapsed") +}}); +var NetInfoBody=Firebug.NetMonitor.NetInfoBody; +Firebug.NetMonitor.NetInfoHeaders=domplate(Firebug.Rep,{tag:DIV({"class":"netInfoHeadersTable",role:"tabpanel"},DIV({"class":"netInfoHeadersGroup netInfoResponseHeadersTitle"},SPAN($STR("ResponseHeaders")),SPAN({"class":"netHeadersViewSource response collapsed",onclick:"$onViewSource",_sourceDisplayed:false,_rowName:"ResponseHeaders"},$STR("net.headers.view source"))),TABLE({cellpadding:0,cellspacing:0},TBODY({"class":"netInfoResponseHeadersBody",role:"list","aria-label":$STR("ResponseHeaders")})),DIV({"class":"netInfoHeadersGroup netInfoRequestHeadersTitle"},SPAN($STR("RequestHeaders")),SPAN({"class":"netHeadersViewSource request collapsed",onclick:"$onViewSource",_sourceDisplayed:false,_rowName:"RequestHeaders"},$STR("net.headers.view source"))),TABLE({cellpadding:0,cellspacing:0},TBODY({"class":"netInfoRequestHeadersBody",role:"list","aria-label":$STR("RequestHeaders")}))),sourceTag:TR({role:"presentation"},TD({colspan:2,role:"presentation"},PRE({"class":"source"}))),onViewSource:function(event){var target=event.target; +var requestHeaders=(target.rowName=="RequestHeaders"); +var netInfoBox=getAncestorByClass(target,"netInfoBody"); +var file=netInfoBox.repObject; +if(target.sourceDisplayed){var headers=requestHeaders?file.requestHeaders:file.responseHeaders; +this.insertHeaderRows(netInfoBox,headers,target.rowName); +target.innerHTML=$STR("net.headers.view source") +}else{var source=requestHeaders?file.requestHeadersText:file.responseHeadersText; +this.insertSource(netInfoBox,source,target.rowName); +target.innerHTML=$STR("net.headers.pretty print") +}target.sourceDisplayed=!target.sourceDisplayed; +cancelEvent(event) +},insertSource:function(netInfoBox,source,rowName){var tbody=$$(".netInfo"+rowName+"Body",netInfoBox)[0]; +var node=this.sourceTag.replace({},tbody); +var sourceNode=$$(".source",node)[0]; +sourceNode.innerHTML=source +},insertHeaderRows:function(netInfoBox,headers,rowName){var headersTable=$$(".netInfoHeadersTable",netInfoBox)[0]; +var tbody=$$(".netInfo"+rowName+"Body",headersTable)[0]; +clearNode(tbody); +if(!headers.length){return +}NetInfoBody.headerDataTag.insertRows({headers:headers},tbody); +var titleRow=getChildByClass(headersTable,"netInfo"+rowName+"Title"); +removeClass(titleRow,"collapsed") +},init:function(parent){var rootNode=this.tag.append({},parent); +var netInfoBox=getAncestorByClass(parent,"netInfoBody"); +var file=netInfoBox.repObject; +var viewSource; +viewSource=$$(".request",rootNode)[0]; +if(file.requestHeadersText){removeClass(viewSource,"collapsed") +}viewSource=$$(".response",rootNode)[0]; +if(file.responseHeadersText){removeClass(viewSource,"collapsed") +}},renderHeaders:function(parent,headers,rowName){if(!parent.firstChild){this.init(parent) +}this.insertHeaderRows(parent,headers,rowName) +}}); +var NetInfoHeaders=Firebug.NetMonitor.NetInfoHeaders; +Firebug.NetMonitor.NetInfoPostData=domplate(Firebug.Rep,{paramsTable:TABLE({"class":"netInfoPostParamsTable",cellpadding:0,cellspacing:0,role:"presentation"},TBODY({role:"list","aria-label":$STR("net.label.Parameters")},TR({"class":"netInfoPostParamsTitle",role:"presentation"},TD({colspan:3,role:"presentation"},DIV({"class":"netInfoPostParams"},$STR("net.label.Parameters"),SPAN({"class":"netInfoPostContentType"},"application/x-www-form-urlencoded")))))),partsTable:TABLE({"class":"netInfoPostPartsTable",cellpadding:0,cellspacing:0,role:"presentation"},TBODY({role:"list","aria-label":$STR("net.label.Parts")},TR({"class":"netInfoPostPartsTitle",role:"presentation"},TD({colspan:2,role:"presentation"},DIV({"class":"netInfoPostParams"},$STR("net.label.Parts"),SPAN({"class":"netInfoPostContentType"},"multipart/form-data")))))),jsonTable:TABLE({"class":"netInfoPostJSONTable",cellpadding:0,cellspacing:0,role:"presentation"},TBODY({role:"list","aria-label":$STR("JSON")},TR({"class":"netInfoPostJSONTitle",role:"presentation"},TD({role:"presentation"},DIV({"class":"netInfoPostParams"},$STR("JSON")))),TR(TD({"class":"netInfoPostJSONBody"})))),xmlTable:TABLE({"class":"netInfoPostXMLTable",cellpadding:0,cellspacing:0,role:"presentation"},TBODY({role:"list","aria-label":$STR("xmlviewer.tab.XML")},TR({"class":"netInfoPostXMLTitle",role:"presentation"},TD({role:"presentation"},DIV({"class":"netInfoPostParams"},$STR("xmlviewer.tab.XML")))),TR(TD({"class":"netInfoPostXMLBody"})))),sourceTable:TABLE({"class":"netInfoPostSourceTable",cellpadding:0,cellspacing:0,role:"presentation"},TBODY({role:"list","aria-label":$STR("net.label.Source")},TR({"class":"netInfoPostSourceTitle",role:"presentation"},TD({colspan:2,role:"presentation"},DIV({"class":"netInfoPostSource"},$STR("net.label.Source")))))),sourceBodyTag:TR({role:"presentation"},TD({colspan:2,role:"presentation"},FOR("line","$param|getParamValueIterator",CODE({"class":"focusRow subFocusRow",role:"listitem"},"$line")))),getParamValueIterator:function(param){return NetInfoBody.getParamValueIterator(param) +},render:function(context,parentNode,file){var spy=getAncestorByClass(parentNode,"spyHead"); +var spyObject=spy.repObject; +var data=spyObject.data; +var contentType=file.mimeType; +if(contentType&&contentType=="application/x-www-form-urlencoded"||data&&data.indexOf("=")!=-1){var params=parseURLEncodedTextArray(data); +if(params){this.insertParameters(parentNode,params) +}}var jsonData={responseText:data}; +if(Firebug.JSONViewerModel.isJSON(contentType,data)){this.insertJSON(parentNode,jsonData,context) +}var postText=data; +if(postText){this.insertSource(parentNode,postText) +}},insertParameters:function(parentNode,params){if(!params||!params.length){return +}var paramTable=this.paramsTable.append({object:{}},parentNode); +var row=$$(".netInfoPostParamsTitle",paramTable)[0]; +var tbody=paramTable.getElementsByTagName("tbody")[0]; +NetInfoBody.headerDataTag.insertRows({headers:params},row) +},insertParts:function(parentNode,data){if(!data.params||!data.params.length){return +}var partsTable=this.partsTable.append({object:{}},parentNode); +var row=$$(".netInfoPostPartsTitle",paramTable)[0]; +NetInfoBody.headerDataTag.insertRows({headers:data.params},row) +},insertJSON:function(parentNode,file,context){var text=file.responseText; +var data=parseJSONString(text); +if(!data){return +}var jsonTable=this.jsonTable.append({},parentNode); +var jsonBody=$$(".netInfoPostJSONBody",jsonTable)[0]; +if(!this.toggles){this.toggles={} +}Firebug.DOMPanel.DirTable.tag.replace({object:data,toggles:this.toggles},jsonBody) +},insertXML:function(parentNode,file,context){var text=Utils.getPostText(file,context); +var jsonTable=this.xmlTable.append(null,parentNode); +var jsonBody=$$(".netInfoPostXMLBody",jsonTable)[0]; +Firebug.XMLViewerModel.insertXML(jsonBody,text) +},insertSource:function(parentNode,text){var sourceTable=this.sourceTable.append({object:{}},parentNode); +var row=$$(".netInfoPostSourceTitle",sourceTable)[0]; +var param={value:[text]}; +this.sourceBodyTag.insertRows({param:param},row) +},parseMultiPartText:function(file,context){var text=Utils.getPostText(file,context); +if(text==undefined){return null +}FBTrace.sysout("net.parseMultiPartText; boundary: ",text); +var boundary=text.match(/\s*boundary=\s*(.*)/)[1]; +var divider="\r\n\r\n"; +var bodyStart=text.indexOf(divider); +var body=text.substr(bodyStart+divider.length); +var postData={}; +postData.mimeType="multipart/form-data"; +postData.params=[]; +var parts=body.split("--"+boundary); +for(var i=0; +i1)?m[1]:"",value:trim(part[1])}) +}return postData +}}); +var NetInfoPostData=Firebug.NetMonitor.NetInfoPostData; +var $STRP=function(a){return a +}; +Firebug.NetMonitor.NetLimit=domplate(Firebug.Rep,{collapsed:true,tableTag:DIV(TABLE({width:"100%",cellpadding:0,cellspacing:0},TBODY())),limitTag:TR({"class":"netRow netLimitRow",$collapsed:"$isCollapsed"},TD({"class":"netCol netLimitCol",colspan:6},TABLE({cellpadding:0,cellspacing:0},TBODY(TR(TD(SPAN({"class":"netLimitLabel"},$STRP("plural.Limit_Exceeded",[0]))),TD({style:"width:100%"}),TD(BUTTON({"class":"netLimitButton",title:"$limitPrefsTitle",onclick:"$onPreferences"},$STR("LimitPrefs"))),TD(" ")))))),isCollapsed:function(){return this.collapsed +},onPreferences:function(event){openNewTab("about:config") +},updateCounter:function(row){removeClass(row,"collapsed"); +var limitLabel=row.getElementsByClassName("netLimitLabel").item(0); +limitLabel.firstChild.nodeValue=$STRP("plural.Limit_Exceeded",[row.limitInfo.totalCount]) +},createTable:function(parent,limitInfo){var table=this.tableTag.replace({},parent); +var row=this.createRow(table.firstChild.firstChild,limitInfo); +return[table,row] +},createRow:function(parent,limitInfo){var row=this.limitTag.insertRows(limitInfo,parent,this)[0]; +row.limitInfo=limitInfo; +return row +},observe:function(subject,topic,data){if(topic!="nsPref:changed"){return +}if(data.indexOf("net.logLimit")!=-1){this.updateMaxLimit() +}},updateMaxLimit:function(){var value=Firebug.getPref(Firebug.prefDomain,"net.logLimit"); +maxQueueRequests=value?value:maxQueueRequests +}}); +var NetLimit=Firebug.NetMonitor.NetLimit; +Firebug.NetMonitor.ResponseSizeLimit=domplate(Firebug.Rep,{tag:DIV({"class":"netInfoResponseSizeLimit"},SPAN("$object.beforeLink"),A({"class":"objectLink",onclick:"$onClickLink"},"$object.linkText"),SPAN("$object.afterLink")),reLink:/^(.*)(.*)<\/a>(.*$)/,append:function(obj,parent){var m=obj.text.match(this.reLink); +return this.tag.append({onClickLink:obj.onClickLink,object:{beforeLink:m[1],linkText:m[2],afterLink:m[3]}},parent,this) +}}); +Firebug.NetMonitor.Utils={findHeader:function(headers,name){if(!headers){return null +}name=name.toLowerCase(); +for(var i=0; +ilimit&&!noLimit){return cropString(file.postText,limit,"\n\n... "+$STR("net.postDataSizeLimitMessage")+" ...\n\n") +}return file.postText +},getResponseText:function(file,context){return(typeof(file.responseText)!="undefined")?file.responseText:context.sourceCache.loadText(file.href,file.method,file) +},isURLEncodedRequest:function(file,context){var text=Utils.getPostText(file,context); +if(text&&text.toLowerCase().indexOf("content-type: application/x-www-form-urlencoded")==0){return true +}var headerValue=Utils.findHeader(file.requestHeaders,"content-type"); +if(headerValue&&headerValue.indexOf("application/x-www-form-urlencoded")==0){return true +}return false +},isMultiPartRequest:function(file,context){var text=Utils.getPostText(file,context); +if(text&&text.toLowerCase().indexOf("content-type: multipart/form-data")==0){return true +}return false +},getMimeType:function(mimeType,uri){if(!mimeType||!(mimeCategoryMap.hasOwnProperty(mimeType))){var ext=getFileExtension(uri); +if(!ext){return mimeType +}else{var extMimeType=mimeExtensionMap[ext.toLowerCase()]; +return extMimeType?extMimeType:mimeType +}}else{return mimeType +}},getDateFromSeconds:function(s){var d=new Date(); +d.setTime(s*1000); +return d +},getHttpHeaders:function(request,file){try{var http=QI(request,Ci.nsIHttpChannel); +file.status=request.responseStatus; +file.method=http.requestMethod; +file.urlParams=parseURLParams(file.href); +file.mimeType=Utils.getMimeType(request.contentType,request.name); +if(!file.responseHeaders&&Firebug.collectHttpHeaders){var requestHeaders=[],responseHeaders=[]; +http.visitRequestHeaders({visitHeader:function(name,value){requestHeaders.push({name:name,value:value}) +}}); +http.visitResponseHeaders({visitHeader:function(name,value){responseHeaders.push({name:name,value:value}) +}}); +file.requestHeaders=requestHeaders; +file.responseHeaders=responseHeaders +}}catch(exc){if(FBTrace.DBG_ERRORS){FBTrace.sysout("net.getHttpHeaders FAILS "+file.href,exc) +}}},isXHR:function(request){try{var callbacks=request.notificationCallbacks; +var xhrRequest=callbacks?callbacks.getInterface(Ci.nsIXMLHttpRequest):null; +if(FBTrace.DBG_NET){FBTrace.sysout("net.isXHR; "+(xhrRequest!=null)+", "+safeGetName(request)) +}return(xhrRequest!=null) +}catch(exc){}return false +},getFileCategory:function(file){if(file.category){if(FBTrace.DBG_NET){FBTrace.sysout("net.getFileCategory; current: "+file.category+" for: "+file.href,file) +}return file.category +}if(file.isXHR){if(FBTrace.DBG_NET){FBTrace.sysout("net.getFileCategory; XHR for: "+file.href,file) +}return file.category="xhr" +}if(!file.mimeType){var ext=getFileExtension(file.href); +if(ext){file.mimeType=mimeExtensionMap[ext.toLowerCase()] +}}if(!file.mimeType){return"" +}var mimeType=file.mimeType; +if(mimeType){mimeType=mimeType.split(";")[0] +}return(file.category=mimeCategoryMap[mimeType]) +}}; +var Utils=Firebug.NetMonitor.Utils; +Firebug.registerModule(Firebug.NetMonitor) +}}); +FBL.ns(function(){with(FBL){var contexts=[]; +Firebug.Spy=extend(Firebug.Module,{dispatchName:"spy",initialize:function(){if(Firebug.TraceModule){Firebug.TraceModule.addListener(this.TraceListener) +}Firebug.Module.initialize.apply(this,arguments) +},shutdown:function(){Firebug.Module.shutdown.apply(this,arguments); +if(Firebug.TraceModule){Firebug.TraceModule.removeListener(this.TraceListener) +}},initContext:function(context){context.spies=[]; +if(Firebug.showXMLHttpRequests&&Firebug.Console.isAlwaysEnabled()){this.attachObserver(context,context.window) +}if(FBTrace.DBG_SPY){FBTrace.sysout("spy.initContext "+contexts.length+" ",context.getName()) +}},destroyContext:function(context){this.detachObserver(context,null); +if(FBTrace.DBG_SPY&&context.spies.length){FBTrace.sysout("spy.destroyContext; ERROR There are leaking Spies ("+context.spies.length+") "+context.getName()) +}delete context.spies; +if(FBTrace.DBG_SPY){FBTrace.sysout("spy.destroyContext "+contexts.length+" ",context.getName()) +}},watchWindow:function(context,win){if(Firebug.showXMLHttpRequests&&Firebug.Console.isAlwaysEnabled()){this.attachObserver(context,win) +}},unwatchWindow:function(context,win){try{this.detachObserver(context,win) +}catch(ex){ERROR(ex) +}},updateOption:function(name,value){if(name=="showXMLHttpRequests"){var tach=value?this.attachObserver:this.detachObserver; +for(var i=0; +i\s*/,""); +var div=parentNode.ownerDocument.createElement("div"); +div.innerHTML=xmlText; +var root=div.getElementsByTagName("*")[0]; +if(FBTrace.DBG_XMLVIEWER){FBTrace.sysout("xmlviewer.updateTabBody; XML response parsed",doc) +}var html=[]; +Firebug.Reps.appendNode(root,html); +parentNode.innerHTML=html.join("") +}}); +Firebug.XMLViewerModel.ParseError=domplate(Firebug.Rep,{tag:DIV({"class":"xmlInfoError"},DIV({"class":"xmlInfoErrorMsg"},"$error.message"),PRE({"class":"xmlInfoErrorSource"},"$error|getSource")),getSource:function(error){var parts=error.source.split("\n"); +if(parts.length!=2){return error.source +}var limit=50; +var column=parts[1].length; +if(column>=limit){parts[0]="..."+parts[0].substr(column-limit); +parts[1]="..."+parts[1].substr(column-limit) +}if(parts[0].length>80){parts[0]=parts[0].substr(0,80)+"..." +}return parts.join("\n") +}}); +Firebug.registerModule(Firebug.XMLViewerModel) +}}); +FBL.ns(function(){with(FBL){var ElementCache=Firebug.Lite.Cache.Element; +var cacheID=Firebug.Lite.Cache.ID; +var ignoreHTMLProps={sizcache:1,sizset:1}; +ignoreHTMLProps[cacheID]=1; +Firebug.HTML=extend(Firebug.Module,{appendTreeNode:function(nodeArray,html){var reTrim=/^\s+|\s+$/g; +if(!nodeArray.length){nodeArray=[nodeArray] +}for(var n=0,node; +node=nodeArray[n]; +n++){if(node.nodeType==1){if(Firebug.ignoreFirebugElements&&node.firebugIgnore){continue +}var uid=ElementCache(node); +var child=node.childNodes; +var childLength=child.length; +var nodeName=node.nodeName.toLowerCase(); +var nodeVisible=isVisible(node); +var hasSingleTextChild=childLength==1&&node.firstChild.nodeType==3&&nodeName!="script"&&nodeName!="style"; +var nodeControl=!hasSingleTextChild&&childLength>0?('
                  '):""; +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',name,'="',escapeHTML(value),""") +}if(hasSingleTextChild){var value=child[0].nodeValue.replace(reTrim,""); +if(value){html.push('>',escapeHTML(value),'</',nodeName,">
                  ") +}else{html.push("/>
                  ") +}}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; +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; +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); +if(fbPanel1){fbPanel1.scrollTop=Math.round(node.offsetTop-fbPanel1.clientHeight/2) +}}}); +Firebug.registerModule(Firebug.HTML); +function HTMLPanel(){}HTMLPanel.prototype=extend(Firebug.Panel,{name:"HTML",title:"HTML",options:{hasSidePanel:true,isPreRendered:true,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.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.HTML.selectTreeNode(ElementCache(Firebug.browser.document.body)) +}addEvent(fbPanel1,"mousemove",Firebug.HTML.onListMouseMove); +addEvent($("fbContent"),"mouseout",Firebug.HTML.onListMouseMove); +addEvent(Firebug.chrome.node,"mouseout",Firebug.HTML.onListMouseMove) +},shutdown:function(){removeEvent(fbPanel1,"mousemove",Firebug.HTML.onListMouseMove); +removeEvent($("fbContent"),"mouseout",Firebug.HTML.onListMouseMove); +removeEvent(Firebug.chrome.node,"mouseout",Firebug.HTML.onListMouseMove); +removeEvent(this.panelNode,"click",Firebug.HTML.onTreeClick); +fbPanel1=null; +Firebug.Panel.shutdown.apply(this,arguments) +},reattach:function(){if(FirebugChrome.selectedHTMLElementId){Firebug.HTML.selectTreeNode(FirebugChrome.selectedHTMLElementId) +}},updateSelection:function(object){var id=ElementCache(object); +if(id){Firebug.HTML.selectTreeNode(id) +}}}); +Firebug.registerPanel(HTMLPanel); +var formatStyles=function(styles){return isIE?styles.replace(/([^\s]+)\s*:/g,function(m,g){return g.toLowerCase()+":" +}):styles +}; +var selectedElement=null; +var fbPanel1=null; +var selectedSidePanelTS,selectedSidePanelTimer; +var selectElement=function selectElement(e){if(e!=selectedElement){if(selectedElement){selectedElement.className="objectBox-element" +}e.className=e.className+" selectedElement"; +if(FBL.isFirefox){e.style.MozBorderRadius="2px" +}else{if(FBL.isSafari){e.style.WebkitBorderRadius="2px" +}}selectedElement=e; +FirebugChrome.selectedHTMLElementId=e.id; +var target=ElementCache.get(e.id); +var selectedSidePanel=Firebug.chrome.getPanel("HTML").sidePanelBar.selectedPanel; +var stack=FirebugChrome.htmlSelectionStack; +stack.unshift(target); +if(stack.length>2){stack.pop() +}var lazySelect=function(){selectedSidePanelTS=new Date().getTime(); +selectedSidePanel.select(target,true) +}; +if(selectedSidePanelTimer){clearTimeout(selectedSidePanelTimer); +selectedSidePanelTimer=null +}if(new Date().getTime()-selectedSidePanelTS>100){setTimeout(lazySelect,0) +}else{selectedSidePanelTimer=setTimeout(lazySelect,150) +}}}; +Firebug.HTML.onTreeClick=function(e){e=e||event; +var targ; +if(e.target){targ=e.target +}else{if(e.srcElement){targ=e.srcElement +}}if(targ.nodeType==3){targ=targ.parentNode +}if(targ.className.indexOf("nodeControl")!=-1||targ.className=="nodeTag"){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; +if(control.className.indexOf(" nodeMaximized")!=-1){FBL.Firebug.HTML.removeTreeChildren(treeNode) +}else{FBL.Firebug.HTML.appendTreeChildren(treeNode) +}}else{if(targ.className=="nodeValue"||targ.className=="nodeName"){}}}; +function onListMouseOut(e){e=e||event||window; +var targ; +if(e.target){targ=e.target +}else{if(e.srcElement){targ=e.srcElement +}}if(targ.nodeType==3){targ=targ.parentNode +}if(hasClass(targ,"fbPanel")){FBL.Firebug.Inspector.hideBoxModel(); +hoverElement=null +}}var hoverElement=null; +var hoverElementTS=0; +Firebug.HTML.onListMouseMove=function onListMouseMove(e){try{e=e||event||window; +var targ; +if(e.target){targ=e.target +}else{if(e.srcElement){targ=e.srcElement +}}if(targ.nodeType==3){targ=targ.parentNode +}var found=false; +while(targ&&!found){if(!/\snodeBox\s|\sobjectBox-selector\s/.test(" "+targ.className+" ")){targ=targ.parentNode +}else{found=true +}}if(!targ){FBL.Firebug.Inspector.hideBoxModel(); +hoverElement=null; +return +}if(typeof targ.attributes[cacheID]=="undefined"){return +}var uid=targ.attributes[cacheID]; +if(!uid){return +}var el=ElementCache.get(uid.value); +var nodeName=el.nodeName.toLowerCase(); +if(FBL.isIE&&" meta title script link ".indexOf(" "+nodeName+" ")!=-1){return +}if(!/\snodeBox\s|\sobjectBox-selector\s/.test(" "+targ.className+" ")){return +}if(el.id=="FirebugUI"||" html head body br script link iframe ".indexOf(" "+nodeName+" ")!=-1){FBL.Firebug.Inspector.hideBoxModel(); +hoverElement=null; +return +}if((new Date().getTime()-hoverElementTS>40)&&hoverElement!=el){hoverElementTS=new Date().getTime(); +hoverElement=el; +FBL.Firebug.Inspector.drawBoxModel(el) +}}catch(E){}}; +Firebug.Reps={appendText:function(object,html){html.push(escapeHTML(objectToString(object))) +},appendNull:function(object,html){html.push('',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){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',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]
                  ") +}} +}}); +FBL.ns(function(){with(FBL){var maxWidth=100,maxHeight=80; +var infoTipMargin=10; +var infoTipWindowPadding=25; +Firebug.InfoTip=extend(Firebug.Module,{dispatchName:"infoTip",tags:domplate({infoTipTag:DIV({"class":"infoTip"}),colorTag:DIV({style:"background: $rgbValue; width: 100px; height: 40px"}," "),imgTag:DIV({"class":"infoTipImageBox infoTipLoading"},IMG({"class":"infoTipImage",src:"$urlValue",repeat:"$repeat",onload:"$onLoadImage"}),IMG({"class":"infoTipBgImage",collapsed:true,src:"blank.gif"}),DIV({"class":"infoTipCaption"})),onLoadImage:function(event){var img=event.currentTarget||event.srcElement; +var innerBox=img.parentNode; +var caption=getElementByClass(innerBox,"infoTipCaption"); +var bgImg=getElementByClass(innerBox,"infoTipBgImage"); +if(!bgImg){return +}if(isIE){removeClass(innerBox,"infoTipLoading") +}var updateInfoTip=function(){var w=img.naturalWidth||img.width||10,h=img.naturalHeight||img.height||10; +var repeat=img.getAttribute("repeat"); +if(repeat=="repeat-x"||(w==1&&h>1)){collapse(img,true); +collapse(bgImg,false); +bgImg.style.background="url("+img.src+") repeat-x"; +bgImg.style.width=maxWidth+"px"; +if(h>maxHeight){bgImg.style.height=maxHeight+"px" +}else{bgImg.style.height=h+"px" +}}else{if(repeat=="repeat-y"||(h==1&&w>1)){collapse(img,true); +collapse(bgImg,false); +bgImg.style.background="url("+img.src+") repeat-y"; +bgImg.style.height=maxHeight+"px"; +if(w>maxWidth){bgImg.style.width=maxWidth+"px" +}else{bgImg.style.width=w+"px" +}}else{if(repeat=="repeat"||(w==1&&h==1)){collapse(img,true); +collapse(bgImg,false); +bgImg.style.background="url("+img.src+") repeat"; +bgImg.style.width=maxWidth+"px"; +bgImg.style.height=maxHeight+"px" +}else{if(w>maxWidth||h>maxHeight){if(w>h){img.style.width=maxWidth+"px"; +img.style.height=Math.round((h/w)*maxWidth)+"px" +}else{img.style.width=Math.round((w/h)*maxHeight)+"px"; +img.style.height=maxHeight+"px" +}}}}}caption.innerHTML=$STRF(w+" x "+h) +}; +if(isIE){setTimeout(updateInfoTip,0) +}else{updateInfoTip(); +removeClass(innerBox,"infoTipLoading") +}}}),initializeBrowser:function(browser){browser.onInfoTipMouseOut=bind(this.onMouseOut,this,browser); +browser.onInfoTipMouseMove=bind(this.onMouseMove,this,browser); +var doc=browser.document; +if(!doc){return +}addEvent(doc,"mouseover",browser.onInfoTipMouseMove); +addEvent(doc,"mouseout",browser.onInfoTipMouseOut); +addEvent(doc,"mousemove",browser.onInfoTipMouseMove); +return browser.infoTip=this.tags.infoTipTag.append({},getBody(doc)) +},uninitializeBrowser:function(browser){if(browser.infoTip){var doc=browser.document; +removeEvent(doc,"mouseover",browser.onInfoTipMouseMove); +removeEvent(doc,"mouseout",browser.onInfoTipMouseOut); +removeEvent(doc,"mousemove",browser.onInfoTipMouseMove); +browser.infoTip.parentNode.removeChild(browser.infoTip); +delete browser.infoTip; +delete browser.onInfoTipMouseMove +}},showInfoTip:function(infoTip,panel,target,x,y,rangeParent,rangeOffset){if(!Firebug.showInfoTips){return +}var scrollParent=getOverflowParent(target); +var scrollX=x+(scrollParent?scrollParent.scrollLeft:0); +if(panel.showInfoTip(infoTip,target,scrollX,y,rangeParent,rangeOffset)){var htmlElt=infoTip.ownerDocument.documentElement; +var panelWidth=htmlElt.clientWidth; +var panelHeight=htmlElt.clientHeight; +if(x+infoTip.offsetWidth+infoTipMargin>panelWidth){infoTip.style.left=Math.max(0,panelWidth-(infoTip.offsetWidth+infoTipMargin))+"px"; +infoTip.style.right="auto" +}else{infoTip.style.left=(x+infoTipMargin)+"px"; +infoTip.style.right="auto" +}if(y+infoTip.offsetHeight+infoTipMargin>panelHeight){infoTip.style.top=Math.max(0,panelHeight-(infoTip.offsetHeight+infoTipMargin))+"px"; +infoTip.style.bottom="auto" +}else{infoTip.style.top=(y+infoTipMargin)+"px"; +infoTip.style.bottom="auto" +}if(FBTrace.DBG_INFOTIP){FBTrace.sysout("infotip.showInfoTip; top: "+infoTip.style.top+", left: "+infoTip.style.left+", bottom: "+infoTip.style.bottom+", right:"+infoTip.style.right+", offsetHeight: "+infoTip.offsetHeight+", offsetWidth: "+infoTip.offsetWidth+", x: "+x+", panelWidth: "+panelWidth+", y: "+y+", panelHeight: "+panelHeight) +}infoTip.setAttribute("active","true") +}else{this.hideInfoTip(infoTip) +}},hideInfoTip:function(infoTip){if(infoTip){infoTip.removeAttribute("active") +}},onMouseOut:function(event,browser){if(!event.relatedTarget){this.hideInfoTip(browser.infoTip) +}},onMouseMove:function(event,browser){if(getAncestorByClass(event.target,"infoTip")){return +}if(browser.currentPanel){var x=event.clientX,y=event.clientY,target=event.target||event.srcElement; +this.showInfoTip(browser.infoTip,browser.currentPanel,target,x,y,event.rangeParent,event.rangeOffset) +}else{this.hideInfoTip(browser.infoTip) +}},populateColorInfoTip:function(infoTip,color){this.tags.colorTag.replace({rgbValue:color},infoTip); +return true +},populateImageInfoTip:function(infoTip,url,repeat){if(!repeat){repeat="no-repeat" +}this.tags.imgTag.replace({urlValue:url,repeat:repeat},infoTip); +return true +},disable:function(){},showPanel:function(browser,panel){if(panel){var infoTip=panel.panelBrowser.infoTip; +if(!infoTip){infoTip=this.initializeBrowser(panel.panelBrowser) +}this.hideInfoTip(infoTip) +}},showSidePanel:function(browser,panel){this.showPanel(browser,panel) +}}); +Firebug.registerModule(Firebug.InfoTip) +}}); +(function(){this.getElementXPath=function(element){if(element&&element.id){return'//*[@id="'+element.id+'"]' +}else{return this.getElementTreeXPath(element) +}}; +this.getElementTreeXPath=function(element){var paths=[]; +for(; +element&&element.nodeType==1; +element=element.parentNode){var index=0; +for(var sibling=element.previousSibling; +sibling; +sibling=sibling.previousSibling){if(sibling.nodeName==element.nodeName){++index +}}var tagName=element.nodeName.toLowerCase(); +var pathIndex=(index?"["+(index+1)+"]":""); +paths.splice(0,0,tagName+pathIndex) +}return paths.length?"/"+paths.join("/"):null +}; +this.getElementsByXPath=function(doc,xpath){var nodes=[]; +try{var result=doc.evaluate(xpath,doc,null,XPathResult.ANY_TYPE,null); +for(var item=result.iterateNext(); +item; +item=result.iterateNext()){nodes.push(item) +}}catch(exc){}return nodes +}; +this.getRuleMatchingElements=function(rule,doc){var css=rule.selectorText; +var xpath=this.cssToXPath(css); +return this.getElementsByXPath(doc,xpath) +} +}).call(FBL); +FBL.ns(function(){with(FBL){var toCamelCase=function toCamelCase(s){return s.replace(reSelectorCase,toCamelCaseReplaceFn) +}; +var toSelectorCase=function toSelectorCase(s){return s.replace(reCamelCase,"-$1").toLowerCase() +}; +var reCamelCase=/([A-Z])/g; +var reSelectorCase=/\-(.)/g; +var toCamelCaseReplaceFn=function toCamelCaseReplaceFn(m,g){return g.toUpperCase() +}; +var ElementCache=Firebug.Lite.Cache.Element; +var StyleSheetCache=Firebug.Lite.Cache.StyleSheet; +var globalCSSRuleIndex; +var externalStyleSheetURLs=[]; +var 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"))}); +var processAllStyleSheetsTimeout=null; +var loadExternalStylesheet=function(doc,styleSheetIterator,styleSheet){var url=styleSheet.href; +styleSheet.firebugIgnore=true; +var source=Firebug.Lite.Proxy.load(url); +source=source.replace(/url\(([^\)]+)\)/g,function(a,name){var hasDomain=/\w+:\/\/./.test(name); +if(!hasDomain){name=name.replace(/^(["'])(.+)\1$/,"$2"); +var first=name.charAt(0); +if(first=="/"){var m=/^([^:]+:\/{1,3}[^\/]+)/.exec(url); +return m?"url("+m[1]+name+")":"url("+name+")" +}else{var path=url.replace(/[^\/]+\.[\w\d]+(\?.+|#.+)?$/g,""); +path=path+name; +var reBack=/[^\/]+\/\.\.\//; +while(reBack.test(path)){path=path.replace(reBack,"") +}return"url("+path+")" +}}return a +}); +var oldStyle=styleSheet.ownerNode; +if(!oldStyle){return +}if(!oldStyle.parentNode){return +}var style=createGlobalElement("style"); +style.setAttribute("charset","utf-8"); +style.setAttribute("type","text/css"); +style.innerHTML=source; +oldStyle.parentNode.insertBefore(style,oldStyle.nextSibling); +oldStyle.parentNode.removeChild(oldStyle); +doc.styleSheets[doc.styleSheets.length-1].externalURL=url; +console.log(url,"call "+externalStyleSheetURLs.length,source); +externalStyleSheetURLs.pop(); +if(processAllStyleSheetsTimeout){clearTimeout(processAllStyleSheetsTimeout) +}processAllStyleSheetsTimeout=setTimeout(function(){console.log("processing"); +FBL.processAllStyleSheets(doc,styleSheetIterator); +processAllStyleSheetsTimeout=null +},200) +}; +FBL.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; +imaxSpecificity){maxSpecificity=spec; +mostSpecificSelector=sel +}}}rule.specificity=maxSpecificity +}}rules.sort(sortElementRules); +return rules +}; +var sortElementRules=function(a,b){var ruleA=CSSRuleMap[a]; +var ruleB=CSSRuleMap[b]; +var specificityA=ruleA.specificity; +var specificityB=ruleB.specificity; +if(specificityA>specificityB){return 1 +}else{if(specificityAruleB.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 reSelectorTag=/(^|\s)(?:\w+)/g; +var reSelectorClass=/\.[\w\d_-]+/g; +var reSelectorId=/#[\w\d_-]+/g; +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 +}; +Firebug.SourceBoxPanel=Firebug.Panel; +var domUtils=null; +var textContent=isIE?"innerText":"textContent"; +var CSSDomplateBase={isEditable:function(rule){return !rule.isSystemSheet +},isSelectorEditable:function(rule){return rule.isSelectorEditable&&this.isEditable(rule) +}}; +var CSSPropTag=domplate(CSSDomplateBase,{tag:DIV({"class":"cssProp focusRow",$disabledStyle:"$prop.disabled",$editGroup:"$rule|isEditable",$cssOverridden:"$prop.overridden",role:"option"},A({"class":"cssPropDisable"},"  "),SPAN({"class":"cssPropName",$editable:"$rule|isEditable"},"$prop.name"),SPAN({"class":"cssColon"},":"),SPAN({"class":"cssPropValue",$editable:"$rule|isEditable"},"$prop.value$prop.important"),SPAN({"class":"cssSemi"},";"))}); +var CSSRuleTag=TAG("$rule.tag",{rule:"$rule"}); +var CSSImportRuleTag=domplate({tag:DIV({"class":"cssRule insertInto focusRow importRule",_repObject:"$rule.rule"},"@import "",A({"class":"objectLink",_repObject:"$rule.rule.styleSheet"},"$rule.rule.href"),"";")}); +var CSSStyleRuleTag=domplate(CSSDomplateBase,{tag:DIV({"class":"cssRule insertInto",$cssEditableRule:"$rule|isEditable",$editGroup:"$rule|isSelectorEditable",_repObject:"$rule.rule",ruleId:"$rule.id",role:"presentation"},DIV({"class":"cssHead focusRow",role:"listitem"},SPAN({"class":"cssSelector",$editable:"$rule|isSelectorEditable"},"$rule.selector")," {"),DIV({role:"group"},DIV({"class":"cssPropertyListBox",role:"listbox"},FOR("prop","$rule.props",TAG(CSSPropTag.tag,{rule:"$rule",prop:"$prop"})))),DIV({"class":"editable insertBefore",role:"presentation"},"}"))}); +var reSplitCSS=/(url\("?[^"\)]+?"?\))|(rgb\(.*?\))|(#[\dA-Fa-f]+)|(-?\d+(\.\d+)?(%|[a-z]{1,2})?)|([^,\s]+)|"(.*?)"/; +var reURL=/url\("?([^"\)]+)?"?\)/; +var reRepeat=/no-repeat|repeat-x|repeat-y|repeat/; +var sothinkInstalled=false; +var styleGroups={text:["font-family","font-size","font-weight","font-style","color","text-transform","text-decoration","letter-spacing","word-spacing","line-height","text-align","vertical-align","direction","column-count","column-gap","column-width"],background:["background-color","background-image","background-repeat","background-position","background-attachment","opacity"],box:["width","height","top","right","bottom","left","margin-top","margin-right","margin-bottom","margin-left","padding-top","padding-right","padding-bottom","padding-left","border-top-width","border-right-width","border-bottom-width","border-left-width","border-top-color","border-right-color","border-bottom-color","border-left-color","border-top-style","border-right-style","border-bottom-style","border-left-style","-moz-border-top-radius","-moz-border-right-radius","-moz-border-bottom-radius","-moz-border-left-radius","outline-top-width","outline-right-width","outline-bottom-width","outline-left-width","outline-top-color","outline-right-color","outline-bottom-color","outline-left-color","outline-top-style","outline-right-style","outline-bottom-style","outline-left-style"],layout:["position","display","visibility","z-index","overflow-x","overflow-y","overflow-clip","white-space","clip","float","clear","-moz-box-sizing"],other:["cursor","list-style-image","list-style-position","list-style-type","marker-offset","user-focus","user-select","user-modify","user-input"]}; +var styleGroupTitles={text:"Text",background:"Background",box:"Box Model",layout:"Layout",other:"Other"}; +Firebug.CSSModule=extend(Firebug.Module,{freeEdit:function(styleSheet,value){if(!styleSheet.editStyleSheet){var ownerNode=getStyleSheetOwnerNode(styleSheet); +styleSheet.disabled=true; +var url=CCSV("@mozilla.org/network/standard-url;1",Components.interfaces.nsIURL); +url.spec=styleSheet.href; +var editStyleSheet=ownerNode.ownerDocument.createElementNS("http://www.w3.org/1999/xhtml","style"); +unwrapObject(editStyleSheet).firebugIgnore=true; +editStyleSheet.setAttribute("type","text/css"); +editStyleSheet.setAttributeNS("http://www.w3.org/XML/1998/namespace","base",url.directory); +if(ownerNode.hasAttribute("media")){editStyleSheet.setAttribute("media",ownerNode.getAttribute("media")) +}ownerNode.parentNode.insertBefore(editStyleSheet,ownerNode.nextSibling); +styleSheet.editStyleSheet=editStyleSheet +}styleSheet.editStyleSheet.innerHTML=value; +if(FBTrace.DBG_CSS){FBTrace.sysout("css.saveEdit styleSheet.href:"+styleSheet.href+" got innerHTML:"+value+"\n") +}dispatch(this.fbListeners,"onCSSFreeEdit",[styleSheet,value]) +},insertRule:function(styleSheet,cssText,ruleIndex){if(FBTrace.DBG_CSS){FBTrace.sysout("Insert: "+ruleIndex+" "+cssText) +}var insertIndex=styleSheet.insertRule(cssText,ruleIndex); +dispatch(this.fbListeners,"onCSSInsertRule",[styleSheet,cssText,ruleIndex]); +return insertIndex +},deleteRule:function(styleSheet,ruleIndex){if(FBTrace.DBG_CSS){FBTrace.sysout("deleteRule: "+ruleIndex+" "+styleSheet.cssRules.length,styleSheet.cssRules) +}dispatch(this.fbListeners,"onCSSDeleteRule",[styleSheet,ruleIndex]); +styleSheet.deleteRule(ruleIndex) +},setProperty:function(rule,propName,propValue,propPriority){var style=rule.style||rule; +var baseText=style.cssText; +if(style.getPropertyValue){var prevValue=style.getPropertyValue(propName); +var prevPriority=style.getPropertyPriority(propName); +style.removeProperty(propName); +style.setProperty(propName,propValue,propPriority) +}else{style[toCamelCase(propName)]=propValue +}if(propName){dispatch(this.fbListeners,"onCSSSetProperty",[style,propName,propValue,propPriority,prevValue,prevPriority,rule,baseText]) +}},removeProperty:function(rule,propName,parent){var style=rule.style||rule; +var baseText=style.cssText; +if(style.getPropertyValue){var prevValue=style.getPropertyValue(propName); +var prevPriority=style.getPropertyPriority(propName); +style.removeProperty(propName) +}else{style[toCamelCase(propName)]="" +}if(propName){dispatch(this.fbListeners,"onCSSRemoveProperty",[style,propName,prevValue,prevPriority,rule,baseText]) +}}}); +Firebug.CSSStyleSheetPanel=function(){}; +Firebug.CSSStyleSheetPanel.prototype=extend(Firebug.SourceBoxPanel,{template:domplate({tag:DIV({"class":"cssSheet insertInto a11yCSSView"},FOR("rule","$rules",CSSRuleTag),DIV({"class":"cssSheet editable insertBefore"},""))}),refresh:function(){if(this.location){this.updateLocation(this.location) +}else{if(this.selection){this.updateSelection(this.selection) +}}},toggleEditing:function(){if(!this.stylesheetEditor){this.stylesheetEditor=new StyleSheetEditor(this.document) +}if(this.editing){Firebug.Editor.stopEditing() +}else{if(!this.location){return +}var styleSheet=this.location.editStyleSheet?this.location.editStyleSheet.sheet:this.location; +var css=getStyleSheetCSS(styleSheet,this.context); +this.stylesheetEditor.styleSheet=this.location; +Firebug.Editor.startEditing(this.panelNode,css,this.stylesheetEditor) +}},getStylesheetURL:function(rule){if(this.location.href){return this.location.href +}else{return this.context.window.location.href +}},getRuleByLine:function(styleSheet,line){if(!domUtils){return null +}var cssRules=styleSheet.cssRules; +for(var i=0; +i=line){return rule +}}}},highlightRule:function(rule){var ruleElement=Firebug.getElementByRepObject(this.panelNode.firstChild,rule); +if(ruleElement){scrollIntoCenterView(ruleElement,this.panelNode); +setClassTimed(ruleElement,"jumpHighlight",this.context) +}},getStyleSheetRules:function(context,styleSheet){var isSystemSheet=isSystemStyleSheet(styleSheet); +function appendRules(cssRules){for(var i=0; +i20){return +}var target=event.target||event.srcElement; +if(hasClass(target,"textEditor")){return +}var row=getAncestorByClass(target,"cssProp"); +if(row&&hasClass(row,"editGroup")){this.disablePropertyRow(row); +cancelEvent(event) +}},onDoubleClick:function(event){var offset=event.clientX-this.panelNode.parentNode.offsetLeft; +if(!isLeftClick(event)||offset<=20){return +}var target=event.target||event.srcElement; +if(hasClass(target,"textEditorInner")){return +}var row=getAncestorByClass(target,"cssRule"); +if(row&&!getAncestorByClass(target,"cssPropName")&&!getAncestorByClass(target,"cssPropValue")){this.insertPropertyRow(row); +cancelEvent(event) +}},name:"stylesheet",title:"CSS",parentPanel:null,searchable:true,dependents:["css","stylesheet","dom","domSide","layout"],options:{hasToolButtons:true},create:function(){Firebug.Panel.create.apply(this,arguments); +this.onMouseDown=bind(this.onMouseDown,this); +this.onDoubleClick=bind(this.onDoubleClick,this); +if(this.name=="stylesheet"){this.onChangeSelect=bind(this.onChangeSelect,this); +var doc=Firebug.browser.document; +var selectNode=this.selectNode=createElement("select"); +processAllStyleSheets(doc,function(doc,styleSheet){var key=StyleSheetCache.key(styleSheet); +var fileName=getFileName(styleSheet.href)||getFileName(doc.location.href); +var option=createElement("option",{value:key}); +option.appendChild(Firebug.chrome.document.createTextNode(fileName)); +selectNode.appendChild(option) +}); +this.toolButtonsNode.appendChild(selectNode) +}},onChangeSelect:function(event){event=event||window.event; +var target=event.srcElement||event.currentTarget; +var key=target.value; +var styleSheet=StyleSheetCache.get(key); +this.updateLocation(styleSheet) +},initialize:function(){Firebug.Panel.initialize.apply(this,arguments); +this.context=Firebug.chrome; +this.document=Firebug.chrome.document; +this.initializeNode(); +if(this.name=="stylesheet"){var styleSheets=Firebug.browser.document.styleSheets; +if(styleSheets.length>0){addEvent(this.selectNode,"change",this.onChangeSelect); +this.updateLocation(styleSheets[0]) +}}},shutdown:function(){Firebug.Editor.stopEditing(); +if(this.name=="stylesheet"){removeEvent(this.selectNode,"change",this.onChangeSelect) +}this.destroyNode(); +Firebug.Panel.shutdown.apply(this,arguments) +},destroy:function(state){Firebug.Panel.destroy.apply(this,arguments) +},initializeNode:function(oldPanelNode){addEvent(this.panelNode,"mousedown",this.onMouseDown); +addEvent(this.panelNode,"dblclick",this.onDoubleClick) +},destroyNode:function(){removeEvent(this.panelNode,"mousedown",this.onMouseDown); +removeEvent(this.panelNode,"dblclick",this.onDoubleClick) +},ishow:function(state){Firebug.Inspector.stopInspecting(true); +this.showToolbarButtons("fbCSSButtons",true); +if(this.context.loaded&&!this.location){restoreObjects(this,state); +if(!this.location){this.location=this.getDefaultLocation() +}if(state&&state.scrollTop){this.panelNode.scrollTop=state.scrollTop +}}},ihide:function(){this.showToolbarButtons("fbCSSButtons",false); +this.lastScrollTop=this.panelNode.scrollTop +},supportsObject:function(object){if(object instanceof CSSStyleSheet){return 1 +}else{if(object instanceof CSSStyleRule){return 2 +}else{if(object instanceof CSSStyleDeclaration){return 2 +}else{if(object instanceof SourceLink&&object.type=="css"&&reCSS.test(object.href)){return 2 +}else{return 0 +}}}}},updateLocation:function(styleSheet){if(!styleSheet){return +}if(styleSheet.editStyleSheet){styleSheet=styleSheet.editStyleSheet.sheet +}if(styleSheet.restricted){FirebugReps.Warning.tag.replace({object:"AccessRestricted"},this.panelNode); +externalStyleSheetWarning.tag.append({object:"The stylesheet could not be loaded due to access restrictions. ",link:"more...",href:"http://getfirebug.com/wiki/index.php/Firebug_Lite_FAQ#I_keep_seeing_.22Access_to_restricted_URI_denied.22"},this.panelNode); +return +}var rules=this.getStyleSheetRules(this.context,styleSheet); +var result; +if(rules.length){result=this.template.tag.replace({rules:rules},this.panelNode) +}else{result=FirebugReps.Warning.tag.replace({object:"EmptyStyleSheet"},this.panelNode) +}},updateSelection:function(object){this.selection=null; +if(object instanceof CSSStyleDeclaration){object=object.parentRule +}if(object instanceof CSSStyleRule){this.navigate(object.parentStyleSheet); +this.highlightRule(object) +}else{if(object instanceof CSSStyleSheet){this.navigate(object) +}else{if(object instanceof SourceLink){try{var sourceLink=object; +var sourceFile=getSourceFileByHref(sourceLink.href,this.context); +if(sourceFile){clearNode(this.panelNode); +this.showSourceFile(sourceFile); +var lineNo=object.line; +if(lineNo){this.scrollToLine(lineNo,this.jumpHighlightFactory(lineNo,this.context)) +}}else{var stylesheet=getStyleSheetByHref(sourceLink.href,this.context); +if(stylesheet){this.navigate(stylesheet) +}else{if(FBTrace.DBG_CSS){FBTrace.sysout("css.updateSelection no sourceFile for "+sourceLink.href,sourceLink) +}}}}catch(exc){if(FBTrace.DBG_CSS){FBTrace.sysout("css.upDateSelection FAILS "+exc,exc) +}}}}}},updateOption:function(name,value){if(name=="expandShorthandProps"){this.refresh() +}},getLocationList:function(){var styleSheets=getAllStyleSheets(this.context); +return styleSheets +},getOptionsMenuItems:function(){return[{label:"Expand Shorthand Properties",type:"checkbox",checked:Firebug.expandShorthandProps,command:bindFixed(Firebug.togglePref,Firebug,"expandShorthandProps")},"-",{label:"Refresh",command:bind(this.refresh,this)}] +},getContextMenuItems:function(style,target){var items=[]; +if(this.infoTipType=="color"){items.push({label:"CopyColor",command:bindFixed(copyToClipboard,FBL,this.infoTipObject)}) +}else{if(this.infoTipType=="image"){items.push({label:"CopyImageLocation",command:bindFixed(copyToClipboard,FBL,this.infoTipObject)},{label:"OpenImageInNewTab",command:bindFixed(openNewTab,FBL,this.infoTipObject)}) +}}if(isElement(this.selection)){items.push({label:"EditStyle",command:bindFixed(this.editElementStyle,this)}) +}else{if(!isSystemStyleSheet(this.selection)){items.push({label:"NewRule",command:bindFixed(this.insertRule,this,target)}) +}}var cssRule=getAncestorByClass(target,"cssRule"); +if(cssRule&&hasClass(cssRule,"cssEditableRule")){items.push("-",{label:"NewProp",command:bindFixed(this.insertPropertyRow,this,target)}); +var propRow=getAncestorByClass(target,"cssProp"); +if(propRow){var propName=getChildByClass(propRow,"cssPropName")[textContent]; +var isDisabled=hasClass(propRow,"disabledStyle"); +items.push({label:$STRF("EditProp",[propName]),nol10n:true,command:bindFixed(this.editPropertyRow,this,propRow)},{label:$STRF("DeleteProp",[propName]),nol10n:true,command:bindFixed(this.deletePropertyRow,this,propRow)},{label:$STRF("DisableProp",[propName]),nol10n:true,type:"checkbox",checked:isDisabled,command:bindFixed(this.disablePropertyRow,this,propRow)}) +}}items.push("-",{label:"Refresh",command:bind(this.refresh,this)}); +return items +},browseObject:function(object){if(this.infoTipType=="image"){openNewTab(this.infoTipObject); +return true +}},showInfoTip:function(infoTip,target,x,y){var propValue=getAncestorByClass(target,"cssPropValue"); +if(propValue){var offset=getClientOffset(propValue); +var offsetX=x-offset.x; +var text=propValue[textContent]; +var charWidth=propValue.offsetWidth/text.length; +var charOffset=Math.floor(offsetX/charWidth); +var cssValue=parseCSSValue(text,charOffset); +if(cssValue){if(cssValue.value==this.infoTipValue){return true +}this.infoTipValue=cssValue.value; +if(cssValue.type=="rgb"||(!cssValue.type&&isColorKeyword(cssValue.value))){this.infoTipType="color"; +this.infoTipObject=cssValue.value; +return Firebug.InfoTip.populateColorInfoTip(infoTip,cssValue.value) +}else{if(cssValue.type=="url"){var propNameNode=getElementByClass(target.parentNode,"cssPropName"); +if(propNameNode&&isImageRule(propNameNode[textContent])){var rule=Firebug.getRepObject(target); +var baseURL=this.getStylesheetURL(rule); +var relURL=parseURLValue(cssValue.value); +var absURL=isDataURL(relURL)?relURL:absoluteURL(relURL,baseURL); +var repeat=parseRepeatValue(text); +this.infoTipType="image"; +this.infoTipObject=absURL; +return Firebug.InfoTip.populateImageInfoTip(infoTip,absURL,repeat) +}}}}}delete this.infoTipType; +delete this.infoTipValue; +delete this.infoTipObject +},getEditor:function(target,value){if(target==this.panelNode||hasClass(target,"cssSelector")||hasClass(target,"cssRule")||hasClass(target,"cssSheet")){if(!this.ruleEditor){this.ruleEditor=new CSSRuleEditor(this.document) +}return this.ruleEditor +}else{if(!this.editor){this.editor=new CSSEditor(this.document) +}return this.editor +}},getDefaultLocation:function(){try{var styleSheets=this.context.window.document.styleSheets; +if(styleSheets.length){var sheet=styleSheets[0]; +return(Firebug.filterSystemURLs&&isSystemURL(getURLForStyleSheet(sheet)))?null:sheet +}}catch(exc){if(FBTrace.DBG_LOCATIONS){FBTrace.sysout("css.getDefaultLocation FAILS "+exc,exc) +}}},getObjectDescription:function(styleSheet){var url=getURLForStyleSheet(styleSheet); +var instance=getInstanceForStyleSheet(styleSheet); +var baseDescription=splitURLBase(url); +if(instance){baseDescription.name=baseDescription.name+" #"+(instance+1) +}return baseDescription +},search:function(text,reverse){var curDoc=this.searchCurrentDoc(!Firebug.searchGlobal,text,reverse); +if(!curDoc&&Firebug.searchGlobal){return this.searchOtherDocs(text,reverse) +}return curDoc +},searchOtherDocs:function(text,reverse){var scanRE=Firebug.Search.getTestingRegex(text); +function scanDoc(styleSheet){for(var i=0; +i0){externalStyleSheetWarning.tag.append({object:"The results here may be inaccurate because some stylesheets could not be loaded due to access restrictions. ",link:"more...",href:"http://getfirebug.com/wiki/index.php/Firebug_Lite_FAQ#I_keep_seeing_.22This_element_has_no_style_rules.22"},this.panelNode) +}},getStylesheetURL:function(rule){if(rule&&rule.parentStyleSheet&&rule.parentStyleSheet.href){return rule.parentStyleSheet.href +}else{return this.selection.ownerDocument.location.href +}},getInheritedRules:function(element,sections,usedProps){var parent=element.parentNode; +if(parent&&parent.nodeType==1){this.getInheritedRules(parent,sections,usedProps); +var rules=[]; +this.getElementRules(parent,rules,usedProps,true); +if(rules.length){sections.splice(0,0,{element:parent,rules:rules}) +}}},getElementRules:function(element,rules,usedProps,inheritMode){var inspectedRules,displayedRules={}; +inspectedRules=getElementCSSRules(element); +if(inspectedRules){for(var i=0,length=inspectedRules.length; +i"+value+" = "+propValue+"\n") +}if(previousValue){Firebug.CSSModule.removeProperty(rule,previousValue) +}Firebug.CSSModule.setProperty(rule,value,parsedValue.value,parsedValue.priority) +}}else{if(!value){Firebug.CSSModule.removeProperty(rule,previousValue) +}}}else{if(getAncestorByClass(target,"cssPropValue")){var propName=getChildByClass(row,"cssPropName")[textContent]; +var propValue=getChildByClass(row,"cssPropValue")[textContent]; +if(FBTrace.DBG_CSS){FBTrace.sysout("CSSEditor.saveEdit propName=propValue: "+propName+" = "+propValue+"\n") +}if(value&&value!="null"){var parsedValue=parsePriority(value); +Firebug.CSSModule.setProperty(rule,propName,parsedValue.value,parsedValue.priority) +}else{if(previousValue&&previousValue!="null"){Firebug.CSSModule.removeProperty(rule,propName) +}}}}this.panel.markChange(this.panel.name=="stylesheet") +},advanceToNext:function(target,charCode){if(charCode==58&&hasClass(target,"cssPropName")){return true +}},getAutoCompleteRange:function(value,offset){if(hasClass(this.target,"cssPropName")){return{start:0,end:value.length-1} +}else{return parseCSSValue(value,offset) +}},getAutoCompleteList:function(preExpr,expr,postExpr){if(hasClass(this.target,"cssPropName")){return getCSSPropertyNames() +}else{var row=getAncestorByClass(this.target,"cssProp"); +var propName=getChildByClass(row,"cssPropName")[textContent]; +return getCSSKeywordsByProperty(propName) +}}}); +function CSSRuleEditor(doc){this.initializeInline(doc); +this.completeAsYouType=false +}CSSRuleEditor.uniquifier=0; +CSSRuleEditor.prototype=domplate(Firebug.InlineEditor.prototype,{insertNewRow:function(target,insertWhere){var emptyRule={selector:"",id:"",props:[],isSelectorEditable:true}; +if(insertWhere=="before"){return CSSStyleRuleTag.tag.insertBefore({rule:emptyRule},target) +}else{return CSSStyleRuleTag.tag.insertAfter({rule:emptyRule},target) +}},saveEdit:function(target,value,previousValue){if(FBTrace.DBG_CSS){FBTrace.sysout("CSSRuleEditor.saveEdit: '"+value+"' '"+previousValue+"'",target) +}target.innerHTML=escapeForCss(value); +if(value===previousValue){return +}var row=getAncestorByClass(target,"cssRule"); +var styleSheet=this.panel.location; +styleSheet=styleSheet.editStyleSheet?styleSheet.editStyleSheet.sheet:styleSheet; +var cssRules=styleSheet.cssRules; +var rule=Firebug.getRepObject(target),oldRule=rule; +var ruleIndex=cssRules.length; +if(rule||Firebug.getRepObject(row.nextSibling)){var searchRule=rule||Firebug.getRepObject(row.nextSibling); +for(ruleIndex=0; +ruleIndexb.name?1:-1 +}) +}function getTopmostRuleLine(panelNode){for(var child=panelNode.firstChild; +child; +child=child.nextSibling){if(child.offsetTop+child.offsetHeight>panelNode.scrollTop){var rule=child.repObject; +if(rule){return{line:domUtils.getRuleLine(rule),offset:panelNode.scrollTop-child.offsetTop} +}}}return 0 +}function getStyleSheetCSS(sheet,context){if(sheet.ownerNode instanceof HTMLStyleElement){return sheet.ownerNode.innerHTML +}else{return context.sourceCache.load(sheet.href).join("") +}}function getStyleSheetOwnerNode(sheet){for(; +sheet&&!sheet.ownerNode; +sheet=sheet.parentStyleSheet){}return sheet.ownerNode +}function scrollSelectionIntoView(panel){var selCon=getSelectionController(panel); +selCon.scrollSelectionIntoView(nsISelectionController.SELECTION_NORMAL,nsISelectionController.SELECTION_FOCUS_REGION,true) +}function getSelectionController(panel){var browser=Firebug.chrome.getPanelBrowser(panel); +return browser.docShell.QueryInterface(nsIInterfaceRequestor).getInterface(nsISelectionDisplay).QueryInterface(nsISelectionController) +}Firebug.registerModule(Firebug.CSSModule); +Firebug.registerPanel(Firebug.CSSStyleSheetPanel); +Firebug.registerPanel(CSSElementPanel); +Firebug.registerPanel(CSSComputedElementPanel) +}}); +FBL.ns(function(){with(FBL){Firebug.Script=extend(Firebug.Module,{getPanel:function(){return Firebug.chrome?Firebug.chrome.getPanel("Script"):null +},selectSourceCode:function(index){this.getPanel().selectSourceCode(index) +}}); +Firebug.registerModule(Firebug.Script); +function ScriptPanel(){}ScriptPanel.prototype=extend(Firebug.Panel,{name:"Script",title:"Script",selectIndex:0,sourceIndex:-1,options:{hasToolButtons:true},create:function(){Firebug.Panel.create.apply(this,arguments); +this.onChangeSelect=bind(this.onChangeSelect,this); +var doc=Firebug.browser.document; +var scripts=doc.getElementsByTagName("script"); +var selectNode=this.selectNode=createElement("select"); +for(var i=0,script; +script=scripts[i]; +i++){if(Firebug.ignoreFirebugElements&&script.getAttribute("firebugIgnore")){continue +}var fileName=getFileName(script.src)||getFileName(doc.location.href); +var option=createElement("option",{value:i}); +option.appendChild(Firebug.chrome.document.createTextNode(fileName)); +selectNode.appendChild(option) +}this.toolButtonsNode.appendChild(selectNode) +},initialize:function(){this.selectSourceCode(this.selectIndex); +Firebug.Panel.initialize.apply(this,arguments); +addEvent(this.selectNode,"change",this.onChangeSelect) +},shutdown:function(){removeEvent(this.selectNode,"change",this.onChangeSelect); +Firebug.Panel.shutdown.apply(this,arguments) +},detach:function(oldChrome,newChrome){Firebug.Panel.detach.apply(this,arguments); +var oldPanel=oldChrome.getPanel("Script"); +var index=oldPanel.selectIndex; +this.selectNode.selectedIndex=index; +this.selectIndex=index; +this.sourceIndex=-1 +},onChangeSelect:function(event){var select=this.selectNode; +this.selectIndex=select.selectedIndex; +var option=select.options[select.selectedIndex]; +if(!option){return +}var selectedSourceIndex=parseInt(option.value); +this.renderSourceCode(selectedSourceIndex) +},selectSourceCode:function(index){var select=this.selectNode; +select.selectedIndex=index; +var option=select.options[index]; +if(!option){return +}var selectedSourceIndex=parseInt(option.value); +this.renderSourceCode(selectedSourceIndex) +},renderSourceCode:function(index){if(this.sourceIndex!=index){var renderProcess=function renderProcess(src){var html=[],hl=0; +src=isIE&&!isExternal?src+"\n":"\n"+src; +src=src.replace(/\n\r|\r\n/g,"\n"); +var match=src.match(/[\n]/g); +var lines=match?match.length:0; +html[hl++]='
                  0){path=reLastDir.exec(path)[1] +}path+=backDir[2] +}else{if(src.indexOf("/")!=-1){if(/^\.\/./.test(src)){path+=src.substring(2) +}else{if(/^\/./.test(src)){var domain=/^(\w+:\/\/[^\/]+)/.exec(path); +path=domain[1]+src +}else{path+=src +}}}}}}var m=path&&path.match(/([^\/]+)\/$/)||null; +if(path&&m){return path+fileName +}}; +var getFileName=function getFileName(path){if(!path){return"" +}var match=path&&path.match(/[^\/]+(\?.*)?(#.*)?$/); +return match&&match[0]||path +} +}}); +FBL.ns(function(){with(FBL){var ElementCache=Firebug.Lite.Cache.Element; +var insertSliceSize=18; +var insertInterval=40; +var ignoreVars={__firebug__:1,"eval":1,java:1,sun:1,Packages:1,JavaArray:1,JavaMember:1,JavaObject:1,JavaClass:1,JavaPackage:1,_firebug:1,_FirebugConsole:1,_FirebugCommandLine:1}; +if(Firebug.ignoreFirebugElements){ignoreVars[Firebug.Lite.Cache.ID]=1 +}var memberPanelRep=isIE6?{"class":"memberLabel $member.type\\Label",href:"javacript:void(0)"}:{"class":"memberLabel $member.type\\Label"}; +var RowTag=TR({"class":"memberRow $member.open $member.type\\Row",$hasChildren:"$member.hasChildren",role:"presentation",level:"$member.level"},TD({"class":"memberLabelCell",style:"padding-left: $member.indent\\px",role:"presentation"},A(memberPanelRep,SPAN({},"$member.name"))),TD({"class":"memberValueCell",role:"presentation"},TAG("$member.tag",{object:"$member.value"}))); +var WatchRowTag=TR({"class":"watchNewRow",level:0},TD({"class":"watchEditCell",colspan:2},DIV({"class":"watchEditBox a11yFocusNoTab",role:"button",tabindex:"0","aria-label":$STR("press enter to add new watch expression")},$STR("NewWatch")))); +var SizerRow=TR({role:"presentation"},TD({width:"30%"}),TD({width:"70%"})); +var domTableClass=isIElt8?"domTable domTableIE":"domTable"; +var DirTablePlate=domplate(Firebug.Rep,{tag:TABLE({"class":domTableClass,cellpadding:0,cellspacing:0,onclick:"$onClick",role:"tree"},TBODY({role:"presentation"},SizerRow,FOR("member","$object|memberIterator",RowTag))),watchTag:TABLE({"class":domTableClass,cellpadding:0,cellspacing:0,_toggles:"$toggles",_domPanel:"$domPanel",onclick:"$onClick",role:"tree"},TBODY({role:"presentation"},SizerRow,WatchRowTag)),tableTag:TABLE({"class":domTableClass,cellpadding:0,cellspacing:0,_toggles:"$toggles",_domPanel:"$domPanel",onclick:"$onClick",role:"tree"},TBODY({role:"presentation"},SizerRow)),rowTag:FOR("member","$members",RowTag),memberIterator:function(object,level){return getMembers(object,level) +},onClick:function(event){if(!isLeftClick(event)){return +}var target=event.target||event.srcElement; +var row=getAncestorByClass(target,"memberRow"); +var label=getAncestorByClass(target,"memberLabel"); +if(label&&hasClass(row,"hasChildren")){var row=label.parentNode.parentNode; +this.toggleRow(row) +}else{var object=Firebug.getRepObject(target); +if(typeof(object)=="function"){Firebug.chrome.select(object,"script"); +cancelEvent(event) +}else{if(event.detail==2&&!object){var panel=row.parentNode.parentNode.domPanel; +if(panel){var rowValue=panel.getRowPropertyValue(row); +if(typeof(rowValue)=="boolean"){panel.setPropertyValue(row,!rowValue) +}else{panel.editProperty(row) +}cancelEvent(event) +}}}}return false +},toggleRow:function(row){var level=parseInt(row.getAttribute("level")); +var toggles=row.parentNode.parentNode.toggles; +if(hasClass(row,"opened")){removeClass(row,"opened"); +if(toggles){var path=getPath(row); +for(var i=0; +i=priorScrollTop){panelNode.scrollTop=priorScrollTop +}},delay)); +delay+=insertInterval +}}if(offscreen){timeouts.push(this.context.setTimeout(function(){if(panelNode.firstChild){panelNode.replaceChild(table,panelNode.firstChild) +}else{panelNode.appendChild(table) +}panelNode.scrollTop=priorScrollTop +},delay)) +}else{timeouts.push(this.context.setTimeout(function(){panelNode.scrollTop=scrollTop==undefined?0:scrollTop +},delay)) +}this.timeouts=timeouts +},showEmptyMembers:function(){FirebugReps.Warning.tag.replace({object:"NoMembersWarning"},this.panelNode) +},findPathObject:function(object){var pathIndex=-1; +for(var i=0; +i1){for(var i=1; +i"); +r.push(i==0?"window":path[i]||"Object"); +r.push(""); +if(i>') +}}panel.statusBarNode.innerHTML=r.join("") +}; +var DOMMainPanel=Firebug.DOMPanel=function(){}; +Firebug.DOMPanel.DirTable=DirTablePlate; +DOMMainPanel.prototype=extend(Firebug.DOMBasePanel.prototype,{onClickStatusBar:function(event){var target=event.srcElement||event.target; +var element=getAncestorByClass(target,"fbHover"); +if(element){var pathIndex=element.getAttribute("pathIndex"); +if(pathIndex){this.select(this.getPathObject(pathIndex)) +}}},selectRow:function(row,target){if(!target){target=row.lastChild.firstChild +}if(!target||!target.repObject){return +}this.pathToAppend=getPath(row); +var valueBox=row.lastChild.firstChild; +if(hasClass(valueBox,"objectBox-array")){var arrayIndex=FirebugReps.Arr.getItemIndex(target); +this.pathToAppend.push(arrayIndex) +}this.select(target.repObject,true) +},onClick:function(event){var target=event.srcElement||event.target; +var repNode=Firebug.getRepNode(target); +if(repNode){var row=getAncestorByClass(target,"memberRow"); +if(row){this.selectRow(row,repNode); +cancelEvent(event) +}}},name:"DOM",title:"DOM",searchable:true,statusSeparator:">",options:{hasToolButtons:true,hasStatusBar:true},create:function(){Firebug.DOMBasePanel.prototype.create.apply(this,arguments); +this.onClick=bind(this.onClick,this); +this.onClickStatusBar=bind(this.onClickStatusBar,this); +this.panelNode.style.padding="0 1px" +},initialize:function(oldPanelNode){Firebug.DOMBasePanel.prototype.initialize.apply(this,arguments); +addEvent(this.panelNode,"click",this.onClick); +this.ishow(); +addEvent(this.statusBarNode,"click",this.onClickStatusBar) +},shutdown:function(){removeEvent(this.panelNode,"click",this.onClick); +Firebug.DOMBasePanel.prototype.shutdown.apply(this,arguments) +}}); +Firebug.registerPanel(DOMMainPanel); +var getMembers=function getMembers(object,level){if(!level){level=0 +}var ordinals=[],userProps=[],userClasses=[],userFuncs=[],domProps=[],domFuncs=[],domConstants=[]; +try{var domMembers=getDOMMembers(object); +if(object.wrappedJSObject){var insecureObject=object.wrappedJSObject +}else{var insecureObject=object +}if(isIE&&isFunction(object)){addMember("user",userProps,"prototype",object.prototype,level) +}for(var name in insecureObject){if(ignoreVars[name]==1){continue +}var val; +try{val=insecureObject[name] +}catch(exc){if(FBTrace.DBG_ERRORS&&FBTrace.DBG_DOM){FBTrace.sysout("dom.getMembers cannot access "+name,exc) +}}var ordinal=parseInt(name); +if(ordinal||ordinal==0){addMember("ordinal",ordinals,name,val,level) +}else{if(isFunction(val)){if(isClassFunction(val)&&!(name in domMembers)){addMember("userClass",userClasses,name,val,level) +}else{if(name in domMembers){addMember("domFunction",domFuncs,name,val,level,domMembers[name]) +}else{addMember("userFunction",userFuncs,name,val,level) +}}}else{var prefix=""; +if(name in domMembers&&!(name in domConstantMap)){addMember("dom",domProps,(prefix+name),val,level,domMembers[name]) +}else{if(name in domConstantMap){addMember("dom",domConstants,(prefix+name),val,level) +}else{addMember("user",userProps,(prefix+name),val,level) +}}}}}}catch(exc){throw exc; +if(FBTrace.DBG_ERRORS&&FBTrace.DBG_DOM){FBTrace.sysout("dom.getMembers FAILS: ",exc) +}}function sortName(a,b){return a.name>b.name?1:-1 +}function sortOrder(a,b){return a.order>b.order?1:-1 +}var members=[]; +members.push.apply(members,ordinals); +Firebug.showUserProps=true; +Firebug.showUserFuncs=true; +Firebug.showDOMProps=true; +Firebug.showDOMFuncs=true; +Firebug.showDOMConstants=true; +if(Firebug.showUserProps){userProps.sort(sortName); +members.push.apply(members,userProps) +}if(Firebug.showUserFuncs){userClasses.sort(sortName); +members.push.apply(members,userClasses); +userFuncs.sort(sortName); +members.push.apply(members,userFuncs) +}if(Firebug.showDOMProps){domProps.sort(sortName); +members.push.apply(members,domProps) +}if(Firebug.showDOMFuncs){domFuncs.sort(sortName); +members.push.apply(members,domFuncs) +}if(Firebug.showDOMConstants){members.push.apply(members,domConstants) +}return members +}; +function expandMembers(members,toggles,offset,level){var expanded=0; +for(var i=offset; +ilevel){break +}if(toggles.hasOwnProperty(member.name)){member.open="opened"; +var newMembers=getMembers(member.value,level+1); +var args=[i+1,0]; +args.push.apply(args,newMembers); +members.splice.apply(members,args); +expanded+=newMembers.length; +i+=newMembers.length+expandMembers(members,toggles[member.name],i+1,level+1) +}}return expanded +}function isClassFunction(fn){try{for(var name in fn.prototype){return true +}}catch(exc){}return false +}var hasProperties=function hasProperties(ob){try{for(var name in ob){return true +}}catch(exc){}if(isFunction(ob)){return true +}return false +}; +FBL.ErrorCopy=function(message){this.message=message +}; +var addMember=function addMember(type,props,name,value,level,order){var rep=Firebug.getRep(value); +var tag=rep.shortTag?rep.shortTag:rep.tag; +var ErrorCopy=function(){}; +var valueType=typeof(value); +var hasChildren=hasProperties(value)&&!(value instanceof ErrorCopy)&&(isFunction(value)||(valueType=="object"&&value!=null)||(valueType=="string"&&value.length>Firebug.stringCropLength)); +props.push({name:name,value:value,type:type,rowClass:"memberRow-"+type,open:"",order:order,level:level,indent:level*16,hasChildren:hasChildren,tag:tag}) +}; +var getWatchRowIndex=function getWatchRowIndex(row){var index=-1; +for(; +row&&hasClass(row,"watchRow"); +row=row.previousSibling){++index +}return index +}; +var getRowName=function getRowName(row){var node=row.firstChild; +return node.textContent?node.textContent:node.innerText +}; +var getRowValue=function getRowValue(row){return row.lastChild.firstChild.repObject +}; +var getRowOwnerObject=function getRowOwnerObject(row){var parentRow=getParentRow(row); +if(parentRow){return getRowValue(parentRow) +}}; +var getParentRow=function getParentRow(row){var level=parseInt(row.getAttribute("level"))-1; +for(row=row.previousSibling; +row; +row=row.previousSibling){if(parseInt(row.getAttribute("level"))==level){return row +}}}; +var getPath=function getPath(row){var name=getRowName(row); +var path=[name]; +var level=parseInt(row.getAttribute("level"))-1; +for(row=row.previousSibling; +row; +row=row.previousSibling){if(parseInt(row.getAttribute("level"))==level){var name=getRowName(row); +path.splice(0,0,name); +--level +}}return path +}; +Firebug.DOM=extend(Firebug.Module,{getPanel:function(){return Firebug.chrome?Firebug.chrome.getPanel("DOM"):null +}}); +Firebug.registerModule(Firebug.DOM); +var lastHighlightedObject; +function DOMSidePanel(){}DOMSidePanel.prototype=extend(Firebug.DOMBasePanel.prototype,{selectRow:function(row,target){if(!target){target=row.lastChild.firstChild +}if(!target||!target.repObject){return +}this.pathToAppend=getPath(row); +var valueBox=row.lastChild.firstChild; +if(hasClass(valueBox,"objectBox-array")){var arrayIndex=FirebugReps.Arr.getItemIndex(target); +this.pathToAppend.push(arrayIndex) +}var object=target.repObject; +if(instanceOf(object,"Element")){Firebug.HTML.selectTreeNode(ElementCache(object)) +}else{Firebug.chrome.selectPanel("DOM"); +Firebug.chrome.getPanel("DOM").select(object,true) +}},onClick:function(event){var target=event.srcElement||event.target; +var repNode=Firebug.getRepNode(target); +if(repNode){var row=getAncestorByClass(target,"memberRow"); +if(row){this.selectRow(row,repNode); +cancelEvent(event) +}}},name:"DOMSidePanel",parentPanel:"HTML",title:"DOM",options:{hasToolButtons:true},isInitialized:false,create:function(){Firebug.DOMBasePanel.prototype.create.apply(this,arguments); +this.onClick=bind(this.onClick,this) +},initialize:function(){Firebug.DOMBasePanel.prototype.initialize.apply(this,arguments); +addEvent(this.panelNode,"click",this.onClick); +var selection=ElementCache.get(FirebugChrome.selectedHTMLElementId); +if(selection){this.select(selection,true) +}},shutdown:function(){removeEvent(this.panelNode,"click",this.onClick); +Firebug.DOMBasePanel.prototype.shutdown.apply(this,arguments) +},reattach:function(oldChrome){this.toggles=oldChrome.getPanel("DOMSidePanel").toggles +}}); +Firebug.registerPanel(DOMSidePanel) +}}); +FBL.FBTrace={}; +(function(){var traceOptions={DBG_TIMESTAMP:1,DBG_INITIALIZE:1,DBG_CHROME:1,DBG_ERRORS:1,DBG_DISPATCH:1,DBG_CSS:1}; +this.module=null; +this.initialize=function(){if(!this.messageQueue){this.messageQueue=[] +}for(var name in traceOptions){this[name]=traceOptions[name] +}}; +this.sysout=function(){return this.logFormatted(arguments,"") +}; +this.dumpProperties=function(title,object){return this.logFormatted("dumpProperties() not supported.","warning") +}; +this.dumpStack=function(){return this.logFormatted("dumpStack() not supported.","warning") +}; +this.flush=function(module){this.module=module; +var queue=this.messageQueue; +this.messageQueue=[]; +for(var i=0; +i"); +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); +FBL.ns(function(){with(FBL){if(!Env.Options.enableTrace){return +}Firebug.Trace=extend(Firebug.Module,{getPanel:function(){return Firebug.chrome?Firebug.chrome.getPanel("Trace"):null +},clear:function(){this.getPanel().panelNode.innerHTML="" +}}); +Firebug.registerModule(Firebug.Trace); +function TracePanel(){}TracePanel.prototype=extend(Firebug.Panel,{name:"Trace",title:"Trace",options:{hasToolButtons:true,innerHTMLSync:true},create:function(){Firebug.Panel.create.apply(this,arguments); +this.clearButton=new Button({caption:"Clear",title:"Clear FBTrace logs",owner:Firebug.Trace,onClick:Firebug.Trace.clear}) +},initialize:function(){Firebug.Panel.initialize.apply(this,arguments); +this.clearButton.initialize() +}}); +Firebug.registerPanel(TracePanel) +}}); +FBL.ns(function(){with(FBL){var modules=[]; +var panelTypes=[]; +var panelTypeMap={}; +var parentPanelMap={}; +var registerModule=Firebug.registerModule; +var registerPanel=Firebug.registerPanel; +append(Firebug,{extend:function(fn){if(Firebug.chrome&&Firebug.chrome.addPanel){var namespace=ns(fn); +fn.call(namespace,FBL) +}else{setTimeout(function(){Firebug.extend(fn) +},100) +}},registerModule:function(){registerModule.apply(Firebug,arguments); +modules.push.apply(modules,arguments); +dispatch(modules,"initialize",[]); +if(FBTrace.DBG_INITIALIZE){FBTrace.sysout("Firebug.registerModule") +}},registerPanel:function(){registerPanel.apply(Firebug,arguments); +panelTypes.push.apply(panelTypes,arguments); +for(var i=0,panelType; +panelType=arguments[i]; +++i){if(panelType.prototype.name=="Dev"){continue +}panelTypeMap[panelType.prototype.name]=arguments[i]; +var parentPanelName=panelType.prototype.parentPanel; +if(parentPanelName){parentPanelMap[parentPanelName]=1 +}else{var panelName=panelType.prototype.name; +var chrome=Firebug.chrome; +chrome.addPanel(panelName); +var onTabClick=function onTabClick(){chrome.selectPanel(panelName); +return false +}; +chrome.addController([chrome.panelMap[panelName].tabNode,"mousedown",onTabClick]) +}}if(FBTrace.DBG_INITIALIZE){for(var i=0; +i .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;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;}#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;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 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;}',HTML:'
                   
                   
                  >>>
                  2 errors'} +}}); +FBL.initialize() +})(); \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/license.txt b/php/kindeditor_demo/kindeditor/lib/firebug-lite/license.txt new file mode 100755 index 0000000..ba43b75 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/firebug-lite/license.txt @@ -0,0 +1,30 @@ +Software License Agreement (BSD License) + +Copyright (c) 2007, Parakey Inc. +All rights reserved. + +Redistribution and use of this software in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of Parakey Inc. nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of Parakey Inc. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/plugin/proxy/proxy.php b/php/kindeditor_demo/kindeditor/lib/firebug-lite/plugin/proxy/proxy.php new file mode 100755 index 0000000..3bf3f92 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/firebug-lite/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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/blank.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/blank.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/buttonBg.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/buttonBg.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/buttonBgHover.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/buttonBgHover.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/detach.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/detach.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/disable.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/disable.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/disableHover.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/disableHover.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/disableHover.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/disableHover.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/downActive.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/downActive.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/downHover.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/downHover.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/errorIcon-sm.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/errorIcon-sm.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/firebug.css b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/firebug.css new file mode 100755 index 0000000..004925f --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/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: 6px; + 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) #d4d0c8 0 0; + height: 28px; + font-size: 11px; +} + +#fbPanelBarBox { + background: url(sprite.png) #c5c1ba 0 -28px; + 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; + 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: #d4d0c8 #fff #d4d0c8 #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: 8px 0 4px 5px; + z-index: 6; + background: url(sprite.png) #D4D0C8 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) #c5c1ba 0 -28px; + position: absolute; + left: 4px; +} + +#fbPanelBar2Box { + background: url(sprite.png) #c5c1ba 0 -28px; + 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: 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: #D4D0C8; + 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; + 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) #d4d0c8 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: #d4d0c8; + 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: 28px; +} + +/************************************************************************************************/ +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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/firebug.html b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/firebug.html new file mode 100755 index 0000000..4432a32 --- /dev/null +++ b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/firebug.html @@ -0,0 +1,213 @@ + + + + +Firebug Lite + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                  + + + + +
                  +   +   +   +
                  + + +
                  +
                  + + + +   + + + + + + + + + Inspect + + + + + Clear + + + + + + + + + + + + + +
                  + +
                  + + + + + +
                   
                  + +
                  +
                  +
                  +
                  +
                  +
                  + + +
                   
                  + + +
                  + + +
                  +
                  +
                  + +
                  + + + + + +
                  + Run + Clear + + +
                  + +
                  +
                  +
                  >>>
                  + + +
                  +
                  + + + + 2 errors + + + + + \ No newline at end of file diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/firebug.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/firebug.png new file mode 100755 index 0000000000000000000000000000000000000000..123545a19a079c41ac812114bc2a67452fd17dc6 GIT binary patch literal 1059 zcmV+;1l;?HP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iXP% z2Pq=e5-MK+000?uMObu0Z*6U5Zgc=ca%Ew3Wn>_CX>@2HM@dakSAh-}000AiNklA#8Y0GKpmC|zSSSSTLMdUJs5FBPT3uB@?XQ7EZqyA5BjENf;8m}`! z!Qf=L3Nj$W^g>IimRn1Kws6Wh$HfE^>>%W zv3Sgxs&ZN>VU<;~2P%eP(AOKmWHJFDas%nqbFzPYMans~)q|V_-5@2b0 z1x?p4=Wi5tc16jXLp)2QktGSU*@R-PC!R<#F*S|ZY+-hG5ml|C>pJpHLX*itSrusy z_yMRp&Z1}5`24ePus3(0C?#Tv6v@prp-`}P!%De?WT;pEQrR3{?SQ8BuW7Ovw7vN@ z4@SF4#Wu+89k9K<#T$K5bls>GCN~x-C#O+Wm1KIGnb}1mm33}yevfGLplg6y<%5qu z<&*oj$)ytv4Gqv6?IF-$Lil&erP2|Pe*P7Q&5qY9aw|JUkJn65^dKq@yv;4hEuG+O z1(V3~w_i{{`hfHEa}v-0tQB5hRF1GOeTl49NEQr=WtFxD8=;;q1W5tcErfa}`?(A! zzSlX|G!lu_e~03F`W43~MOKfj92SbSdt}=DHn!q%6srrjCLm=NI0?TCfGkP4T#l>4 zYPHIvsTsPpBz@I5lZ9pqg*?MPgQ0dWtEqhoCmKC15=Ls4jm9yGJNsB*cSRm1j(HYKVylzTwx+0- zkC2laD|Gm6tZb`DdX=G|o5Y5V`Pd$B`3m&E=3_p#%VOR_sKrCb4Vwo??6lnDosnTA z@x@M?ai~K?)J2iyr|V??-eY8V0DbFs9xkW3YtJzdbTSv)B8F=NY0&BGEX8 zr_p~Y18DDzVzaxDJHx#gol*J)f%8(4SZ0^7T_qCmFuAtJOxe$!kdOP09Mm^+IQSvE zzs+$k;CpG9B7h(WFCNu0Zj(x|)x}&q&sss`y@-jst^?-PR!XBEAy^bNLEtp=1W`ME zx$pu(sYhw;K(3VW+O51l-i^{T&cs<430s7VP8lD)!*<2WVM(nK)*QA`IYh6N&}9qf zvX#ll3s@BkVG literal 0 HcmV?d00001 diff --git a/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/group.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/group.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/infoIcon.gif b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/infoIcon.gif new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/min.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/min.png new file mode 100755 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/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/off.png b/php/kindeditor_demo/kindeditor/lib/firebug-lite/skin/classic/off.png new file mode 100755 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%