From 211b165c0789f79601c146e5f5fe37f12ef321d1 Mon Sep 17 00:00:00 2001 From: shizuki Date: Fri, 26 Jun 2009 08:18:54 +0000 Subject: [PATCH] git-svn-id: https://svn.sourceforge.jp/svnroot/nucleus-jp/plugin@1020 1ca29b6e-896d-4ea0-84a5-967f57386b96 --- NP_TrackBack/branches/DOM-branch/NP_TrackBack.php | 1984 ++++++++++++ .../branches/DOM-branch/trackback/CHANGELOG.txt | 123 + .../branches/DOM-branch/trackback/autodetect.php | 259 ++ .../branches/DOM-branch/trackback/detectlist.php | 70 + .../branches/DOM-branch/trackback/grid.php | 238 ++ .../branches/DOM-branch/trackback/help.html | 111 + .../branches/DOM-branch/trackback/index.php | 496 +++ .../DOM-branch/trackback/japanese-euc.help.html | 116 + .../trackback/japanese-euc.templates/all.html | 106 + .../trackback/japanese-euc.templates/all_ajax.html | 130 + .../trackback/japanese-euc.templates/blocked.html | 119 + .../japanese-euc.templates/blocked_ajax.html | 134 + .../trackback/japanese-euc.templates/form.html | 56 + .../trackback/japanese-euc.templates/index.html | 34 + .../trackback/japanese-euc.templates/list.html | 107 + .../trackback/japanese-euc.templates/menu.html | 32 + .../trackback/japanese-euc.templates/ping.html | 50 + .../japanese-euc.templates/response_all.xml | 35 + .../japanese-euc.templates/response_blocked.xml | 41 + .../japanese-euc.templates/response_doblock.xml | 8 + .../japanese-euc.templates/response_dodelete.xml | 8 + .../japanese-euc.templates/response_dounblock.xml | 8 + .../japanese-euc.templates/updatetable.html | 13 + .../updatetablefinished.html | 5 + .../DOM-branch/trackback/japanese-utf8.help.html | 116 + .../trackback/japanese-utf8.templates/all.html | 106 + .../japanese-utf8.templates/all_ajax.html | 130 + .../trackback/japanese-utf8.templates/blocked.html | 119 + .../japanese-utf8.templates/blocked_ajax.html | 134 + .../trackback/japanese-utf8.templates/form.html | 56 + .../trackback/japanese-utf8.templates/index.html | 34 + .../trackback/japanese-utf8.templates/list.html | 107 + .../trackback/japanese-utf8.templates/menu.html | 32 + .../trackback/japanese-utf8.templates/ping.html | 50 + .../japanese-utf8.templates/response_all.xml | 35 + .../japanese-utf8.templates/response_blocked.xml | 41 + .../japanese-utf8.templates/response_doblock.xml | 8 + .../japanese-utf8.templates/response_dodelete.xml | 8 + .../japanese-utf8.templates/response_dounblock.xml | 8 + .../japanese-utf8.templates/updatetable.html | 13 + .../updatetablefinished.html | 5 + .../branches/DOM-branch/trackback/js/prototype.js | 3271 ++++++++++++++++++++ .../trackback/js/rico/css/coffee-with-milk.css | 73 + .../DOM-branch/trackback/js/rico/css/grayedout.css | 68 + .../DOM-branch/trackback/js/rico/css/greenHdg.css | 8 + .../trackback/js/rico/css/iegradient.css | 3 + .../trackback/js/rico/css/ricoCalendar.css | 112 + .../DOM-branch/trackback/js/rico/css/ricoGrid.css | 125 + .../trackback/js/rico/css/ricoLiveGridForms.css | 81 + .../DOM-branch/trackback/js/rico/css/ricoMenu.css | 95 + .../DOM-branch/trackback/js/rico/css/ricoTree.css | 42 + .../DOM-branch/trackback/js/rico/css/tanChisel.css | 36 + .../DOM-branch/trackback/js/rico/css/warmfall.css | 63 + .../DOM-branch/trackback/js/rico/export-owc.html | 34 + .../DOM-branch/trackback/js/rico/export-plain.html | 28 + .../DOM-branch/trackback/js/rico/images/aline.gif | Bin 0 -> 47 bytes .../trackback/js/rico/images/calarrow.png | Bin 0 -> 917 bytes .../trackback/js/rico/images/calendaricon.gif | Bin 0 -> 259 bytes .../DOM-branch/trackback/js/rico/images/close.gif | Bin 0 -> 111 bytes .../trackback/js/rico/images/divider.gif | Bin 0 -> 49 bytes .../DOM-branch/trackback/js/rico/images/doc.gif | Bin 0 -> 949 bytes .../trackback/js/rico/images/dotbutton.gif | Bin 0 -> 874 bytes .../DOM-branch/trackback/js/rico/images/drop.gif | Bin 0 -> 102 bytes .../trackback/js/rico/images/filtercol.gif | Bin 0 -> 293 bytes .../trackback/js/rico/images/folderclosed.gif | Bin 0 -> 901 bytes .../trackback/js/rico/images/folderopen.gif | Bin 0 -> 909 bytes .../trackback/js/rico/images/grayedout.gif | Bin 0 -> 2983 bytes .../DOM-branch/trackback/js/rico/images/left.gif | Bin 0 -> 105 bytes .../DOM-branch/trackback/js/rico/images/link.gif | Bin 0 -> 954 bytes .../DOM-branch/trackback/js/rico/images/node.gif | Bin 0 -> 846 bytes .../trackback/js/rico/images/nodeblank.gif | Bin 0 -> 828 bytes .../trackback/js/rico/images/nodelast.gif | Bin 0 -> 838 bytes .../trackback/js/rico/images/nodeline.gif | Bin 0 -> 836 bytes .../DOM-branch/trackback/js/rico/images/nodem.gif | Bin 0 -> 97 bytes .../trackback/js/rico/images/nodemlast.gif | Bin 0 -> 125 bytes .../DOM-branch/trackback/js/rico/images/nodep.gif | Bin 0 -> 133 bytes .../trackback/js/rico/images/nodeplast.gif | Bin 0 -> 130 bytes .../DOM-branch/trackback/js/rico/images/resize.gif | Bin 0 -> 51 bytes .../trackback/js/rico/images/ricologo.gif | Bin 0 -> 1105 bytes .../DOM-branch/trackback/js/rico/images/right.gif | Bin 0 -> 105 bytes .../DOM-branch/trackback/js/rico/images/shadow.png | Bin 0 -> 3576 bytes .../trackback/js/rico/images/shadow_ll.png | Bin 0 -> 274 bytes .../trackback/js/rico/images/shadow_ur.png | Bin 0 -> 275 bytes .../trackback/js/rico/images/sort_asc.gif | Bin 0 -> 77 bytes .../trackback/js/rico/images/sort_desc.gif | Bin 0 -> 76 bytes .../DOM-branch/trackback/js/rico/prototype.js | 3269 +++++++++++++++++++ .../branches/DOM-branch/trackback/js/rico/rico.js | 214 ++ .../DOM-branch/trackback/js/rico/ricoAjaxEngine.js | 178 ++ .../DOM-branch/trackback/js/rico/ricoBehaviors.js | 188 ++ .../DOM-branch/trackback/js/rico/ricoCalendar.js | 443 +++ .../DOM-branch/trackback/js/rico/ricoColor.js | 29 + .../trackback/js/rico/ricoColorPicker.js | 75 + .../DOM-branch/trackback/js/rico/ricoCommon.js | 739 +++++ .../DOM-branch/trackback/js/rico/ricoComponents.js | 194 ++ .../DOM-branch/trackback/js/rico/ricoDashboard.js | 329 ++ .../DOM-branch/trackback/js/rico/ricoDragDrop.js | 770 +++++ .../DOM-branch/trackback/js/rico/ricoEffects.js | 389 +++ .../DOM-branch/trackback/js/rico/ricoGridCommon.js | 685 ++++ .../DOM-branch/trackback/js/rico/ricoLiveGrid.js | 1806 +++++++++++ .../trackback/js/rico/ricoLiveGridAjax.js | 412 +++ .../trackback/js/rico/ricoLiveGridForms.js | 830 +++++ .../trackback/js/rico/ricoLiveGridMenu.js | 110 + .../DOM-branch/trackback/js/rico/ricoMenu.js | 197 ++ .../DOM-branch/trackback/js/rico/ricoSheet.js | 1577 ++++++++++ .../DOM-branch/trackback/js/rico/ricoSimpleGrid.js | 160 + .../trackback/js/rico/ricoSimpleGrid.xsl | 285 ++ .../trackback/js/rico/ricoSimpleGrid2xl.xsl | 160 + .../DOM-branch/trackback/js/rico/ricoStyles.js | 469 +++ .../DOM-branch/trackback/js/rico/ricoTree.js | 318 ++ .../trackback/js/rico/translations/livegrid_de.js | 86 + .../trackback/js/rico/translations/livegrid_es.js | 79 + .../trackback/js/rico/translations/livegrid_fr.js | 79 + .../trackback/js/rico/translations/livegrid_it.js | 80 + .../trackback/js/rico/translations/livegrid_ja.js | 49 + .../trackback/js/rico/translations/livegrid_pt.js | 55 + .../trackback/js/rico/translations/livegrid_ru.js | 82 + .../trackback/js/rico/translations/livegrid_ua.js | 82 + .../trackback/js/rico/translations/livegrid_zh.js | 55 + .../DOM-branch/trackback/language/english.php | 87 + .../DOM-branch/trackback/language/japanese-euc.php | 69 + .../trackback/language/japanese-utf8.php | 84 + .../branches/DOM-branch/trackback/mkeuc.sh | 11 + .../branches/DOM-branch/trackback/silk/accept.png | Bin 0 -> 1012 bytes .../trackback/silk/application_view_list.png | Bin 0 -> 647 bytes .../branches/DOM-branch/trackback/silk/cross.png | Bin 0 -> 820 bytes .../branches/DOM-branch/trackback/silk/delete.png | Bin 0 -> 893 bytes .../DOM-branch/trackback/silk/exclamation.png | Bin 0 -> 890 bytes .../branches/DOM-branch/trackback/silk/help.png | Bin 0 -> 1016 bytes .../DOM-branch/trackback/silk/house_go.png | Bin 0 -> 1054 bytes .../branches/DOM-branch/trackback/silk/link.png | Bin 0 -> 504 bytes .../DOM-branch/trackback/silk/link_break.png | Bin 0 -> 726 bytes .../DOM-branch/trackback/silk/plugin_edit.png | Bin 0 -> 985 bytes .../branches/DOM-branch/trackback/silk/readme.txt | 22 + .../branches/DOM-branch/trackback/silk/tick.png | Bin 0 -> 627 bytes .../DOM-branch/trackback/silk/transmit_go.png | Bin 0 -> 1156 bytes .../branches/DOM-branch/trackback/template.php | 35 + .../DOM-branch/trackback/templates/all.html | 106 + .../DOM-branch/trackback/templates/all_ajax.html | 128 + .../DOM-branch/trackback/templates/blocked.html | 119 + .../trackback/templates/blocked_ajax.html | 133 + .../DOM-branch/trackback/templates/form.html | 56 + .../DOM-branch/trackback/templates/index.html | 34 + .../DOM-branch/trackback/templates/list.html | 107 + .../DOM-branch/trackback/templates/menu.html | 33 + .../DOM-branch/trackback/templates/ping.html | 50 + .../trackback/templates/response_all.xml | 35 + .../trackback/templates/response_blocked.xml | 41 + .../trackback/templates/response_doblock.xml | 8 + .../trackback/templates/response_dodelete.xml | 8 + .../trackback/templates/response_dounblock.xml | 8 + .../trackback/templates/updatetable.html | 9 + .../trackback/templates/updatetablefinished.html | 5 + NP_TrackBack/trunk/NP_TrackBack.php | 2586 ++++++++++++++++ NP_TrackBack/trunk/trackback/CHANGELOG.txt | 123 + NP_TrackBack/trunk/trackback/autodetect.php | 259 ++ NP_TrackBack/trunk/trackback/detectlist.php | 70 + NP_TrackBack/trunk/trackback/grid.php | 238 ++ NP_TrackBack/trunk/trackback/help.html | 111 + NP_TrackBack/trunk/trackback/index.php | 496 +++ .../trunk/trackback/japanese-euc.help.html | 116 + .../trackback/japanese-euc.templates/all.html | 106 + .../trackback/japanese-euc.templates/all_ajax.html | 130 + .../trackback/japanese-euc.templates/blocked.html | 119 + .../japanese-euc.templates/blocked_ajax.html | 134 + .../trackback/japanese-euc.templates/form.html | 56 + .../trackback/japanese-euc.templates/index.html | 34 + .../trackback/japanese-euc.templates/list.html | 107 + .../trackback/japanese-euc.templates/menu.html | 32 + .../trackback/japanese-euc.templates/ping.html | 50 + .../japanese-euc.templates/response_all.xml | 35 + .../japanese-euc.templates/response_blocked.xml | 41 + .../japanese-euc.templates/response_doblock.xml | 8 + .../japanese-euc.templates/response_dodelete.xml | 8 + .../japanese-euc.templates/response_dounblock.xml | 8 + .../japanese-euc.templates/updatetable.html | 13 + .../updatetablefinished.html | 5 + .../trunk/trackback/japanese-utf8.help.html | 116 + .../trackback/japanese-utf8.templates/all.html | 106 + .../japanese-utf8.templates/all_ajax.html | 130 + .../trackback/japanese-utf8.templates/blocked.html | 119 + .../japanese-utf8.templates/blocked_ajax.html | 134 + .../trackback/japanese-utf8.templates/form.html | 56 + .../trackback/japanese-utf8.templates/index.html | 34 + .../trackback/japanese-utf8.templates/list.html | 107 + .../trackback/japanese-utf8.templates/menu.html | 32 + .../trackback/japanese-utf8.templates/ping.html | 50 + .../japanese-utf8.templates/response_all.xml | 35 + .../japanese-utf8.templates/response_blocked.xml | 41 + .../japanese-utf8.templates/response_doblock.xml | 8 + .../japanese-utf8.templates/response_dodelete.xml | 8 + .../japanese-utf8.templates/response_dounblock.xml | 8 + .../japanese-utf8.templates/updatetable.html | 13 + .../updatetablefinished.html | 5 + NP_TrackBack/trunk/trackback/js/prototype.js | 3271 ++++++++++++++++++++ .../trackback/js/rico/css/coffee-with-milk.css | 73 + .../trunk/trackback/js/rico/css/grayedout.css | 68 + .../trunk/trackback/js/rico/css/greenHdg.css | 8 + .../trunk/trackback/js/rico/css/iegradient.css | 3 + .../trunk/trackback/js/rico/css/ricoCalendar.css | 112 + .../trunk/trackback/js/rico/css/ricoGrid.css | 125 + .../trackback/js/rico/css/ricoLiveGridForms.css | 81 + .../trunk/trackback/js/rico/css/ricoMenu.css | 95 + .../trunk/trackback/js/rico/css/ricoTree.css | 42 + .../trunk/trackback/js/rico/css/tanChisel.css | 36 + .../trunk/trackback/js/rico/css/warmfall.css | 63 + .../trunk/trackback/js/rico/export-owc.html | 34 + .../trunk/trackback/js/rico/export-plain.html | 28 + .../trunk/trackback/js/rico/images/aline.gif | Bin 0 -> 47 bytes .../trunk/trackback/js/rico/images/calarrow.png | Bin 0 -> 917 bytes .../trackback/js/rico/images/calendaricon.gif | Bin 0 -> 259 bytes .../trunk/trackback/js/rico/images/close.gif | Bin 0 -> 111 bytes .../trunk/trackback/js/rico/images/divider.gif | Bin 0 -> 49 bytes .../trunk/trackback/js/rico/images/doc.gif | Bin 0 -> 949 bytes .../trunk/trackback/js/rico/images/dotbutton.gif | Bin 0 -> 874 bytes .../trunk/trackback/js/rico/images/drop.gif | Bin 0 -> 102 bytes .../trunk/trackback/js/rico/images/filtercol.gif | Bin 0 -> 293 bytes .../trackback/js/rico/images/folderclosed.gif | Bin 0 -> 901 bytes .../trunk/trackback/js/rico/images/folderopen.gif | Bin 0 -> 909 bytes .../trunk/trackback/js/rico/images/grayedout.gif | Bin 0 -> 2983 bytes .../trunk/trackback/js/rico/images/left.gif | Bin 0 -> 105 bytes .../trunk/trackback/js/rico/images/link.gif | Bin 0 -> 954 bytes .../trunk/trackback/js/rico/images/node.gif | Bin 0 -> 846 bytes .../trunk/trackback/js/rico/images/nodeblank.gif | Bin 0 -> 828 bytes .../trunk/trackback/js/rico/images/nodelast.gif | Bin 0 -> 838 bytes .../trunk/trackback/js/rico/images/nodeline.gif | Bin 0 -> 836 bytes .../trunk/trackback/js/rico/images/nodem.gif | Bin 0 -> 97 bytes .../trunk/trackback/js/rico/images/nodemlast.gif | Bin 0 -> 125 bytes .../trunk/trackback/js/rico/images/nodep.gif | Bin 0 -> 133 bytes .../trunk/trackback/js/rico/images/nodeplast.gif | Bin 0 -> 130 bytes .../trunk/trackback/js/rico/images/resize.gif | Bin 0 -> 51 bytes .../trunk/trackback/js/rico/images/ricologo.gif | Bin 0 -> 1105 bytes .../trunk/trackback/js/rico/images/right.gif | Bin 0 -> 105 bytes .../trunk/trackback/js/rico/images/shadow.png | Bin 0 -> 3576 bytes .../trunk/trackback/js/rico/images/shadow_ll.png | Bin 0 -> 274 bytes .../trunk/trackback/js/rico/images/shadow_ur.png | Bin 0 -> 275 bytes .../trunk/trackback/js/rico/images/sort_asc.gif | Bin 0 -> 77 bytes .../trunk/trackback/js/rico/images/sort_desc.gif | Bin 0 -> 76 bytes NP_TrackBack/trunk/trackback/js/rico/prototype.js | 3269 +++++++++++++++++++ NP_TrackBack/trunk/trackback/js/rico/rico.js | 214 ++ .../trunk/trackback/js/rico/ricoAjaxEngine.js | 178 ++ .../trunk/trackback/js/rico/ricoBehaviors.js | 188 ++ .../trunk/trackback/js/rico/ricoCalendar.js | 443 +++ NP_TrackBack/trunk/trackback/js/rico/ricoColor.js | 29 + .../trunk/trackback/js/rico/ricoColorPicker.js | 75 + NP_TrackBack/trunk/trackback/js/rico/ricoCommon.js | 739 +++++ .../trunk/trackback/js/rico/ricoComponents.js | 194 ++ .../trunk/trackback/js/rico/ricoDashboard.js | 329 ++ .../trunk/trackback/js/rico/ricoDragDrop.js | 770 +++++ .../trunk/trackback/js/rico/ricoEffects.js | 389 +++ .../trunk/trackback/js/rico/ricoGridCommon.js | 685 ++++ .../trunk/trackback/js/rico/ricoLiveGrid.js | 1806 +++++++++++ .../trunk/trackback/js/rico/ricoLiveGridAjax.js | 412 +++ .../trunk/trackback/js/rico/ricoLiveGridForms.js | 830 +++++ .../trunk/trackback/js/rico/ricoLiveGridMenu.js | 110 + NP_TrackBack/trunk/trackback/js/rico/ricoMenu.js | 197 ++ NP_TrackBack/trunk/trackback/js/rico/ricoSheet.js | 1577 ++++++++++ .../trunk/trackback/js/rico/ricoSimpleGrid.js | 160 + .../trunk/trackback/js/rico/ricoSimpleGrid.xsl | 285 ++ .../trunk/trackback/js/rico/ricoSimpleGrid2xl.xsl | 160 + NP_TrackBack/trunk/trackback/js/rico/ricoStyles.js | 469 +++ NP_TrackBack/trunk/trackback/js/rico/ricoTree.js | 318 ++ .../trackback/js/rico/translations/livegrid_de.js | 86 + .../trackback/js/rico/translations/livegrid_es.js | 79 + .../trackback/js/rico/translations/livegrid_fr.js | 79 + .../trackback/js/rico/translations/livegrid_it.js | 80 + .../trackback/js/rico/translations/livegrid_ja.js | 49 + .../trackback/js/rico/translations/livegrid_pt.js | 55 + .../trackback/js/rico/translations/livegrid_ru.js | 82 + .../trackback/js/rico/translations/livegrid_ua.js | 82 + .../trackback/js/rico/translations/livegrid_zh.js | 55 + NP_TrackBack/trunk/trackback/language/english.php | 52 + .../trunk/trackback/language/japanese-euc.php | 51 + .../trunk/trackback/language/japanese-utf8.php | 52 + NP_TrackBack/trunk/trackback/mkeuc.sh | 11 + NP_TrackBack/trunk/trackback/silk/accept.png | Bin 0 -> 1012 bytes .../trunk/trackback/silk/application_view_list.png | Bin 0 -> 647 bytes NP_TrackBack/trunk/trackback/silk/cross.png | Bin 0 -> 820 bytes NP_TrackBack/trunk/trackback/silk/delete.png | Bin 0 -> 893 bytes NP_TrackBack/trunk/trackback/silk/exclamation.png | Bin 0 -> 890 bytes NP_TrackBack/trunk/trackback/silk/help.png | Bin 0 -> 1016 bytes NP_TrackBack/trunk/trackback/silk/house_go.png | Bin 0 -> 1054 bytes NP_TrackBack/trunk/trackback/silk/link.png | Bin 0 -> 504 bytes NP_TrackBack/trunk/trackback/silk/link_break.png | Bin 0 -> 726 bytes NP_TrackBack/trunk/trackback/silk/plugin_edit.png | Bin 0 -> 985 bytes NP_TrackBack/trunk/trackback/silk/readme.txt | 22 + NP_TrackBack/trunk/trackback/silk/tick.png | Bin 0 -> 627 bytes NP_TrackBack/trunk/trackback/silk/transmit_go.png | Bin 0 -> 1156 bytes NP_TrackBack/trunk/trackback/template.php | 35 + NP_TrackBack/trunk/trackback/templates/all.html | 106 + .../trunk/trackback/templates/all_ajax.html | 128 + .../trunk/trackback/templates/blocked.html | 119 + .../trunk/trackback/templates/blocked_ajax.html | 133 + NP_TrackBack/trunk/trackback/templates/form.html | 56 + NP_TrackBack/trunk/trackback/templates/index.html | 34 + NP_TrackBack/trunk/trackback/templates/list.html | 107 + NP_TrackBack/trunk/trackback/templates/menu.html | 33 + NP_TrackBack/trunk/trackback/templates/ping.html | 50 + .../trunk/trackback/templates/response_all.xml | 35 + .../trunk/trackback/templates/response_blocked.xml | 41 + .../trunk/trackback/templates/response_doblock.xml | 8 + .../trackback/templates/response_dodelete.xml | 8 + .../trackback/templates/response_dounblock.xml | 8 + .../trunk/trackback/templates/updatetable.html | 9 + .../trackback/templates/updatetablefinished.html | 5 + 304 files changed, 50487 insertions(+) create mode 100644 NP_TrackBack/branches/DOM-branch/NP_TrackBack.php create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/CHANGELOG.txt create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/autodetect.php create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/detectlist.php create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/grid.php create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/help.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/index.php create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.help.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/all.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/all_ajax.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/blocked.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/blocked_ajax.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/form.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/index.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/list.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/menu.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/ping.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/response_all.xml create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/response_blocked.xml create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/response_doblock.xml create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/response_dodelete.xml create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/response_dounblock.xml create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/updatetable.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/updatetablefinished.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.help.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/all.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/all_ajax.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/blocked.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/blocked_ajax.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/form.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/index.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/list.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/menu.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/ping.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/response_all.xml create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/response_blocked.xml create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/response_doblock.xml create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/response_dodelete.xml create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/response_dounblock.xml create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/updatetable.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/updatetablefinished.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/prototype.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/coffee-with-milk.css create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/grayedout.css create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/greenHdg.css create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/iegradient.css create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/ricoCalendar.css create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/ricoGrid.css create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/ricoLiveGridForms.css create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/ricoMenu.css create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/ricoTree.css create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/tanChisel.css create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/warmfall.css create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/export-owc.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/export-plain.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/aline.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/calarrow.png create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/calendaricon.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/close.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/divider.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/doc.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/dotbutton.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/drop.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/filtercol.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/folderclosed.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/folderopen.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/grayedout.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/left.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/link.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/node.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/nodeblank.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/nodelast.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/nodeline.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/nodem.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/nodemlast.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/nodep.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/nodeplast.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/resize.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/ricologo.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/right.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/shadow.png create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/shadow_ll.png create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/shadow_ur.png create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/sort_asc.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/sort_desc.gif create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/prototype.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/rico.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoAjaxEngine.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoBehaviors.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoCalendar.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoColor.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoColorPicker.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoCommon.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoComponents.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoDashboard.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoDragDrop.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoEffects.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoGridCommon.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoLiveGrid.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoLiveGridAjax.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoLiveGridForms.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoLiveGridMenu.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoMenu.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoSheet.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoSimpleGrid.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoSimpleGrid.xsl create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoSimpleGrid2xl.xsl create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoStyles.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoTree.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_de.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_es.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_fr.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_it.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_ja.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_pt.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_ru.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_ua.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_zh.js create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/language/english.php create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/language/japanese-euc.php create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/language/japanese-utf8.php create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/mkeuc.sh create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/silk/accept.png create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/silk/application_view_list.png create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/silk/cross.png create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/silk/delete.png create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/silk/exclamation.png create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/silk/help.png create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/silk/house_go.png create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/silk/link.png create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/silk/link_break.png create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/silk/plugin_edit.png create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/silk/readme.txt create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/silk/tick.png create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/silk/transmit_go.png create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/template.php create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/templates/all.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/templates/all_ajax.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/templates/blocked.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/templates/blocked_ajax.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/templates/form.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/templates/index.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/templates/list.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/templates/menu.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/templates/ping.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/templates/response_all.xml create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/templates/response_blocked.xml create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/templates/response_doblock.xml create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/templates/response_dodelete.xml create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/templates/response_dounblock.xml create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/templates/updatetable.html create mode 100644 NP_TrackBack/branches/DOM-branch/trackback/templates/updatetablefinished.html create mode 100644 NP_TrackBack/trunk/NP_TrackBack.php create mode 100644 NP_TrackBack/trunk/trackback/CHANGELOG.txt create mode 100644 NP_TrackBack/trunk/trackback/autodetect.php create mode 100644 NP_TrackBack/trunk/trackback/detectlist.php create mode 100644 NP_TrackBack/trunk/trackback/grid.php create mode 100644 NP_TrackBack/trunk/trackback/help.html create mode 100644 NP_TrackBack/trunk/trackback/index.php create mode 100644 NP_TrackBack/trunk/trackback/japanese-euc.help.html create mode 100644 NP_TrackBack/trunk/trackback/japanese-euc.templates/all.html create mode 100644 NP_TrackBack/trunk/trackback/japanese-euc.templates/all_ajax.html create mode 100644 NP_TrackBack/trunk/trackback/japanese-euc.templates/blocked.html create mode 100644 NP_TrackBack/trunk/trackback/japanese-euc.templates/blocked_ajax.html create mode 100644 NP_TrackBack/trunk/trackback/japanese-euc.templates/form.html create mode 100644 NP_TrackBack/trunk/trackback/japanese-euc.templates/index.html create mode 100644 NP_TrackBack/trunk/trackback/japanese-euc.templates/list.html create mode 100644 NP_TrackBack/trunk/trackback/japanese-euc.templates/menu.html create mode 100644 NP_TrackBack/trunk/trackback/japanese-euc.templates/ping.html create mode 100644 NP_TrackBack/trunk/trackback/japanese-euc.templates/response_all.xml create mode 100644 NP_TrackBack/trunk/trackback/japanese-euc.templates/response_blocked.xml create mode 100644 NP_TrackBack/trunk/trackback/japanese-euc.templates/response_doblock.xml create mode 100644 NP_TrackBack/trunk/trackback/japanese-euc.templates/response_dodelete.xml create mode 100644 NP_TrackBack/trunk/trackback/japanese-euc.templates/response_dounblock.xml create mode 100644 NP_TrackBack/trunk/trackback/japanese-euc.templates/updatetable.html create mode 100644 NP_TrackBack/trunk/trackback/japanese-euc.templates/updatetablefinished.html create mode 100644 NP_TrackBack/trunk/trackback/japanese-utf8.help.html create mode 100644 NP_TrackBack/trunk/trackback/japanese-utf8.templates/all.html create mode 100644 NP_TrackBack/trunk/trackback/japanese-utf8.templates/all_ajax.html create mode 100644 NP_TrackBack/trunk/trackback/japanese-utf8.templates/blocked.html create mode 100644 NP_TrackBack/trunk/trackback/japanese-utf8.templates/blocked_ajax.html create mode 100644 NP_TrackBack/trunk/trackback/japanese-utf8.templates/form.html create mode 100644 NP_TrackBack/trunk/trackback/japanese-utf8.templates/index.html create mode 100644 NP_TrackBack/trunk/trackback/japanese-utf8.templates/list.html create mode 100644 NP_TrackBack/trunk/trackback/japanese-utf8.templates/menu.html create mode 100644 NP_TrackBack/trunk/trackback/japanese-utf8.templates/ping.html create mode 100644 NP_TrackBack/trunk/trackback/japanese-utf8.templates/response_all.xml create mode 100644 NP_TrackBack/trunk/trackback/japanese-utf8.templates/response_blocked.xml create mode 100644 NP_TrackBack/trunk/trackback/japanese-utf8.templates/response_doblock.xml create mode 100644 NP_TrackBack/trunk/trackback/japanese-utf8.templates/response_dodelete.xml create mode 100644 NP_TrackBack/trunk/trackback/japanese-utf8.templates/response_dounblock.xml create mode 100644 NP_TrackBack/trunk/trackback/japanese-utf8.templates/updatetable.html create mode 100644 NP_TrackBack/trunk/trackback/japanese-utf8.templates/updatetablefinished.html create mode 100644 NP_TrackBack/trunk/trackback/js/prototype.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/css/coffee-with-milk.css create mode 100644 NP_TrackBack/trunk/trackback/js/rico/css/grayedout.css create mode 100644 NP_TrackBack/trunk/trackback/js/rico/css/greenHdg.css create mode 100644 NP_TrackBack/trunk/trackback/js/rico/css/iegradient.css create mode 100644 NP_TrackBack/trunk/trackback/js/rico/css/ricoCalendar.css create mode 100644 NP_TrackBack/trunk/trackback/js/rico/css/ricoGrid.css create mode 100644 NP_TrackBack/trunk/trackback/js/rico/css/ricoLiveGridForms.css create mode 100644 NP_TrackBack/trunk/trackback/js/rico/css/ricoMenu.css create mode 100644 NP_TrackBack/trunk/trackback/js/rico/css/ricoTree.css create mode 100644 NP_TrackBack/trunk/trackback/js/rico/css/tanChisel.css create mode 100644 NP_TrackBack/trunk/trackback/js/rico/css/warmfall.css create mode 100644 NP_TrackBack/trunk/trackback/js/rico/export-owc.html create mode 100644 NP_TrackBack/trunk/trackback/js/rico/export-plain.html create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/aline.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/calarrow.png create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/calendaricon.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/close.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/divider.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/doc.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/dotbutton.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/drop.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/filtercol.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/folderclosed.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/folderopen.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/grayedout.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/left.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/link.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/node.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/nodeblank.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/nodelast.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/nodeline.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/nodem.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/nodemlast.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/nodep.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/nodeplast.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/resize.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/ricologo.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/right.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/shadow.png create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/shadow_ll.png create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/shadow_ur.png create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/sort_asc.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/images/sort_desc.gif create mode 100644 NP_TrackBack/trunk/trackback/js/rico/prototype.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/rico.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/ricoAjaxEngine.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/ricoBehaviors.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/ricoCalendar.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/ricoColor.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/ricoColorPicker.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/ricoCommon.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/ricoComponents.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/ricoDashboard.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/ricoDragDrop.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/ricoEffects.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/ricoGridCommon.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/ricoLiveGrid.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/ricoLiveGridAjax.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/ricoLiveGridForms.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/ricoLiveGridMenu.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/ricoMenu.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/ricoSheet.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/ricoSimpleGrid.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/ricoSimpleGrid.xsl create mode 100644 NP_TrackBack/trunk/trackback/js/rico/ricoSimpleGrid2xl.xsl create mode 100644 NP_TrackBack/trunk/trackback/js/rico/ricoStyles.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/ricoTree.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_de.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_es.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_fr.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_it.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_ja.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_pt.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_ru.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_ua.js create mode 100644 NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_zh.js create mode 100644 NP_TrackBack/trunk/trackback/language/english.php create mode 100644 NP_TrackBack/trunk/trackback/language/japanese-euc.php create mode 100644 NP_TrackBack/trunk/trackback/language/japanese-utf8.php create mode 100644 NP_TrackBack/trunk/trackback/mkeuc.sh create mode 100644 NP_TrackBack/trunk/trackback/silk/accept.png create mode 100644 NP_TrackBack/trunk/trackback/silk/application_view_list.png create mode 100644 NP_TrackBack/trunk/trackback/silk/cross.png create mode 100644 NP_TrackBack/trunk/trackback/silk/delete.png create mode 100644 NP_TrackBack/trunk/trackback/silk/exclamation.png create mode 100644 NP_TrackBack/trunk/trackback/silk/help.png create mode 100644 NP_TrackBack/trunk/trackback/silk/house_go.png create mode 100644 NP_TrackBack/trunk/trackback/silk/link.png create mode 100644 NP_TrackBack/trunk/trackback/silk/link_break.png create mode 100644 NP_TrackBack/trunk/trackback/silk/plugin_edit.png create mode 100644 NP_TrackBack/trunk/trackback/silk/readme.txt create mode 100644 NP_TrackBack/trunk/trackback/silk/tick.png create mode 100644 NP_TrackBack/trunk/trackback/silk/transmit_go.png create mode 100644 NP_TrackBack/trunk/trackback/template.php create mode 100644 NP_TrackBack/trunk/trackback/templates/all.html create mode 100644 NP_TrackBack/trunk/trackback/templates/all_ajax.html create mode 100644 NP_TrackBack/trunk/trackback/templates/blocked.html create mode 100644 NP_TrackBack/trunk/trackback/templates/blocked_ajax.html create mode 100644 NP_TrackBack/trunk/trackback/templates/form.html create mode 100644 NP_TrackBack/trunk/trackback/templates/index.html create mode 100644 NP_TrackBack/trunk/trackback/templates/list.html create mode 100644 NP_TrackBack/trunk/trackback/templates/menu.html create mode 100644 NP_TrackBack/trunk/trackback/templates/ping.html create mode 100644 NP_TrackBack/trunk/trackback/templates/response_all.xml create mode 100644 NP_TrackBack/trunk/trackback/templates/response_blocked.xml create mode 100644 NP_TrackBack/trunk/trackback/templates/response_doblock.xml create mode 100644 NP_TrackBack/trunk/trackback/templates/response_dodelete.xml create mode 100644 NP_TrackBack/trunk/trackback/templates/response_dounblock.xml create mode 100644 NP_TrackBack/trunk/trackback/templates/updatetable.html create mode 100644 NP_TrackBack/trunk/trackback/templates/updatetablefinished.html diff --git a/NP_TrackBack/branches/DOM-branch/NP_TrackBack.php b/NP_TrackBack/branches/DOM-branch/NP_TrackBack.php new file mode 100644 index 0000000..c03d820 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/NP_TrackBack.php @@ -0,0 +1,1984 @@ +' . _TB_DESCRIPTION; + } + +// }}} +// {{{ function getTableList() + + /** + * return data base tables this plugin uses + * + * @retrun array + */ + function getTableList() + { + $retArr = array( + sql_table("plugin_tb"), + sql_table("plugin_tb_lookup"), + sql_table('plugin_tb_lc') + ); + return $retArr; + } + +// }}} +// {{{ function getEventList() + + /** + * return Nucleus CMS APIs this plugin uses + * + * @retrun array + */ + function getEventList() + { + $retArr = array( + 'QuickMenu', + 'PostAddItem', + 'AddItemFormExtras', + 'EditItemFormExtras', + 'PreUpdateItem', + 'PrepareItemForEdit', +// 'BookmarkletExtraHead', + 'RetrieveTrackback', + 'SendTrackback', + 'InitSkinParse', + 'TemplateExtraFields' + ); + return $retArr; + } + +// }}} +// {{{ function getMinNucleusVersion() + + /** + * return Lowest Nucleus CMS version by which this plugin operates + * + * @retrun array + */ + function getMinNucleusVersion() + { + return 341; + } + +// }}} +// {{{ function supportsFeature($feature) + + /** + * return "true" if feature support + * + * @param str feature name + * @retrun int + */ + function supportsFeature($feature) + { + switch($feature) { + case 'SqlTablePrefix': + return 1; + default: + return 0; + } + } + +// }}} +// {{{ function install() + + /** + * setup NP_TrackBack + * + * @retrun void + */ + function install() + { + switch (strtoupper(_CHARSET) == 'UTF-8') { + case 'UTF-8': + $collate = 'utf8_unicode_ci'; + $charset = 'utf8'; + break; + case 'EUC-JP': + $collate = 'ujis_japanese_ci'; + $charset = 'ujis'; + break; + default: + $collate = 'latin1_swedish_ci'; + $charset = 'latin1'; + break; + } + // Create tables + sql_query(" + CREATE TABLE IF NOT EXISTS `" . sql_table('plugin_tb') . "` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `tb_id` int(11) NOT NULL, + `url` text COLLATE utf8_unicode_ci NOT NULL, + `block` tinyint(4) NOT NULL, + `spam` tinyint(4) NOT NULL, + `link` tinyint(4) NOT NULL, + `title` text COLLATE " . $collate . ", + `excerpt` text COLLATE " . $collate . ", + `blog_name` text COLLATE " . $collate . ", + `timestamp` datetime DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `tb_id_block_timestamp_idx` (`tb_id`,`block`,`timestamp`) + ) ENGINE=MyISAM DEFAULT CHARSET=" . $charset . " COLLATE=" . $collate + ); + + sql_query(" + CREATE TABLE IF NOT EXISTS `" . sql_table('plugin_tb_lc') . "` ( + `tb_id` int(11) NOT NULL, + `from_id` int(11) NOT NULL, + PRIMARY KEY (`tb_id`,`from_id`) + ) ENGINE=MyISAM DEFAULT CHARSET=" . $charset . " COLLATE=" . $collate + ); + + sql_query(" + CREATE TABLE IF NOT EXISTS `" . sql_table('plugin_tb_lookup') . "` ( + `link` text COLLATE " . $collate . " NOT NULL, + `url` text COLLATE " . $collate . " NOT NULL, + `title` text COLLATE " . $collate . ", + PRIMARY KEY (`link`(100)) + ) ENGINE=MyISAM DEFAULT CHARSET=" . $charset . " COLLATE=" . $collate + ); + + // plugin options + + // global options + $this->createOption('AcceptPing', _TB_AcceptPing, 'yesno', 'yes'); + $this->createOption('SendPings', _TB_SendPings, 'yesno', 'yes'); + $this->createOption('AutoXMLHttp', _TB_AutoXMLHttp, 'yesno', 'yes'); + $this->createOption('CheckIDs', _TB_CheckIDs, 'yesno', 'yes'); + $this->createOption('dateFormat', _TB_dateFormat, 'text', _TB_dateFormat_VAL); + $this->createOption('NotifyEmail', _TB_NotifyEmail, 'text', ''); + $this->createOption('DropTable', _TB_DropTable, 'yesno', 'no'); + $this->createOption('HideUrl', _TB_HideUrl, 'yesno', 'yes'); + $this->createOption('ajaxEnabled', _TB_ajaxEnabled, 'yesno', 'no'); + + // default templates + $this->createOption('tplHeader', _TB_tplHeader, 'textarea', _TB_tplHeader_VAL); + $this->createOption('tplEmpty', _TB_tplEmpty, 'textarea', _TB_tplEmpty_VAL); + $this->createOption('tplItem', _TB_tplItem, 'textarea', _TB_tplItem_VAL); + $this->createOption('tplFooter', _TB_tplFooter, 'textarea', _TB_tplFooter_VAL); + $this->createOption('tplLocalHeader', _TB_tplLocalHeader, 'textarea', _TB_tplLocalHeader_VAL); + $this->createOption('tplLocalEmpty', _TB_tplLocalEmpty, 'textarea', _TB_tplLocalEmpty_VAL); + $this->createOption('tplLocalItem', _TB_tplLocalItem, 'textarea', _TB_tplLocalItem_VAL); + $this->createOption('tplLocalFooter', _TB_tplLocalFooter, 'textarea', _TB_tplLocalFooter_VAL); + $this->createOption('tplTbNone', _TB_tplTbNone, 'text', "No Trackbacks"); + $this->createOption('tplTbOne', _TB_tplTbOne, 'text', "1 Trackback"); + $this->createOption('tplTbMore', _TB_tplTbMore, 'text', "<%number%> Trackbacks"); + $this->createOption('tplTbNoAccept', _TB_tplNO_ACCEPT, 'text', "Sorry, no trackback pings are accepted."); + + // blog options + $this->createBlogOption('NotifyEmailBlog', _TB_NotifyEmailBlog, 'text', ''); + $this->createBlogOption('isAcceptW/OLinkDef', _TB_isAcceptWOLinkDef, 'select', 'block', _TB_isAcceptWOLinkDef_VAL); + $this->createBlogOption('AllowTrackBack', _TB_AllowTrackBack, 'yesno', 'yes'); + + // item options + $this->createItemOption('ItemAcceptPing', _TB_ItemAcceptPing, 'yesno', 'yes'); + $this->createItemOption('isAcceptW/OLink', _TB_isAcceptWOLink, 'select', 'default', _TB_isAcceptWOLink_VAL); + } + +// }}} +// {{{ function uninstall() + + /** + * delete TrackBack table if uninstall + * + * @retrun void + */ + function uninstall() + { + if ($this->getOption('DropTable') == 'yes') { + sql_query ('DROP TABLE ' . sql_table('plugin_tb')); + sql_query ('DROP TABLE ' . sql_table('plugin_tb_lookup')); + sql_query ('DROP TABLE ' . sql_table('plugin_tb_lc')); + } + } + +// }}} +// {{{ function init() + + /** + * initialize + * + * @retrun void + */ + function init() + { + // include language file for this plugin + $language = ereg_replace( '[\\|/]', '', getLanguageName()); + if (file_exists($this->getDirectory() . 'language/' . $language . '.php')) { + include_once($this->getDirectory() . 'language/' . $language . '.php'); + } else { + include_once($this->getDirectory() . 'language/english.php'); + } + $this->notificationMail = _TB_NORTIFICATION_MAIL_BODY; + $this->notificationMailTitle = _TB_NORTIFICATION_MAIL_TITLE; + $this->userAgent = $this->getName() . ' ( ' . $this->getVersion() . ' )'; + } + +// }}} +// {{{ function doSkinVar($skinType, $what = '', $tb_id = '', $amount = 'limit-1', $template = '') + + /** + * skin vars process + * + * @param str + * @param str + * @param int + * @param int/str + * @param str + */ + function doSkinVar($skinType, $what = '', $tb_id = '', $amount = 'limit-1', $template = '') + { + global $itemid, $manager, $CONF; + if(preg_match('/limit/i', $tb_id)){ + $amount = $tb_id; + $tb_id = ''; + } + $amount = intval(str_replace('limit', '', $amount)); + if ($tb_id == '') { + $tb_id = intval($itemid); + } + $isAcceptPing = $this->isAcceptTrackBack($tb_id); + switch ($what) { + case 'tbcode': + case 'code': + // Insert Auto-discovery RDF code + $spamcheck = array ( + 'type' => 'tbcode', + 'id' => -1, + 'title' => '', + 'excerpt' => '', + 'blogname' => '', + 'url' => '', + 'return' => true, + 'live' => true, + 'data' => '', //Backwards compatibility with SpamCheck API 1 + 'ipblock' => true, + ); +// $manager->notify('SpamCheck', array ('spamcheck' => & $spamcheck)); + $spam = false; + if (isset($spamcheck['result']) && $spamcheck['result'] == true){ + $spam = true; + } + if($skinType == 'item' && !$spam && $isAcceptPing) { + $this->insertCode($tb_id); + } + break; + case 'tburl': + case 'url': + // Insert TrackBack URL + if($isAcceptPing) { + echo $this->getTrackBackUrl($tb_id); + } else { + if (!empty($template)) { + $template =& $manager->getTemplate($template); + $template = $template['NP_TrackBack_tplTbNoAccept']; + } else { + $template = $this->getOption('tplTbNoAccept'); + } + echo TEMPLATE::fill($template, array()); + } + break; + case 'form': + case 'manualpingformlink': + // Insert manual ping URL + echo $this->getManualPingUrl($tb_id); + break; + case 'sendpinglink': + echo $manager->addTicketToUrl($this->getAdminURL() . 'index.php?action=ping&id=' . intval($tb_id)); + break; + case 'count': + // Insert TrackBack count + $count = $this->getTrackBackCount($tb_id); + if (!empty($template)) { + $template =& $manager->getTemplate($template); + } + switch ($count) { + case 0: + if (is_array($template)) { + $template = $template['NP_TrackBack_tplTbNone']; + } else { + $template = $this->getOption('tplTbNone'); + } + break; + case 1: + if (is_array($template)) { + $template = $template['NP_TrackBack_tplTbOne']; + } else { + $template = $this->getOption('tplTbOne'); + } + break; + default: + if (is_array($template)) { + $template = $template['NP_TrackBack_tplTbMore']; + } else { + $template = $this->getOption('tplTbMore'); + } + break; + } + echo TEMPLATE::fill($template, array('number' => $count)); + break; + case 'list': + case '': + // Shows the TrackBack list + $this->showList($tb_id, $amount); + break; + case 'required': + // show requred URL + echo $this->getRequiredURL($tb_id); + break; + case 'locallist': + // shows the Local list + $this->showLocalList($tb_id); + break; + default: + return; + } + } + +// }}} +// {{{ function doTemplateVar(&$item, $what = '', $template = '') + + /** + * template vars process + * + * @param obj + * @param str + * @param str + */ + function doTemplateVar(&$item, $what = '', $template = '') + { + $this->doSkinVar('template', $what, $item->itemid, $template); + } + +// }}} +// {{{ function doTemplateCommentsVar(&$item, &$comment, $what = '', $template = '') + + /** + * comment template vars process + * + * @param obj + * @param obj + * @param str + * @param str + */ + function doTemplateCommentsVar(&$item, &$comment, $what = '', $template = '') + { + $this->doSkinVar('templatecomments', $what, $item->itemid, $template); + } + +// }}} +// {{{ function doAction($type) + + /** + * A trackback ping is to be received on the URL + * http://yourdomain.com/action.php?action=plugin&name=TrackBack&tb_id=1234 + * Extra variables to be passed along are url, title, excerpt, blog_name + * + * @param str + */ + function doAction($type) + { + global $CONF,$manager; + $aActionsNotToCheck = array( + '', + 'ping', + 'form', + 'redirect', + 'left', + ); + if (!in_array($type, $aActionsNotToCheck)) { + if (!$manager->checkTicket()) return _ERROR_BADTICKET; + } + switch ($type) { + case '': + // When no action type is given, assume it's a ping + $errorMsg = $this->handlePing(); + $this->xmlResponse($errorMsg); + break; + case 'ping': + // Manual ping + $errorMsg = $this->handlePing(); + if ($errorMsg != '') { + $this->showManualPingError(intRequestVar('tb_id'), $errorMsg); + } else { + $this->showManualPingSuccess(intRequestVar('tb_id')); + } + break; + case 'form': + // Show manual ping form + $tb_id = intRequestVar('tb_id'); + $isAcceptPing = $this->isAcceptTrackBack($tb_id); + if ($isAcceptPing) { + $this->showManualPingForm($tb_id); + } else { + if (!empty(requestVar['template'])) { + $template =& $manager->getTemplate(requestVar['template']); + $template = $template['NP_TrackBack_tplTbNoAccept']; + } else { + $template = $this->getOption('tplTbNoAccept'); + } + echo TEMPLATE::fill($template, array()); + } + break; + case 'detect': + // Detect trackback + list($url, $title) = $this->getURIfromLink(html_entity_decode(requestVar('tb_link'))); + $url = addslashes($url); + $url = $this->_utf8_to_javascript($url); + $title = addslashes($title); + $title = $this->_utf8_to_javascript($title); + echo "tbDone('" . requestVar('tb_link') . "', '" . $url . "', '" . $title . "');"; + break; + case 'redirect': + // redirect + return $this->redirect(intRequestVar('tb_id'), requestVar('urlHash')); + break; + case 'left': + echo $this->showLeftList(intRequestVar('tb_id'), intRequestVar('amount')); + break; + case 'deletelc': + // delete a trackback(local) + $err = $this->deleteLocal(intRequestVar('tb_id'), intRequestVar('from_id')); + if ($err) { + return $err; + } + header('Location: ' . serverVar('HTTP_REFERER')); + break; + } + exit; + } + +// }}} +// {{{ function doIf($key = '', $value = '') + + /** + * COMPARE key and value + * + * @param str + * @param str + */ + function doIf($key = '', $value = '') + { + global $itemid; + //echo "key: $key, value: $value"; + switch (strtolower($key)) { + case '': + case 'accept': + if ($value == '') { + $value = 'yes'; + } + $value = ($value == 'no' || (!$value)) ? false : true; + $ret = false; + if ($itemid) { + $ret = $this->isAcceptTrackBack($itemid); + } else { + $ret = $this->isAcceptTrackBack(); + } + return ($value == false) ? (!$ret) : $ret; + case 'required': + if ($value == '') { + $value = 'yes'; + } + $value = ($value == 'no' || (!$value)) ? false : true; + $ret = false; + if( $itemid ) { + $ret = $this->isEnableLinkCheck($itemid); + } + return ($value == false) ? (!$ret) : $ret; + default: + return false; + } + } + +// }}} +// {{{ function event_InitSkinParse(&$data) + + /** + * A trackback ping is to be received on the URL + * http://yourdomain.com/item/1234.trackback + * Extra variables to be passed along are url, title, excerpt, blog_name + * + * @param arr + */ + function event_InitSkinParse(&$data) + { + global $CONF, $itemid; + $format = requestVar('format'); + if ($CONF['URLMode'] == 'pathinfo') { + if (preg_match('/(\/|\.)(trackback)(\/|$)/', serverVar('PATH_INFO'), $matches)) { + $format = $matches[2]; + } + } + + if ($format == 'trackback' && $data['type'] == 'item') { + $errorMsg = $this->handlePing(intval($itemid)); + if ($errorMsg != '') { + $this->xmlResponse($errorMsg); + } else { + $this->xmlResponse(); + } + exit; + } + } + +// }}} +// {{{ function event_TemplateExtraFields(&$data) + + /** + * extra template field + * + * @param arr + */ + function event_TemplateExtraFields(&$data) + { + $data['fields']['NP_TrackBack'] = array( + 'NP_TrackBack_tplTbNoAccept' => _TB_tplNO_ACCEPT, + 'NP_TrackBack_tplTbNone' => _TB_tplTbNone, + 'NP_TrackBack_tplTbOne' => _TB_tplTbOne, + 'NP_TrackBack_tplTbMore' => _TB_tplTbMore, + 'NP_TrackBack_tplItem' => _TB_tplItem, + ); + } + +// }}} +// {{{ function event_SendTrackback($data) + + /** + * trackbackping send via xmlrpc + * + * @param arr + */ + function event_SendTrackback($data) + { + global $manager; + // Enable sending trackbacks for the XML-RPC API, otherwise we would + // get an error because the current user is not exactly logged in. + $this->xmlrpc = true; + $itemid = intval($data['tb_id']); + $item =& $manager->getItem($itemid, 0, 0); + if (!$item) { + return; // don't ping for draft & future + } + if ($item['draft']) { + return; // don't ping on draft items + } + // gather some more information, needed to send the ping (blog name, etc) + $blog =& $manager->getBlog(getBlogIDFromItemID($itemid)); + $blog_name = $blog->getName(); + $title = $data['title'] != '' ? $data['title'] : $item['title']; + $title = strip_tags($title); + $excerpt = $data['body'] != '' ? $data['body'] : $item['body']; + $excerpt = strip_tags($excerpt); + $excerpt = $this->_cut_string($excerpt, 200); + $url = $this->_createItemLink($itemid, $blog); + + while (list(,$url) = each($data['urls'])) { + $res = $this->sendPing($itemid, $title, $url, $excerpt, $blog_name, $url); + if ($res) { + ACTIONLOG::add(WARNING, 'TrackBack Error:' . $res . ' (' . $url . ')'); + } + } + } + +// }}} +// {{{ function event_RetrieveTrackback($data) + + /** + * trackbackping receive via xmlrpc + * + * @param arr + */ + function event_RetrieveTrackback($data) + { + + $res = sql_query(' + SELECT + `url`, + `title`, + UNIX_TIMESTAMP(`timestamp`) AS timestamp + FROM + `' . sql_table('plugin_tb') . '` + WHERE + `tb_id` = ' . intval($data['tb_id']) . ' AND + `block` = 0 + ORDER BY + `timestamp` ASC + '); + + while ($row = sql_fetch_assoc($res)) { + $trackback = array( + 'title' => $row['title'], + 'url' => $row['url'], + 'ip' => '' + ); + $data['trackbacks'][] = $trackback; + } + } + +// }}} +// {{{ function event_BookmarkletExtraHead($data) + + /** + * insert extra code to tags on bookmarklet + * + * @param arr + * + function event_BookmarkletExtraHead($data) + { + global $NP_TB_URL; + list ($NP_TB_URL,) = $this->getURIfromLink(requestVar('loglink')); + } + +// }}} +// {{{ function event_PrepareItemForEdit($data) + + /** + * auto discover from item body + * + * @param arr + */ + function event_PrepareItemForEdit($data) + { + if ($this->getOption('AutoXMLHttp') == 'no') { + // The space between body and more is to make sure we didn't join 2 words accidently.... + $this->larray = $this->autoDiscovery($data['item']['body'] . ' ' . $data['item']['more']); + } + } + +// }}} +// {{{ function event_PostAddItem($data) + + /** + * After an item has been added to the database, send out a ping if requested + * (trackback_ping_url variable in request) + * + * @param arr + */ + function event_PostAddItem($data) + { + $this->pingTrackback($data); + } + +// }}} +// {{{ function event_PreUpdateItem($data) + + /** + * After an item has been updated on the database, send out a ping if requested + * (trackback_ping_url variable in request) + * + * @param arr + */ + function event_PreUpdateItem($data) + { + $this->pingTrackback($data); + } + +// }}} +// {{{ function event_AddItemFormExtras($data) + + /** + * Add trackback options to add item form/bookmarklet + * + * @param arr + */ + function event_AddItemFormExtras($data) + { + $this->itemFormExtra($data, 'add'); + } + +// }}} +// {{{ function event_PreUpdateItem($data) + + /** + * Add trackback options to edit item form/bookmarklet + * + * @param arr + */ + function event_EditItemFormExtras($data) + { + $this->itemFormExtra($data, 'edit'); + } + +// }}} +// {{{ function showLeftList($tb_id, $offset = 0, $amount = 99999999, $templateName = '') + + /** + * Show a list of left trackbacks for this ID + * + * @param int + * @param int + * @param int + * @param str + */ + function showLeftList($tb_id, $offset = 0, $amount = 99999999, $templateName = '') + { + global $manager, $blog, $CONF; + $tb_id = intval($tb_id); + $out = array(); + $query = ' + SELECT + `url`, + md5(`url`) as urlHash, + `blog_name`, + `excerpt`, + `title`, + UNIX_TIMESTAMP(`timestamp`) AS timestamp + FROM + `' . sql_table('plugin_tb') . '` + WHERE + `tb_id` = ' . $tb_id . ' AND + `block` = 0 + ORDER BY + `timestamp` DESC + '; + if ($offset) { + $query .= ' LIMIT ' . intval($offset) . ', ' . intval($amount); + } + $res = sql_query($query); + $templates = ''; + if (!empty($templateName)) { + $templates =& $manager->getTemplate($templateName); + } + while($row = sql_fetch_array($res)) { + $row['blog_name'] = htmlspecialchars($row['blog_name'], ENT_QUOTES); + $row['title'] = htmlspecialchars($row['title'], ENT_QUOTES); + $row['excerpt'] = htmlspecialchars($row['excerpt'], ENT_QUOTES); + if (strtoupper(_CHARSET) != 'UTF-8') { + $row['blog_name'] = $this->_restore_to_utf8($row['blog_name']); + $row['title'] = $this->_restore_to_utf8($row['title']); + $row['excerpt'] = $this->_restore_to_utf8($row['excerpt']); + $row['blog_name'] = $this->_utf8_to_entities($row['blog_name']); + $row['title'] = $this->_utf8_to_entities($row['title']); + $row['excerpt'] = $this->_utf8_to_entities($row['excerpt']); + } + $iVars = array( + 'action' => $this->getTrackBackUrl($tb_id), + 'form' => $this->getManualPingUrl($tb_id), + 'name' => $row['blog_name'], ENT_QUOTES), + 'title' => $row['title'], + 'excerpt' => $this->_cut_string($row['excerpt'], 400), + 'url' => htmlspecialchars($row['url'], ENT_QUOTES), + 'date' => htmlspecialchars(strftime($this->getOption('dateFormat'), $row['timestamp']), ENT_QUOTES) + ); + if ($this->getOption('HideUrl') == 'yes') { + $iVars['url'] = $CONF['ActionURL'] . '?action=plugin&name=TrackBack' + . '&type=redirect&tb_id=' . $tb_id + . '&urlHash=' . $row['urlHash'] + . '&template=' . $templateName; + } else { + $iVars['url'] = $row['url']; + } + if (is_array($templates)) { + $template = $templates['NP_TrackBack_tplItem']; + } else { + $template = $this->getOption('tplItem'); + } + $out[] = TEMPLATE::fill($template, $iVars); + } + sql_free_result($res); + return implode("\n", $out); + } + +// }}} +// {{{ function showList($tb_id, $amount = 0, $templateName = '') + + /** + * Show a list of trackbacks for this ID + * + * @param int + * @param int + * @param str + */ + function showList($tb_id, $amount = 0, $templateName = '') + { + $tb_id = intval($tb_id); + global $manager, $blog, $CONF, $member; + $enableHideurl = true; + // for TB LinkLookup + if( + strpos(serverVar('HTTP_USER_AGENT'), 'Hatena Diary Track') === false + || strpos(serverVar('HTTP_USER_AGENT'), 'NP_TrackBack') === false + || strpos(serverVar('HTTP_USER_AGENT'), 'TBPingLinkLookup') === false + || strpos(serverVar('HTTP_USER_AGENT'), 'MT::Plugin::BanNoReferTb') === false + || strpos(serverVar('HTTP_USER_AGENT'), 'livedoorBlog') === false + ) { + $enableHideurl = false; + $amount = '-1'; + } + $query = ' + SELECT + `url`, + md5(`url`) as urlHash, + `blog_name`, + `excerpt`, + `title`, + UNIX_TIMESTAMP(`timestamp`) AS timestamp + FROM + `' . sql_table('plugin_tb') . '` + WHERE + `tb_id` = ' . $tb_id . ' AND + `block` = 0 + ORDER BY + `timestamp` DESC + '; + if ($amount == '-1') { + $query .= ' LIMIT 9999999'; + } elseif($amount) { + $query .= ' LIMIT ' . intval($amount); + } + if ($amount != 0) { + $res = sql_query($query); + } + $gVars = array( + 'action' => $this->getTrackBackUrl($tb_id), + 'form' => $this->getManualPingUrl($tb_id), + 'required' => $this->getRequiredURL($tb_id), + ); + $templates = ''; + if (!empty($templateName)) { + $templates =& $manager->getTemplate($templateName); + } + if ($member->isLoggedIn()) { + $adminurl = $manager->addTicketToUrl($this->getAdminURL() . 'index.php?action=list&id=' . $tb_id); + $pingformurl = $manager->addTicketToUrl($this->getAdminURL() . 'index.php?action=ping&id=' . $tb_id); + $gVars['admin'] = '[admin]'; + $gVars['pingform'] = '[pingform]'; + } + if (is_array($templates)) { + $tpl_Head = $templates['NP_TrackBack_tplHeader']; + $tpl_Item = $templates['NP_TrackBack_tplItem']; + $tpl_Empt = $templates['NP_TrackBack_tplEmpty']; + $tpl_Foot = $templates['NP_TrackBack_tplFooter']; + } else { + $tpl_Head = $this->getOption('tplHeader'); + $tpl_Item = $this->getOption('tplItem'); + $tpl_Empt = $this->getOption('tplEmpty'); + $tpl_Foot = $this->getOption('tplFooter'); + } + echo TEMPLATE::fill($tpl_Head, $gVars); + while ($amount != 0 && $row = sql_fetch_array($res)) { + $row['blog_name'] = htmlspecialchars($row['blog_name'], ENT_QUOTES); + $row['title'] = htmlspecialchars($row['title'], ENT_QUOTES); + $row['excerpt'] = htmlspecialchars($row['excerpt'], ENT_QUOTES); + if (strtoupper(_CHARSET) != 'UTF-8') { + $row['blog_name'] = $this->_restore_to_utf8($row['blog_name']); + $row['title'] = $this->_restore_to_utf8($row['title']); + $row['excerpt'] = $this->_restore_to_utf8($row['excerpt']); + $row['blog_name'] = mb_convert_encoding($row['blog_name'], _CHARSET, 'UTF-8'); + $row['title'] = mb_convert_encoding($row['title'], _CHARSET, 'UTF-8'); + $row['excerpt'] = mb_convert_encoding($row['excerpt'], _CHARSET, 'UTF-8'); + } + $iVars = array( + 'action' => $this->getTrackBackUrl($tb_id), + 'form' => $this->getManualPingUrl($tb_id), + 'name' => htmlspecialchars($row['blog_name'], ENT_QUOTES), + 'title' => htmlspecialchars($row['title'], ENT_QUOTES), + 'excerpt' => htmlspecialchars($this->_cut_string($row['excerpt'], 400), ENT_QUOTES), + 'url' => htmlspecialchars($row['url'], ENT_QUOTES), + 'date' => htmlspecialchars(strftime($this->getOption('dateFormat'), $row['timestamp']), ENT_QUOTES) + ); + if ($enableHideurl && $this->getOption('HideUrl') == 'yes') { + $iVars['url'] = $CONF['ActionURL'] . '?action=plugin&name=TrackBack' + . '&type=redirect&tb_id=' . $tb_id + . '&urlHash=' . $row['urlHash']; + } else { + $iVars['url'] = $row['url']; + } + echo TEMPLATE::fill($tpl_Item, $iVars); + } + $q = ' + SELECT + count(*) + FROM + `' . sql_table('plugin_tb') . '` + WHERE + `tb_id` = ' . $tb_id . ' AND + `block` = 0 + ORDER BY + `timestamp` DESC + '; + $result = sql_query($q); + $total = sql_result($result, 0, 0); + if ($amount != -1 && $total > $amount) { + $leftcount = $total - $amount; + $adminURL = $this->getAdminURL(); + $tb_id = intval($tb_id); + $amount = intval($amount); + echo <<<___SCRIPTCODE___ + '; + +
Show left {$leftcount} Trackbacks
+ +
+ +___SCRIPTCODE___; + } + if (sql_num_rows($res) == 0) { + echo TEMPLATE::fill($tpl_Empt, $gVars); + } + sql_free_result($res); + echo TEMPLATE::fill($tpl_Foot, $gVars); + } + +// }}} +// {{{ function getTrackBackCount($tb_id) + + /** + * Returns the TrackBack count for a TrackBack item + * + * @param int + * @return str + */ + function getTrackBackCount($tb_id) + { + $query = 'SELECT COUNT(*) as result FROM %s WHERE tb_id=%d AND block = 0' + return quickQuery(sprintf($query, sql_table('plugin_tb'), $tb_id)); + } + +// }}} +// {{{ function getManualPingUrl($itemid) + + /** + * Returns the manual ping URL + * + * @param int + * @return str + */ + function getManualPingUrl($itemid) + { + global $CONF; + return $CONF['ActionURL'] . '?action=plugin&name=TrackBack&type=form&tb_id=' . intval($itemid); + } + +// }}} +// {{{ function showManualPingError($itemid, $status = '') + + /** + * Show the manual ping form + * + * @param int + * @param str + */ + function showManualPingError($itemid, $status = '') + { + global $CONF; + $form = true; + $error = true; + $success = false; + sendContentType('text/html', 'admin-trackback', _CHARSET); + require_once($this->getDirectory() . '/template.php'); + $mTemplate = new Trackback_Template(null, $this->getDirectory()); + $mTemplate->set ('CONF', $CONF); + $mTemplate->set ('itemid', $itemid); + $mTemplate->set ('form', $form); + $mTemplate->set ('error', $error); + $mTemplate->set ('success', $success); + $mTemplate->set ('status', $status); + $mTemplate->template('templates/form.html'); + echo $mTemplate->fetch(); + } + +// }}} +// {{{ function showManualPingSuccess($itemid, $status = '') + + /** + * Show the manual ping form + * + * @param int + * @param str + */ + function showManualPingSuccess($itemid, $status = '') + { + global $CONF; + $form = false; + $error = false; + $success = true; + sendContentType('text/html', 'admin-trackback', _CHARSET); + require_once($this->getDirectory() . '/template.php'); + $mTemplate = new Trackback_Template(null, $this->getDirectory()); + $mTemplate->set ('CONF', $CONF); + $mTemplate->set ('itemid', $itemid); + $mTemplate->set ('form', $form); + $mTemplate->set ('error', $error); + $mTemplate->set ('success', $success); + $mTemplate->set ('status', $status); + $mTemplate->template('templates/form.html'); + echo $mTemplate->fetch(); + } + +// }}} +// {{{ function showManualPingForm($itemid, $text = '', $templateName = '') + + /** + * Show the manual ping form + * + * @param int + * @param str + * @param str + */ + function showManualPingForm($itemid, $text = '', $templateName = '') + { + global $CONF; + $form = true; + $error = false; + $success = false; + // Check if we are allowed to accept pings + if ( !$this->isAcceptTrackBack($itemid) ) { + if (!empty($templateName)) { + $templates =& $manager->getTemplate($templateName); + $template = $templates['NP_TrackBack_tplTbNoAccept']; + } else { + $template = $this->getOption('tplTbNoAccept'); + } + $text = TEMPLATE::fill($template, array()); + $form = false; + $error = true; + } + sendContentType('text/html', 'admin-trackback', _CHARSET); + require_once($this->getDirectory() . '/template.php'); + $mTemplate = new Trackback_Template(null, $this->getDirectory()); + $mTemplate->set ('CONF', $CONF); + $mTemplate->set ('itemid', $itemid); + $mTemplate->set ('form', $form); + $mTemplate->set ('error', $error); + $mTemplate->set ('success', $success); + $mTemplate->set ('status', $status); + $mTemplate->template('templates/form.html'); + echo $mTemplate->fetch(); + } + +// }}} +// {{{ function getTrackBackUrl($itemid) + + /** + * Returns the trackback URL + * + * @param int + */ + function getTrackBackUrl($itemid) + { + global $CONF; + return $CONF['ActionURL'] . '?action=plugin&name=TrackBack&tb_id='.$itemid; + } + +// }}} +// {{{ function itemFormExtra($data, $type = 'add') + + /** + * Add trackback options to add/edit item form/bookmarklet + * + * @param int + * @param str + */ + function itemFormExtra($data, $type = 'add') + { + $listIt = _TB_LIST_IT; + $admURL = $this->getAdminURL(); + echo <<<___FORMEXTRA___ +

TrackBack

+

+
+ +
+ +___FORMEXTRA___; + $XMLHttp = $this->getOption('AutoXMLHttp'); + if ($XMLHttp == 'yes') { + echo <<<___FORMEXTRA___ +

+ +
+
+ + +
+ +
+ +___FORMEXTRA___; + $this->jsautodiscovery(); + } elseif ($type == 'edit' && $XMLHttp != 'yes') { + if (count($this->larray) > 0) { + echo "\nAuto Discovered Ping URL's:
\n"; + echo ''; + $i = 0; + while (list($url, $title) = each($this->larray)) { + if (_CHARSET != 'UTF-8') { + $title = $this->_utf8_to_entities($title); + $title = mb_convert_encoding($title, _CHARSET, 'UTF-8'); + } + echo ''; + echo '
'; + $i++; + } + } + } + echo "

\n"; + } + +// }}} +// {{{ function jsautodiscovery() + + /** + * Insert Javascript AutoDiscovery routines + */ + function jsautodiscovery() + { + echo ''; + } + +// }}} +// {{{ function insertCode($itemid) + + /** + * Insert RDF code for item + * + * @param int + */ + function insertCode($itemid) + { + $itemid = intval($itemid); + global $manager, $CONF; + $item =& $manager->getItem($itemid, 0, 0); + $blog =& $manager->getBlog(getBlogIDFromItemID($item['itemid'])); + $uri = $this->_createItemLink($item['itemid'], $blog); + $title = strip_tags($item['title']); + $desc = strip_tags($item['body']); + $desc = $this->_cut_string($desc, 200); + $desc = htmlspecialchars($desc, ENT_QUOTES); + $tburl = $this->getTrackBackUrl($itemid); + $time = strftime('%Y-%m-%dT%H:%M:%S'); + echo <<<___RDFCODE___ + + +___RDFCODE___; + } + +// }}} +// {{{ function rssResponse($tb_id) + + /** + * Retrieving TrackBack Pings (when __mode=rss) + * + * @param int + */ + function rssResponse($tb_id) + { + $tb_id = intval($tb_id); + global $manager, $CONF; + $item =& $manager->getItem($tb_id, 0, 0); + if ($item) { + $blog =& $manager->getBlog(getBlogIDFromItemID($item['itemid'])); + $blog_name = $this->_restore_to_utf8($blog->getName()); + $title = $this->_restore_to_utf8($item['title']); + $excerpt = $this->_restore_to_utf8($item['body']); + $excerpt = $this->_cut_string($excerpt, 200); + $url = $this->_createItemLink($item['itemid'], $blog); + + // Create response XML + $dom = new DOMDocument('1.0', 'UTF-8'); + $response = $dom->appendChild($dom->createElement('response')); + $response->appendChild($dom->createElement('error', '0')); + $rss = $response->appendChild($dom->createElement('rss')); + $rss->setAttribute("version", "0.91"); + $channel = $rss->appendChild($dom->createElement('channel')); + $channel->appendChild($dom->createElement('title', htmlspecialchars($title, ENT_QUOTES))); + $channel->appendChild($dom->createElement('link', htmlspecialchars($url, ENT_QUOTES))); + $channel->appendChild($dom->createElement('description', htmlspecialchars($excerpt, ENT_QUOTES))); + + $query = 'SELECT ' + . '`url`, ' + . '`blog_name`, ' + . '`excerpt`, ' + . '`title`, ' + . 'UNIX_TIMESTAMP(`timestamp`) as timestamp ' + . 'FROM ' + . sql_table('plugin_tb') . ' ' + . 'WHERE ' + . '`tb_id` = ' . $tb_id . ' AND ' + . '`block` = 0 ' + . 'ORDER BY ' + . '`timestamp` DESC'; + $res = sql_query($query); + while($data = sql_fetch_assoc($res)) { + $data['title'] = htmlspecialchars($this->_restore_to_utf8($data['title']), ENT_QUOTES); + $data['excerpt'] = htmlspecialchars($this->_restore_to_utf8($data['excerpt']), ENT_QUOTES); + $data['url'] = htmlspecialchars($data['url'], ENT_QUOTES); + $item = $channel->appendChild($dom->createElement('item')); + $item->appendChild($dom->createElement('title', $data['title']); + $item->appendChild($dom->createElement('link', $data['url']); + $item->appendChild($dom->createElement('description', $data['excerpt']); + } + header('Content-Type: text/xml'); + echo $dom->saveXML(); + } else { + $this->xmlResponse(_ERROR_NOSUCHITEM); + } + } + +// }}} +// {{{ function sendPing($itemid, $title, $url, $excerpt, $blog_name, $ping_url) + + /** + * Send a Trackback ping to another website + * + * @param int + * @param str + * @param str + * @param str + * @param str + * @param str + */ + function sendPing($itemid, $title, $url, $excerpt, $blog_name, $ping_url) + { +// $sendEncoding = 'UTF-8'; + // 1. Check some basic things + if (!$this->canSendPing()) { + return _TB_msgNOTALLOWED_SEND; + } + if ($this->getOption('SendPings') == 'no') { + return _TB_msgDISABLED_SEND; + } + if ($ping_url == '') { + return _TB_msgNO_SENDER_URL; + } + // 2. Check if protocol is correct http URL + $parsed_url = parse_url($ping_url); + if (strpos($parsed_url['scheme'], 'http') !== 0 || !$parsed_url['host']) { + return _TB_msgBAD_SENDER_URL; + } + // 3. Create contents +// if ($sendEncoding != _CHARSET) { + if (strtoupper(_CHARSET) != 'UTF-8') { + $title = mb_convert_encoding($title, 'UTF-8', _CHARSET); + $excerpt = mb_convert_encoding($excerpt, 'UTF-8', _CHARSET); + $blog_name = mb_convert_encoding($blog_name, 'UTF-8', _CHARSET); + } + $ch = curl_init(); + $data = array( + 'title' => $title, + 'url' => $url, + 'excerpt' => $excerpt, + 'blog_name' => $blog_name + ); + $options = array( + CURLOPT_URL => $ping_url, + CURLOPT_POST => 1, + CURLOPT_POSTFIELDS => $data, + CURLOPT_RETURNTRANSFER => 1, + ); + curl_setopt_array($ch, $options); + $response = curl_exec($ch); + if ($response === false) { + return sprintf(_TB_msgCOULDNOT_SEND_PING, curl_error($ch), curl_errno($ch)); + } + $respCd = curl_getinfo($ch, CURLINFO_HTTP_CODE); + if ($respCd != 200) { + return sprintf(_TB_msgRESP_HTTP_ERROR, $respCd, curl_error($ch)); + } + $domDoc = new DOMDocument; + $domDoc->preserveWhiteSpace = false; + $domDoc->loadXML($response); + $encoding = $dom->encoding; + if (empty($encoding)) { + $encoding = $this->_detect_encoding($response); //mb_detect_encoding($response, 'ASCII,ISO-2022-JP,UTF-8,EUC-JP,SJIS') + } + if (strtoupper($encoding) != "UTF-8" && strtoupper($encoding) != "ISO-8859-1") { + $response = @mb_convert_encoding($response, "UTF-8", $encoding); + $domDoc = new DOMDocument; + $domDoc->preserveWhiteSpace = false; + $domDoc->loadXML($response); + } + $errors = $domDoc->getElementsByTagName('error'); + $error = $errors->item(0)->nodeValue; + if (intval($error)) { + $mesages = $domDoc->getElementsByTagName('message'); + $mesage = $mesages->item(0)->nodeValue; + if (strtoupper(_CHARSET) != 'UTF-8') { + $mesage = @mb_convert_encoding($mesage, _CHARSET, "UTF-8"); + } + return sprintf(_TB_msgAN_ERROR_OCCURRED, htmlspecialchars($mesage, ENT_QUOTES)); + } + return ''; + } + +// }}} +// {{{ function handlePing($tb_id = 0) + + /** + * Send a Trackback ping to another website + * + * @param int + * @return str + */ + function handlePing($tb_id = 0) + { + global $manager; + // Defaults + $span = false; + $link = false; + $block = false; + $rss = false; + if ($tb_id == 0) { + $tb_id = intRequestVar('tb_id'); + } + if (requestVar('__mode') == 'rss') { + $rss = true; + } + if ($this->isEnableLinkCheck($tb_id)) { + $block = true; + } + if (!$tb_id) { + return _TB_msgTBID_IS_MISSING; + } + if ((!$manager->existsItem($tb_id,0,0)) && ($this->getOption('CheckIDs') == 'yes')) { + return _ERROR_NOSUCHITEM; + } + // 0. Check if we need to output the list as rss + if ($rss) { + $this->rssResponse($tb_id); + return; + } + // check: accept pings. + $blogId = getBlogIDFromItemID($tb_id); + $isAcceptPing = $this->isAcceptTrackBack($tb_id); + if (!$isAcceptPing) { + return _TB_tplNO_ACCEPT; + } + // 1. Get attributes + $b =& $manager->getBlog(intval($blogId)); + $url = requestVar('url'); + $title = requestVar('title'); + $excerpt = requestVar('excerpt'); + $blog_name = requestVar('blog_name'); + if ($url && preg_match('/https?:\/\/([^\/]+)/', $url, $matches) ){ + if( gethostbynamel($matches[1]) === FALSE ) { + return _TB_msgBAD_SENDER_URL; + } + } else { + return _TB_msgNO_SENDER_URL; + } + // 2. Conversion of encoding... + $encoding = $this->_detect_encoding($excerpt); + if (strtoupper(_CHARSET) != 'UTF-8') { + $title = $this->_strip_controlchar(strip_tags(mb_convert_encoding($title, _CHARSET, $encoding))); + $excerpt = $this->_strip_controlchar(strip_tags(mb_convert_encoding($excerpt, _CHARSET, $encoding))); + $blog_name = $this->_strip_controlchar(strip_tags(mb_convert_encoding($blog_name, _CHARSET, $encoding))); + } else { + $title = $this->_strip_controlchar($this->_convert_to_utf8($title, $encoding)); + $title = $this->_decode_entities(strip_tags($title)); + $excerpt = $this->_strip_controlchar($this->_convert_to_utf8($excerpt, $encoding)); + $excerpt = $this->_decode_entities(strip_tags($excerpt)); + $blog_name = $this->_strip_controlchar($this->_convert_to_utf8($blog_name, $encoding)); + $blog_name = $this->_decode_entities(strip_tags($blog_name)); + } + // 3. Save data in the DB + $res = sql_query(" + SELECT + `tb_id`, + `block`, + `spam` + FROM + `' . sql_table('plugin_tb') . '` + WHERE + `url` = '" . sql_real_escape_string($url) . "' AND + `tb_id` = '" . intval($tb_id) . "' + "); + if (sql_num_rows($res) != 0) { + $rows = sql_fetch_assoc($res); + $spam = ($rows['block'] || $rows['spam'] ) ? true : false; + $res = sql_query(" + UPDATE + `" . sql_table('plugin_tb') . "` + SET + `title` = '" . sql_real_escape_string($title) . "', + `excerpt` = '" . sql_real_escape_string($excerpt) . "', + `blog_name` = '" . sql_real_escape_string($blog_name) . "', + `timestamp` = ' . mysqldate($b->getCorrectTime()) . ' + WHERE + `url` = '" . sql_real_escape_string($url) . "' AND + `tb_id` = '" . sql_real_escape_string(intval($tb_id)) . "' + '); + if (!$res) { + return sprintf(_TB_msgTB_COULDNOT_TB_UPDATE, sql_error()); + } + } else { + // spam block + $res = sql_query(' + SELECT + `id` + FROM + `' . sql_table('plugin_tb') . '` + WHERE + `block` = 1 and + `url` = "' . sql_real_escape_string($url) . '" + '); + if (mysql_num_rows($res) != 0) { + // NP_Trackback has blocked tb ! + ACTIONLOG :: add(INFO, sprintf(_TB_msgDUPLICATED_TB_BLOCKED, $tb_id, $url)); + return _TB_tplNO_ACCEPT; + } + // 4. SPAM check (for SpamCheck API 2 /w compat. API 1) + $spamcheck = array ( + 'type' => 'trackback', + 'id' => $tb_id, + 'title' => $title, + 'excerpt' => $excerpt, + 'blogname' => $blog_name, + 'url' => $url, + 'return' => true, + 'live' => true, + /* Backwards compatibility with SpamCheck API 1*/ + 'data' => $url . "\n" . $title . "\n" . $excerpt . "\n" . $blog_name . "\n" . serverVar('HTTP_USER_AGENT'), + 'ipblock' => true, + ); + $manager->notify('SpamCheck', array ('spamcheck' => & $spamcheck)); + if (isset($spamcheck['result']) && $spamcheck['result'] == true) { + $spam = true; + } + // 5. Content check (TO DO) + $enableLinkCheck = $this->isEnableLinkCheck($tb_id); + if ($spam == false || $enableLinkCheck == 'ignore') { + if ($enableLinkCheck) { + $contents = $this->retrieveUrl($url); + $linkArray = $this->getPermaLinksFromText($contents); + if (defined('NP_TRACKBACK_LINKCHECK_STRICT')) { + $itemLink = $this->_createItemLink($tb_id, $b); + } else { + $itemLink = $b->getURL(); + } + $itemLinkPat = '{^' . preg_quote($itemLink) .'}i'; + $itemLinkPat = str_replace('&','&(amp;)?', $itemLinkPat); + foreach ($linkArray as $l) { + if(preg_match($itemLinkPat, $l)) { + ACTIONLOG :: add(INFO, sprintf(_TB_msgLINK_CHECK_OK, $l, $itemLinkPat)); + $link = true; + break; + } + } + if (!$link) { + $cnt = @count($linkArray); + if ($enableLinkCheck == 'ignore') { + ACTIONLOG :: add(INFO, sprintf(_TB_msgLINK_CHECK_IGNORE, $tb_id, $url, $cnt, $itemLinkPat)); + return _TB_tplNO_ACCEPT; + } else { + ACTIONLOG :: add(INFO, sprintf(_TB_msgLINK_CHECK_BLOCK, $tb_id, $url, $cnt, $itemLinkPat)); + } + } + } + } + // 6. Determine if Trackback is safe... + if ($enableLinkCheck) { + $block = ($spam == true || $link == false); + } else { + $block = $spam == true; + } + $query = ' + INSERT INTO + `' . sql_table('plugin_tb') . '` + SET + `tb_id` = \'' . sql_real_escape_string(intval($tb_id)) . '\', + `block` = \'' . ($block ? '1' : '0') . '\', + `spam` = \'' . ($spam ? '1' : '0') . '\', + `link` = \'' . ($link ? '1' : '0') . '\', + `url` = \'' . sql_real_escape_string($url) . '\', + `title` = \'' . sql_real_escape_string($title) . '\', + `excerpt` = \'' . sql_real_escape_string($excerpt) . '\', + `blog_name` = \'' . sql_real_escape_string($blog_name) . '\', + `timestamp` = ' . mysqldate($b->getCorrectTime()) . ' + '; + $res = sql_query($query); + if (!$res) { + return _TB_msgCOULDNOT_SAVE_DOUBLE . mysql_error() . $query; + } + } + // 7. Send notification e-mail if needed + $notifyAddrs = $this->getOption('NotifyEmail'); + $notifyAddrs = ($notifyAddrs ? $notifyAddrs . ';' : '') + . $this->getBlogOption($blogId, 'NotifyEmailBlog'); + if ($notifyAddrs && $spam == false) { + $vars = array ( + 'tb_id' => $tb_id, + 'url' => $url, + 'title' => $title, + 'excerpt' => $excerpt, + 'blogname' => $blog_name + ); + $mailto_title = TEMPLATE::fill($this->notificationMailTitle, $vars); + $mailto_msg = TEMPLATE::fill($this->notificationMail, $vars); + global $CONF, $DIR_LIBS; + // make sure notification class is loaded + if (!class_exists('notification')) { + include($DIR_LIBS . 'NOTIFICATION.php'); + } + $notify = new NOTIFICATION($notifyAddrs); + $notify->notify($mailto_title, $mailto_msg , $CONF['AdminEmail']); + if ($manager->pluginInstalled('NP_Cache')) { + $p =& $manager->getPlugin('NP_Cache'); + $p->setCurrentBlog($tb_id); + $p->cleanItem($tb_id); + $p->cleanArray(array('index')); + } + } + if( $block ) { + return _TB_tplNO_ACCEPT; + } + return ''; + } + +// }}} +// {{{ function xmlResponse($errorMessage = '') + + /** + * Send a Trackback ping to another website + * + * @param str + */ + function xmlResponse($errorMessage = '') + { + $dom = new DOMDocument('1.0', 'UTF-8'); + $response = $dom->appendChild($dom->createElement('response')); + if ($errorMessage) { + if (strtoupper(_CHARSET) != 'UTF-8') { + $errorMessage = mb_convert_encoding($errorMessage, 'UTF-8'); + $response->appendChild($dom->createElement('error', '1')); + $response->appendChild($dom->createElement('message', htmlspecialchars($errorMessage, ENT_QUOTES))); + } elase { + $response->appendChild($dom->createElement('error', '0')); + } + } + exit; + } + +// }}} +// {{{ function canSendPing() + + /** + * Check if member may send ping (check if logged in) + * + * @return bool + */ + function canSendPing() + { + global $member; + return $member->isLoggedIn() || $this->xmlrpc; + } + +// }}} +// {{{ function redirect($tb_id, $urlHash) + + /** + * Redirect to trackbacked + * + * @param int + * @param str + */ + function redirect($tb_id, $urlHash) + { + $que = ' + SELECT + `url` as result + FROM + `%s` + WHERE + `tb_id` = %d AND + md5(`url`) = "%s" + '; + $url = htmlspecialchars(quickQuery(sprintf($que, $tb_id, $url_Hash)), ENT_QUOTES); + if (empty($url)) { + global $CONF; + $url = $CONF['SiteURL']; + } + $url = htmlspecialchars_decode(stripslashes($url), ENT_QUOTES); + header('Location: ' . $url); + } + +// }}} +// {{{ function getRequiredURL($itemid) + + /** + * Get required URL for link check + * + * @param int + * @return str + */ + function getRequiredURL($itemid) + { + global $manager; + $blog =& $manager->getBlog(getBlogIDFromItemID(intval($itemid))); + if ($this->isEnableLinkCheck(intval($itemid))) { + return $this->_createItemLink(intval($itemid), $blog); + } + return ''; + } + +// }}} +// {{{ function isEnableLinkCheck($itemid) + + /** + * Is link check Enable ? + * + * @param int + * @return bool + */ + function isEnableLinkCheck($itemid) + { + switch($this->getItemOption($itemid, 'isAcceptW/OLink')) { + case 'yes': + return false; + break; + case 'no': + return true; + break; + case 'default' + default: + $blogid = getBlogIDFromItemID(intval($itemid)); + $def = $this->getBlogOption(intval($blogid), 'isAcceptW/OLinkDef'); + return $def != 'yes'; + break; + } + } + +// }}} +// {{{ function isAcceptTrackBack($itemid = null) + + /** + * Is TrackBack Accept ? + * + * @param int + * @return bool + */ + function isAcceptTrackBack($itemid = null) + { + $ret = false; + if ($this->getOption('AcceptPing') == 'yes') { + if ($itemid) { + $bid = getBlogIDFromItemID(intval($itemid)); + } else { + global $blog; + if ($blog) { + $bid = $blog->getID(); + } else { + global $CONF; + $bid = $CONF['DefaultBlog']; + } + } + if ($this->getBlogOption($bid, 'AllowTrackBack') == 'yes') { + if ($itemid) { + $ret = $this->$this->getItemOption(intval($itemid), 'ItemAcceptPing') == 'yes' ? true : false; + } else { + $ret = true; + } + } else { + $ret = false; + } + } + return $ret; + } + +// }}} +// {{{ function pingTrackback($data) + + /** + * Ping all URLs + * + * @param array + */ + function pingTrackback($data) + { + global $manager, $CONF; + $ping_urls_count = 0; + $ping_urls = array(); + $ping_url = requestVar('trackback_ping_url'); + $localflag = array(); + if (trim($ping_url)) { + $ping_urlsTemp = array(); + $ping_urlsTemp = preg_split("/[\s,]+/", trim($ping_url)); + for ($i=0; $igetItem($itemid, 0, 0); + if (!$item) return; // don't ping for draft & future + if ($item['draft']) return; // don't ping on draft items + + // gather some more information, needed to send the ping (blog name, etc) + $blog =& $manager->getBlog(getBlogIDFromItemID($itemid)); + $blog_name = $blog->getName(); + + $title = $data['title'] != '' ? $data['title'] : $item['title']; + $title = strip_tags($title); + + $excerpt = $data['body'] != '' ? $data['body'] : $item['body']; + $excerpt = strip_tags($excerpt); + $excerpt = $this->_cut_string($excerpt, 200); + +/* + $CONF['ItemURL'] = preg_replace('/\/$/', '', $blog->getURL()); + $url = createItemLink($itemid); +*/ + $url = $this->_createItemLink($item['itemid'],$blog); + + // send the ping(s) (add errors to actionlog) + for ($i=0; $isendPing($itemid, $title, $url, $excerpt, $blog_name, $ping_urls[$i]); + else + $res = $this->handleLocalPing($itemid, $title, $excerpt, $blog_name, $ping_urls[$i]); + if ($res) ACTIONLOG::add(WARNING, 'TrackBack Error:' . $res . ' (' . $ping_urls[$i] . ')'); + } + } + + + + + + + + + + + + $dom = new DOMDocument('1.0', 'UTF-8'); + $response = $dom->appendChild($dom->createElement('response')); + $response->appendChild($dom->createElement('error', '0')); + $rss = $response->appendChild($dom->createElement('rss')); + $rss->setAttribute("version", "0.91"); + $channel = $rss->appendChild($dom->createElement('channel')); + $channel->appendChild($dom->createElement('title', htmlspecialchars($title, ENT_QUOTES))); + $channel->appendChild($dom->createElement('link', htmlspecialchars($url, ENT_QUOTES))); + $channel->appendChild($dom->createElement('description', htmlspecialchars($excerpt, ENT_QUOTES))); + + $query = 'SELECT ' + . '`url`, ' + . '`blog_name`, ' + . '`excerpt`, ' + . '`title`, ' + . 'UNIX_TIMESTAMP(`timestamp`) as timestamp ' + . 'FROM ' + . sql_table('plugin_tb') . ' ' + . 'WHERE ' + . '`tb_id` = ' . $tb_id . ' AND ' + . '`block` = 0 ' + . 'ORDER BY ' + . '`timestamp` DESC'; + $res = sql_query($query); + while($data = sql_fetch_assoc($res)) { + $data['title'] = htmlspecialchars($this->_restore_to_utf8($data['title']), ENT_QUOTES); + $data['excerpt'] = htmlspecialchars($this->_restore_to_utf8($data['excerpt']), ENT_QUOTES); + $data['url'] = htmlspecialchars($data['url'], ENT_QUOTES); + $item = $channel->appendChild($dom->createElement('item')); + $item->appendChild($dom->createElement('title', $data['title']); + $item->appendChild($dom->createElement('link', $data['url']); + $item->appendChild($dom->createElement('description', $data['excerpt']); + } + header('Content-Type: text/xml'); + echo $dom->saveXML(); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/CHANGELOG.txt b/NP_TrackBack/branches/DOM-branch/trackback/CHANGELOG.txt new file mode 100644 index 0000000..299c1d4 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/CHANGELOG.txt @@ -0,0 +1,123 @@ + + + 0.9.0 Initial version of Referer by Xiffy + 0.9.1 Added the possibility to call pop, 10 to show the most populair pages + Minor bugfixes for htmlspecialchars + Added substr to trim the line. Internet Explorer makes long lines instead of braking them + 0.9.2 Added timeoffset functionality to refWhen ... + 0.9.3 Added three display options (needs reinstallation!) + Bugfixes and another calling option; lastall + Added "-" on each refer* + + ------------------------------------------------------------ + + 1.0 Initial release + 1.1 Version that takes advantage of the new features in Nucleus v2.0 + (v1.55 users still need to addapt their templates) + 1.2 - Fix: Typo (cechkids) + - Fix: $CONF['ActionURL'] instead of $CONF['SiteURL'] . 'action.php' + - Fix: also works with php option 'short_open_tags' set to Off + - Added: manualpingform + - Requires Nucleus v2.0... + - Support for tableprefix (Nucleus versions > 2.0) + + 1.3 Release by caw + - Removed: Table backwards compatibility code + - Added: Support for adding TrackBack when editing item + - Change: Table name changed from [nucleus_]plugin_tb to [nucleus_]plug_trackback + + 1.4 Release by TeRanEX + (didn't wrote anything myself, only merged some modifications) + - Added: Table backwards compatibility code (was removed in 1.3 but I don't + see any reason why) + - Change: Table name changed from [nucleus_]plug_trackback to [nucleus_]plugin_tb + again (what was the reason for the change in 1.3? + - Added all fixes/mods/additions of thread http://forum.nucleuscms.org/viewtopic.php?t=3247 + - Send a ping on edit item + - sendPing with POST instead of GET + - "Retrieving TrackBack Pings" Implementation + - "Auto-Discovery of TrackBack Ping URLs" Implementation + - automatically-detecting trackbackURL of permalink linked by item + - Change: the RDF output so that it looks the same as in the MT TrackBack Spec + (see http://forum.nucleuscms.org/viewtopic.php?t=1974) + + 1.5 Release by admun and TeRanEX + - Added: Trackback updates, sending the newest data + - Added: Autodiscovery to the bookmarklet + - Added: Autodiscovery to the pingform + - Fixed: Autodiscovery now looks also in the 'more'-part of an item + - Changed/fixed: autodiscovery when editing an item, now you can check a checkbox for + every trackback that was discovered and you want to ping + - Added: License info + - Changed: The description of the plugin + + ------------------------------------------------------------ + + 2.0a Release by Niels Leenheer (rakaz) + - Added: Caching of auto-detected trackback URLs in a database table + - Added: If the cURL extension is present a HEAD request is send first, to make + sure we are dealing with a (X)HTML page and not some large binary file format. + - Added: The auto-detection of trackback URLs now happen in real time - as you type - + thanks to client-side Javascript and the XmlHttpRequest object which requests + the required data from the plugin. + + 2.0b - Added spinning auto-detection indicator + - Added support for multiple character encoding methods. The plugin + works internally fully in UTF-8 (Unicode) and can convert other + character encodings. The output of the plugin is in UTF-8 or in US-ASCII + with unicode characters encoded using numeric entities. + - Added spam protection using the Blacklist plugin (thanks to Xiffy for + helping me out by adding a generic spam check API to his plugin). + - Added a check to see if the page which send the trackback actually + contains a link to our server. If not, then it is probably a spamming + attempt and block by default. + - The output of this plugin is now fully configurable. You can specify + you're own (X)HTML code. + - Added a admin interface which can be used to manage trackbacks and + manually send trackbacks to other sites. It is possible to delete + trackbacks, but also to block and unblock trackbacks. All trackbacks + which are marked as spam are not deleted automatically, but they end + up in a list called 'Blocked trackbacks'. You can manually verify this + list and unblock any trackback which is marked as spam by mistake. + - Fixed a number of bugs, including missing hostnames and double // in + URLs. Fixed a bug introduced in 2.0a which prevented the title and + excerpt from showing up when sending trackbacks from a newly created + story. Also filtering of tags is more stringent. + + - REMOVED: Manual ping forms. The form which is need to ping other + weblogs is now integrated into the admin interface. The form needed + for other weblog authors to manually add trackbacks to your website + will return in the next release. + - REMOVED: The ability to show a list of trackbacks in a popup window. + This will probably return in the next release. + - REMOVED: The ability to delete trackbacks directly from the list + shown to administrators. This is now handled by the admin interface. + + 2.0 final + - Made the help page Nucleus 3.2 compatible + - Added a manual ping form, which allows weblog authors to add a trackback + to your stories even when their software doesn't support trackbacks. + - Removed en from the RSS output, because we can't + be sure about the language of the contents of the RSS stream. + + 2.0.1 - Security fix: Plugin admin interface was exposed to all logged in users, + not only to users with admin rights. + + 2.0.2 - Added autodetection of the encoding of trackbacks, which is needed when + a trackback is send in a foreign encoding by a sender which does not + support version 1.2 of the trackback specifications. Supported encodings: + US-ASCII, ISO-2022-JP, UTF-8, EUC-JP, Shift_JIS. If the encoding is not + specified according to version 1.2 of the specs AND it is not one of the + encodings specified above, the plugin will assume it is encoding using + ISO-8859-1. + - Added two new events SendTrackback and RetrieveTrackback which can be + used by other plugins or the XML-RPC APIs to allow external blog editors + to send trackbacks. (This functionality does require a modification to + the XML-RPC APIs). + - Added support for more clean Trackback URLs, for example: + http://www.rakaz.nl/nucleus/item/84.trackback or + http://www.rakaz.nl/nucleus/item.php?id=84&format=trackback + + 2.0.3 - Added support for a more advanced version of the SpamCheck API + + \ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/autodetect.php b/NP_TrackBack/branches/DOM-branch/trackback/autodetect.php new file mode 100644 index 0000000..a3f107d --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/autodetect.php @@ -0,0 +1,259 @@ +addTicketToUrl($CONF['ActionURL'] . '?action=plugin&name=TrackBack&type=detect') +?> + var xmlhttp = false; + var inProgress = false; + + var TrackbackAction = ""; + var TrackbackSource = new Array; + var TrackbackName = new Array; + var TrackbackURL = new Array; + + var LookupTable = new Array; + var Lookup = ''; + var countTotal = 0; + + var regexp = /href\s*=\s*([\"\'])(http:[^\"\'>]+)([\"\'])/ig; + + + function tbParseLinks () + { + oinputbody = document.getElementById('inputbody'); + oinputmore = document.getElementById('inputmore'); + full = oinputbody.value + ' ' + oinputmore.value; + + while (vArray = regexp.exec(full)) + { + unused = true; + + if (Lookup == vArray[2]) + unused = false; + + for (var i = 0; i < LookupTable.length; i++) + if (LookupTable[i] == vArray[2]) + unused = false; + + for (var i = 0; i < TrackbackSource.length; i++) + if (TrackbackSource[i] == vArray[2]) + unused = false; + + if (unused == true) + LookupTable.push(vArray[2]); + } + } + + function tbAutoDetect() + { + if (LookupTable.length > 0) + { + tbBusy(true); + + if (!inProgress) + { + // We have something to do and the connection is free + Lookup = LookupTable.shift(); + inProgress = true; + + // The reason we use GET instead of POST is because + // Opera does not properly support setting headers yet, + // which is a requirement for using POST. + xmlhttp.open("GET", TrackbackAction + "&tb_link=" + escape(Lookup), true); + xmlhttp.onreadystatechange = tbStateChange; + xmlhttp.send(''); + } + else + { + // Still busy... simply wait until next turn + } + } + else + { + // Nothing to do, check back later... + if (Lookup == '') + { + tbBusy(false); + } + } + } + + function tbStateChange () + { + if (inProgress == true && xmlhttp.readyState == 4 && xmlhttp.status == 200) + { + eval (xmlhttp.responseText); + inProgress = false; + Lookup = ''; + } + } + + function tbBusy(toggle) + { + + if (toggle) + { + document.forms[0].discoverit.style.color = "#888888"; + document.forms[0].discoverit.style.fontWeight="bold"; + document.forms[0].discoverit.value = " Loading ...."; + } + else + { + document.forms[0].discoverit.style.color = "#888888"; + document.forms[0].discoverit.style.fontWeight="bold"; + document.forms[0].discoverit.value = " D o n e ! "; + } + + o = document.getElementById('tb_busy'); + + if (o) + { + if (toggle) + o.style.display = ''; + else + o.style.display = 'none' + } + } + + function tbDone(source, url, name) + { + TrackbackSource.push(source); + TrackbackURL.push(url); + TrackbackName.push(name); + +// var parent = document.getElementById('tb_auto'); + var amount = document.getElementById('tb_url_amount'); + var subtitle = document.getElementById('tb_auto_title'); + var listtable = document.getElementById('tb_ping_list'); + + if (url != '') + { +// count = parseInt(amount.value); + count = countTotal; + + mycurrent_row=document.createElement("TR"); + + checkbox = document.createElement("input"); + checkbox.type = 'checkbox'; + checkbox.name = "tb_url_" + count; + checkbox.id = "tb_url_" + count; + checkbox.value = url; + checkbox.defaultChecked = true; + + label = document.createElement("label"); + label.htmlFor = "tb_url_" + count; + label.title = source; + + text = document.createTextNode(name); + label.appendChild(text); + + +// br = document.createElement("br"); + +// subtitle.innerHTML = "Auto Discovered Ping URL's:"; +// parent.appendChild(checkbox); +// parent.appendChild(label); + + mycurrent_cell=document.createElement("TD"); + mycurrent_cell.appendChild(checkbox); + mycurrent_row.appendChild(mycurrent_cell); + mycurrent_cell=document.createElement("TD"); + mycurrent_cell.appendChild(label); + mycurrent_row.appendChild(mycurrent_cell); + + mycurrent_row.appendChild(mycurrent_cell); + + + if(url.indexOf("",0) != -1) + { + //local? + checkboxL = document.createElement("input"); + checkboxL.type = 'checkbox'; + checkboxL.name = "tb_url_" + count + "_local"; + checkboxL.id = "tb_url_" + count + "_local"; + checkboxL.defaultChecked = true; + + labelL = document.createElement("label"); + labelL.htmlFor = "tb_url_" + count + "_local"; + labelL.title = "local?"; + + text = document.createTextNode("local?"); + labelL.appendChild(text); +// parent.appendChild(checkboxL); +// parent.appendChild(labelL); + mycurrent_cell=document.createElement("TD"); + mycurrent_cell.appendChild(checkboxL); + mycurrent_cell.appendChild(labelL); + mycurrent_row.appendChild(mycurrent_cell); + + } + else + { + mycurrent_cell=document.createElement("TD"); + mycurrent_row.appendChild(mycurrent_cell); + } +// parent.appendChild(br); + listtable.appendChild(mycurrent_row); + +// amount.value = count + 1; + countTotal++; + amount.value = countTotal; + } + else + { + subtitle.innerHTML = "No Trackbak URLs."; + } + } + + function tbSetup() + { + try + { + xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); + } + catch (e) + { + try + { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } + catch (e) + { + xmlhttp = false; + } + } + + if (!xmlhttp && typeof XMLHttpRequest!='undefined') + { + xmlhttp = new XMLHttpRequest(); + } + + setInterval ('tbParseLinks();', 500); + setInterval ('tbAutoDetect();', 500); + + if (window.onloadtrackback) + window.onloadtrackback(); + } + + function AddStart() + { + var strString = ""; + strString = document.forms[0].trackback_ping_url.value; + strArray = strString.split("\n"); + for (var i = 0; i < strArray.length; i++) + { + strTemp = trim(strArray[i]); + if (strTemp != "" && strTemp.match(/^http/)) + { + tbDone(strTemp,strTemp,strTemp); + } + } + document.forms[0].trackback_ping_url.value = ''; + } + + function trim(string) + { + return string.replace(/(^\s*)|(\s*$)/g,''); + } diff --git a/NP_TrackBack/branches/DOM-branch/trackback/detectlist.php b/NP_TrackBack/branches/DOM-branch/trackback/detectlist.php new file mode 100644 index 0000000..c3affe6 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/detectlist.php @@ -0,0 +1,70 @@ + + var TrackbackAction = ""; + var tb_id = ""; + var tb_amount = ""; + var xmlhttp = false; + + function resttbStart() + { + document.getElementById("tbhidenavi").style.display = "block"; + document.getElementById("tbshownavi").style.display = "none"; + try + { + xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); + } + catch (e) + { + try + { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } + catch (e) + { + xmlhttp = false; + } + } + + if (!xmlhttp && typeof XMLHttpRequest!='undefined') + { + xmlhttp = new XMLHttpRequest(); + } + + if (xmlhttp) + { + loadXMLDoc(); + } + + } + + function loadXMLDoc() + { + + var url = TrackbackAction + '?action=plugin&name=TrackBack&type=left&tb_id=' + tb_id + '&amount=' + tb_amount; + + xmlhttp.onreadystatechange=xmlhttpChange + xmlhttp.open("GET",url,true) + xmlhttp.send('') + } + + function xmlhttpChange() + { + if (xmlhttp.readyState == 4 && xmlhttp.status == 200) + { + var result = document.getElementById("resttb"); + result.innerHTML = xmlhttp.responseText; + } + } + + function hideresttb() + { + var result = document.getElementById("resttb"); + result.innerHTML = ""; + + document.getElementById("tbhidenavi").style.display = "none"; + document.getElementById("tbshownavi").style.display = "block"; + + } diff --git a/NP_TrackBack/branches/DOM-branch/trackback/grid.php b/NP_TrackBack/branches/DOM-branch/trackback/grid.php new file mode 100644 index 0000000..5b3ed15 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/grid.php @@ -0,0 +1,238 @@ +isLoggedIn() ) + { + $oPluginAdmin->start(); + echo '

' . _ERROR_DISALLOWED . '

'; + $oPluginAdmin->end(); + exit; + } + + // Actions + $action = requestVar('action'); + $aActionsNotToCheck = array( + '', + ); + if (!in_array($action, $aActionsNotToCheck)) { + if (!$manager->checkTicket()) doError(_ERROR_BADTICKET); + } + +//modify start+++++++++ + $plug =& $oPluginAdmin->plugin; + $tableVersion = $plug->checkTableVersion(); + + // include language file for this plugin + $language = ereg_replace( '[\\|/]', '', getLanguageName()); + if (file_exists($plug->getDirectory().'language/'.$language.'.php')) + include_once($plug->getDirectory().'language/'.$language.'.php'); + else + include_once($plug->getDirectory().'language/'.'english.php'); +//modify end+++++++++ + + $oTemplate = new Trackback_Template(); + $oTemplate->set ('CONF', $CONF); + $oTemplate->set ('plugindirurl', $oPluginAdmin->plugin->getAdminURL()); + $oTemplate->set ('ticket', $manager->_generateTicket()); + + $whereClause = ''; + if( ! $member->isAdmin() ){ + // where clause + $res = sql_query('SELECT tblog FROM '.sql_table('team').' WHERE tadmin = 1 AND tmember = '.$member->getID() ); + $adminBlog = array(); + while ($row = mysql_fetch_array($res)){ + $adminBlog[] = $row[0]; + } + if($adminBlog) + $whereClause = ' i.iblog in (' . implode(', ', $adminBlog) . ') '; + + if( $whereClause ) + $whereClause = ' AND ( i.iauthor = '.$member->getID().' OR ' . $whereClause . ' )'; + else + $whereClause = ' AND i.iauthor = '.$member->getID(); + } + + $requiredItemEditRights = array( + 'dodelete', + 'doblock', + 'dounblock', + ); + $safeids = array(); + if (in_array($action, $requiredItemEditRights)) { + $ids = explode(',', requestVar('ids')); + $safeids = array(); + foreach( $ids as $id ){ + $id = trim($id); + if( is_numeric($id) ) + $safeids[] = $id; + } + if( ! $member->isAdmin() ){ + $query = 'SELECT t.id FROM ' . sql_table('plugin_tb') . ' t, ' . sql_table('item') . ' i WHERE t.tb_id = i.inumber AND t.id in ( '. implode(',', $safeids) . ' ) '. $whereClause ; + $res = sql_query($query); + $safeids = array(); + while ($row = mysql_fetch_array($res)){ + $safeids[] = $row[0]; + } + } + } + + // Pages + switch($action) { + + case 'ajax': + $type = requestVar('type') == 'all' ? 'all' : 'blocked' ; + $filter['all'] = ' t.block = 0 '; + $filter['blocked'] = ' t.block = 1 '; + + $start = intRequestVar('offset') ? intRequestVar('offset') : 0; + $amount = intRequestVar('page_size') ? intRequestVar('page_size') : 25; + + $colname = array(); + $colname['date'] = 'timestamp'; + $colname['item'] = 'story_id'; + $colname['title'] = 'title'; + + $sort_col = requestVar('sort_col'); + $sort_col = $colname[$sort_col]; + if( !$sort_col ) $sort_col = $colname['date']; + + $sort_dir = ( requestVar('sort_dir') == 'ASC' ) ? 'ASC' : 'DESC'; + + $rres = sql_query (" + SELECT + count(*) as count + FROM + ".sql_table('plugin_tb')." AS t, + ".sql_table('item')." AS i + WHERE + t.tb_id = i.inumber AND + ".$filter[$type].$whereClause); + $rrow = mysql_fetch_array($rres); + $count = $rrow['count']; + + $rres = sql_query (" + SELECT + i.ititle AS story, + i.inumber AS story_id, + t.id AS id, + t.title AS title, + t.blog_name AS blog_name, + t.excerpt AS excerpt, + t.url AS url, + t.spam AS spam, + UNIX_TIMESTAMP(t.timestamp) AS timestamp + FROM + ".sql_table('plugin_tb')." AS t, + ".sql_table('item')." AS i + WHERE + t.tb_id = i.inumber AND + ".$filter[$type].$whereClause." + ORDER BY + ".$sort_col." ".$sort_dir." + LIMIT + ".$start.",".$amount." + "); + + $items = array(); + + while ($rrow = mysql_fetch_array($rres)) + { + $rrow['title'] = $oPluginAdmin->plugin->_cut_string($rrow['title'], 50); + $rrow['title'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['title']); + $rrow['title'] = htmlspecialchars($rrow['title']); + $rrow['title'] = preg_replace("/-+/","-",$rrow['title']); + + $rrow['blog_name'] = $oPluginAdmin->plugin->_cut_string($rrow['blog_name'], 50); + $rrow['blog_name'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['blog_name']); + $rrow['blog_name'] = htmlspecialchars($rrow['blog_name']); + $rrow['blog_name'] = preg_replace("/-+/","-",$rrow['blog_name']); + + $rrow['excerpt'] = $oPluginAdmin->plugin->_cut_string($rrow['excerpt'], 100); + $rrow['excerpt'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['excerpt']); + $rrow['excerpt'] = htmlspecialchars($rrow['excerpt']); + $rrow['excerpt'] = preg_replace("/-+/","-",$rrow['excerpt']); + + $rrow['url'] = htmlspecialchars($rrow['url'], ENT_QUOTES); + + $blog = & $manager->getBlog(getBlogIDFromItemID($rrow['story_id'])); + $rrow['story_url'] = $oPluginAdmin->plugin->_createItemLink($rrow['story_id'], $blog); + $rrow['story'] = htmlspecialchars(strip_tags($rrow['story']), ENT_QUOTES); + + $items[] = $rrow; + } + + $oTemplate->set ('amount', $amount); + $oTemplate->set ('count', $count); + $oTemplate->set ('start', $start); + $oTemplate->set ('items', $items); + $oTemplate->template('templates/response_'.$type.'.xml'); + break; + + case 'dodelete': + if( count($safeids) > 0 ){ + $safeids = implode(',',$safeids); + + $res = sql_query( + ' DELETE FROM ' + . sql_table('plugin_tb') + . ' WHERE id in (' . $safeids. ')' + ); + $oTemplate->set ('message', $safeids . ' deleted.'); + } else { + $oTemplate->set ('message', 'no rows deleted.'); + } + + $oTemplate->template('templates/response_dodelete.xml'); + break; + + case 'doblock': + if( count($safeids) > 0 ){ + $safeids = implode(',',$safeids); + + $res = sql_query( + ' UPDATE ' + . sql_table('plugin_tb') + .' SET block = 1 ' + . ' WHERE id in (' . $safeids. ')' + ); + $oTemplate->set ('message', $safeids . ' blocked.'); + } else { + $oTemplate->set ('message', 'no rows blocked.'); + } + + $oTemplate->template('templates/response_doblock.xml'); + break; + + case 'dounblock': + if( count($safeids) > 0 ){ + $safeids = implode(',',$safeids); + + $res = sql_query( + ' UPDATE ' + . sql_table('plugin_tb') + .' SET block = 0 ' + . ' WHERE id in (' . $safeids. ')' + ); + $oTemplate->set ('message', $safeids . ' unblocked.'); + } else { + $oTemplate->set ('message', 'no rows unblocked.'); + } + + $oTemplate->template('templates/response_dounblock.xml'); + break; + } + + // Create the admin area page + echo $oTemplate->fetch(); + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/help.html b/NP_TrackBack/branches/DOM-branch/trackback/help.html new file mode 100644 index 0000000..41a60ae --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/help.html @@ -0,0 +1,111 @@ +

Help

+ + +

Skin variables

+ +

+ <%TrackBack(list)%> +

+

+ Show a list of trackbacks for the current page. Optionally it is also possible to + add an additional parameter, the story id number, which makes it possible to + show a list of trackbacks from a different page. The output of this variable is + fully configurable in the plugin options. +

+ +

+ <%TrackBack(code)%> +

+

+ Inserts a small piece of invisible RDF code in the page, which is used by other + weblogs to auto-detect the trackback URL. If you do not include this variable in + your skin for item pages, other weblogs will not be able to auto-detect that your + weblog is able to accept trackbacks. +

+ +

+ <%TrackBack(form)%> +

+

+ Insert the URL to a manual ping form. Using this form authors of other weblogs + can add trackbacks to your stories, even when their software does not support + trackbacks, such as Blogger. A link to this form is included in the footer of + the trackback list by default. If you want to place this link somewhere else + on your page, simply remove the <%form%> variable from the + Footer field in the plugin settings and add the skinvar somewhere on + your webpage. +

+ +

+ <%TrackBack(url)%> +

+

+ Insert the Trackback Ping URL. A this URL is also included in the footer of + the trackback list by default. If you want to place this link somewhere else + on your page, simply remove the <%action%> variable from the + Footer field in the plugin settings and add the skinvar somewhere on + your webpage. +

+ +

Template variables

+ +

+ All the skin variables documented above are also available as template variables. +

+ +

+ <%TrackBack(count)%> +

+

+ If you want to include an indication of how many trackbacks are present for each + page you can use this variable. By default this variable will show: "No Trackbacks", + "1 Trackback", "2 Trackbacks", etc. This is however also fully configurable in + the plugin options. +

+ + +

Changing the output

+ +

+ It is possible to fully change the output of this plugin. You can manually change + the XHTML code in the plugin options, but you can also use CSS to style the default + output to your liking. Below you will find an example of what a little snippet of + CSS can do. +

+ +
div.tb {
+	border: 1px solid #000; background: #FFF;
+}
+div.tb div.head {
+	padding: 4px;
+	background: #000; color: #FFF;
+	font-weight: bold; text-transform: lowercase; letter-spacing: 0.6em;
+}
+div.tb div.empty {
+	padding: 4px;
+	font-size: 95%;
+}
+div.tb div.item {
+	padding: 4px;
+}
+div.tb div.item div.name {
+	margin-bottom: 8px;
+	font-size: 120%; font-weight: bold;
+}
+div.tb div.item div.body {
+	font-size: 95%;
+}
+div.tb div.item div.body a {
+	font-weight: bold;
+}
+div.tb div.item div.date {
+	margin-bottom: 8px;
+	color: #888;
+	font-size: 85%; text-align: right;
+}
+div.tb div.info {
+	padding: 4px;
+	color: #FFF; background: #888;
+	font-size: 85%; font-style: italic;
+}
+ diff --git a/NP_TrackBack/branches/DOM-branch/trackback/index.php b/NP_TrackBack/branches/DOM-branch/trackback/index.php new file mode 100644 index 0000000..ef09755 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/index.php @@ -0,0 +1,496 @@ +isLoggedIn() ) + { + $oPluginAdmin->start(); + echo '

' . _ERROR_DISALLOWED . '

'; + $oPluginAdmin->end(); + exit; + } + + // Actions + $action = requestVar('action'); + $aActionsNotToCheck = array( + '', + 'ping', + ); + if (!in_array($action, $aActionsNotToCheck)) { + if (!$manager->checkTicket()) doError(_ERROR_BADTICKET); + } + + $oPluginAdmin->start(); + +//modify start+++++++++ + $plug =& $oPluginAdmin->plugin; + $tableVersion = $plug->checkTableVersion(); + + // include language file for this plugin + $language = ereg_replace( '[\\|/]', '', getLanguageName()); + if (file_exists($plug->getDirectory().'language/'.$language.'.php')) + include_once($plug->getDirectory().'language/'.$language.'.php'); + else + include_once($plug->getDirectory().'language/'.'english.php'); +//modify end+++++++++ + + $mTemplate = new Trackback_Template(); + $mTemplate->set ('CONF', $CONF); + $mTemplate->set ('plugid', $plug->getID()); + $mTemplate->set ('plugindirurl', $oPluginAdmin->plugin->getAdminURL()); + $mTemplate->template('templates/menu.html'); + echo $mTemplate->fetch(); + + $oTemplate = new Trackback_Template(); + $oTemplate->set ('CONF', $CONF); + $oTemplate->set ('plugindirurl', $oPluginAdmin->plugin->getAdminURL()); + $oTemplate->set ('ticket', $manager->_generateTicket()); + $ajaxEnabled = ($oPluginAdmin->plugin->getOption('ajaxEnabled') == 'yes') ? true : false; + $oTemplate->set ('ajaxEnabled', $ajaxEnabled); + + $whereClause = ''; + if( ! $member->isAdmin() ){ + // where clause + $res = sql_query('SELECT tblog FROM '.sql_table('team').' WHERE tadmin = 1 AND tmember = '.$member->getID() ); + $adminBlog = array(); + while ($row = mysql_fetch_array($res)){ + $adminBlog[] = $row[0]; + } + if($adminBlog) + $whereClause = ' i.iblog in (' . implode(', ', $adminBlog) . ') '; + + if( $whereClause ) + $whereClause = ' AND ( i.iauthor = '.$member->getID().' OR ' . $whereClause . ' )'; + else + $whereClause = ' AND i.iauthor = '.$member->getID(); + } + //echo "

Debug: $whereClause

"; + + $requiredAdminRights = array( + 'tableUpgrade', + 'blocked_clear', + 'blocked_spamclear', + ); + if (in_array($action, $requiredAdminRights)) { + if( ! $member->isAdmin() ){ + echo '

' . _ERROR_DISALLOWED . '

'; + echo '

Reason: ' . __LINE__ . '

'; + $oPluginAdmin->end(); + exit; + } + } + + $requiredItemEditRights = array( + 'block', + 'unblock', + 'delete', + ); + if (in_array($action, $requiredItemEditRights)) { + if( ! $member->isAdmin() ){ + $tb = intRequestVar('tb'); + $query = 'SELECT i.inumber FROM ' . sql_table('plugin_tb') . ' t, ' . sql_table('item') . ' i WHERE t.tb_id = i.inumber AND t.id = '. $tb . $whereClause ; + $res = sql_query($query); + if( ! @mysql_num_rows($res) ){ + echo '

' . _ERROR_DISALLOWED . '

'; + echo '

Reason: ' . __LINE__ . '

'; + $oPluginAdmin->end(); + exit; + } + } + } + + switch($action) { + +//modify start+++++++++ + case 'tableUpgrade': + sql_query(" + CREATE TABLE IF NOT EXISTS + ".sql_table('plugin_tb_lookup')." + ( + `link` TEXT NOT NULL, + `url` TEXT NOT NULL, + `title` TEXT, + + PRIMARY KEY (`link` (100)) + ) + "); + echo $q = "ALTER TABLE ".sql_table('plugin_tb')." + ADD `block` TINYINT( 4 ) NOT NULL AFTER `url` , + ADD `spam` TINYINT( 4 ) NOT NULL AFTER `block` , + ADD `link` TINYINT( 4 ) NOT NULL AFTER `spam` , + CHANGE `url` `url` TEXT NOT NULL, + CHANGE `title` `title` TEXT NOT NULL, + CHANGE `excerpt` `excerpt` TEXT NOT NULL, + CHANGE `blog_name` `blog_name` TEXT NOT NULL, + DROP PRIMARY KEY, + ADD `id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST ;"; + $res = @sql_query($q); + if (!$res){ + echo 'Could not alter table: ' . mysql_error(); + }else{ + $tableVersion = 1; + $oTemplate->template('templates/updatetablefinished.html'); + } + @sql_query('ALTER TABLE `' . sql_table('plugin_tb') . '` ADD INDEX `tb_id_block_timestamp_idx` ( `tb_id`, `block`, `timestamp` DESC )'); + break; +//modify end+++++++++ + + case 'block': + $tb = intRequestVar('tb'); + + $res = sql_query (" + UPDATE + ".sql_table('plugin_tb')." + SET + block = 1 + WHERE + id = '".$tb."' + "); + + $action = requestVar('next'); + break; + + case 'blocked_clear': + $res = sql_query ("DELETE FROM ".sql_table('plugin_tb')." WHERE block = 1"); + $action = requestVar('next'); + break; + + case 'blocked_spamclear': + $res = sql_query ("DELETE FROM ".sql_table('plugin_tb')." WHERE block = 1 and spam = 1"); + $action = requestVar('next'); + break; + + case 'unblock': + $tb = intRequestVar('tb'); + + $res = sql_query (" + UPDATE + ".sql_table('plugin_tb')." + SET + block = 0 + WHERE + id = '".$tb."' + "); + + $action = requestVar('next'); + break; + + case 'delete': + $tb = intRequestVar('tb'); + + $res = sql_query (" + DELETE FROM + ".sql_table('plugin_tb')." + WHERE + id = '".$tb."' + "); + + $action = requestVar('next'); + break; + + case 'sendping': + $title = requestVar('title'); + $url = requestVar('url'); + $excerpt = requestVar('excerpt'); + $blog_name = requestVar('blog_name'); + $ping_url = requestVar('ping_url'); + + // No charset conversion needs to be done here, because + // the charset used to receive the info is used to send + // it... + + if ($ping_url) { + $error = $oPluginAdmin->plugin->sendPing(0, $title, $url, $excerpt, $blog_name, $ping_url); + + if ($error) { + echo 'TrackBack Error:' . $error . ''; + } + } + + $action = requestVar('next'); + break; + + case 'ping': + $id = intRequestVar('id'); + + $usePathInfo = ($CONF['URLMode'] == 'pathinfo'); + if ($usePathInfo) + @ include($strRel . 'fancyurls.config.php'); + + global $manager; + $itemData = $manager->getItem($id, 0, 0); + + if(is_array($itemData)){ + $blog =& $manager->getBlog($itemData['blogid']); + $CONF['ItemURL'] = ($usePathInfo)? preg_replace('/\/$/', '', $blog->getURL()): $blog->getURL(); + $itemData['url'] = createItemLink($id); + $itemData['excerpt'] = shorten(strip_tags($itemData['body'].$itemData['more']), 250, '...'); + $itemData['blogname'] = $blog->getName(); + }else{ + $itemData = array(); + $itemData['url'] = $CONF['IndexURL']; + $itemData['blogname'] = $CONF['SiteName']; + } + $oTemplate->set('item', $itemData); + + $oTemplate->template('templates/ping.html'); + break; + } + + // Pages + switch($action) { + + case 'help': + $oTemplate->template('help.html'); + break; + + case 'ping': + $oTemplate->template('templates/ping.html'); + break; + + case 'blocked': + case 'all': + $rres = sql_query (" + SELECT + COUNT(*) AS count + FROM + ".sql_table('plugin_tb')." AS t, + ".sql_table('item')." AS i + WHERE + t.tb_id = i.inumber AND + t.block = " . (( $action == 'all') ? 0 : 1) . $whereClause ); + + if ($row = mysql_fetch_array($rres)) + $count = $row['count']; + else + $count = 0; + $oTemplate->set('count', $count); + + if($ajaxEnabled){ + if( $action == 'all') + $oTemplate->template('templates/all_ajax.html'); + else + $oTemplate->template('templates/blocked_ajax.html'); + } else { + $start = intRequestVar('start') ? intRequestVar('start') : 0; + $amount = intRequestVar('amount') ? intRequestVar('amount') : 25; + + $rres = sql_query (" + SELECT + i.ititle AS story, + i.inumber AS story_id, + t.id AS id, + t.title AS title, + t.blog_name AS blog_name, + t.excerpt AS excerpt, + t.url AS url, + UNIX_TIMESTAMP(t.timestamp) AS timestamp, + t.spam AS spam, + t.link AS link + FROM + ".sql_table('plugin_tb')." AS t, + ".sql_table('item')." AS i + WHERE + t.tb_id = i.inumber AND + t.block = " . (( $action == 'all') ? 0 : 1) . $whereClause ." + ORDER BY + timestamp DESC + LIMIT + ".$start.",".$amount); + + $items = array(); + + while ($rrow = mysql_fetch_array($rres)){ + $rrow['title'] = $oPluginAdmin->plugin->_cut_string($rrow['title'], 50); + $rrow['title'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['title']); + $rrow['title'] = htmlspecialchars($rrow['title']); + + $rrow['blog_name'] = $oPluginAdmin->plugin->_cut_string($rrow['blog_name'], 50); + $rrow['blog_name'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['blog_name']); + $rrow['blog_name'] = htmlspecialchars($rrow['blog_name']); + + $rrow['excerpt'] = $oPluginAdmin->plugin->_cut_string($rrow['excerpt'], 800); + $rrow['excerpt'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['excerpt']); + $rrow['excerpt'] = htmlspecialchars($rrow['excerpt']); + + $rrow['url'] = htmlspecialchars($rrow['url'], ENT_QUOTES); + $rrow['timestamp'] = htmlspecialchars($rrow['timestamp'], ENT_QUOTES); + + $blog = & $manager->getBlog(getBlogIDFromItemID($item['itemid'])); + $rrow['story_url'] = $oPluginAdmin->plugin->_createItemLink($rrow['story_id'], $blog); + $rrow['story'] = htmlspecialchars(strip_tags($rrow['story']), ENT_QUOTES); + + $items[] = $rrow; + } + + $oTemplate->set('amount', $amount); + $oTemplate->set('start', $start); + $oTemplate->set('items', $items); + + if( $action == 'all') + $oTemplate->template('templates/all.html'); + else + $oTemplate->template('templates/blocked.html'); + } + break; + + case 'list': + $id = requestVar('id'); + $start = intRequestVar('start') ? intRequestVar('start') : 0; + $amount = intRequestVar('amount') ? intRequestVar('amount') : 25; + + $ires = sql_query (" + SELECT + i.ititle, + i.inumber + FROM + ".sql_table('item')." i + WHERE + i.inumber = '".$id."' + ". $whereClause ); + + if ($irow = mysql_fetch_array($ires)) + { + $story['id'] = $id; + $story['title'] = $irow['ititle']; + + $rres = sql_query (" + SELECT + COUNT(*) AS count + FROM + ".sql_table('plugin_tb')." AS t + WHERE + t.tb_id = '".$id."' AND + t.block = 0 + "); + + if ($row = mysql_fetch_array($rres)) + $count = $row['count']; + else + $count = 0; + + $rres = sql_query (" + SELECT + t.id AS id, + t.title AS title, + t.blog_name AS blog_name, + t.excerpt AS excerpt, + t.url AS url, + UNIX_TIMESTAMP(t.timestamp) AS timestamp + FROM + ".sql_table('plugin_tb')." AS t + WHERE + t.tb_id = '".$id."' AND + t.block = 0 + ORDER BY + timestamp DESC + LIMIT + ".$start.",".$amount." + "); + + $items = array(); + + while ($rrow = mysql_fetch_array($rres)) + { + $rrow['title'] = $oPluginAdmin->plugin->_cut_string($rrow['title'], 50); + $rrow['title'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['title']); + $rrow['title'] = htmlspecialchars($rrow['title']); +// $rrow['title'] = _CHARSET == 'UTF-8' ? $rrow['title'] : $oPluginAdmin->plugin->_utf8_to_entities($rrow['title']); + + $rrow['blog_name'] = $oPluginAdmin->plugin->_cut_string($rrow['blog_name'], 50); + $rrow['blog_name'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['blog_name']); + $rrow['blog_name'] = htmlspecialchars($rrow['blog_name']); +// $rrow['blog_name'] = _CHARSET == 'UTF-8' ? $rrow['blog_name'] : $oPluginAdmin->plugin->_utf8_to_entities($rrow['blog_name']); + + $rrow['excerpt'] = $oPluginAdmin->plugin->_cut_string($rrow['excerpt'], 800); + $rrow['excerpt'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['excerpt']); + $rrow['excerpt'] = htmlspecialchars($rrow['excerpt']); +// $rrow['excerpt'] = _CHARSET == 'UTF-8' ? $rrow['excerpt'] : $oPluginAdmin->plugin->_utf8_to_entities($rrow['excerpt']); + + $rrow['url'] = htmlspecialchars($rrow['url'], ENT_QUOTES); + $rrow['story'] = htmlspecialchars(strip_tags($rrow['story']), ENT_QUOTES); + $items[] = $rrow; + } + + $oTemplate->set ('amount', $amount); + $oTemplate->set ('count', $count); + $oTemplate->set ('start', $start); + $oTemplate->set ('items', $items); + $oTemplate->set ('story', $story); + $oTemplate->template('templates/list.html'); + } + + break; + + + case 'index': + $bres = sql_query (" + SELECT + bnumber AS bnumber, + bname AS bname, + burl AS burl + FROM + ".sql_table('blog')." + ORDER BY + bname + "); + + $blogs = array(); + + while ($brow = mysql_fetch_array($bres)) + { + if( !$member->isTeamMember($brow['bnumber']) ) continue; + $ires = sql_query (" + SELECT + i.inumber AS inumber, + i.ititle AS ititle, + COUNT(*) AS total + FROM + ".sql_table('item')." AS i, + ".sql_table('plugin_tb')." AS t + WHERE + i.iblog = ".$brow['bnumber']." AND + t.tb_id = i.inumber AND + t.block = 0 ".$whereClause." + GROUP BY + i.inumber + ORDER BY + i.inumber DESC + "); + + $items = array(); + + while ($irow = mysql_fetch_array($ires)) + { + $items[] = $irow; + } + + $brow['items'] = $items; + $blogs[] = $brow; + } + + $oTemplate->set ('blogs', $blogs); + $oTemplate->template('templates/index.html'); + break; + + default: + //modify start+++++++++ + if(!$tableVersion){ + $oTemplate->template('templates/updatetable.html'); + } + //modify end+++++++++ + break; + } + + // Create the admin area page + echo $oTemplate->fetch(); + + echo '
Powered by Silk icon
'; + $oPluginAdmin->end(); + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.help.html b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.help.html new file mode 100644 index 0000000..aa0b185 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.help.html @@ -0,0 +1,116 @@ +

¥Ø¥ë¥×

+ + +

¥¹¥­¥ó¤Ø¤Îµ­½ÒÎã

+

+Nucleus CMS Japan Wiki¤ÎNP_TrackBack¤Î¥Ú¡¼¥¸¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£ +

+ +

ɽ¼¨¤Î¥«¥¹¥¿¥Þ¥¤¥º

+

+ ¥È¥é¥Ã¥¯¥Ð¥Ã¥¯´ØÏ¢¤Îɽ¼¨ÊýË¡¤Ï¥Æ¥ó¥×¥ì¡¼¥È¤òÊÔ½¸¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤Ç¤­¤Þ¤¹¤¬¡¢¿§¤ä;Çò¤Ê¤É¤Î¥Ç¥¶¥¤¥ó¤ÏCSS¦¤Ç»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥Æ¥ó¥×¥ì¡¼¥ÈÆâ¤ËÆþÎϤ·¤¿¥¯¥é¥¹Ì¾¤Î¥×¥í¥Ñ¥Æ¥£¤Ïcss¤Ç»ØÄꤷ¤Æ¤¯¤À¤µ¤¤¡£¥Ç¥Õ¥©¥ë¥È¤Î¥Æ¥ó¥×¥ì¡¼¥È¤ò¾þ¤ëCSS¥×¥í¥Ñ¥Æ¥£¤ÎÎã¤ò¤¢¤²¤Æ¤ª¤­¤Þ¤¹¡£ +

+ +
div.tb {
+	border: 1px solid #000; background: #FFF;
+}
+div.tb div.head {
+	padding: 4px;
+	background: #000; color: #FFF;
+	font-weight: bold; text-transform: lowercase; letter-spacing: 0.6em;
+}
+div.tb div.empty {
+	padding: 4px;
+	font-size: 95%;
+}
+div.tb div.item {
+	padding: 4px;
+}
+div.tb div.item div.name {
+	margin-bottom: 8px;
+	font-size: 120%; font-weight: bold;
+}
+div.tb div.item div.body {
+	font-size: 95%;
+}
+div.tb div.item div.body a {
+	font-weight: bold;
+}
+div.tb div.item div.date {
+	margin-bottom: 8px;
+	color: #888;
+	font-size: 85%; text-align: right;
+}
+div.tb div.info {
+	padding: 4px;
+	color: #FFF; background: #888;
+	font-size: 85%; font-style: italic;
+}
+ +

ÆüËܸìÈǹ¹¿·ÍúÎò

+ +
    +
  • Version 2.0.3jp13 : (2008/12/14)
  • +
  • ¡¡[Fixed] Ping¥Õ¥©¡¼¥à¤Ø¤Î¥ê¥ó¥¯¤ò³«¤³¤¦¤È¤¹¤ë¤ÈInvalid or expired ticket.¤Ë¤Ê¤ëÌäÂê¤ò½¤Àµ
  • +
  • ¡¡[Fixed] TrackBackÁ÷¿®»þ¤Î¥¨¥é¡¼¥Ï¥ó¥É¥ê¥ó¥°¤ò²þÎɤ·¤¿
  • +
  • ¡¡[Fixed] TrackBack¤Îʸ»ú¥³¡¼¥É¤Î¸¡½Ð¤¬Àµ¤·¤¯¹Ô¤ï¤ì¤Ê¤¤¾ì¹ç¤¬¤¢¤ëÌäÂê¤ò½¤Àµ
  • + +
  • Version 2.0.3jp12 : (2008/01/12)
  • +
  • ¡¡[Fixed] ¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤Îʸ»ú¥³¡¼¥É¤¬Å¬ÀڤǤʤ«¤Ã¤¿ÌäÂê¤ò½¤Àµ
  • +
  • ¡¡[Fixed] ¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤ÎÁ÷¿®Ê¸»ú¥³¡¼¥É¤òUTF-8¸ÇÄê¤Ë¤·¤¿
  • +
  • ¡¡[Fixed] ¥È¥é¥Ã¥¯¥Ð¥Ã¥¯²Ä/ÉԲĤÎȽÄ꤬¤ª¤«¤·¤«¤Ã¤¿ÌäÂê¤ò½¤Àµ
  • + +
  • Version 2.0.3jp11 : (2007/09/30)
  • +
  • ¡¡[Added] SuperAdmin°Ê³°¤Ç¤âTrackBack¤¬´ÉÍý¤Ç¤­¤ë¤è¤¦¤Ë¤·¤¿
  • + +
  • Version 2.0.3jp10 : (2007/06/30)
  • +
  • ¡¡[Fixed] mysql_query()¤òsql_query()¤ËÊѹ¹
  • +
  • ¡¡[Changed] ¼ÂÂλ²¾È¥Æ¡¼¥Ö¥ë¤Ë¤Ä¤¤¤ÆNucleusɸ½à¤â¤Î¤ò»È¤¦¤è¤¦¤Ë¤·¤¿
  • +
  • ¡¡[Changed] ¥¤¥ó¥¹¥È¡¼¥ë¤Ç¤­¤ë¥Ð¡¼¥¸¥ç¥ó¤ò3.3°Ê¹ß¤·¤¿
  • +
  • ¡¡[Changed] Rico¤ò2.0¤Ë¥¢¥Ã¥×¥Ç¡¼¥È¤·¤¿¤Î¤Ëȼ¤¤¡¢´ÉÍý²èÌ̤ε¡Ç½¤òÁý¶¯
  • +
  • ¡¡[Added] ¥³¥á¥ó¥ÈÉôʬ¤Ç¤â¥Æ¥ó¥×¥ì¡¼¥ÈÊÑ¿ô¤¬»È¤¨¤ë¤è¤¦¤Ë¤·¤¿
  • +
  • ¡¡[Fixed] ¥È¥é¥Ã¥¯¥Ð¥Ã¥¯Á÷¿®Éôʬ¤ÎÉÔ¶ñ¹ç¤ò½¤Àµ(FC2Âкö)
  • +
  • ¡¡[Changed] UserAgent¤ò¥ª¥ê¥¸¥Ê¥ëÈǤˤ¢¤ï¤»¤ÆÊѹ¹
  • +
  • ¡¡[Changed] TrackBack¤Î¥ì¥¹¥Ý¥ó¥¹¤Î²òÀϤËXML¥Ñ¡¼¥µ¡¼¤ò»È¤¦¤è¤¦¤Ë¤·¤¿
  • +
  • ¡¡[Fixed] ¸ÀµÚ¥ê¥ó¥¯¥Á¥§¥Ã¥¯¤ÎÉÔ¶ñ¹ç¤ò½¤Àµ
  • +
  • ¡¡[Added] ÊÝα¤Ë¤·¤Æ¤¤¤ëURL¤ÈƱ¤¸URL¤Î¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤ò̵»ë¤¹¤ë¤è¤¦¤Ë¤·¤¿
  • + +
  • ¡¡[Fixed] ¸ÀµÚ¥ê¥ó¥¯¥Á¥§¥Ã¥¯¤ÎÍѤÎURLÀ¸À®¥ë¡¼¥Á¥ó¤ÎÉÔ¶ñ¹ç¤ò½¤Àµ
  • + +
  • ¡¡[Added] spam¥È¥é¥Ã¥¯¥Ð¥Ã¥¯°ì³ç¾Ãµî»þ¤Ë³Îǧ¤¬½Ð¤ë¤è¤¦¤Ë¤·¤¿
  • + +
  • Version 2.0.3jp9 : (2007/05/04)
  • +
  • ¡¡[Added] doIf()¤òÄɲÃ(Nucleus 3.3¸þ¤±)
  • +
  • ¡¡[Added] URL¤¬Ìµ¸ú¤Ê¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤ò̵»ë¤¹¤ë¤è¤¦¤Ë¤·¤¿
  • + +
  • Version 2.0.3jp8 : (2007/03/18)
  • +
  • ¡¡[Fixed] ´ÉÍý²èÌ̤ÇStory¤Î¥ê¥ó¥¯¤ÎÉÔ¶ñ¹ç¤ò½¤Àµ
  • +
  • ¡¡[Changed] URLÃê½Ð¥ë¡¼¥Á¥ó¤ò²þÎÉ
  • +
  • ¡¡[Changed] ´ÉÍý²èÌ̤ؤΥê¥ó¥¯¤ò½¤Àµ
  • +
  • ¡¡[Changed] ´ÉÍý²èÌ̤Υڡ¼¥¸¥ó¥°¤òAjaxÂбþ¤Ë¤·¤¿
  • +
  • ¡¡[Changed] ¥È¥é¥Ã¥¯¥Ð¥Ã¥¯ÄÌÃÎ¥¢¥É¥ì¥¹¤ò¥Ö¥í¥°¤´¤È¤ËÀßÄê¤Ç¤­¤ë¤è¤¦¤Ë¤·¤¿
  • +
  • ¡¡[Fixed] php¤Îshort open¥¿¥°¤ò½¤Àµ
  • +
  • ¡¡[Fixed] ´ÉÍý²èÌ̤Υȥé¥Ã¥¯¥Ð¥Ã¥¯°ìÍ÷¤ÇÆüÉÕ¤¬Àµ¾ï¤Ëɽ¼¨¤µ¤ì¤Ê¤¤ÌäÂê¤ò½¤Àµ
  • + +
  • Version 2.0.3jp7 : (2006/11/26)
  • +
  • ¡¡[Changed] SpamChek¤Ë¤Ä¤¤¤ÆÈùÄ´À°
  • +
  • ¡¡[Added] Ticket½èÍý¤òÄɲÃ(CSRFÂкö)
  • +
  • ¡¡[Fixed] URL¤Ë&¤¬Æþ¤Ã¤Æ¤¤¤ë¤È¤­¤ÎÆ°ºî¤òÊѹ¹
  • +
  • ¡¡[Added] ´ÉÍý²èÌ̤˥¢¥¤¥³¥ó¤òÄɲÃ
  • + +
  • Version 2.0.3jp6 : (2006/09/30)
  • +
  • ¡¡[Fixed] ¥»¥­¥å¥ê¥Æ¥£¤Î¸þ¾å
  • + +
  • Version 2.0.3jp5 : (2006/09/16)
  • +
  • ¡¡[Fixed] getPermaLinksFromText()Æâ¤ÎURLÃê½Ð¥ë¡¼¥Á¥ó¤ÎÉÔ¶ñ¹ç¤ò½¤Àµ
  • +
  • ¡¡[Fixed] Auto-Discovery»þ¤ËSQL¥¨¥é¡¼¤¬½Ð¤ëÉÔ¶ñ¹ç¤ò½¤Àµ
  • +
  • ¡¡[Fixed] ´ÉÍý²èÌ̤ǥѡ¼¥¹¥¨¥é¡¼¤¬½Ð¤ë¾ì¹ç¤¬¤¢¤ëÉÔ¶ñ¹ç¤ò½¤Àµ
  • +
  • ¡¡[Changed] SQL¤Î¥¯¥©¡¼¥È¤ò"¤«¤é'¤ËÊѹ¹
  • +
  • ¡¡[Fixed] mb_emulator´Ä¶­¤Ë¤Æ¥¨¥é¡¼¤¬½Ð¤ëÌäÂê¤ò½¤Àµ
  • +
  • ¡¡[Fixed] curl¤¬Í­¸ú¤Ê´Ä¶­¤Ç¥¨¥é¡¼¤¬½Ð¤ëÌäÂê¤ò½¤Àµ
  • + +
  • Version 2.0.3jp4 : (2006/07/15)
  • +
  • ¡¡[Added] AutoDiscoveryURL½ÐÎÏ»þ¤ËSpamCheck¤ò¹Ô¤¦¤è¤¦¤Ë¤·¤¿
  • +
  • ¡¡[Added] ¥á¥Ã¥»¡¼¥¸¡¢¥Ç¥Õ¥©¥ë¥ÈÃͤòÆüËܸ첽
  • +
  • ¡¡[Added] Âç¼êASP¤Î¸ÀµÚ¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¥Á¥§¥Ã¥¯¤ÎºÝ¤ËURL¤Î¥ê¥À¥¤¥ì¥¯¥È¤ò²ò½ü¤¹¤ë¤è¤¦¤Ë¤·¤¿
  • +
\ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/all.html b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/all.html new file mode 100644 index 0000000..67ea054 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/all.html @@ -0,0 +1,106 @@ + +

+ All trackbacks + $amount): ?> + (Page of ) + +

+ + + $amount): ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateStoryTitle, Blog and ExcerptActions
+ + + + + Visit + + ()
+ +
+ Block + + Delete +
+ + $amount): ?> + + + + + + + + \ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/all_ajax.html b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/all_ajax.html new file mode 100644 index 0000000..f75b50c --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/all_ajax.html @@ -0,0 +1,130 @@ + +

+ All trackbacks +

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
 idDateStoryTitle, Blog and Excerpt 
+ +¾åµ­¤ÇÁªÂò¤·¤¿¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤ò°ì³ç¤·¤Æ½èÍý¤·¤Þ¤¹ +Delete +Block +
+ + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/blocked.html b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/blocked.html new file mode 100644 index 0000000..e510f86 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/blocked.html @@ -0,0 +1,119 @@ + +

+ ¥Ö¥í¥Ã¥¯¤µ¤ì¤¿¥È¥é¥Ã¥¯¥Ð¥Ã¥¯ + $amount): ?> + (Page of ) + +

+ + + + + $amount): ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateStoryTitle, Blog and ExcerptActions
+ + + + + Visit + + () + ' : + '';?> + ';?> +
+ +
+ Unblock + + Delete +
+ + $amount): ?> + + + + + + + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/blocked_ajax.html b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/blocked_ajax.html new file mode 100644 index 0000000..7f5aa82 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/blocked_ajax.html @@ -0,0 +1,134 @@ + +

+ ¥Ö¥í¥Ã¥¯¤µ¤ì¤¿¥È¥é¥Ã¥¯¥Ð¥Ã¥¯ +

+ + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
 idDateStoryTitle, Blog and Excerpt 
+¾åµ­¤ÇÁªÂò¤·¤¿¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤ò°ì³ç¤·¤Æ½èÍý¤·¤Þ¤¹ +Unblock +Delete +
+ + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/form.html b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/form.html new file mode 100644 index 0000000..24ce702 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/form.html @@ -0,0 +1,56 @@ + + + + TrackBack¤Î¼êÆ°Á÷¿® + + + + +

TrackBack¤Î¼êÆ°Á÷¿®

+ +

+ ¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤ÎÁ÷¿®¤¬´°Î»¤·¤Þ¤·¤¿ +

+ + +

+ +

+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
¤¢¤Ê¤¿¤Îµ­»ö¤Îurl
µ­»ö¤Î¥¿¥¤¥È¥ë
µ­»ö¤ÎÍ×Ìóʸ
¤¢¤Ê¤¿¤Îblog¤Î̾Á°
¥È¥é¥Ã¥¯¥Ð¥Ã¥¯Á÷¿®
+
+ +
+ + + \ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/index.html b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/index.html new file mode 100644 index 0000000..a2a00ed --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/index.html @@ -0,0 +1,34 @@ + +

Overview of all items

+ + + + + + + + + + + + + + + + + + + + + + + + +
Blog: TotalAction
+ + + + + Trackbacks +
+ \ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/list.html b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/list.html new file mode 100644 index 0000000..05eeeb8 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/list.html @@ -0,0 +1,107 @@ + +

+ All trackbacks for "" + $amount): ?> + (Page of ) + +

+ + + $amount): ?> + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateTitle, Blog and ExcerptActions
+ + + Visit + + ()
+ +
+ Block + + Delete +
+ + $amount): ?> + + + + + + + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/menu.html b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/menu.html new file mode 100644 index 0000000..e98b6af --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/menu.html @@ -0,0 +1,32 @@ + +

Trackback

+ + + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/ping.html b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/ping.html new file mode 100644 index 0000000..0d993ec --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/ping.html @@ -0,0 +1,50 @@ + +

¼êÆ°ping¥Õ¥©¡¼¥à

+ +
+ + + + addTicketHidden(); ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
¼êÆ°ping
¤¢¤Ê¤¿¤Îurl + +
µ­»ö¤Î¥¿¥¤¥È¥ë + +
µ­»ö¤ÎÍ×Ìóʸ + +
Blog̾ + +
pingÀèurl + +
Á÷¿®
+ +
\ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/response_all.xml b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/response_all.xml new file mode 100644 index 0000000..4ae2445 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/response_all.xml @@ -0,0 +1,35 @@ +';?> + + + + + + + + + 0 + + + + + + "> + ]]> + + + "> + Visit + + + + () + ]]> + + + + + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/response_blocked.xml b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/response_blocked.xml new file mode 100644 index 0000000..29faac9 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/response_blocked.xml @@ -0,0 +1,41 @@ +';?> + + + + + + + + + 0 + + + + + + "> + ]]> + + + "> + Visit + + + ' : + '';?> + ';?> + + () + ]]> + + + + + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/response_doblock.xml b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/response_doblock.xml new file mode 100644 index 0000000..fdceb49 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/response_doblock.xml @@ -0,0 +1,8 @@ +';?> + + + + + + + \ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/response_dodelete.xml b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/response_dodelete.xml new file mode 100644 index 0000000..fdceb49 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/response_dodelete.xml @@ -0,0 +1,8 @@ +';?> + + + + + + + \ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/response_dounblock.xml b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/response_dounblock.xml new file mode 100644 index 0000000..fdceb49 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/response_dounblock.xml @@ -0,0 +1,8 @@ +';?> + + + + + + + \ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/updatetable.html b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/updatetable.html new file mode 100644 index 0000000..7435a03 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/updatetable.html @@ -0,0 +1,13 @@ + +
¥¢¥Ã¥×¥Ç¡¼¥È¤¬É¬ÍפǤ¹:
+¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç±¿ÍѤ¹¤ë¤¿¤á¤Ë¤ÏDBÆâ¤Î¥Æ¡¼¥Ö¥ë¤Î¥¢¥Ã¥×¥Ç¡¼¥È¤¬É¬ÍפǤ¹¡£
+º£¤Þ¤Ç¤Î¥Ç¡¼¥¿¤¬ºï½ü¤µ¤ì¤ë¤³¤È¤Ï¤¢¤ê¤Þ¤»¤ó¡£ +²¼¤Î¥¢¥Ã¥×¥Ç¡¼¥È¥Ü¥¿¥ó¤ò²¡¤·¤Æ¤¯¤À¤µ¤¤¡£ + +
+ + + addTicketHidden(); ?> +
+
+ diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/updatetablefinished.html b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/updatetablefinished.html new file mode 100644 index 0000000..a16df97 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-euc.templates/updatetablefinished.html @@ -0,0 +1,5 @@ + +
+¥Æ¡¼¥Ö¥ë¤Î¥¢¥Ã¥×¥Ç¡¼¥È¤Ï´°Î»¤·¤Þ¤·¤¿¡£ +
+ diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.help.html b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.help.html new file mode 100644 index 0000000..752f956 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.help.html @@ -0,0 +1,116 @@ +

ヘルプ

+ + +

スキンへの記述例

+

+Nucleus CMS Japan WikiのNP_TrackBackのページを参照してください。 +

+ +

表示のカスタマイズ

+

+ トラックバック関連の表示方法はテンプレートを編集することによってカスタマイズできますが、色や余白などのデザインはCSS側で指定する必要があります。テンプレート内に入力したクラス名のプロパティはcssで指定してください。デフォルトのテンプレートを飾るCSSプロパティの例をあげておきます。 +

+ +
div.tb {
+	border: 1px solid #000; background: #FFF;
+}
+div.tb div.head {
+	padding: 4px;
+	background: #000; color: #FFF;
+	font-weight: bold; text-transform: lowercase; letter-spacing: 0.6em;
+}
+div.tb div.empty {
+	padding: 4px;
+	font-size: 95%;
+}
+div.tb div.item {
+	padding: 4px;
+}
+div.tb div.item div.name {
+	margin-bottom: 8px;
+	font-size: 120%; font-weight: bold;
+}
+div.tb div.item div.body {
+	font-size: 95%;
+}
+div.tb div.item div.body a {
+	font-weight: bold;
+}
+div.tb div.item div.date {
+	margin-bottom: 8px;
+	color: #888;
+	font-size: 85%; text-align: right;
+}
+div.tb div.info {
+	padding: 4px;
+	color: #FFF; background: #888;
+	font-size: 85%; font-style: italic;
+}
+ +

日本語版更新履歴

+ +
    +
  • Version 2.0.3jp13 : (2008/12/14)
  • +
  •  [Fixed] Pingフォームへのリンクを開こうとするとInvalid or expired ticket.になる問題を修正
  • +
  •  [Fixed] TrackBack送信時のエラーハンドリングを改良した
  • +
  •  [Fixed] TrackBackの文字コードの検出が正しく行われない場合がある問題を修正
  • + +
  • Version 2.0.3jp12 : (2008/01/12)
  • +
  •  [Fixed] エラーメッセージの文字コードが適切でなかった問題を修正
  • +
  •  [Fixed] トラックバックの送信文字コードをUTF-8固定にした
  • +
  •  [Fixed] トラックバック可/不可の判定がおかしかった問題を修正
  • + +
  • Version 2.0.3jp11 : (2007/09/30)
  • +
  •  [Added] SuperAdmin以外でもTrackBackが管理できるようにした
  • + +
  • Version 2.0.3jp10 : (2007/06/30)
  • +
  •  [Fixed] mysql_query()をsql_query()に変更
  • +
  •  [Changed] 実体参照テーブルについてNucleus標準ものを使うようにした
  • +
  •  [Changed] インストールできるバージョンを3.3以降した
  • +
  •  [Changed] Ricoを2.0にアップデートしたのに伴い、管理画面の機能を増強
  • +
  •  [Added] コメント部分でもテンプレート変数が使えるようにした
  • +
  •  [Fixed] トラックバック送信部分の不具合を修正(FC2対策)
  • +
  •  [Changed] UserAgentをオリジナル版にあわせて変更
  • +
  •  [Changed] TrackBackのレスポンスの解析にXMLパーサーを使うようにした
  • +
  •  [Fixed] 言及リンクチェックの不具合を修正
  • +
  •  [Added] 保留にしているURLと同じURLのトラックバックを無視するようにした
  • + +
  •  [Fixed] 言及リンクチェックの用のURL生成ルーチンの不具合を修正
  • + +
  •  [Added] spamトラックバック一括消去時に確認が出るようにした
  • + +
  • Version 2.0.3jp9 : (2007/05/04)
  • +
  •  [Added] doIf()を追加(Nucleus 3.3向け)
  • +
  •  [Added] URLが無効なトラックバックを無視するようにした
  • + +
  • Version 2.0.3jp8 : (2007/03/18)
  • +
  •  [Fixed] 管理画面でStoryのリンクの不具合を修正
  • +
  •  [Changed] URL抽出ルーチンを改良
  • +
  •  [Changed] 管理画面へのリンクを修正
  • +
  •  [Changed] 管理画面のページングをAjax対応にした
  • +
  •  [Changed] トラックバック通知アドレスをブログごとに設定できるようにした
  • +
  •  [Fixed] phpのshort openタグを修正
  • +
  •  [Fixed] 管理画面のトラックバック一覧で日付が正常に表示されない問題を修正
  • + +
  • Version 2.0.3jp7 : (2006/11/26)
  • +
  •  [Changed] SpamChekについて微調整
  • +
  •  [Added] Ticket処理を追加(CSRF対策)
  • +
  •  [Fixed] URLに&が入っているときの動作を変更
  • +
  •  [Added] 管理画面にアイコンを追加
  • + +
  • Version 2.0.3jp6 : (2006/09/30)
  • +
  •  [Fixed] セキュリティの向上
  • + +
  • Version 2.0.3jp5 : (2006/09/16)
  • +
  •  [Fixed] getPermaLinksFromText()内のURL抽出ルーチンの不具合を修正
  • +
  •  [Fixed] Auto-Discovery時にSQLエラーが出る不具合を修正
  • +
  •  [Fixed] 管理画面でパースエラーが出る場合がある不具合を修正
  • +
  •  [Changed] SQLのクォートを"から'に変更
  • +
  •  [Fixed] mb_emulator環境にてエラーが出る問題を修正
  • +
  •  [Fixed] curlが有効な環境でエラーが出る問題を修正
  • + +
  • Version 2.0.3jp4 : (2006/07/15)
  • +
  •  [Added] AutoDiscoveryURL出力時にSpamCheckを行うようにした
  • +
  •  [Added] メッセージ、デフォルト値を日本語化
  • +
  •  [Added] 大手ASPの言及トラックバックチェックの際にURLのリダイレクトを解除するようにした
  • +
\ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/all.html b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/all.html new file mode 100644 index 0000000..56c75b1 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/all.html @@ -0,0 +1,106 @@ + +

+ All trackbacks + $amount): ?> + (Page of ) + +

+ + + $amount): ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateStoryTitle, Blog and ExcerptActions
+ + + + + Visit + + ()
+ +
+ Block + + Delete +
+ + $amount): ?> + + + + + + + + \ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/all_ajax.html b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/all_ajax.html new file mode 100644 index 0000000..38788e4 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/all_ajax.html @@ -0,0 +1,130 @@ + +

+ All trackbacks +

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
 idDateStoryTitle, Blog and Excerpt 
+ +上記で選択したトラックバックを一括して処理します +Delete +Block +
+ + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/blocked.html b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/blocked.html new file mode 100644 index 0000000..b6d553b --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/blocked.html @@ -0,0 +1,119 @@ + +

+ ブロックされたトラックバック + $amount): ?> + (Page of ) + +

+ + + + + $amount): ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateStoryTitle, Blog and ExcerptActions
+ + + + + Visit + + () + ' : + '';?> + ';?> +
+ +
+ Unblock + + Delete +
+ + $amount): ?> + + + + + + + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/blocked_ajax.html b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/blocked_ajax.html new file mode 100644 index 0000000..7474160 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/blocked_ajax.html @@ -0,0 +1,134 @@ + +

+ ブロックされたトラックバック +

+ + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
 idDateStoryTitle, Blog and Excerpt 
+上記で選択したトラックバックを一括して処理します +Unblock +Delete +
+ + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/form.html b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/form.html new file mode 100644 index 0000000..add813a --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/form.html @@ -0,0 +1,56 @@ + + + + TrackBackの手動送信 + + + + +

TrackBackの手動送信

+ +

+ トラックバックの送信が完了しました +

+ + +

+ +

+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
あなたの記事のurl
記事のタイトル
記事の要約文
あなたのblogの名前
トラックバック送信
+
+ +
+ + + \ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/index.html b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/index.html new file mode 100644 index 0000000..15a2ce4 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/index.html @@ -0,0 +1,34 @@ + +

Overview of all items

+ + + + + + + + + + + + + + + + + + + + + + + + +
Blog: TotalAction
+ + + + + Trackbacks +
+ \ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/list.html b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/list.html new file mode 100644 index 0000000..0fcf3c3 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/list.html @@ -0,0 +1,107 @@ + +

+ All trackbacks for "" + $amount): ?> + (Page of ) + +

+ + + $amount): ?> + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateTitle, Blog and ExcerptActions
+ + + Visit + + ()
+ +
+ Block + + Delete +
+ + $amount): ?> + + + + + + + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/menu.html b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/menu.html new file mode 100644 index 0000000..ac37024 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/menu.html @@ -0,0 +1,32 @@ + +

Trackback

+ + + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/ping.html b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/ping.html new file mode 100644 index 0000000..84a882c --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/ping.html @@ -0,0 +1,50 @@ + +

手動pingフォーム

+ +
+ + + + addTicketHidden(); ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
手動ping
あなたのurl + +
記事のタイトル + +
記事の要約文 + +
Blog名 + +
ping先url + +
送信
+ +
\ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/response_all.xml b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/response_all.xml new file mode 100644 index 0000000..4ae2445 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/response_all.xml @@ -0,0 +1,35 @@ +';?> + + + + + + + + + 0 + + + + + + "> + ]]> + + + "> + Visit + + + + () + ]]> + + + + + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/response_blocked.xml b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/response_blocked.xml new file mode 100644 index 0000000..29faac9 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/response_blocked.xml @@ -0,0 +1,41 @@ +';?> + + + + + + + + + 0 + + + + + + "> + ]]> + + + "> + Visit + + + ' : + '';?> + ';?> + + () + ]]> + + + + + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/response_doblock.xml b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/response_doblock.xml new file mode 100644 index 0000000..a53f37c --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/response_doblock.xml @@ -0,0 +1,8 @@ +';?> + + + + + + + \ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/response_dodelete.xml b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/response_dodelete.xml new file mode 100644 index 0000000..a53f37c --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/response_dodelete.xml @@ -0,0 +1,8 @@ +';?> + + + + + + + \ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/response_dounblock.xml b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/response_dounblock.xml new file mode 100644 index 0000000..a53f37c --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/response_dounblock.xml @@ -0,0 +1,8 @@ +';?> + + + + + + + \ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/updatetable.html b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/updatetable.html new file mode 100644 index 0000000..a426a8a --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/updatetable.html @@ -0,0 +1,13 @@ + +
アップデートが必要です:
+このバージョンで運用するためにはDB内のテーブルのアップデートが必要です。
+今までのデータが削除されることはありません。 +下のアップデートボタンを押してください。 + +
+ + + addTicketHidden(); ?> +
+
+ diff --git a/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/updatetablefinished.html b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/updatetablefinished.html new file mode 100644 index 0000000..6b1ea94 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/japanese-utf8.templates/updatetablefinished.html @@ -0,0 +1,5 @@ + +
+テーブルのアップデートは完了しました。 +
+ diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/prototype.js b/NP_TrackBack/branches/DOM-branch/trackback/js/prototype.js new file mode 100644 index 0000000..5d2100f --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/prototype.js @@ -0,0 +1,3271 @@ +/* Prototype JavaScript framework, version 1.5.1 + * (c) 2005-2007 Sam Stephenson + * + * Prototype is freely distributable under the terms of an MIT-style license. + * For details, see the Prototype web site: http://www.prototypejs.org/ + * +/*--------------------------------------------------------------------------*/ + +var Prototype = { + Version: '1.5.1', + + Browser: { + IE: !!(window.attachEvent && !window.opera), + Opera: !!window.opera, + WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1, + Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1 + }, + + BrowserFeatures: { + XPath: !!document.evaluate, + ElementExtensions: !!window.HTMLElement, + SpecificElementExtensions: + (document.createElement('div').__proto__ !== + document.createElement('form').__proto__) + }, + + ScriptFragment: ']*>([\u0001-\uFFFF]*?)', + JSONFilter: /^\/\*-secure-\s*(.*)\s*\*\/\s*$/, + + emptyFunction: function() { }, + K: function(x) { return x } +} + +var Class = { + create: function() { + return function() { + this.initialize.apply(this, arguments); + } + } +} + +var Abstract = new Object(); + +Object.extend = function(destination, source) { + for (var property in source) { + destination[property] = source[property]; + } + return destination; +} + +Object.extend(Object, { + inspect: function(object) { + try { + if (object === undefined) return 'undefined'; + if (object === null) return 'null'; + return object.inspect ? object.inspect() : object.toString(); + } catch (e) { + if (e instanceof RangeError) return '...'; + throw e; + } + }, + + toJSON: function(object) { + var type = typeof object; + switch(type) { + case 'undefined': + case 'function': + case 'unknown': return; + case 'boolean': return object.toString(); + } + if (object === null) return 'null'; + if (object.toJSON) return object.toJSON(); + if (object.ownerDocument === document) return; + var results = []; + for (var property in object) { + var value = Object.toJSON(object[property]); + if (value !== undefined) + results.push(property.toJSON() + ': ' + value); + } + return '{' + results.join(', ') + '}'; + }, + + keys: function(object) { + var keys = []; + for (var property in object) + keys.push(property); + return keys; + }, + + values: function(object) { + var values = []; + for (var property in object) + values.push(object[property]); + return values; + }, + + clone: function(object) { + return Object.extend({}, object); + } +}); + +Function.prototype.bind = function() { + var __method = this, args = $A(arguments), object = args.shift(); + return function() { + return __method.apply(object, args.concat($A(arguments))); + } +} + +Function.prototype.bindAsEventListener = function(object) { + var __method = this, args = $A(arguments), object = args.shift(); + return function(event) { + return __method.apply(object, [event || window.event].concat(args)); + } +} + +Object.extend(Number.prototype, { + toColorPart: function() { + return this.toPaddedString(2, 16); + }, + + succ: function() { + return this + 1; + }, + + times: function(iterator) { + $R(0, this, true).each(iterator); + return this; + }, + + toPaddedString: function(length, radix) { + var string = this.toString(radix || 10); + return '0'.times(length - string.length) + string; + }, + + toJSON: function() { + return isFinite(this) ? this.toString() : 'null'; + } +}); + +Date.prototype.toJSON = function() { + return '"' + this.getFullYear() + '-' + + (this.getMonth() + 1).toPaddedString(2) + '-' + + this.getDate().toPaddedString(2) + 'T' + + this.getHours().toPaddedString(2) + ':' + + this.getMinutes().toPaddedString(2) + ':' + + this.getSeconds().toPaddedString(2) + '"'; +}; + +var Try = { + these: function() { + var returnValue; + + for (var i = 0, length = arguments.length; i < length; i++) { + var lambda = arguments[i]; + try { + returnValue = lambda(); + break; + } catch (e) {} + } + + return returnValue; + } +} + +/*--------------------------------------------------------------------------*/ + +var PeriodicalExecuter = Class.create(); +PeriodicalExecuter.prototype = { + initialize: function(callback, frequency) { + this.callback = callback; + this.frequency = frequency; + this.currentlyExecuting = false; + + this.registerCallback(); + }, + + registerCallback: function() { + this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); + }, + + stop: function() { + if (!this.timer) return; + clearInterval(this.timer); + this.timer = null; + }, + + onTimerEvent: function() { + if (!this.currentlyExecuting) { + try { + this.currentlyExecuting = true; + this.callback(this); + } finally { + this.currentlyExecuting = false; + } + } + } +} +Object.extend(String, { + interpret: function(value) { + return value == null ? '' : String(value); + }, + specialChar: { + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '\\': '\\\\' + } +}); + +Object.extend(String.prototype, { + gsub: function(pattern, replacement) { + var result = '', source = this, match; + replacement = arguments.callee.prepareReplacement(replacement); + + while (source.length > 0) { + if (match = source.match(pattern)) { + result += source.slice(0, match.index); + result += String.interpret(replacement(match)); + source = source.slice(match.index + match[0].length); + } else { + result += source, source = ''; + } + } + return result; + }, + + sub: function(pattern, replacement, count) { + replacement = this.gsub.prepareReplacement(replacement); + count = count === undefined ? 1 : count; + + return this.gsub(pattern, function(match) { + if (--count < 0) return match[0]; + return replacement(match); + }); + }, + + scan: function(pattern, iterator) { + this.gsub(pattern, iterator); + return this; + }, + + truncate: function(length, truncation) { + length = length || 30; + truncation = truncation === undefined ? '...' : truncation; + return this.length > length ? + this.slice(0, length - truncation.length) + truncation : this; + }, + + strip: function() { + return this.replace(/^\s+/, '').replace(/\s+$/, ''); + }, + + stripTags: function() { + return this.replace(/<\/?[^>]+>/gi, ''); + }, + + stripScripts: function() { + return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); + }, + + extractScripts: function() { + var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); + var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); + return (this.match(matchAll) || []).map(function(scriptTag) { + return (scriptTag.match(matchOne) || ['', ''])[1]; + }); + }, + + evalScripts: function() { + return this.extractScripts().map(function(script) { return eval(script) }); + }, + + escapeHTML: function() { + var self = arguments.callee; + self.text.data = this; + return self.div.innerHTML; + }, + + unescapeHTML: function() { + var div = document.createElement('div'); + div.innerHTML = this.stripTags(); + return div.childNodes[0] ? (div.childNodes.length > 1 ? + $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) : + div.childNodes[0].nodeValue) : ''; + }, + + toQueryParams: function(separator) { + var match = this.strip().match(/([^?#]*)(#.*)?$/); + if (!match) return {}; + + return match[1].split(separator || '&').inject({}, function(hash, pair) { + if ((pair = pair.split('='))[0]) { + var key = decodeURIComponent(pair.shift()); + var value = pair.length > 1 ? pair.join('=') : pair[0]; + if (value != undefined) value = decodeURIComponent(value); + + if (key in hash) { + if (hash[key].constructor != Array) hash[key] = [hash[key]]; + hash[key].push(value); + } + else hash[key] = value; + } + return hash; + }); + }, + + toArray: function() { + return this.split(''); + }, + + succ: function() { + return this.slice(0, this.length - 1) + + String.fromCharCode(this.charCodeAt(this.length - 1) + 1); + }, + + times: function(count) { + var result = ''; + for (var i = 0; i < count; i++) result += this; + return result; + }, + + camelize: function() { + var parts = this.split('-'), len = parts.length; + if (len == 1) return parts[0]; + + var camelized = this.charAt(0) == '-' + ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1) + : parts[0]; + + for (var i = 1; i < len; i++) + camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1); + + return camelized; + }, + + capitalize: function() { + return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); + }, + + underscore: function() { + return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase(); + }, + + dasherize: function() { + return this.gsub(/_/,'-'); + }, + + inspect: function(useDoubleQuotes) { + var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) { + var character = String.specialChar[match[0]]; + return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16); + }); + if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; + return "'" + escapedString.replace(/'/g, '\\\'') + "'"; + }, + + toJSON: function() { + return this.inspect(true); + }, + + unfilterJSON: function(filter) { + return this.sub(filter || Prototype.JSONFilter, '#{1}'); + }, + + evalJSON: function(sanitize) { + var json = this.unfilterJSON(); + try { + if (!sanitize || (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(json))) + return eval('(' + json + ')'); + } catch (e) { } + throw new SyntaxError('Badly formed JSON string: ' + this.inspect()); + }, + + include: function(pattern) { + return this.indexOf(pattern) > -1; + }, + + startsWith: function(pattern) { + return this.indexOf(pattern) === 0; + }, + + endsWith: function(pattern) { + var d = this.length - pattern.length; + return d >= 0 && this.lastIndexOf(pattern) === d; + }, + + empty: function() { + return this == ''; + }, + + blank: function() { + return /^\s*$/.test(this); + } +}); + +if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, { + escapeHTML: function() { + return this.replace(/&/g,'&').replace(//g,'>'); + }, + unescapeHTML: function() { + return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); + } +}); + +String.prototype.gsub.prepareReplacement = function(replacement) { + if (typeof replacement == 'function') return replacement; + var template = new Template(replacement); + return function(match) { return template.evaluate(match) }; +} + +String.prototype.parseQuery = String.prototype.toQueryParams; + +Object.extend(String.prototype.escapeHTML, { + div: document.createElement('div'), + text: document.createTextNode('') +}); + +with (String.prototype.escapeHTML) div.appendChild(text); + +var Template = Class.create(); +Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; +Template.prototype = { + initialize: function(template, pattern) { + this.template = template.toString(); + this.pattern = pattern || Template.Pattern; + }, + + evaluate: function(object) { + return this.template.gsub(this.pattern, function(match) { + var before = match[1]; + if (before == '\\') return match[2]; + return before + String.interpret(object[match[3]]); + }); + } +} + +var $break = {}, $continue = new Error('"throw $continue" is deprecated, use "return" instead'); + +var Enumerable = { + each: function(iterator) { + var index = 0; + try { + this._each(function(value) { + iterator(value, index++); + }); + } catch (e) { + if (e != $break) throw e; + } + return this; + }, + + eachSlice: function(number, iterator) { + var index = -number, slices = [], array = this.toArray(); + while ((index += number) < array.length) + slices.push(array.slice(index, index+number)); + return slices.map(iterator); + }, + + all: function(iterator) { + var result = true; + this.each(function(value, index) { + result = result && !!(iterator || Prototype.K)(value, index); + if (!result) throw $break; + }); + return result; + }, + + any: function(iterator) { + var result = false; + this.each(function(value, index) { + if (result = !!(iterator || Prototype.K)(value, index)) + throw $break; + }); + return result; + }, + + collect: function(iterator) { + var results = []; + this.each(function(value, index) { + results.push((iterator || Prototype.K)(value, index)); + }); + return results; + }, + + detect: function(iterator) { + var result; + this.each(function(value, index) { + if (iterator(value, index)) { + result = value; + throw $break; + } + }); + return result; + }, + + findAll: function(iterator) { + var results = []; + this.each(function(value, index) { + if (iterator(value, index)) + results.push(value); + }); + return results; + }, + + grep: function(pattern, iterator) { + var results = []; + this.each(function(value, index) { + var stringValue = value.toString(); + if (stringValue.match(pattern)) + results.push((iterator || Prototype.K)(value, index)); + }) + return results; + }, + + include: function(object) { + var found = false; + this.each(function(value) { + if (value == object) { + found = true; + throw $break; + } + }); + return found; + }, + + inGroupsOf: function(number, fillWith) { + fillWith = fillWith === undefined ? null : fillWith; + return this.eachSlice(number, function(slice) { + while(slice.length < number) slice.push(fillWith); + return slice; + }); + }, + + inject: function(memo, iterator) { + this.each(function(value, index) { + memo = iterator(memo, value, index); + }); + return memo; + }, + + invoke: function(method) { + var args = $A(arguments).slice(1); + return this.map(function(value) { + return value[method].apply(value, args); + }); + }, + + max: function(iterator) { + var result; + this.each(function(value, index) { + value = (iterator || Prototype.K)(value, index); + if (result == undefined || value >= result) + result = value; + }); + return result; + }, + + min: function(iterator) { + var result; + this.each(function(value, index) { + value = (iterator || Prototype.K)(value, index); + if (result == undefined || value < result) + result = value; + }); + return result; + }, + + partition: function(iterator) { + var trues = [], falses = []; + this.each(function(value, index) { + ((iterator || Prototype.K)(value, index) ? + trues : falses).push(value); + }); + return [trues, falses]; + }, + + pluck: function(property) { + var results = []; + this.each(function(value, index) { + results.push(value[property]); + }); + return results; + }, + + reject: function(iterator) { + var results = []; + this.each(function(value, index) { + if (!iterator(value, index)) + results.push(value); + }); + return results; + }, + + sortBy: function(iterator) { + return this.map(function(value, index) { + return {value: value, criteria: iterator(value, index)}; + }).sort(function(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }).pluck('value'); + }, + + toArray: function() { + return this.map(); + }, + + zip: function() { + var iterator = Prototype.K, args = $A(arguments); + if (typeof args.last() == 'function') + iterator = args.pop(); + + var collections = [this].concat(args).map($A); + return this.map(function(value, index) { + return iterator(collections.pluck(index)); + }); + }, + + size: function() { + return this.toArray().length; + }, + + inspect: function() { + return '#'; + } +} + +Object.extend(Enumerable, { + map: Enumerable.collect, + find: Enumerable.detect, + select: Enumerable.findAll, + member: Enumerable.include, + entries: Enumerable.toArray +}); +var $A = Array.from = function(iterable) { + if (!iterable) return []; + if (iterable.toArray) { + return iterable.toArray(); + } else { + var results = []; + for (var i = 0, length = iterable.length; i < length; i++) + results.push(iterable[i]); + return results; + } +} + +if (Prototype.Browser.WebKit) { + $A = Array.from = function(iterable) { + if (!iterable) return []; + if (!(typeof iterable == 'function' && iterable == '[object NodeList]') && + iterable.toArray) { + return iterable.toArray(); + } else { + var results = []; + for (var i = 0, length = iterable.length; i < length; i++) + results.push(iterable[i]); + return results; + } + } +} + +Object.extend(Array.prototype, Enumerable); + +if (!Array.prototype._reverse) + Array.prototype._reverse = Array.prototype.reverse; + +Object.extend(Array.prototype, { + _each: function(iterator) { + for (var i = 0, length = this.length; i < length; i++) + iterator(this[i]); + }, + + clear: function() { + this.length = 0; + return this; + }, + + first: function() { + return this[0]; + }, + + last: function() { + return this[this.length - 1]; + }, + + compact: function() { + return this.select(function(value) { + return value != null; + }); + }, + + flatten: function() { + return this.inject([], function(array, value) { + return array.concat(value && value.constructor == Array ? + value.flatten() : [value]); + }); + }, + + without: function() { + var values = $A(arguments); + return this.select(function(value) { + return !values.include(value); + }); + }, + + indexOf: function(object) { + for (var i = 0, length = this.length; i < length; i++) + if (this[i] == object) return i; + return -1; + }, + + reverse: function(inline) { + return (inline !== false ? this : this.toArray())._reverse(); + }, + + reduce: function() { + return this.length > 1 ? this : this[0]; + }, + + uniq: function(sorted) { + return this.inject([], function(array, value, index) { + if (0 == index || (sorted ? array.last() != value : !array.include(value))) + array.push(value); + return array; + }); + }, + + clone: function() { + return [].concat(this); + }, + + size: function() { + return this.length; + }, + + inspect: function() { + return '[' + this.map(Object.inspect).join(', ') + ']'; + }, + + toJSON: function() { + var results = []; + this.each(function(object) { + var value = Object.toJSON(object); + if (value !== undefined) results.push(value); + }); + return '[' + results.join(', ') + ']'; + } +}); + +Array.prototype.toArray = Array.prototype.clone; + +function $w(string) { + string = string.strip(); + return string ? string.split(/\s+/) : []; +} + +if (Prototype.Browser.Opera){ + Array.prototype.concat = function() { + var array = []; + for (var i = 0, length = this.length; i < length; i++) array.push(this[i]); + for (var i = 0, length = arguments.length; i < length; i++) { + if (arguments[i].constructor == Array) { + for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++) + array.push(arguments[i][j]); + } else { + array.push(arguments[i]); + } + } + return array; + } +} +var Hash = function(object) { + if (object instanceof Hash) this.merge(object); + else Object.extend(this, object || {}); +}; + +Object.extend(Hash, { + toQueryString: function(obj) { + var parts = []; + parts.add = arguments.callee.addPair; + + this.prototype._each.call(obj, function(pair) { + if (!pair.key) return; + var value = pair.value; + + if (value && typeof value == 'object') { + if (value.constructor == Array) value.each(function(value) { + parts.add(pair.key, value); + }); + return; + } + parts.add(pair.key, value); + }); + + return parts.join('&'); + }, + + toJSON: function(object) { + var results = []; + this.prototype._each.call(object, function(pair) { + var value = Object.toJSON(pair.value); + if (value !== undefined) results.push(pair.key.toJSON() + ': ' + value); + }); + return '{' + results.join(', ') + '}'; + } +}); + +Hash.toQueryString.addPair = function(key, value, prefix) { + key = encodeURIComponent(key); + if (value === undefined) this.push(key); + else this.push(key + '=' + (value == null ? '' : encodeURIComponent(value))); +} + +Object.extend(Hash.prototype, Enumerable); +Object.extend(Hash.prototype, { + _each: function(iterator) { + for (var key in this) { + var value = this[key]; + if (value && value == Hash.prototype[key]) continue; + + var pair = [key, value]; + pair.key = key; + pair.value = value; + iterator(pair); + } + }, + + keys: function() { + return this.pluck('key'); + }, + + values: function() { + return this.pluck('value'); + }, + + merge: function(hash) { + return $H(hash).inject(this, function(mergedHash, pair) { + mergedHash[pair.key] = pair.value; + return mergedHash; + }); + }, + + remove: function() { + var result; + for(var i = 0, length = arguments.length; i < length; i++) { + var value = this[arguments[i]]; + if (value !== undefined){ + if (result === undefined) result = value; + else { + if (result.constructor != Array) result = [result]; + result.push(value) + } + } + delete this[arguments[i]]; + } + return result; + }, + + toQueryString: function() { + return Hash.toQueryString(this); + }, + + inspect: function() { + return '#'; + }, + + toJSON: function() { + return Hash.toJSON(this); + } +}); + +function $H(object) { + if (object instanceof Hash) return object; + return new Hash(object); +}; + +// Safari iterates over shadowed properties +if (function() { + var i = 0, Test = function(value) { this.key = value }; + Test.prototype.key = 'foo'; + for (var property in new Test('bar')) i++; + return i > 1; +}()) Hash.prototype._each = function(iterator) { + var cache = []; + for (var key in this) { + var value = this[key]; + if ((value && value == Hash.prototype[key]) || cache.include(key)) continue; + cache.push(key); + var pair = [key, value]; + pair.key = key; + pair.value = value; + iterator(pair); + } +}; +ObjectRange = Class.create(); +Object.extend(ObjectRange.prototype, Enumerable); +Object.extend(ObjectRange.prototype, { + initialize: function(start, end, exclusive) { + this.start = start; + this.end = end; + this.exclusive = exclusive; + }, + + _each: function(iterator) { + var value = this.start; + while (this.include(value)) { + iterator(value); + value = value.succ(); + } + }, + + include: function(value) { + if (value < this.start) + return false; + if (this.exclusive) + return value < this.end; + return value <= this.end; + } +}); + +var $R = function(start, end, exclusive) { + return new ObjectRange(start, end, exclusive); +} + +var Ajax = { + getTransport: function() { + return Try.these( + function() {return new XMLHttpRequest()}, + function() {return new ActiveXObject('Msxml2.XMLHTTP')}, + function() {return new ActiveXObject('Microsoft.XMLHTTP')} + ) || false; + }, + + activeRequestCount: 0 +} + +Ajax.Responders = { + responders: [], + + _each: function(iterator) { + this.responders._each(iterator); + }, + + register: function(responder) { + if (!this.include(responder)) + this.responders.push(responder); + }, + + unregister: function(responder) { + this.responders = this.responders.without(responder); + }, + + dispatch: function(callback, request, transport, json) { + this.each(function(responder) { + if (typeof responder[callback] == 'function') { + try { + responder[callback].apply(responder, [request, transport, json]); + } catch (e) {} + } + }); + } +}; + +Object.extend(Ajax.Responders, Enumerable); + +Ajax.Responders.register({ + onCreate: function() { + Ajax.activeRequestCount++; + }, + onComplete: function() { + Ajax.activeRequestCount--; + } +}); + +Ajax.Base = function() {}; +Ajax.Base.prototype = { + setOptions: function(options) { + this.options = { + method: 'post', + asynchronous: true, + contentType: 'application/x-www-form-urlencoded', + encoding: 'UTF-8', + parameters: '' + } + Object.extend(this.options, options || {}); + + this.options.method = this.options.method.toLowerCase(); + if (typeof this.options.parameters == 'string') + this.options.parameters = this.options.parameters.toQueryParams(); + } +} + +Ajax.Request = Class.create(); +Ajax.Request.Events = + ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; + +Ajax.Request.prototype = Object.extend(new Ajax.Base(), { + _complete: false, + + initialize: function(url, options) { + this.transport = Ajax.getTransport(); + this.setOptions(options); + this.request(url); + }, + + request: function(url) { + this.url = url; + this.method = this.options.method; + var params = Object.clone(this.options.parameters); + + if (!['get', 'post'].include(this.method)) { + // simulate other verbs over post + params['_method'] = this.method; + this.method = 'post'; + } + + this.parameters = params; + + if (params = Hash.toQueryString(params)) { + // when GET, append parameters to URL + if (this.method == 'get') + this.url += (this.url.include('?') ? '&' : '?') + params; + else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) + params += '&_='; + } + + try { + if (this.options.onCreate) this.options.onCreate(this.transport); + Ajax.Responders.dispatch('onCreate', this, this.transport); + + this.transport.open(this.method.toUpperCase(), this.url, + this.options.asynchronous); + + if (this.options.asynchronous) + setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10); + + this.transport.onreadystatechange = this.onStateChange.bind(this); + this.setRequestHeaders(); + + this.body = this.method == 'post' ? (this.options.postBody || params) : null; + this.transport.send(this.body); + + /* Force Firefox to handle ready state 4 for synchronous requests */ + if (!this.options.asynchronous && this.transport.overrideMimeType) + this.onStateChange(); + + } + catch (e) { + this.dispatchException(e); + } + }, + + onStateChange: function() { + var readyState = this.transport.readyState; + if (readyState > 1 && !((readyState == 4) && this._complete)) + this.respondToReadyState(this.transport.readyState); + }, + + setRequestHeaders: function() { + var headers = { + 'X-Requested-With': 'XMLHttpRequest', + 'X-Prototype-Version': Prototype.Version, + 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' + }; + + if (this.method == 'post') { + headers['Content-type'] = this.options.contentType + + (this.options.encoding ? '; charset=' + this.options.encoding : ''); + + /* Force "Connection: close" for older Mozilla browsers to work + * around a bug where XMLHttpRequest sends an incorrect + * Content-length header. See Mozilla Bugzilla #246651. + */ + if (this.transport.overrideMimeType && + (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005) + headers['Connection'] = 'close'; + } + + // user-defined headers + if (typeof this.options.requestHeaders == 'object') { + var extras = this.options.requestHeaders; + + if (typeof extras.push == 'function') + for (var i = 0, length = extras.length; i < length; i += 2) + headers[extras[i]] = extras[i+1]; + else + $H(extras).each(function(pair) { headers[pair.key] = pair.value }); + } + + for (var name in headers) + this.transport.setRequestHeader(name, headers[name]); + }, + + success: function() { + return !this.transport.status + || (this.transport.status >= 200 && this.transport.status < 300); + }, + + respondToReadyState: function(readyState) { + var state = Ajax.Request.Events[readyState]; + var transport = this.transport, json = this.evalJSON(); + + if (state == 'Complete') { + try { + this._complete = true; + (this.options['on' + this.transport.status] + || this.options['on' + (this.success() ? 'Success' : 'Failure')] + || Prototype.emptyFunction)(transport, json); + } catch (e) { + this.dispatchException(e); + } + + var contentType = this.getHeader('Content-type'); + if (contentType && contentType.strip(). + match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i)) + this.evalResponse(); + } + + try { + (this.options['on' + state] || Prototype.emptyFunction)(transport, json); + Ajax.Responders.dispatch('on' + state, this, transport, json); + } catch (e) { + this.dispatchException(e); + } + + if (state == 'Complete') { + // avoid memory leak in MSIE: clean up + this.transport.onreadystatechange = Prototype.emptyFunction; + } + }, + + getHeader: function(name) { + try { + return this.transport.getResponseHeader(name); + } catch (e) { return null } + }, + + evalJSON: function() { + try { + var json = this.getHeader('X-JSON'); + return json ? json.evalJSON() : null; + } catch (e) { return null } + }, + + evalResponse: function() { + try { + return eval((this.transport.responseText || '').unfilterJSON()); + } catch (e) { + this.dispatchException(e); + } + }, + + dispatchException: function(exception) { + (this.options.onException || Prototype.emptyFunction)(this, exception); + Ajax.Responders.dispatch('onException', this, exception); + } +}); + +Ajax.Updater = Class.create(); + +Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { + initialize: function(container, url, options) { + this.container = { + success: (container.success || container), + failure: (container.failure || (container.success ? null : container)) + } + + this.transport = Ajax.getTransport(); + this.setOptions(options); + + var onComplete = this.options.onComplete || Prototype.emptyFunction; + this.options.onComplete = (function(transport, param) { + this.updateContent(); + onComplete(transport, param); + }).bind(this); + + this.request(url); + }, + + updateContent: function() { + var receiver = this.container[this.success() ? 'success' : 'failure']; + var response = this.transport.responseText; + + if (!this.options.evalScripts) response = response.stripScripts(); + + if (receiver = $(receiver)) { + if (this.options.insertion) + new this.options.insertion(receiver, response); + else + receiver.update(response); + } + + if (this.success()) { + if (this.onComplete) + setTimeout(this.onComplete.bind(this), 10); + } + } +}); + +Ajax.PeriodicalUpdater = Class.create(); +Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), { + initialize: function(container, url, options) { + this.setOptions(options); + this.onComplete = this.options.onComplete; + + this.frequency = (this.options.frequency || 2); + this.decay = (this.options.decay || 1); + + this.updater = {}; + this.container = container; + this.url = url; + + this.start(); + }, + + start: function() { + this.options.onComplete = this.updateComplete.bind(this); + this.onTimerEvent(); + }, + + stop: function() { + this.updater.options.onComplete = undefined; + clearTimeout(this.timer); + (this.onComplete || Prototype.emptyFunction).apply(this, arguments); + }, + + updateComplete: function(request) { + if (this.options.decay) { + this.decay = (request.responseText == this.lastText ? + this.decay * this.options.decay : 1); + + this.lastText = request.responseText; + } + this.timer = setTimeout(this.onTimerEvent.bind(this), + this.decay * this.frequency * 1000); + }, + + onTimerEvent: function() { + this.updater = new Ajax.Updater(this.container, this.url, this.options); + } +}); +function $(element) { + if (arguments.length > 1) { + for (var i = 0, elements = [], length = arguments.length; i < length; i++) + elements.push($(arguments[i])); + return elements; + } + if (typeof element == 'string') + element = document.getElementById(element); + return Element.extend(element); +} + +if (Prototype.BrowserFeatures.XPath) { + document._getElementsByXPath = function(expression, parentElement) { + var results = []; + var query = document.evaluate(expression, $(parentElement) || document, + null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); + for (var i = 0, length = query.snapshotLength; i < length; i++) + results.push(query.snapshotItem(i)); + return results; + }; + + document.getElementsByClassName = function(className, parentElement) { + var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]"; + return document._getElementsByXPath(q, parentElement); + } + +} else document.getElementsByClassName = function(className, parentElement) { + var children = ($(parentElement) || document.body).getElementsByTagName('*'); + var elements = [], child; + for (var i = 0, length = children.length; i < length; i++) { + child = children[i]; + if (Element.hasClassName(child, className)) + elements.push(Element.extend(child)); + } + return elements; +}; + +/*--------------------------------------------------------------------------*/ + +if (!window.Element) var Element = {}; + +Element.extend = function(element) { + var F = Prototype.BrowserFeatures; + if (!element || !element.tagName || element.nodeType == 3 || + element._extended || F.SpecificElementExtensions || element == window) + return element; + + var methods = {}, tagName = element.tagName, cache = Element.extend.cache, + T = Element.Methods.ByTag; + + // extend methods for all tags (Safari doesn't need this) + if (!F.ElementExtensions) { + Object.extend(methods, Element.Methods), + Object.extend(methods, Element.Methods.Simulated); + } + + // extend methods for specific tags + if (T[tagName]) Object.extend(methods, T[tagName]); + + for (var property in methods) { + var value = methods[property]; + if (typeof value == 'function' && !(property in element)) + element[property] = cache.findOrStore(value); + } + + element._extended = Prototype.emptyFunction; + return element; +}; + +Element.extend.cache = { + findOrStore: function(value) { + return this[value] = this[value] || function() { + return value.apply(null, [this].concat($A(arguments))); + } + } +}; + +Element.Methods = { + visible: function(element) { + return $(element).style.display != 'none'; + }, + + toggle: function(element) { + element = $(element); + Element[Element.visible(element) ? 'hide' : 'show'](element); + return element; + }, + + hide: function(element) { + $(element).style.display = 'none'; + return element; + }, + + show: function(element) { + $(element).style.display = ''; + return element; + }, + + remove: function(element) { + element = $(element); + element.parentNode.removeChild(element); + return element; + }, + + update: function(element, html) { + html = typeof html == 'undefined' ? '' : html.toString(); + $(element).innerHTML = html.stripScripts(); + setTimeout(function() {html.evalScripts()}, 10); + return element; + }, + + replace: function(element, html) { + element = $(element); + html = typeof html == 'undefined' ? '' : html.toString(); + if (element.outerHTML) { + element.outerHTML = html.stripScripts(); + } else { + var range = element.ownerDocument.createRange(); + range.selectNodeContents(element); + element.parentNode.replaceChild( + range.createContextualFragment(html.stripScripts()), element); + } + setTimeout(function() {html.evalScripts()}, 10); + return element; + }, + + inspect: function(element) { + element = $(element); + var result = '<' + element.tagName.toLowerCase(); + $H({'id': 'id', 'className': 'class'}).each(function(pair) { + var property = pair.first(), attribute = pair.last(); + var value = (element[property] || '').toString(); + if (value) result += ' ' + attribute + '=' + value.inspect(true); + }); + return result + '>'; + }, + + recursivelyCollect: function(element, property) { + element = $(element); + var elements = []; + while (element = element[property]) + if (element.nodeType == 1) + elements.push(Element.extend(element)); + return elements; + }, + + ancestors: function(element) { + return $(element).recursivelyCollect('parentNode'); + }, + + descendants: function(element) { + return $A($(element).getElementsByTagName('*')).each(Element.extend); + }, + + firstDescendant: function(element) { + element = $(element).firstChild; + while (element && element.nodeType != 1) element = element.nextSibling; + return $(element); + }, + + immediateDescendants: function(element) { + if (!(element = $(element).firstChild)) return []; + while (element && element.nodeType != 1) element = element.nextSibling; + if (element) return [element].concat($(element).nextSiblings()); + return []; + }, + + previousSiblings: function(element) { + return $(element).recursivelyCollect('previousSibling'); + }, + + nextSiblings: function(element) { + return $(element).recursivelyCollect('nextSibling'); + }, + + siblings: function(element) { + element = $(element); + return element.previousSiblings().reverse().concat(element.nextSiblings()); + }, + + match: function(element, selector) { + if (typeof selector == 'string') + selector = new Selector(selector); + return selector.match($(element)); + }, + + up: function(element, expression, index) { + element = $(element); + if (arguments.length == 1) return $(element.parentNode); + var ancestors = element.ancestors(); + return expression ? Selector.findElement(ancestors, expression, index) : + ancestors[index || 0]; + }, + + down: function(element, expression, index) { + element = $(element); + if (arguments.length == 1) return element.firstDescendant(); + var descendants = element.descendants(); + return expression ? Selector.findElement(descendants, expression, index) : + descendants[index || 0]; + }, + + previous: function(element, expression, index) { + element = $(element); + if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element)); + var previousSiblings = element.previousSiblings(); + return expression ? Selector.findElement(previousSiblings, expression, index) : + previousSiblings[index || 0]; + }, + + next: function(element, expression, index) { + element = $(element); + if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element)); + var nextSiblings = element.nextSiblings(); + return expression ? Selector.findElement(nextSiblings, expression, index) : + nextSiblings[index || 0]; + }, + + getElementsBySelector: function() { + var args = $A(arguments), element = $(args.shift()); + return Selector.findChildElements(element, args); + }, + + getElementsByClassName: function(element, className) { + return document.getElementsByClassName(className, element); + }, + + readAttribute: function(element, name) { + element = $(element); + if (Prototype.Browser.IE) { + if (!element.attributes) return null; + var t = Element._attributeTranslations; + if (t.values[name]) return t.values[name](element, name); + if (t.names[name]) name = t.names[name]; + var attribute = element.attributes[name]; + return attribute ? attribute.nodeValue : null; + } + return element.getAttribute(name); + }, + + getHeight: function(element) { + return $(element).getDimensions().height; + }, + + getWidth: function(element) { + return $(element).getDimensions().width; + }, + + classNames: function(element) { + return new Element.ClassNames(element); + }, + + hasClassName: function(element, className) { + if (!(element = $(element))) return; + var elementClassName = element.className; + if (elementClassName.length == 0) return false; + if (elementClassName == className || + elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) + return true; + return false; + }, + + addClassName: function(element, className) { + if (!(element = $(element))) return; + Element.classNames(element).add(className); + return element; + }, + + removeClassName: function(element, className) { + if (!(element = $(element))) return; + Element.classNames(element).remove(className); + return element; + }, + + toggleClassName: function(element, className) { + if (!(element = $(element))) return; + Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className); + return element; + }, + + observe: function() { + Event.observe.apply(Event, arguments); + return $A(arguments).first(); + }, + + stopObserving: function() { + Event.stopObserving.apply(Event, arguments); + return $A(arguments).first(); + }, + + // removes whitespace-only text node children + cleanWhitespace: function(element) { + element = $(element); + var node = element.firstChild; + while (node) { + var nextNode = node.nextSibling; + if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) + element.removeChild(node); + node = nextNode; + } + return element; + }, + + empty: function(element) { + return $(element).innerHTML.blank(); + }, + + descendantOf: function(element, ancestor) { + element = $(element), ancestor = $(ancestor); + while (element = element.parentNode) + if (element == ancestor) return true; + return false; + }, + + scrollTo: function(element) { + element = $(element); + var pos = Position.cumulativeOffset(element); + window.scrollTo(pos[0], pos[1]); + return element; + }, + + getStyle: function(element, style) { + element = $(element); + style = style == 'float' ? 'cssFloat' : style.camelize(); + var value = element.style[style]; + if (!value) { + var css = document.defaultView.getComputedStyle(element, null); + value = css ? css[style] : null; + } + if (style == 'opacity') return value ? parseFloat(value) : 1.0; + return value == 'auto' ? null : value; + }, + + getOpacity: function(element) { + return $(element).getStyle('opacity'); + }, + + setStyle: function(element, styles, camelized) { + element = $(element); + var elementStyle = element.style; + + for (var property in styles) + if (property == 'opacity') element.setOpacity(styles[property]) + else + elementStyle[(property == 'float' || property == 'cssFloat') ? + (elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') : + (camelized ? property : property.camelize())] = styles[property]; + + return element; + }, + + setOpacity: function(element, value) { + element = $(element); + element.style.opacity = (value == 1 || value === '') ? '' : + (value < 0.00001) ? 0 : value; + return element; + }, + + getDimensions: function(element) { + element = $(element); + var display = $(element).getStyle('display'); + if (display != 'none' && display != null) // Safari bug + return {width: element.offsetWidth, height: element.offsetHeight}; + + // All *Width and *Height properties give 0 on elements with display none, + // so enable the element temporarily + var els = element.style; + var originalVisibility = els.visibility; + var originalPosition = els.position; + var originalDisplay = els.display; + els.visibility = 'hidden'; + els.position = 'absolute'; + els.display = 'block'; + var originalWidth = element.clientWidth; + var originalHeight = element.clientHeight; + els.display = originalDisplay; + els.position = originalPosition; + els.visibility = originalVisibility; + return {width: originalWidth, height: originalHeight}; + }, + + makePositioned: function(element) { + element = $(element); + var pos = Element.getStyle(element, 'position'); + if (pos == 'static' || !pos) { + element._madePositioned = true; + element.style.position = 'relative'; + // Opera returns the offset relative to the positioning context, when an + // element is position relative but top and left have not been defined + if (window.opera) { + element.style.top = 0; + element.style.left = 0; + } + } + return element; + }, + + undoPositioned: function(element) { + element = $(element); + if (element._madePositioned) { + element._madePositioned = undefined; + element.style.position = + element.style.top = + element.style.left = + element.style.bottom = + element.style.right = ''; + } + return element; + }, + + makeClipping: function(element) { + element = $(element); + if (element._overflow) return element; + element._overflow = element.style.overflow || 'auto'; + if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') + element.style.overflow = 'hidden'; + return element; + }, + + undoClipping: function(element) { + element = $(element); + if (!element._overflow) return element; + element.style.overflow = element._overflow == 'auto' ? '' : element._overflow; + element._overflow = null; + return element; + } +}; + +Object.extend(Element.Methods, { + childOf: Element.Methods.descendantOf, + childElements: Element.Methods.immediateDescendants +}); + +if (Prototype.Browser.Opera) { + Element.Methods._getStyle = Element.Methods.getStyle; + Element.Methods.getStyle = function(element, style) { + switch(style) { + case 'left': + case 'top': + case 'right': + case 'bottom': + if (Element._getStyle(element, 'position') == 'static') return null; + default: return Element._getStyle(element, style); + } + }; +} +else if (Prototype.Browser.IE) { + Element.Methods.getStyle = function(element, style) { + element = $(element); + style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize(); + var value = element.style[style]; + if (!value && element.currentStyle) value = element.currentStyle[style]; + + if (style == 'opacity') { + if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/)) + if (value[1]) return parseFloat(value[1]) / 100; + return 1.0; + } + + if (value == 'auto') { + if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none')) + return element['offset'+style.capitalize()] + 'px'; + return null; + } + return value; + }; + + Element.Methods.setOpacity = function(element, value) { + element = $(element); + var filter = element.getStyle('filter'), style = element.style; + if (value == 1 || value === '') { + style.filter = filter.replace(/alpha\([^\)]*\)/gi,''); + return element; + } else if (value < 0.00001) value = 0; + style.filter = filter.replace(/alpha\([^\)]*\)/gi, '') + + 'alpha(opacity=' + (value * 100) + ')'; + return element; + }; + + // IE is missing .innerHTML support for TABLE-related elements + Element.Methods.update = function(element, html) { + element = $(element); + html = typeof html == 'undefined' ? '' : html.toString(); + var tagName = element.tagName.toUpperCase(); + if (['THEAD','TBODY','TR','TD'].include(tagName)) { + var div = document.createElement('div'); + switch (tagName) { + case 'THEAD': + case 'TBODY': + div.innerHTML = '' + html.stripScripts() + '
'; + depth = 2; + break; + case 'TR': + div.innerHTML = '' + html.stripScripts() + '
'; + depth = 3; + break; + case 'TD': + div.innerHTML = '
' + html.stripScripts() + '
'; + depth = 4; + } + $A(element.childNodes).each(function(node) { element.removeChild(node) }); + depth.times(function() { div = div.firstChild }); + $A(div.childNodes).each(function(node) { element.appendChild(node) }); + } else { + element.innerHTML = html.stripScripts(); + } + setTimeout(function() { html.evalScripts() }, 10); + return element; + } +} +else if (Prototype.Browser.Gecko) { + Element.Methods.setOpacity = function(element, value) { + element = $(element); + element.style.opacity = (value == 1) ? 0.999999 : + (value === '') ? '' : (value < 0.00001) ? 0 : value; + return element; + }; +} + +Element._attributeTranslations = { + names: { + colspan: "colSpan", + rowspan: "rowSpan", + valign: "vAlign", + datetime: "dateTime", + accesskey: "accessKey", + tabindex: "tabIndex", + enctype: "encType", + maxlength: "maxLength", + readonly: "readOnly", + longdesc: "longDesc" + }, + values: { + _getAttr: function(element, attribute) { + return element.getAttribute(attribute, 2); + }, + _flag: function(element, attribute) { + return $(element).hasAttribute(attribute) ? attribute : null; + }, + style: function(element) { + return element.style.cssText.toLowerCase(); + }, + title: function(element) { + var node = element.getAttributeNode('title'); + return node.specified ? node.nodeValue : null; + } + } +}; + +(function() { + Object.extend(this, { + href: this._getAttr, + src: this._getAttr, + type: this._getAttr, + disabled: this._flag, + checked: this._flag, + readonly: this._flag, + multiple: this._flag + }); +}).call(Element._attributeTranslations.values); + +Element.Methods.Simulated = { + hasAttribute: function(element, attribute) { + var t = Element._attributeTranslations, node; + attribute = t.names[attribute] || attribute; + node = $(element).getAttributeNode(attribute); + return node && node.specified; + } +}; + +Element.Methods.ByTag = {}; + +Object.extend(Element, Element.Methods); + +if (!Prototype.BrowserFeatures.ElementExtensions && + document.createElement('div').__proto__) { + window.HTMLElement = {}; + window.HTMLElement.prototype = document.createElement('div').__proto__; + Prototype.BrowserFeatures.ElementExtensions = true; +} + +Element.hasAttribute = function(element, attribute) { + if (element.hasAttribute) return element.hasAttribute(attribute); + return Element.Methods.Simulated.hasAttribute(element, attribute); +}; + +Element.addMethods = function(methods) { + var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag; + + if (!methods) { + Object.extend(Form, Form.Methods); + Object.extend(Form.Element, Form.Element.Methods); + Object.extend(Element.Methods.ByTag, { + "FORM": Object.clone(Form.Methods), + "INPUT": Object.clone(Form.Element.Methods), + "SELECT": Object.clone(Form.Element.Methods), + "TEXTAREA": Object.clone(Form.Element.Methods) + }); + } + + if (arguments.length == 2) { + var tagName = methods; + methods = arguments[1]; + } + + if (!tagName) Object.extend(Element.Methods, methods || {}); + else { + if (tagName.constructor == Array) tagName.each(extend); + else extend(tagName); + } + + function extend(tagName) { + tagName = tagName.toUpperCase(); + if (!Element.Methods.ByTag[tagName]) + Element.Methods.ByTag[tagName] = {}; + Object.extend(Element.Methods.ByTag[tagName], methods); + } + + function copy(methods, destination, onlyIfAbsent) { + onlyIfAbsent = onlyIfAbsent || false; + var cache = Element.extend.cache; + for (var property in methods) { + var value = methods[property]; + if (!onlyIfAbsent || !(property in destination)) + destination[property] = cache.findOrStore(value); + } + } + + function findDOMClass(tagName) { + var klass; + var trans = { + "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph", + "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList", + "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading", + "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote", + "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION": + "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD": + "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR": + "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET": + "FrameSet", "IFRAME": "IFrame" + }; + if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element'; + if (window[klass]) return window[klass]; + klass = 'HTML' + tagName + 'Element'; + if (window[klass]) return window[klass]; + klass = 'HTML' + tagName.capitalize() + 'Element'; + if (window[klass]) return window[klass]; + + window[klass] = {}; + window[klass].prototype = document.createElement(tagName).__proto__; + return window[klass]; + } + + if (F.ElementExtensions) { + copy(Element.Methods, HTMLElement.prototype); + copy(Element.Methods.Simulated, HTMLElement.prototype, true); + } + + if (F.SpecificElementExtensions) { + for (var tag in Element.Methods.ByTag) { + var klass = findDOMClass(tag); + if (typeof klass == "undefined") continue; + copy(T[tag], klass.prototype); + } + } + + Object.extend(Element, Element.Methods); + delete Element.ByTag; +}; + +var Toggle = { display: Element.toggle }; + +/*--------------------------------------------------------------------------*/ + +Abstract.Insertion = function(adjacency) { + this.adjacency = adjacency; +} + +Abstract.Insertion.prototype = { + initialize: function(element, content) { + this.element = $(element); + this.content = content.stripScripts(); + + if (this.adjacency && this.element.insertAdjacentHTML) { + try { + this.element.insertAdjacentHTML(this.adjacency, this.content); + } catch (e) { + var tagName = this.element.tagName.toUpperCase(); + if (['TBODY', 'TR'].include(tagName)) { + this.insertContent(this.contentFromAnonymousTable()); + } else { + throw e; + } + } + } else { + this.range = this.element.ownerDocument.createRange(); + if (this.initializeRange) this.initializeRange(); + this.insertContent([this.range.createContextualFragment(this.content)]); + } + + setTimeout(function() {content.evalScripts()}, 10); + }, + + contentFromAnonymousTable: function() { + var div = document.createElement('div'); + div.innerHTML = '' + this.content + '
'; + return $A(div.childNodes[0].childNodes[0].childNodes); + } +} + +var Insertion = new Object(); + +Insertion.Before = Class.create(); +Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), { + initializeRange: function() { + this.range.setStartBefore(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.parentNode.insertBefore(fragment, this.element); + }).bind(this)); + } +}); + +Insertion.Top = Class.create(); +Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), { + initializeRange: function() { + this.range.selectNodeContents(this.element); + this.range.collapse(true); + }, + + insertContent: function(fragments) { + fragments.reverse(false).each((function(fragment) { + this.element.insertBefore(fragment, this.element.firstChild); + }).bind(this)); + } +}); + +Insertion.Bottom = Class.create(); +Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), { + initializeRange: function() { + this.range.selectNodeContents(this.element); + this.range.collapse(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.appendChild(fragment); + }).bind(this)); + } +}); + +Insertion.After = Class.create(); +Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), { + initializeRange: function() { + this.range.setStartAfter(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.parentNode.insertBefore(fragment, + this.element.nextSibling); + }).bind(this)); + } +}); + +/*--------------------------------------------------------------------------*/ + +Element.ClassNames = Class.create(); +Element.ClassNames.prototype = { + initialize: function(element) { + this.element = $(element); + }, + + _each: function(iterator) { + this.element.className.split(/\s+/).select(function(name) { + return name.length > 0; + })._each(iterator); + }, + + set: function(className) { + this.element.className = className; + }, + + add: function(classNameToAdd) { + if (this.include(classNameToAdd)) return; + this.set($A(this).concat(classNameToAdd).join(' ')); + }, + + remove: function(classNameToRemove) { + if (!this.include(classNameToRemove)) return; + this.set($A(this).without(classNameToRemove).join(' ')); + }, + + toString: function() { + return $A(this).join(' '); + } +}; + +Object.extend(Element.ClassNames.prototype, Enumerable); +/* Portions of the Selector class are derived from Jack Slocum’s DomQuery, + * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style + * license. Please see http://www.yui-ext.com/ for more information. */ + +var Selector = Class.create(); + +Selector.prototype = { + initialize: function(expression) { + this.expression = expression.strip(); + this.compileMatcher(); + }, + + compileMatcher: function() { + // Selectors with namespaced attributes can't use the XPath version + if (Prototype.BrowserFeatures.XPath && !(/\[[\w-]*?:/).test(this.expression)) + return this.compileXPathMatcher(); + + var e = this.expression, ps = Selector.patterns, h = Selector.handlers, + c = Selector.criteria, le, p, m; + + if (Selector._cache[e]) { + this.matcher = Selector._cache[e]; return; + } + this.matcher = ["this.matcher = function(root) {", + "var r = root, h = Selector.handlers, c = false, n;"]; + + while (e && le != e && (/\S/).test(e)) { + le = e; + for (var i in ps) { + p = ps[i]; + if (m = e.match(p)) { + this.matcher.push(typeof c[i] == 'function' ? c[i](m) : + new Template(c[i]).evaluate(m)); + e = e.replace(m[0], ''); + break; + } + } + } + + this.matcher.push("return h.unique(n);\n}"); + eval(this.matcher.join('\n')); + Selector._cache[this.expression] = this.matcher; + }, + + compileXPathMatcher: function() { + var e = this.expression, ps = Selector.patterns, + x = Selector.xpath, le, m; + + if (Selector._cache[e]) { + this.xpath = Selector._cache[e]; return; + } + + this.matcher = ['.//*']; + while (e && le != e && (/\S/).test(e)) { + le = e; + for (var i in ps) { + if (m = e.match(ps[i])) { + this.matcher.push(typeof x[i] == 'function' ? x[i](m) : + new Template(x[i]).evaluate(m)); + e = e.replace(m[0], ''); + break; + } + } + } + + this.xpath = this.matcher.join(''); + Selector._cache[this.expression] = this.xpath; + }, + + findElements: function(root) { + root = root || document; + if (this.xpath) return document._getElementsByXPath(this.xpath, root); + return this.matcher(root); + }, + + match: function(element) { + return this.findElements(document).include(element); + }, + + toString: function() { + return this.expression; + }, + + inspect: function() { + return "#"; + } +}; + +Object.extend(Selector, { + _cache: {}, + + xpath: { + descendant: "//*", + child: "/*", + adjacent: "/following-sibling::*[1]", + laterSibling: '/following-sibling::*', + tagName: function(m) { + if (m[1] == '*') return ''; + return "[local-name()='" + m[1].toLowerCase() + + "' or local-name()='" + m[1].toUpperCase() + "']"; + }, + className: "[contains(concat(' ', @class, ' '), ' #{1} ')]", + id: "[@id='#{1}']", + attrPresence: "[@#{1}]", + attr: function(m) { + m[3] = m[5] || m[6]; + return new Template(Selector.xpath.operators[m[2]]).evaluate(m); + }, + pseudo: function(m) { + var h = Selector.xpath.pseudos[m[1]]; + if (!h) return ''; + if (typeof h === 'function') return h(m); + return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m); + }, + operators: { + '=': "[@#{1}='#{3}']", + '!=': "[@#{1}!='#{3}']", + '^=': "[starts-with(@#{1}, '#{3}')]", + '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']", + '*=': "[contains(@#{1}, '#{3}')]", + '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]", + '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]" + }, + pseudos: { + 'first-child': '[not(preceding-sibling::*)]', + 'last-child': '[not(following-sibling::*)]', + 'only-child': '[not(preceding-sibling::* or following-sibling::*)]', + 'empty': "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]", + 'checked': "[@checked]", + 'disabled': "[@disabled]", + 'enabled': "[not(@disabled)]", + 'not': function(m) { + var e = m[6], p = Selector.patterns, + x = Selector.xpath, le, m, v; + + var exclusion = []; + while (e && le != e && (/\S/).test(e)) { + le = e; + for (var i in p) { + if (m = e.match(p[i])) { + v = typeof x[i] == 'function' ? x[i](m) : new Template(x[i]).evaluate(m); + exclusion.push("(" + v.substring(1, v.length - 1) + ")"); + e = e.replace(m[0], ''); + break; + } + } + } + return "[not(" + exclusion.join(" and ") + ")]"; + }, + 'nth-child': function(m) { + return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m); + }, + 'nth-last-child': function(m) { + return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m); + }, + 'nth-of-type': function(m) { + return Selector.xpath.pseudos.nth("position() ", m); + }, + 'nth-last-of-type': function(m) { + return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m); + }, + 'first-of-type': function(m) { + m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m); + }, + 'last-of-type': function(m) { + m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m); + }, + 'only-of-type': function(m) { + var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m); + }, + nth: function(fragment, m) { + var mm, formula = m[6], predicate; + if (formula == 'even') formula = '2n+0'; + if (formula == 'odd') formula = '2n+1'; + if (mm = formula.match(/^(\d+)$/)) // digit only + return '[' + fragment + "= " + mm[1] + ']'; + if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b + if (mm[1] == "-") mm[1] = -1; + var a = mm[1] ? Number(mm[1]) : 1; + var b = mm[2] ? Number(mm[2]) : 0; + predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " + + "((#{fragment} - #{b}) div #{a} >= 0)]"; + return new Template(predicate).evaluate({ + fragment: fragment, a: a, b: b }); + } + } + } + }, + + criteria: { + tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;', + className: 'n = h.className(n, r, "#{1}", c); c = false;', + id: 'n = h.id(n, r, "#{1}", c); c = false;', + attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;', + attr: function(m) { + m[3] = (m[5] || m[6]); + return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m); + }, + pseudo: function(m) { + if (m[6]) m[6] = m[6].replace(/"/g, '\\"'); + return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m); + }, + descendant: 'c = "descendant";', + child: 'c = "child";', + adjacent: 'c = "adjacent";', + laterSibling: 'c = "laterSibling";' + }, + + patterns: { + // combinators must be listed first + // (and descendant needs to be last combinator) + laterSibling: /^\s*~\s*/, + child: /^\s*>\s*/, + adjacent: /^\s*\+\s*/, + descendant: /^\s/, + + // selectors follow + tagName: /^\s*(\*|[\w\-]+)(\b|$)?/, + id: /^#([\w\-\*]+)(\b|$)/, + className: /^\.([\w\-\*]+)(\b|$)/, + pseudo: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|\s|(?=:))/, + attrPresence: /^\[([\w]+)\]/, + attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\]]*?)\4|([^'"][^\]]*?)))?\]/ + }, + + handlers: { + // UTILITY FUNCTIONS + // joins two collections + concat: function(a, b) { + for (var i = 0, node; node = b[i]; i++) + a.push(node); + return a; + }, + + // marks an array of nodes for counting + mark: function(nodes) { + for (var i = 0, node; node = nodes[i]; i++) + node._counted = true; + return nodes; + }, + + unmark: function(nodes) { + for (var i = 0, node; node = nodes[i]; i++) + node._counted = undefined; + return nodes; + }, + + // mark each child node with its position (for nth calls) + // "ofType" flag indicates whether we're indexing for nth-of-type + // rather than nth-child + index: function(parentNode, reverse, ofType) { + parentNode._counted = true; + if (reverse) { + for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) { + node = nodes[i]; + if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++; + } + } else { + for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++) + if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++; + } + }, + + // filters out duplicates and extends all nodes + unique: function(nodes) { + if (nodes.length == 0) return nodes; + var results = [], n; + for (var i = 0, l = nodes.length; i < l; i++) + if (!(n = nodes[i])._counted) { + n._counted = true; + results.push(Element.extend(n)); + } + return Selector.handlers.unmark(results); + }, + + // COMBINATOR FUNCTIONS + descendant: function(nodes) { + var h = Selector.handlers; + for (var i = 0, results = [], node; node = nodes[i]; i++) + h.concat(results, node.getElementsByTagName('*')); + return results; + }, + + child: function(nodes) { + var h = Selector.handlers; + for (var i = 0, results = [], node; node = nodes[i]; i++) { + for (var j = 0, children = [], child; child = node.childNodes[j]; j++) + if (child.nodeType == 1 && child.tagName != '!') results.push(child); + } + return results; + }, + + adjacent: function(nodes) { + for (var i = 0, results = [], node; node = nodes[i]; i++) { + var next = this.nextElementSibling(node); + if (next) results.push(next); + } + return results; + }, + + laterSibling: function(nodes) { + var h = Selector.handlers; + for (var i = 0, results = [], node; node = nodes[i]; i++) + h.concat(results, Element.nextSiblings(node)); + return results; + }, + + nextElementSibling: function(node) { + while (node = node.nextSibling) + if (node.nodeType == 1) return node; + return null; + }, + + previousElementSibling: function(node) { + while (node = node.previousSibling) + if (node.nodeType == 1) return node; + return null; + }, + + // TOKEN FUNCTIONS + tagName: function(nodes, root, tagName, combinator) { + tagName = tagName.toUpperCase(); + var results = [], h = Selector.handlers; + if (nodes) { + if (combinator) { + // fastlane for ordinary descendant combinators + if (combinator == "descendant") { + for (var i = 0, node; node = nodes[i]; i++) + h.concat(results, node.getElementsByTagName(tagName)); + return results; + } else nodes = this[combinator](nodes); + if (tagName == "*") return nodes; + } + for (var i = 0, node; node = nodes[i]; i++) + if (node.tagName.toUpperCase() == tagName) results.push(node); + return results; + } else return root.getElementsByTagName(tagName); + }, + + id: function(nodes, root, id, combinator) { + var targetNode = $(id), h = Selector.handlers; + if (!nodes && root == document) return targetNode ? [targetNode] : []; + if (nodes) { + if (combinator) { + if (combinator == 'child') { + for (var i = 0, node; node = nodes[i]; i++) + if (targetNode.parentNode == node) return [targetNode]; + } else if (combinator == 'descendant') { + for (var i = 0, node; node = nodes[i]; i++) + if (Element.descendantOf(targetNode, node)) return [targetNode]; + } else if (combinator == 'adjacent') { + for (var i = 0, node; node = nodes[i]; i++) + if (Selector.handlers.previousElementSibling(targetNode) == node) + return [targetNode]; + } else nodes = h[combinator](nodes); + } + for (var i = 0, node; node = nodes[i]; i++) + if (node == targetNode) return [targetNode]; + return []; + } + return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : []; + }, + + className: function(nodes, root, className, combinator) { + if (nodes && combinator) nodes = this[combinator](nodes); + return Selector.handlers.byClassName(nodes, root, className); + }, + + byClassName: function(nodes, root, className) { + if (!nodes) nodes = Selector.handlers.descendant([root]); + var needle = ' ' + className + ' '; + for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) { + nodeClassName = node.className; + if (nodeClassName.length == 0) continue; + if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle)) + results.push(node); + } + return results; + }, + + attrPresence: function(nodes, root, attr) { + var results = []; + for (var i = 0, node; node = nodes[i]; i++) + if (Element.hasAttribute(node, attr)) results.push(node); + return results; + }, + + attr: function(nodes, root, attr, value, operator) { + if (!nodes) nodes = root.getElementsByTagName("*"); + var handler = Selector.operators[operator], results = []; + for (var i = 0, node; node = nodes[i]; i++) { + var nodeValue = Element.readAttribute(node, attr); + if (nodeValue === null) continue; + if (handler(nodeValue, value)) results.push(node); + } + return results; + }, + + pseudo: function(nodes, name, value, root, combinator) { + if (nodes && combinator) nodes = this[combinator](nodes); + if (!nodes) nodes = root.getElementsByTagName("*"); + return Selector.pseudos[name](nodes, value, root); + } + }, + + pseudos: { + 'first-child': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) { + if (Selector.handlers.previousElementSibling(node)) continue; + results.push(node); + } + return results; + }, + 'last-child': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) { + if (Selector.handlers.nextElementSibling(node)) continue; + results.push(node); + } + return results; + }, + 'only-child': function(nodes, value, root) { + var h = Selector.handlers; + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (!h.previousElementSibling(node) && !h.nextElementSibling(node)) + results.push(node); + return results; + }, + 'nth-child': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, formula, root); + }, + 'nth-last-child': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, formula, root, true); + }, + 'nth-of-type': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, formula, root, false, true); + }, + 'nth-last-of-type': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, formula, root, true, true); + }, + 'first-of-type': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, "1", root, false, true); + }, + 'last-of-type': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, "1", root, true, true); + }, + 'only-of-type': function(nodes, formula, root) { + var p = Selector.pseudos; + return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root); + }, + + // handles the an+b logic + getIndices: function(a, b, total) { + if (a == 0) return b > 0 ? [b] : []; + return $R(1, total).inject([], function(memo, i) { + if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i); + return memo; + }); + }, + + // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type + nth: function(nodes, formula, root, reverse, ofType) { + if (nodes.length == 0) return []; + if (formula == 'even') formula = '2n+0'; + if (formula == 'odd') formula = '2n+1'; + var h = Selector.handlers, results = [], indexed = [], m; + h.mark(nodes); + for (var i = 0, node; node = nodes[i]; i++) { + if (!node.parentNode._counted) { + h.index(node.parentNode, reverse, ofType); + indexed.push(node.parentNode); + } + } + if (formula.match(/^\d+$/)) { // just a number + formula = Number(formula); + for (var i = 0, node; node = nodes[i]; i++) + if (node.nodeIndex == formula) results.push(node); + } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b + if (m[1] == "-") m[1] = -1; + var a = m[1] ? Number(m[1]) : 1; + var b = m[2] ? Number(m[2]) : 0; + var indices = Selector.pseudos.getIndices(a, b, nodes.length); + for (var i = 0, node, l = indices.length; node = nodes[i]; i++) { + for (var j = 0; j < l; j++) + if (node.nodeIndex == indices[j]) results.push(node); + } + } + h.unmark(nodes); + h.unmark(indexed); + return results; + }, + + 'empty': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) { + // IE treats comments as element nodes + if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue; + results.push(node); + } + return results; + }, + + 'not': function(nodes, selector, root) { + var h = Selector.handlers, selectorType, m; + var exclusions = new Selector(selector).findElements(root); + h.mark(exclusions); + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (!node._counted) results.push(node); + h.unmark(exclusions); + return results; + }, + + 'enabled': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (!node.disabled) results.push(node); + return results; + }, + + 'disabled': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (node.disabled) results.push(node); + return results; + }, + + 'checked': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (node.checked) results.push(node); + return results; + } + }, + + operators: { + '=': function(nv, v) { return nv == v; }, + '!=': function(nv, v) { return nv != v; }, + '^=': function(nv, v) { return nv.startsWith(v); }, + '$=': function(nv, v) { return nv.endsWith(v); }, + '*=': function(nv, v) { return nv.include(v); }, + '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); }, + '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); } + }, + + matchElements: function(elements, expression) { + var matches = new Selector(expression).findElements(), h = Selector.handlers; + h.mark(matches); + for (var i = 0, results = [], element; element = elements[i]; i++) + if (element._counted) results.push(element); + h.unmark(matches); + return results; + }, + + findElement: function(elements, expression, index) { + if (typeof expression == 'number') { + index = expression; expression = false; + } + return Selector.matchElements(elements, expression || '*')[index || 0]; + }, + + findChildElements: function(element, expressions) { + var exprs = expressions.join(','), expressions = []; + exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) { + expressions.push(m[1].strip()); + }); + var results = [], h = Selector.handlers; + for (var i = 0, l = expressions.length, selector; i < l; i++) { + selector = new Selector(expressions[i].strip()); + h.concat(results, selector.findElements(element)); + } + return (l > 1) ? h.unique(results) : results; + } +}); + +function $$() { + return Selector.findChildElements(document, $A(arguments)); +} +var Form = { + reset: function(form) { + $(form).reset(); + return form; + }, + + serializeElements: function(elements, getHash) { + var data = elements.inject({}, function(result, element) { + if (!element.disabled && element.name) { + var key = element.name, value = $(element).getValue(); + if (value != null) { + if (key in result) { + if (result[key].constructor != Array) result[key] = [result[key]]; + result[key].push(value); + } + else result[key] = value; + } + } + return result; + }); + + return getHash ? data : Hash.toQueryString(data); + } +}; + +Form.Methods = { + serialize: function(form, getHash) { + return Form.serializeElements(Form.getElements(form), getHash); + }, + + getElements: function(form) { + return $A($(form).getElementsByTagName('*')).inject([], + function(elements, child) { + if (Form.Element.Serializers[child.tagName.toLowerCase()]) + elements.push(Element.extend(child)); + return elements; + } + ); + }, + + getInputs: function(form, typeName, name) { + form = $(form); + var inputs = form.getElementsByTagName('input'); + + if (!typeName && !name) return $A(inputs).map(Element.extend); + + for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) { + var input = inputs[i]; + if ((typeName && input.type != typeName) || (name && input.name != name)) + continue; + matchingInputs.push(Element.extend(input)); + } + + return matchingInputs; + }, + + disable: function(form) { + form = $(form); + Form.getElements(form).invoke('disable'); + return form; + }, + + enable: function(form) { + form = $(form); + Form.getElements(form).invoke('enable'); + return form; + }, + + findFirstElement: function(form) { + return $(form).getElements().find(function(element) { + return element.type != 'hidden' && !element.disabled && + ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); + }); + }, + + focusFirstElement: function(form) { + form = $(form); + form.findFirstElement().activate(); + return form; + }, + + request: function(form, options) { + form = $(form), options = Object.clone(options || {}); + + var params = options.parameters; + options.parameters = form.serialize(true); + + if (params) { + if (typeof params == 'string') params = params.toQueryParams(); + Object.extend(options.parameters, params); + } + + if (form.hasAttribute('method') && !options.method) + options.method = form.method; + + return new Ajax.Request(form.readAttribute('action'), options); + } +} + +/*--------------------------------------------------------------------------*/ + +Form.Element = { + focus: function(element) { + $(element).focus(); + return element; + }, + + select: function(element) { + $(element).select(); + return element; + } +} + +Form.Element.Methods = { + serialize: function(element) { + element = $(element); + if (!element.disabled && element.name) { + var value = element.getValue(); + if (value != undefined) { + var pair = {}; + pair[element.name] = value; + return Hash.toQueryString(pair); + } + } + return ''; + }, + + getValue: function(element) { + element = $(element); + var method = element.tagName.toLowerCase(); + return Form.Element.Serializers[method](element); + }, + + clear: function(element) { + $(element).value = ''; + return element; + }, + + present: function(element) { + return $(element).value != ''; + }, + + activate: function(element) { + element = $(element); + try { + element.focus(); + if (element.select && (element.tagName.toLowerCase() != 'input' || + !['button', 'reset', 'submit'].include(element.type))) + element.select(); + } catch (e) {} + return element; + }, + + disable: function(element) { + element = $(element); + element.blur(); + element.disabled = true; + return element; + }, + + enable: function(element) { + element = $(element); + element.disabled = false; + return element; + } +} + +/*--------------------------------------------------------------------------*/ + +var Field = Form.Element; +var $F = Form.Element.Methods.getValue; + +/*--------------------------------------------------------------------------*/ + +Form.Element.Serializers = { + input: function(element) { + switch (element.type.toLowerCase()) { + case 'checkbox': + case 'radio': + return Form.Element.Serializers.inputSelector(element); + default: + return Form.Element.Serializers.textarea(element); + } + }, + + inputSelector: function(element) { + return element.checked ? element.value : null; + }, + + textarea: function(element) { + return element.value; + }, + + select: function(element) { + return this[element.type == 'select-one' ? + 'selectOne' : 'selectMany'](element); + }, + + selectOne: function(element) { + var index = element.selectedIndex; + return index >= 0 ? this.optionValue(element.options[index]) : null; + }, + + selectMany: function(element) { + var values, length = element.length; + if (!length) return null; + + for (var i = 0, values = []; i < length; i++) { + var opt = element.options[i]; + if (opt.selected) values.push(this.optionValue(opt)); + } + return values; + }, + + optionValue: function(opt) { + // extend element because hasAttribute may not be native + return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text; + } +} + +/*--------------------------------------------------------------------------*/ + +Abstract.TimedObserver = function() {} +Abstract.TimedObserver.prototype = { + initialize: function(element, frequency, callback) { + this.frequency = frequency; + this.element = $(element); + this.callback = callback; + + this.lastValue = this.getValue(); + this.registerCallback(); + }, + + registerCallback: function() { + setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); + }, + + onTimerEvent: function() { + var value = this.getValue(); + var changed = ('string' == typeof this.lastValue && 'string' == typeof value + ? this.lastValue != value : String(this.lastValue) != String(value)); + if (changed) { + this.callback(this.element, value); + this.lastValue = value; + } + } +} + +Form.Element.Observer = Class.create(); +Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.Observer = Class.create(); +Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { + getValue: function() { + return Form.serialize(this.element); + } +}); + +/*--------------------------------------------------------------------------*/ + +Abstract.EventObserver = function() {} +Abstract.EventObserver.prototype = { + initialize: function(element, callback) { + this.element = $(element); + this.callback = callback; + + this.lastValue = this.getValue(); + if (this.element.tagName.toLowerCase() == 'form') + this.registerFormCallbacks(); + else + this.registerCallback(this.element); + }, + + onElementEvent: function() { + var value = this.getValue(); + if (this.lastValue != value) { + this.callback(this.element, value); + this.lastValue = value; + } + }, + + registerFormCallbacks: function() { + Form.getElements(this.element).each(this.registerCallback.bind(this)); + }, + + registerCallback: function(element) { + if (element.type) { + switch (element.type.toLowerCase()) { + case 'checkbox': + case 'radio': + Event.observe(element, 'click', this.onElementEvent.bind(this)); + break; + default: + Event.observe(element, 'change', this.onElementEvent.bind(this)); + break; + } + } + } +} + +Form.Element.EventObserver = Class.create(); +Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.EventObserver = Class.create(); +Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { + getValue: function() { + return Form.serialize(this.element); + } +}); +if (!window.Event) { + var Event = new Object(); +} + +Object.extend(Event, { + KEY_BACKSPACE: 8, + KEY_TAB: 9, + KEY_RETURN: 13, + KEY_ESC: 27, + KEY_LEFT: 37, + KEY_UP: 38, + KEY_RIGHT: 39, + KEY_DOWN: 40, + KEY_DELETE: 46, + KEY_HOME: 36, + KEY_END: 35, + KEY_PAGEUP: 33, + KEY_PAGEDOWN: 34, + + element: function(event) { + return $(event.target || event.srcElement); + }, + + isLeftClick: function(event) { + return (((event.which) && (event.which == 1)) || + ((event.button) && (event.button == 1))); + }, + + pointerX: function(event) { + return event.pageX || (event.clientX + + (document.documentElement.scrollLeft || document.body.scrollLeft)); + }, + + pointerY: function(event) { + return event.pageY || (event.clientY + + (document.documentElement.scrollTop || document.body.scrollTop)); + }, + + stop: function(event) { + if (event.preventDefault) { + event.preventDefault(); + event.stopPropagation(); + } else { + event.returnValue = false; + event.cancelBubble = true; + } + }, + + // find the first node with the given tagName, starting from the + // node the event was triggered on; traverses the DOM upwards + findElement: function(event, tagName) { + var element = Event.element(event); + while (element.parentNode && (!element.tagName || + (element.tagName.toUpperCase() != tagName.toUpperCase()))) + element = element.parentNode; + return element; + }, + + observers: false, + + _observeAndCache: function(element, name, observer, useCapture) { + if (!this.observers) this.observers = []; + if (element.addEventListener) { + this.observers.push([element, name, observer, useCapture]); + element.addEventListener(name, observer, useCapture); + } else if (element.attachEvent) { + this.observers.push([element, name, observer, useCapture]); + element.attachEvent('on' + name, observer); + } + }, + + unloadCache: function() { + if (!Event.observers) return; + for (var i = 0, length = Event.observers.length; i < length; i++) { + Event.stopObserving.apply(this, Event.observers[i]); + Event.observers[i][0] = null; + } + Event.observers = false; + }, + + observe: function(element, name, observer, useCapture) { + element = $(element); + useCapture = useCapture || false; + + if (name == 'keypress' && + (Prototype.Browser.WebKit || element.attachEvent)) + name = 'keydown'; + + Event._observeAndCache(element, name, observer, useCapture); + }, + + stopObserving: function(element, name, observer, useCapture) { + element = $(element); + useCapture = useCapture || false; + + if (name == 'keypress' && + (Prototype.Browser.WebKit || element.attachEvent)) + name = 'keydown'; + + if (element.removeEventListener) { + element.removeEventListener(name, observer, useCapture); + } else if (element.detachEvent) { + try { + element.detachEvent('on' + name, observer); + } catch (e) {} + } + } +}); + +/* prevent memory leaks in IE */ +if (Prototype.Browser.IE) + Event.observe(window, 'unload', Event.unloadCache, false); +var Position = { + // set to true if needed, warning: firefox performance problems + // NOT neeeded for page scrolling, only if draggable contained in + // scrollable elements + includeScrollOffsets: false, + + // must be called before calling withinIncludingScrolloffset, every time the + // page is scrolled + prepare: function() { + this.deltaX = window.pageXOffset + || document.documentElement.scrollLeft + || document.body.scrollLeft + || 0; + this.deltaY = window.pageYOffset + || document.documentElement.scrollTop + || document.body.scrollTop + || 0; + }, + + realOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.scrollTop || 0; + valueL += element.scrollLeft || 0; + element = element.parentNode; + } while (element); + return [valueL, valueT]; + }, + + cumulativeOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + } while (element); + return [valueL, valueT]; + }, + + positionedOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + if (element) { + if(element.tagName=='BODY') break; + var p = Element.getStyle(element, 'position'); + if (p == 'relative' || p == 'absolute') break; + } + } while (element); + return [valueL, valueT]; + }, + + offsetParent: function(element) { + if (element.offsetParent) return element.offsetParent; + if (element == document.body) return element; + + while ((element = element.parentNode) && element != document.body) + if (Element.getStyle(element, 'position') != 'static') + return element; + + return document.body; + }, + + // caches x/y coordinate pair to use with overlap + within: function(element, x, y) { + if (this.includeScrollOffsets) + return this.withinIncludingScrolloffsets(element, x, y); + this.xcomp = x; + this.ycomp = y; + this.offset = this.cumulativeOffset(element); + + return (y >= this.offset[1] && + y < this.offset[1] + element.offsetHeight && + x >= this.offset[0] && + x < this.offset[0] + element.offsetWidth); + }, + + withinIncludingScrolloffsets: function(element, x, y) { + var offsetcache = this.realOffset(element); + + this.xcomp = x + offsetcache[0] - this.deltaX; + this.ycomp = y + offsetcache[1] - this.deltaY; + this.offset = this.cumulativeOffset(element); + + return (this.ycomp >= this.offset[1] && + this.ycomp < this.offset[1] + element.offsetHeight && + this.xcomp >= this.offset[0] && + this.xcomp < this.offset[0] + element.offsetWidth); + }, + + // within must be called directly before + overlap: function(mode, element) { + if (!mode) return 0; + if (mode == 'vertical') + return ((this.offset[1] + element.offsetHeight) - this.ycomp) / + element.offsetHeight; + if (mode == 'horizontal') + return ((this.offset[0] + element.offsetWidth) - this.xcomp) / + element.offsetWidth; + }, + + page: function(forElement) { + var valueT = 0, valueL = 0; + + var element = forElement; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + + // Safari fix + if (element.offsetParent == document.body) + if (Element.getStyle(element,'position')=='absolute') break; + + } while (element = element.offsetParent); + + element = forElement; + do { + if (!window.opera || element.tagName=='BODY') { + valueT -= element.scrollTop || 0; + valueL -= element.scrollLeft || 0; + } + } while (element = element.parentNode); + + return [valueL, valueT]; + }, + + clone: function(source, target) { + var options = Object.extend({ + setLeft: true, + setTop: true, + setWidth: true, + setHeight: true, + offsetTop: 0, + offsetLeft: 0 + }, arguments[2] || {}) + + // find page position of source + source = $(source); + var p = Position.page(source); + + // find coordinate system to use + target = $(target); + var delta = [0, 0]; + var parent = null; + // delta [0,0] will do fine with position: fixed elements, + // position:absolute needs offsetParent deltas + if (Element.getStyle(target,'position') == 'absolute') { + parent = Position.offsetParent(target); + delta = Position.page(parent); + } + + // correct by body offsets (fixes Safari) + if (parent == document.body) { + delta[0] -= document.body.offsetLeft; + delta[1] -= document.body.offsetTop; + } + + // set position + if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; + if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; + if(options.setWidth) target.style.width = source.offsetWidth + 'px'; + if(options.setHeight) target.style.height = source.offsetHeight + 'px'; + }, + + absolutize: function(element) { + element = $(element); + if (element.style.position == 'absolute') return; + Position.prepare(); + + var offsets = Position.positionedOffset(element); + var top = offsets[1]; + var left = offsets[0]; + var width = element.clientWidth; + var height = element.clientHeight; + + element._originalLeft = left - parseFloat(element.style.left || 0); + element._originalTop = top - parseFloat(element.style.top || 0); + element._originalWidth = element.style.width; + element._originalHeight = element.style.height; + + element.style.position = 'absolute'; + element.style.top = top + 'px'; + element.style.left = left + 'px'; + element.style.width = width + 'px'; + element.style.height = height + 'px'; + }, + + relativize: function(element) { + element = $(element); + if (element.style.position == 'relative') return; + Position.prepare(); + + element.style.position = 'relative'; + var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); + var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); + + element.style.top = top + 'px'; + element.style.left = left + 'px'; + element.style.height = element._originalHeight; + element.style.width = element._originalWidth; + } +} + +// Safari returns margins on body which is incorrect if the child is absolutely +// positioned. For performance reasons, redefine Position.cumulativeOffset for +// KHTML/WebKit only. +if (Prototype.Browser.WebKit) { + Position.cumulativeOffset = function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + if (element.offsetParent == document.body) + if (Element.getStyle(element, 'position') == 'absolute') break; + + element = element.offsetParent; + } while (element); + + return [valueL, valueT]; + } +} + +Element.addMethods(); \ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/coffee-with-milk.css b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/coffee-with-milk.css new file mode 100644 index 0000000..86a1998 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/coffee-with-milk.css @@ -0,0 +1,73 @@ +/* +Based on "Coffee with milk" table design by Roger Johansson, 456 Berea Street +www.456bereastreet.com +================================================*/ + +.ricoLG_table { + border-top:1px solid #523A0B !important; + border-right:none; + font:normal 76%/150% "Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif; + color:#000; +} +tr.ricoLG_hdg .ricoLG_cell, tr.ricoLG_hdg th, tr.ricoLG_hdg td { /* td/th required for IE */ + background:#EBE5D9 !important; + line-height:normal; + text-align:left; +} + +tr.ricoLG_hdg th, tr.ricoLG_hdg td { + border-bottom:1px solid #523A0B; + background:#EBE5D9; + } + +tr.ricoLG_hdg th, tr.ricoLG_hdg td { + border-left: 1px solid #E0D8CD !important; +} + +.ricoLG_bottom th, .ricoLG_bottom td { + border-left: 1px solid #FFF; +} + +tr.ricoLG_hdg div.ricoLG_cell { + background:#EBE5D9; + font-weight:bold; + padding:0.5em 0 0.5em 0.5em; +} +div.ricoLG_outerDiv table a { + color:#523A0B; + text-decoration:none; + border-bottom:1px dotted; + } +div.ricoLG_outerDiv tbody a:visited { + color:#444; + font-weight:normal; + } +div.ricoLG_outerDiv table a:hover { + border-bottom-style:solid; + } + +.ricoLG_bottom div.ricoLG_oddRow { + background-color:#F7F4EE; + border-top: 1px solid #EBE5D9; + border-bottom: 1px solid #EBE5D9; +} +.ricoLG_bottom div.ricoLG_evenRow { + border-top: 1px solid #FFF; + border-bottom: 1px solid #FFF; +} +.ricoLG_selection { + background-color:#ffffee !important; + border-color:#523A0B !important; +} +.ricoLG_table { + border-style:none; +} + +caption { + font-family:Georgia,Times,serif; + font-weight:normal; + font-size:1.4em; + text-align:left; + margin:0; + padding:0.5em 0.25em; + } \ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/grayedout.css b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/grayedout.css new file mode 100644 index 0000000..d5a0dd4 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/grayedout.css @@ -0,0 +1,68 @@ +/* ------------------------------------------------------- +Based on Grayed Out table design +Author: Terence Ordona +URL: http://www.imaputz.com/ + ------------------------------------------------------- */ +div.ricoLG_outerDiv *, div.ricoLG_cell { + font-size: 11px; + font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; +} + +.ricoLG_table { + border-top: 1px solid #CCC; + border-right: 1px solid #CCC; +} + +tr.ricoLG_hdg th, tr.ricoLG_hdg td { + background-color: #FFF !important; + background: url(../images/grayedout.gif) #FFF repeat-x scroll center left; + border-bottom: 1px solid #CCC; +} + +.ricoLG_table th, .ricoLG_table td { + border-left: 1px solid #CCC; +} + +.ricoLG_bottom th, .ricoLG_bottom td { + border-bottom: 1px solid #CCC; +} + +.ricoLG_bottom div.ricoLG_cell { + border-bottom: none; + padding: 5px; +} + +tr.ricoLG_hdg .ricoLG_cell { + font-weight: normal; +} + +div.ricoLG_outerDiv a:visited, div.ricoLG_outerDiv a:link { + color: #009; + text-decoration: none; +} + +div.ricoLG_outerDiv a:hover { + color: #009; + text-decoration: underline; +} + +.ricoLG_oddRow { + background-color: #EEE; +} + +div.ricoLG_selection { + background-color: #999; + color: #FFF; +} + +div.ricoLG_highlightDiv { + border-color: #999; +} + +caption { + text-align: left; + font-size: 100%; + padding: .75em; + color: #000; +} + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/greenHdg.css b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/greenHdg.css new file mode 100644 index 0000000..f46dfb1 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/greenHdg.css @@ -0,0 +1,8 @@ +/* display grid headings with a green background */ + +tr.ricoLG_hdg .ricoLG_cell, tr.ricoLG_hdg th, tr.ricoLG_hdg td { /* td/th required for IE */ + background-color : #cedebd !important; + color : #000000; + font-weight : bold; +} +div.ricoLG_selection { background-color: #cedebd; } diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/iegradient.css b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/iegradient.css new file mode 100644 index 0000000..6d4b80e --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/iegradient.css @@ -0,0 +1,3 @@ +tr.ricoLG_hdg .ricoLG_cell, tr.ricoLG_hdg th, tr.ricoLG_hdg td { /* td/th required for IE */ + Filter: progid:DXImageTransform.Microsoft.Gradient(gradientType=0,startColorStr=white,endColorStr=Gainsboro); +} diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/ricoCalendar.css b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/ricoCalendar.css new file mode 100644 index 0000000..18c3ad4 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/ricoCalendar.css @@ -0,0 +1,112 @@ +/* ricoCalendar */ + +div.ricoCalContainer, div.ricoTreeContainer { + position:absolute; + z-index:9999; + font-size:8pt; + left:0px; + top:0px; +} + +table.ricoCalTab { + border:1px solid #666666; +} + +table.ricoCalTab thead a { + border:1px solid #D4D0C8; + text-decoration: none; + color:black; +} + +table.ricoCalTab thead img { + border:none; + padding-left: 0.3em; + padding-right: 0.3em; +} + +table.ricoCalTab thead a:hover { + border:1px solid #666666; + cursor:pointer; +} + +table.ricoCalTab thead td { + background-color: #D4D0C8; + font-weight: bold; + text-align:center; + padding: 2px; +} + +table.ricoCalTab tfoot td { + color:#FFF; + text-align:center; + background-color: #666666; + padding: 2px; +} + +table.ricoCalTab tfoot span { + text-decoration: underline; + cursor:pointer; +} + +table.ricoCalTab tbody { + background-color: white; +} + +tr.ricoCalDayNames td { + font-weight: bold; + padding: 0px 2px 0px 2px; + text-align:right; +} + +td.ricoCal0, td.ricoCal1, td.ricoCal2, td.ricoCal3, td.ricoCal4, td.ricoCal5, td.ricoCal6, td.ricoCalToday, td.ricoCalEmpty { + text-decoration:none; + text-align:right; + width:3em; +} + +/* Monday-Friday */ +td.ricoCal1, td.ricoCal2, td.ricoCal3, td.ricoCal4, td.ricoCal5 { + cursor:pointer; + color:black; +} + +/* Sunday, Saturday */ +td.ricoCal0, td.ricoCal6 { + cursor:pointer; + color:#999; +} + +td.ricoCalToday { + cursor:pointer; + color:red; + font-weight:bold; +} + +td.ricoCalWeekNum { + background-color: #D4D0C8; + color:black; + text-align:center; +} + +.ricoCalMenu { + position:absolute; + background-color: #FEE; + border-bottom:1px solid #666666; + border-right:1px solid #666666; +} + +.ricoCalMenu td { + border-top:1px solid #666666; + border-left:1px solid #666666; +} + +.ricoCalMenu a { + display:block; + text-decoration:none; + color:black; + cursor:pointer; +} + +.ricoCalMenu a:hover { + background-color: #FCC; +} diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/ricoGrid.css b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/ricoGrid.css new file mode 100644 index 0000000..6760ce6 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/ricoGrid.css @@ -0,0 +1,125 @@ +div.ricoLG_outerDiv { + position:relative; + /*border:thin solid blue; /* for debugging */ +} + +div.ricoLG_innerDiv, div.ricoLG_frozenTabsDiv { + overflow:hidden; + margin:0px; + padding:0px; + position:absolute; + top:0px; +} + +div.ricoLG_scrollDiv { + overflow:scroll; + position:relative; +} + +div.ricoLG_scrollTabsDiv { + position:absolute; + top:0px; +} + +div.ricoLG_resizeDiv { + position:absolute; + top:0px; + width:1px; + z-index:2; + background-color:blue; +} + +div.ricoLG_highlightDiv { + position:absolute; + border: 2px solid black; +} + +.ricoLG_table { + margin: 0px; + padding: 0px; + border-right: 1px solid silver; + border-top: 1px solid silver; +} + +.ricoLG_table th, .ricoLG_table td { + border-left: 1px solid silver; +} + +table.ricoLG_bottom { + border-top-style: none; +} + +.ricoLG_evenRow { } +.ricoLG_oddRow { background-color: #EEE; } +.ricoLG_selection { background-color: #cedebd; } + +div.ricoLG_col { + overflow:hidden; + width:100px; +} + +.ricoLG_top div.ricoLG_col { + position:relative; +} + +.ricoLG_top div.ricoLG_Resize { + position:absolute; + width:5px; + height:100%; + top:0px; + cursor:e-resize; +} + +.ricoLG_HdrIcon { + padding-left:2px; + padding-right:2px; +} + +.ricoLG_bottom div.ricoLG_cell, .ricoLG_top th, .ricoLG_top td { + border-bottom: 1px solid silver; +} + +div.ricoLG_cell { + overflow:hidden; + height:1.2em; + padding-left: 3px; + margin: 0px; + font-size: 10pt; + padding-top:3px; + padding-bottom:3px; +} + +div.ricoLG_messageDiv { + position:absolute; + z-index:200; + border:1px solid green; + background-color:white; + font-weight:bold; + font-size:larger; + color:navy; + text-align:center; + padding:4px; +} + +p.ricoBookmark { + margin-bottom: 3px; + font-size: 10pt; +} + +div.alignleft { + text-align: left; +} + +div.aligncenter { + text-align: center; +} + +div.alignright { + text-align: right; +} + +span.ricoSessionTimer { + background-color:black; + color:white; +} + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/ricoLiveGridForms.css b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/ricoLiveGridForms.css new file mode 100644 index 0000000..e43e729 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/ricoLiveGridForms.css @@ -0,0 +1,81 @@ +/* ricoLiveGridForms */ + +span.ricoSaveMsg { + background-color:yellow; +} + +span.ricoSessionTimer { + background-color:black; + color:white; +} + +div.ricoLG_editDiv, div.ricoLG_editResponseDiv { + color:#000; background:#E8ECF3; + overflow:auto; + padding:8px; + border: 1px solid navy; + position:absolute; + font-size: 10pt; + z-index:300; + top:0px; + left:0px; +} + +form .ricoEditLabel, form .ricoEditLabelWithHelp { + font-weight: bold; + text-align: left; + padding-right: 1em; +} + +form .ricoEditLabelWithHelp { + color: navy; +} + +form { + margin:0px; +} + +.tabHeader { + height: 1.8em; + color : #AAA; + background: #D8E0F2; + font-weight : bold; + float: left; + display: inline; + margin-left: 2px; + margin-right: 2px; + text-align: center; + white-space:nowrap; + overflow:hidden; +} + +.tabHover { + color : #666; + cursor: pointer; +} + +.tabSelected { + color : #444; + background: #CFD4E6; + cursor: auto; +} + +.tabContentContainer { + clear:both; +} + +div.ricoLG_editDiv .tabContent, div.ricoLG_editDiv .noTabContent { + color:#000; background:#CFD4E6; + overflow: hidden; + padding: 4px; + white-space:nowrap; +} + +div.ricoLG_editDiv .noTabContent { + float:left; /* required by IE7 */ +} + +span.ricoLookup { + display:none; +} + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/ricoMenu.css b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/ricoMenu.css new file mode 100644 index 0000000..b694c79 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/ricoMenu.css @@ -0,0 +1,95 @@ +/* ricoMenu */ + +div.ricoMenu, div.ricoMenuSafari { +position: absolute; +z-index: 100; +border:1px solid #666; +padding:2px; +cursor:default; +visibility: hidden; +} + +div.ricoMenu, div.ricoMenu div.ricoMenuHeading, div.ricoMenu a { +background-color:menu; +color: menutext; +text-decoration: none; +font-family:tahoma,arial,helvetica,sans-serif; +font-size: 8pt; +display:block; +} + +div.ricoMenuSafari, div.ricoMenuSafari div.ricoMenuHeading, div.ricoMenuSafari a { +background-color:#EDEDED; +text-decoration: none; +font-family:tahoma,arial,helvetica,sans-serif; +font-size: 8pt; +display:block; +} + +div.ricoMenu div.ricoMenuHeading{ +padding: 1px 0px; +font-weight:bold; +} + +div.ricoMenuSafari div.ricoMenuHeading{ +padding: 1px 0px; +color: black; +display: block; +font-weight:bold; +} + +div.ricoMenu .enabled { +position: relative; +} + +div.ricoMenuSafari .enabled { +color: black; +} + +div.ricoMenu .enabled, div.ricoMenu .enabled-hover, div.ricoMenuSafari .enabled, div.ricoMenuSafari .enabled-hover, div.ricoMenu .disabled, div.ricoMenuSafari .disabled { +padding-left: 1em; +padding-top:0.1em; +padding-bottom:0.1em; +z-index: 101; +} + +div.ricoMenu .disabled, div.ricoMenuSafari .disabled { +color: #999; +} + +div.ricoMenu hr{ +height:1px; +margin:1px; +border:0; +color: menu; +background-color: menu; +} + +div.ricoMenu .enabled-hover, div.ricoMenu .ricoSubMenuOpen { + background-color: Highlight; + color: HighlightText; +} + +div.ricoMenuSafari .enabled-hover, div.ricoMenuSafari .ricoSubMenuOpen { + background-color: #1657B8; + color: white; +} + +div.ricoMenu .ricoSubMenu, div.ricoMenu .ricoSubMenuOpen, div.ricoMenuSafari .ricoSubMenu, div.ricoMenuSafari .ricoSubMenuOpen { +padding: 1px 0px; +display: block; +font-weight:bold; +z-index: 101; +position: relative; +} + +div.ricoMenu div.ricoMenuBreak, div.ricoMenuSafari div.ricoMenuBreak { +height:1px; +margin:3px 0 3px 0; +padding:0; +background-color: #AAA; +width:100%; +line-height:5px; +overflow:hidden; +} + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/ricoTree.css b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/ricoTree.css new file mode 100644 index 0000000..33a457c --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/ricoTree.css @@ -0,0 +1,42 @@ +/* ricoTree */ + +div.ricoTreeContainer { + background-color:#cedebd; + padding:4px; + border:1px solid black; + top:0px; + left:0px; + position:absolute; + z-index:9999; +} + +div.ricoTree { + border:thin inset; + overflow:auto; + background-color:#FFF; +} + +div.ricoTree p, div.ricoTree a { + margin:0px; + padding-left:0.3em; + white-space:nowrap; +} + +div.ricoTree a { + cursor:pointer; + text-decoration:none; +} + +div.ricoTree a:hover { + background-color:#EEE; +} + +div.ricoTree img { + margin:0px; + padding:0px; + display:block; +} + +div.ricoTree * { + font-size:8pt; +} diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/tanChisel.css b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/tanChisel.css new file mode 100644 index 0000000..706437e --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/tanChisel.css @@ -0,0 +1,36 @@ +tr.ricoLG_hdg .ricoLG_cell, tr.ricoLG_hdg th, tr.ricoLG_hdg td { /* td/th required for IE */ + background-color:#e0e0c0 !important; + vertical-align:middle; +} + +tr.ricoLG_hdg div.ricoLG_cell { + border-top: 1px solid #F0F0E8; +} + +.ricoLG_bottom div.ricoLG_cell, .ricoLG_top th, .ricoLG_top td { + border-bottom: 1px solid #D8d0c0;; +} + +.ricoLG_table th, .ricoLG_table td { + border-left: 1px solid #F0F0E8; + border-right: 1px solid #D8d0c0; +} + +div.ricoMenu, div.ricoMenu div.ricoMenuHeading, div.ricoMenu .ricoSubMenu, div.ricoMenuSafari, div.ricoMenuSafari div.ricoMenuHeading, div.ricoMenuSafari .ricoSubMenu { + background-color:#f0f0e0; +} + +div.ricoMenu, div.ricoMenu div.ricoMenuHeading, div.ricoMenu .ricoSubMenu, div.ricoMenu .ricoSubMenuOpen, div.ricoMenuSafari, div.ricoMenuSafari div.ricoMenuHeading, div.ricoMenuSafari .ricoSubMenu, div.ricoMenuSafari .ricoSubMenuOpen { + border-top: 1px solid #F0F0E8; + border-left: 1px solid #F0F0E8; + border-bottom: 1px solid #D8d0c0;; + border-right: 1px solid #D8d0c0; +} + +.ricoLG_table { + border-style:none; +} + +div.ricoLG_selection { + background-color:#e0e0c0; +} diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/warmfall.css b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/warmfall.css new file mode 100644 index 0000000..1af5155 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/css/warmfall.css @@ -0,0 +1,63 @@ +/* ------------------------------------------------------- +Based on warm fall table design +Author: Mya Leigh +Theme: A Warm, Fall Table - Easy to Read +URL: http://www.myaleigh.com + ------------------------------------------------------- */ +.ricoLG_table { + border-top: 1px solid #84785e; + border-right: 1px solid #84785e; +} + +tr.ricoLG_hdg .ricoLG_cell, tr.ricoLG_hdg th, tr.ricoLG_hdg td { /* td/th required for IE */ + background-color: #a24116 !important; + color: #ffffff !important; +} + +.ricoLG_table th, .ricoLG_table td { + border-left: 1px solid #84785e; +} + +.ricoLG_bottom div.ricoLG_cell, .ricoLG_top th, .ricoLG_top td { + border-bottom: 1px solid #84785e; +} + +tr.ricoLG_hdg .ricoLG_cell { + background-color: #a24116; + border: 0; + color: #ffffff; + padding: .75em; + font: "Verdana", Arial, Helvetica, sans-serif; + font-weight: bold; +} + +div.ricoLG_outerDiv a:visited, div.ricoLG_outerDiv a:link, div.ricoLG_outerDiv a:active { + color: #101011; + text-decoration: none; +} + +div.ricoLG_outerDiv a:hover { + text-decoration: underline; +} + +div.ricoLG_outerDiv tbody a:visited { + color:#444; +} + +.ricoLG_oddRow { + background-color: #fffce1; + color: #101011; +} + +.ricoLG_selection { + background-color: #a24116; + color: #ffffff; +} + +caption { + text-align: left; + font-size: 100%; + padding: .75em; + color: #000; +} + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/export-owc.html b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/export-owc.html new file mode 100644 index 0000000..8819eca --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/export-owc.html @@ -0,0 +1,34 @@ + + +Export + + + + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/export-plain.html b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/export-plain.html new file mode 100644 index 0000000..b158c58 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/export-plain.html @@ -0,0 +1,28 @@ + + +Export + + + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/aline.gif b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/aline.gif new file mode 100644 index 0000000000000000000000000000000000000000..7f5cb4346e9fa6b5522328ba104c475b02fb3c68 GIT binary patch literal 47 wcmZ?wbhEHb)M8{}XkY+=|NsB%fM}420~23M|H{*E`4`XGa;tmuyt<8 literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/calarrow.png b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/calarrow.png new file mode 100644 index 0000000000000000000000000000000000000000..acdcfed97b5a1f46d3423708909df78743d87dde GIT binary patch literal 917 zcmeAS@N?(olHy`uVBq!ia0vp^sz5Bn!3-o{+do%fU|?nl@Ck7}aNxlI|Nk2r8i3;e z&!jOh%mgwFS$q7nq1_p*n3~40?7=n&AF*U4`2w>C; z)o?R*4B5DdVS`r6;svWDBmx9nR~h{AD3xBQ=z79!g_4t*5xC%}qXZH5? zHa9mH6&0O#bc~6K`Om;$Y;3HquCA!4$iTqxkC6#T;s=U9Sy)9FL>P2H%0PB9ur?$p z^rcAhIIUXurhvowjE``$gNd*>r;UFn%UQuQl2xso36jhz49!oUT(I^jV`fSW2w<${ zcv|GcR>S(RF!^SLcXLMJ>^FAHZ@$_X%TuuXenJs1e{FGEL3wIQI=hfb{{$1E0#+UY g!5K4W3h;!)aBwYLw3v&7gPWb3XZ4!3>l7KR0p2rH+5i9m literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/close.gif b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/close.gif new file mode 100644 index 0000000000000000000000000000000000000000..65c5f16ff6c1eb9e5b9ec77e5f03de1fc041c443 GIT binary patch literal 111 zcmZ?wbhEHb6kyo|Nk>EFf=qYI5;@CxVQk>K%n@O1x)LJNRV0vW)q2B zcSIFVX&zr}5hc+&V_uo3VgQr$)44A=>Vki5Dq^2+8htJD>9<7(5ZZ}vfiVO*5cq@8>HBXNhWk9<>-=+m;M~a*SNBqywkaMy z{Ct=^cHWmTzL#E=w-Sj&GMP-JQf+N*>2x}i$#isdbaizN4-XFx4(4*XY&L6mybTSl z(?k7bzt>kcH`m|3nPwtKBt!~uCT4O>!lX5Ro# zjV%a;a43bezzs8e+o+(M0*Q-h({89c|L zVxzDP2dIG}c#RVQ6-)pR7?2j0C=eB~5EjgU7<*N*kR7~%8`o-LAxdPAq!BH$L~IBN zsUQaUhF6$_8;C|3WI|ow51=tBVB#L&Iqq?QVWB063=YAHy&=BPOmq)zK@*TVVn(jW z63s(eNC=Uj2JX>IScIpzK9(7`7IMH3LLdSXrFf1@>`)AV{}X1cUebY)k&*H7@j{_c zEEX%3%KZF%wOZZS*r?TN^?JS0XhczDJ6kg|v)=po!!fcjVa5vM2o5R!FPu$2A#2I> z&&@37qs0EB{)?yP-GBGdjp-}7{LU`-sQ=xI(xe?PoTjg}rO7C2w3i-G(^Tj6^0RFF z?8mz_cI(gWHQ(2ixU_PtW$fDLiQb<2$1JAo3yOpP{7t4!>*L-zir*n0& ub&by4k5;;S`ino_7e_x#rRsZ1`GvmT(Qk)}Kl4kzdHddlg}G%Y>goz1`(bFP6gXzIsU#~{__0L`7DypQ#`uvHxfE>( z6}5%*F_Z*-wG0G7(9Xa{C=nFummm8#D{Llh;)>Giz1j7%3v;>ezVpt#@7y=xo|Ekz zu_{zy9grnCem6e<pymOQkPq_~F4A)1~8RRzz_r#pi-TyYdg z_z;&!5*!1J1CLcNePXG?NrQTIzrB!`{ped0buXbwQ0T%%N!|hRAZV6GopPJ_t;v>+ zes5#8*u(&)gL@zkkkZ*-$3}BD`aH}`qrB1u>hZVXfB@>k{g2-qp;i}E4`0v%)lT^? z6ZuwIE_cDO$;`knig4ZT-Bq+T6Q>?XrYhw%DyqNek_R!4)gPZ|c^3_fTM Z_C9ZnC46tIVyDTGi?`-S4(mFO{sT|s+J685 literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/drop.gif b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/drop.gif new file mode 100644 index 0000000000000000000000000000000000000000..afce892c6cbaf6d6ab2de4d71c9005ae6b0584dd GIT binary patch literal 102 zcmZ?wbhEHbSOWl&yb%Hb literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/filtercol.gif b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/filtercol.gif new file mode 100644 index 0000000000000000000000000000000000000000..2e9382829419239c42ce2d23c94ea9e0452d42a8 GIT binary patch literal 293 zcmZ?wbhEHbdun>KCQw{PFEW5>2_+xG3-x2~?P)vH%OeE9J2;lthC-Ip$1x^m^p+_`httXVU8 z^5jpSKHa%CMpunI5vI^uU1~w;$2?ZW9|N2g(TvBdO5ou|7 ztl0U-!M-U`@dJxS&#BNK&N*E3oSlu$__$;kmihkSRgX1P?1Sy=M{(ue&dBu`J7oiwE zLm_^&>L7&p2P$Z7(*rKjfHaF4szI?4!GPfLxz`KfexB#+yeVG3IC<{+Vam{N3L}ZX zBu)u-NwR^lx3S(j7#bQ%rBWj!Bk6QHlgVVW*<3D{&*w{}((LT)^z?M0Q1Dxc&&}=9 zihc7RyPNy_yRTl}XCfg|A_F)RGYOM28I#9577`&9G9iyoSxJ;s$&@@+vXL06kr_GG zPU>VH5CJKK3Or$t1k5bV%52OY`LGvZ6*ggy^tcvfRW@ahYVcZ&)!2+ZR*JJao3lru z5Duk~7Wu&m5}*PGb$A zuP_HU5REd(gu2KdK?5paLJ#m9_c*}t*b+nrhhW9t5npU3x`(!)2}m6=BUfaJ<{>R4 zgh)^W_vj@o!c(XZGDB-22mBxeA|O$U=eWcU#Q^v}Va95W#>(aL($Z43TCLS;J3Bkg zX0zRHcRHPJx7+LW`u+Z3Fz`PI_4>0UNy3NY8tOWwWXJlXv$lHm=dTyd<6D)<`6Fi^o&GwrT3kJ~-1@jydU&O>*!jfAXzCw)DYwi3 literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/folderopen.gif b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/folderopen.gif new file mode 100644 index 0000000000000000000000000000000000000000..c16e11b1b35e55a49e4969ad1c29e94dc554908b GIT binary patch literal 909 zcmX9-U4)cj6h0So@hw{#X{_DZ*cCPGRp+8cWOrjL8J0|U8B5M}>SBvYpDu=`r0g0U zT{PN$FJg^|h^5-K%~2G)T{OhXvZ5WLAv!(p+sk-=&+~V_Iev2L@S&Lj%F%BMBaOc_ zPAPV2x`gp{>GAvROeT{gNq>KTHk-}ma`}9Ibab>(D3r_PQmHgKIaw?gy_)*;^cv0C z5C6Hgyt%pd{Ml_L5+WrsfHN_ZFe#HUdAwsG5mF%&^7xdML`juQ$zvrOiIEzakz?(o zPUZm-kV2@y6ZS~J%)+e9#_W*~dl6P)6ZS}tYf)BZQ}(C^ufInRs*yHR@sxL%|t52T{Q&Y{LO+ zpa@<=BA|i^-~j{D;t~aFsvg6F84zP{rXI6{H*n+HTs=mK?2$C0MV5#SAt4pS0N?Nm zb8rLED1%I>i~JEZpaLfJ0MBuc0}PKXL1b_UR_q<|#b%;=XbYNv)DbgsMV4qD(n3Or z1T}DvUcw?gh58^fv=(x}4?-XU5~X;KOYBe#fd3O_tRB%wrBa!lovqbsjYgy0Zns*k z_4V~mr?auKv9-0;?RI;;p8wfyHXo*G8a^B+j}vCBFvf65;lD7RTp;hupIB^8T6wgZ9VyTfBbB2UJuTEXe5^htE<1hAH8>K&)zFZy71}g>7g^PU%e=Nu1~zF?-<%e GNB#k)k+;wQ literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/grayedout.gif b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/grayedout.gif new file mode 100644 index 0000000000000000000000000000000000000000..ead27afc6c6883ca9b1ea0b88b2af8df279bcac5 GIT binary patch literal 2983 zcmdUq`#%%Ab`TD$GulM8g!{_n-oOiUhu)GZxH2^#S0FH2W?f?MJ z0}KEHgm+K*d_IrIJfFgciic2Aj>^U~dQ!wqRnj*Vors zLbC)V2;szHt*)-F3B0g%A>Y0UL)bJb z?GIEzQ-u;h6TH4AIDd*GT!$l&a9u7}_`ClT#Q0zU6!zrbr%B1rp1(**O-s*snVFTH zlbe_S3jVsF5K&ZIQd(ACQCU@8gRHH4Q{V6w)rfAwV4GW7+uA!i-@X6vv8%hMw-1N! zA0QA1hlWQ!jgrR3Ka(dWDO1xkvtQ=szkd6^u=s;YTl)FyH=VJ(!dzWjXR$Xpn_Jsl z9v>hoq2lni_#;eQR__M>ZAo{Mw5C&m1FE$5g(5I`8jsTKkprjz0J@pq9nPw|BjSr? z{9swyc3tm7Ybx6;7+&9%^o>UDHmhkV}m|{CN?;b=g`kY;dB+u3~ikL{(4-E9bS`@>n6v zhd2H>pK-lcohI|H-LwA6``EH;X_B#Fb6r|1pG~%8Lnny)&Najnf#C~8^|P6~Pi&ct zp;FCPxh}0I$uroqA@mMP?a#T+>ymc|vzss0*jVaE|J*hkFVm#;B}liQ{gw5l8zwdk z^5e+O;_fR9BepkR(k9zOjrgbIHbI^Rp8IccIb0@3K`n8fdtMD99`&OLw8yO47qV9s zuPSaO<)C(vwS%f2V{Yj?@38L_6%ji#uQLzT>Pq^ObhI)?4Z;ahRDEhV;D7+@+|B>? zRAUKW1~XYwm`_*WDSnSB-xcJ`hjL!wG*ay3sT%3d^!&2Si!wE;xgNW#za-CtmdkS- zBrG%cUrhjXNgV0J-pvzFkXD8-L*CwfJ?XEDDA4@->1?5XON~x8sQ%EcctD$@&f{5> zLSPZd3{YMCpl|U5JpN1@6prf64JyrnCI?liKRr}}$P05?s=QzCOGU1LlvI&rw#b^Q zS~v|^RzkN7h>mKk392>Ql&C4mTAb7`fxJWB$$NgYS~sTI9{#Jovl3oY_2#QYC>9f} zq!H72NwOY^4TsZfek{PNp3K~Brsk5O;I-vlxyKrs(nKB~N38|5BirD)?ZGIKDrKX# zHi|@72T;DC7M(pLG0X1~lia#n1i>Dn;?!Z&hB%d^d*S$)gcMY#PIJNi^6}XvCQ;2} z>K75)c7uu2#1-fdqIm`pc{|=CiUiV?2v(-Yvky;qG@!yF)2P`+U?QtXp)Z6VRMQWsgsRM9k^#Uq)rZP#y{8} z8Z#Ic-PSl8${u8XO%XlK{+{T$ul4&G2BnUYBevB2c{(yIXex!k!Qg-mtta5R_fy*l z^$im3Jpqi(O#&p296FEC|7p4WzR@jq95WTyzHsyr8A%DGAQ%*F$^9TA;fqxG9CY6l zSK^cYUm!mHC;<^LHy_fr?a(OeZjD`9olPM3|j*5 zg9E##SI+jH)vxl$tbV2Lhn|9|QC+C0 zrHgN)E_C0LFjcft$}|c#|E0tZ$9Jo4E+^USEtO7k=+RI@C0U;;mC3{R9JPA*Z1r*J z!Rzv!8QKq@dl5C{F!)}>xRn>ad&?AY4t>V(m6Sl2G9_~L-|{UhsSi@hRDL+%tSBpK zF~l-eHXe6ob0rK8?>KM?&djcMsnA2iQoZ@+sK9GExkS7~!=k2{DZ18wH~nJ;f+44@xme%(fm7)IZ*0Y~uH|uEIz3Z*tSsoZ9Y# zA^O^sv6pU54JKT#t75@qw4NF2F$U?^3inEcj=z!}4=GkrHtwNBqGWSuKGBX7xL|od zP{qCD1jnIU`+!9wPiimehmgn4e10qHU+b+i;PU=?&YKUB`qw`yk!OdlH0E^bmRJt@rcNgGhlGgrbOMXqD$1Jx4kNEG$a{4x5(D^GqNjWo?aeyw zJ&}e=32^zQG_}!ZF@#FHtr=GRp@QVwbCt@xsDi#p>j9^PlF&nnl|8xIHDX2eN6PX^3IYNWX)`sZ3=d$tD)d4Gqk9ZktOpjKz4{QXeZ^o2_x{NBVmN zwVEu<-E!P?GcZM5O#eY0D0$)6B`e!|c}5zyLL3dsDmrhcGvcv__4(v1l`(Q|$uu!8 zBKQsq<)Lh$t6ZwPZexLxbF z|Bj2K{rtn#<~l!@S~s0}HzR6D=gfT4Bg3E?QCLmhaMk_26xaK-zNVQq{o!X9E{g=> z&bw#L#1ysum odNc-lEFY@Z0yUU`8g4*OD8h^_U?yHLvly5~{!W;jqBy|%KZmgqnE(I) literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/left.gif b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/left.gif new file mode 100644 index 0000000000000000000000000000000000000000..f65207578a00bc16df73d4f3f7d35177f4698836 GIT binary patch literal 105 zcmZ?wbhEHb)h!xmq)CeDZt2J4FIY*5X=Ao literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/link.gif b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/link.gif new file mode 100644 index 0000000000000000000000000000000000000000..a679f4d33f80ec11cbac551069bf5583196a7fde GIT binary patch literal 954 zcmX9-OGuPa6h1l=jUeSDOs`Q)H;OKbgQz4?gQ){eSmC0T26llxa~76`sETc44^B^S#bL9qIPwrZc-JLBA**f&T@5 z3a|@;X^fB44`oD%H}`VuOKobnatm@Bj-pQsU!1GS;z^AkP4ZvWF@C0N~&a7 z8;OxxhzLkWsK668Pr%HMS(ugCJRkPXu{c)8=IL?mghg0|&8xv{r!2~dd=^8ZoB^L!mQx4n>7V zVH*xm14Zx}CITv$03I+P%`Z_PDq=n?m;o{Ns$xDncmp@C)x><1$R0@}T4agX5E4>B z4Db!FFb6jfjWWoDI?wMxLsY3J9@>H?Aa%ryT#+T3 zhqRCoB0&w@qnEGhJGOjT9ePJ2m`d`T0AAl2b^BTLe)spP&d81}W#>xfT>D6CP2$JPr{i;X8}IKqmTo-zdZ_tmd&8&rqqazI z&D!nS^7^*O-{kV%4;RlLA1+i*^@Bb zb@1`$#mvl1tJRvFoo%<kR((C_yb7Z>wYlS@lSvK7Dc{OH@+ z+0m!nO%*W_7YV>sRK-+WB~-HBsfn4mNtk4PsxIc@F5!~3QbR1nLn0(ur+7+aK?Kr- z3Z7_I0#!9tR}IyyeC*BCO~W)RJ=f;yuHl+h4X-WKLnAb6rKNgmq-GV0aFimg^1}%U zsK8Li+hT(QhMPsT1SK1H3%9HeQQ%<_menn4JS`GK#TlN9sA3e`IG_eacrA%Qg$eM$ zKw4c=;NhM%EX+X6KEktRhc~#nj`XZil08WiEm;y9A(09(;2W=)!wsS-Lni7fe+4b5 zz?2^FoO=!!SzAJ6IE0mb5?^g5-J>lufz*kaT*;E=kroLN2{pKU~UftbX>uxClbwfI}4( z9E6%rP$`PoGdGKwG8BqnI~h*VX{ z>B+|rFI2=tTqFQjQ592hl~BogrzU3NCSj8Gsk)epyM#;DN)53P4~dXuo#H8x1rbOS zDtMw<2~^coT{Tp*^07BlHx1LQ^jw>(yM}94HN3V^4~@{Qm6qzMk(yN~!cmH}$`2s1X3qvawSWeM_MFAB-G%ZUSbhXrM}24twj#} z5P}FKr99`79mN3rpO{&_la1+gy1TnOo6Yw2_KuH_=kxhuu~;sbtJUi4?Cj#=V!dAH zpY#3ww@uTO4<{w-#LS9ugF`9*g*)vH$xDN+gZ+n29D{C4pA=vnvLgI8Oh-h6p} MRUiMo(v{o)0K7tw&;S4c literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/nodelast.gif b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/nodelast.gif new file mode 100644 index 0000000000000000000000000000000000000000..3fe0a7e16c9279b26b6d57be0fcf67a148c87aad GIT binary patch literal 838 zcmXAoJ!_Lu6vxldAwq|SLLAJXb&5I&XVBsz5nmzDrJE26a=t&f4Ep{4>gsAfZE|hxKwii1JURG! ze0=cn!z&dr5f=%-RaC`PTqRVp-l>V1xJj5~eX1_z;x6HmwNgVY#6uz^S*LhPWI+Vd zgbJQ$RsvNuRaXtwtbFXv)J?-QD?Qid>aO9MRSmB#)I%dQYo(=nYNTcrig1)7t@6VO z38=tO$J=6q1BRPLwFD&_cMG?y4pHD?5th|0YCJ6xL&X`Mi>P80+c=;GMR+ZVK!pkL zz(87EQsCj9H7v|P%s#@iW`{SpxsLR#QIb7L6D?U18zGSjG2k1on8OXCDMKdeDt`qn zsKAsS@SJ-N7+G6FWH^MCeG*@7Cf%bgG=bEKnOw<|=8+Z&5eYT8ria9OKXt> zKZGCxNh!~{WJfUo|0iZv@8r^OINaRa9F0cf@pylKe=?aI9v)7o)1#xK*=%-pb~c~S z^Y7{Q_D<6@<-NlLd$4?_Mv2`+ELw=gFfd>v!*LFH2YcNEvPYwRLLQwe2zE z*YU@n7fVY^P1AHbot2f9ZnxX(^;TC``~Cjb*4D(yM}94HN3V^4~@{Qm6qzMk(yN~!cmH}$`2s1X3qvawSWeM_MFAB-G%ZUSbhXrM}24twj#} z5P}FKr99`79mN3rpO{&Fkej2?XlG|>u0QB@8oBomNt2RO literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/nodem.gif b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/nodem.gif new file mode 100644 index 0000000000000000000000000000000000000000..fcc2d37333116b6a7fdafb7eb099b0fbf16f5f63 GIT binary patch literal 97 zcmZ?wbhEHb6krfzn8?h~(9rPz|9=Js1|X^UlZBCiftf)E$YlV@GcXy=>0inAdcV{h y&KuRqH*8MaDwJnxxm_{k(5@=y&r{V-%~+?@{-rzd%6SH^X6Fa%Bnm|s7_0$apd^X_ literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/nodemlast.gif b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/nodemlast.gif new file mode 100644 index 0000000000000000000000000000000000000000..11ae43a5ae00b76b81e0bf2aa8d2b33efbbb5e53 GIT binary patch literal 125 zcmZ?wbhEHb6krfz*v!Dt(9rPz|9=MJ08pjkPZmZ721W)QkPeU;3@lm(Cp=eAeekN* p_`j$^Uvhd>T*aykg+2Kb&IWtk{95(e)U)Zpf&vd6DN{iPYXB-WAG`nn literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/nodep.gif b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/nodep.gif new file mode 100644 index 0000000000000000000000000000000000000000..5b680136ee9db9cd706b2ef642e89d6edda3989a GIT binary patch literal 133 zcmZ?wbhEHb6krfz*v!Dt(9rPz|9=MD;J|?ca7my_#h)yU3=G^1Iv_!i84N5&1t&dM zPkr#J*7(1uLSJ%v)IB91&8h2VXrB2z>Fyhr+skJywiWMW(K^=S5qIfERMD)-91PX~ DC2=QD literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/nodeplast.gif b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/nodeplast.gif new file mode 100644 index 0000000000000000000000000000000000000000..b87f003154502f8e9f569fefb12d57a5a1ebb515 GIT binary patch literal 130 zcmZ?wbhEHb6krfz*v!Dt(9rPz|9=MJ08pjkPZmZ721W)QkPeU;3@rKvCp=eAeekN* v_`j$^Uvhd>oPv+$)O9m7&lFF%`-bKA@>z>*#XDKFr20=RDO%adz+epk!mc6H literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/resize.gif b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/resize.gif new file mode 100644 index 0000000000000000000000000000000000000000..8efd1b5fae11687458f943a1999ce6ed3903078f GIT binary patch literal 51 ycmZ?wbhEHbWM*JyC}3bv{K>+|z`(?y!vF*zu|^<0bLLDC7bwm$MO2-Y!5RR+BL>s} literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/ricologo.gif b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/ricologo.gif new file mode 100644 index 0000000000000000000000000000000000000000..9b142039bef7c315749505367e55bc8c037d0531 GIT binary patch literal 1105 zcmV-X1g`r>Nk%w1VSfNp0K^smwY;s`-PVwrgno%{b%AB|_VkC6d84bCc`B%zQnhFig2v6qNA&snWB!{-qz98%&oMe|NsANd0YSg{{R30000000000000000 z000000000000000A^8LW000&MEC2ui0Dk~d000I5pe2r$^fXnfu59bRa4gSsoi>j| z?qh`7z@TtQbTuNp(WJ<1I-jXY@&T<{udv5%iS2r;Qc>hfE*FuOpLxxWHA?NcoMoEZ z41ejE#QJpJjV#)pJ8&{ZrB4V`%x&cW>i_`%0OrN`SBAe@Ftk2J zP}D`@3I@r(7~obFShIUu5HN^0bLtfiqD^M_RhHe(PQq~x84|!J*)fh1h}>GpVo^D-WE_pXsxT0%svOifPQkkK=M)%xZgI3Ug#|>Yrz&8>0Cd#gQw8wuSAJDi z^lSW1h2F-{=D4g<08B7NrbOQn^-{QJ4{d9}w!L zG9EM=x^P)5$$_SzQXT=Z+$ur5s0wZYmS`d?EpljM3M>*KV=6KBrPq$+37A|^Jr40B z1wl3g#aR^)z)FNVR=9#vGAYSQiY;)n%82_Y*usA2X=tSiP{tr+4F*vt&I}B$XXcwM zgvcZjLuqG&QUN_FCJWe!SRb7$xChq|WcEozpy9a*U<(iq3gA$R1`%f}`7QIIpG3Mq zW`9L?+SMw01~J^9fkoz^qcnuGYN%(bz-V_v7(}I~Q(BQ`1xtQLl~}jVaOx@F!J(MTt)G$Va1Z3PZacacNXSm@9+)l9r$!5COSfrbTKbX`OkBTyms5L)mM_SrR% X&4UkY&u~N%JD6}a+c@aJLkIvni-+cW literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/right.gif b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/right.gif new file mode 100644 index 0000000000000000000000000000000000000000..5517f2bc0c57eaa8fc5b1f58d027ae0e79b7f139 GIT binary patch literal 105 zcmZ?wbhEHbw@-~%V!j>5nyDn1^}}A5n2EM literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/shadow.png b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/shadow.png new file mode 100644 index 0000000000000000000000000000000000000000..7862c9bb23fd861dab3ffdc1511d73421d65a0a7 GIT binary patch literal 3576 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYV2a>i1B%QlYbpRzEX7WqAsj$Z!;#Vf4nJaD4z_MyE9#iRWF{)OWfrBD=NDxcEBHq2o~We)bc&Csi(^Q|oVRy(`#la2 zakw}+@ZbK&;)1NAO^t&5{u3pP92Y6x5}dhJ<#gYrIc2Z!W#>;zm1JOO2)>bH7H(W@ zZES8_ym$Zob7$_JvH559IER7ZK)qW7&=Hc1ObiSuEF26B69g3)7#v0gM+0OuF^pz} z(UM`bR2;1lMr*^-+HkZs9IXw9ZEZN`(x=Fa)&1wU<@J9BoOAJ8}^8TJ#O z-z<7uS0?z$!2R~dZN|lS&vP;`#B?0q9=G?Lp2fU0arxI;C!`d*MM2hE^W87{Y9*iU zcuk;kR&%k!Igoqrm+lbF?w#=b?^e70XY07H-L+I>VPMcZRoJp7|JbkRvlVX7th6~@ k0rbpL%YR(IKGyzY(w^C>%l*A*8&Efcr>mdKI;Vst0C%$>vj6}9 literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/shadow_ll.png b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/shadow_ll.png new file mode 100644 index 0000000000000000000000000000000000000000..cc0665b430c3838bdef71bba52a0acb17c24956b GIT binary patch literal 274 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqEX7WqAsj$Z!;#Vf4nJ zaD4z_MyE9#iRWF{)OWfrBD=NDxcEBHq2o~We)RGa4M;uumf$M@Vpu0swyEf4c| zXNR)%KXU!`kAKC|TX}nzOgJ#1@#oAX54xn~DiRL~m-mS3mKMfoChu@@CJ`sjqq=m1AXa{V&i)22WQ% Jmvv4FO#lyMU1k6P literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/shadow_ur.png b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/shadow_ur.png new file mode 100644 index 0000000000000000000000000000000000000000..cad0f2c75c4ca7478645b0186522e80903f158fc GIT binary patch literal 275 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqEX7WqAsj$Z!;#Vf4nJ zaD4z_MyE9#iRWF{)OWfrBD=NDxcEBHq2o~We)RGaSU;uumf$M>8!7n37T%ft2Z zR$bh&yNb^}`1@XEN07v_yGv9X<(Wb~Lk~(aR~wXHC~$V?eJ0Y=ChBc8HRaNWBb@Cj zeV)ge^Y=V*c(u9w&SU1BACH75MjsWOp3u3XetuW-h309yrpSxk68g5~w*6F~l?dhCYGe8D3oWGWGIAWq$;?3`UWs4{$yd~ eVqj#@VE_V<76vBn9_Hl-y6*7I$v?!zU=0ASUlv;c literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/sort_desc.gif b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/images/sort_desc.gif new file mode 100644 index 0000000000000000000000000000000000000000..b3a681c95431b75e111e29ae7ad6c51607ee7fd7 GIT binary patch literal 76 zcmZ?wbhEHbdhCYGe8D3oWGWGIAWq$;?3`UWs4{$yd~ cVqj#@VE_V<76vA+mik7?E?&u;1Th9{0F68pQUCw| literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/prototype.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/prototype.js new file mode 100644 index 0000000..5906575 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/prototype.js @@ -0,0 +1,3269 @@ +/* Prototype JavaScript framework, version 1.5.1_rc3 + * (c) 2005-2007 Sam Stephenson + * + * Prototype is freely distributable under the terms of an MIT-style license. + * For details, see the Prototype web site: http://www.prototypejs.org/ + * +/*--------------------------------------------------------------------------*/ + +var Prototype = { + Version: '1.5.1_rc3', + + Browser: { + IE: !!(window.attachEvent && !window.opera), + Opera: !!window.opera, + WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1, + Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1 + }, + + BrowserFeatures: { + XPath: !!document.evaluate, + ElementExtensions: !!window.HTMLElement, + SpecificElementExtensions: + (document.createElement('div').__proto__ !== + document.createElement('form').__proto__) + }, + + ScriptFragment: ']*>([\u0001-\uFFFF]*?)', + JSONFilter: /^\/\*-secure-\s*(.*)\s*\*\/\s*$/, + + emptyFunction: function() { }, + K: function(x) { return x } +} + +var Class = { + create: function() { + return function() { + this.initialize.apply(this, arguments); + } + } +} + +var Abstract = new Object(); + +Object.extend = function(destination, source) { + for (var property in source) { + destination[property] = source[property]; + } + return destination; +} + +Object.extend(Object, { + inspect: function(object) { + try { + if (object === undefined) return 'undefined'; + if (object === null) return 'null'; + return object.inspect ? object.inspect() : object.toString(); + } catch (e) { + if (e instanceof RangeError) return '...'; + throw e; + } + }, + + toJSON: function(object) { + var type = typeof object; + switch(type) { + case 'undefined': + case 'function': + case 'unknown': return; + case 'boolean': return object.toString(); + } + if (object === null) return 'null'; + if (object.toJSON) return object.toJSON(); + if (object.ownerDocument === document) return; + var results = []; + for (var property in object) { + var value = Object.toJSON(object[property]); + if (value !== undefined) + results.push(property.toJSON() + ': ' + value); + } + return '{' + results.join(', ') + '}'; + }, + + keys: function(object) { + var keys = []; + for (var property in object) + keys.push(property); + return keys; + }, + + values: function(object) { + var values = []; + for (var property in object) + values.push(object[property]); + return values; + }, + + clone: function(object) { + return Object.extend({}, object); + } +}); + +Function.prototype.bind = function() { + var __method = this, args = $A(arguments), object = args.shift(); + return function() { + return __method.apply(object, args.concat($A(arguments))); + } +} + +Function.prototype.bindAsEventListener = function(object) { + var __method = this, args = $A(arguments), object = args.shift(); + return function(event) { + return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments))); + } +} + +Object.extend(Number.prototype, { + toColorPart: function() { + return this.toPaddedString(2, 16); + }, + + succ: function() { + return this + 1; + }, + + times: function(iterator) { + $R(0, this, true).each(iterator); + return this; + }, + + toPaddedString: function(length, radix) { + var string = this.toString(radix || 10); + return '0'.times(length - string.length) + string; + }, + + toJSON: function() { + return isFinite(this) ? this.toString() : 'null'; + } +}); + +Date.prototype.toJSON = function() { + return '"' + this.getFullYear() + '-' + + (this.getMonth() + 1).toPaddedString(2) + '-' + + this.getDate().toPaddedString(2) + 'T' + + this.getHours().toPaddedString(2) + ':' + + this.getMinutes().toPaddedString(2) + ':' + + this.getSeconds().toPaddedString(2) + '"'; +}; + +var Try = { + these: function() { + var returnValue; + + for (var i = 0, length = arguments.length; i < length; i++) { + var lambda = arguments[i]; + try { + returnValue = lambda(); + break; + } catch (e) {} + } + + return returnValue; + } +} + +/*--------------------------------------------------------------------------*/ + +var PeriodicalExecuter = Class.create(); +PeriodicalExecuter.prototype = { + initialize: function(callback, frequency) { + this.callback = callback; + this.frequency = frequency; + this.currentlyExecuting = false; + + this.registerCallback(); + }, + + registerCallback: function() { + this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); + }, + + stop: function() { + if (!this.timer) return; + clearInterval(this.timer); + this.timer = null; + }, + + onTimerEvent: function() { + if (!this.currentlyExecuting) { + try { + this.currentlyExecuting = true; + this.callback(this); + } finally { + this.currentlyExecuting = false; + } + } + } +} +Object.extend(String, { + interpret: function(value) { + return value == null ? '' : String(value); + }, + specialChar: { + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '\\': '\\\\' + } +}); + +Object.extend(String.prototype, { + gsub: function(pattern, replacement) { + var result = '', source = this, match; + replacement = arguments.callee.prepareReplacement(replacement); + + while (source.length > 0) { + if (match = source.match(pattern)) { + result += source.slice(0, match.index); + result += String.interpret(replacement(match)); + source = source.slice(match.index + match[0].length); + } else { + result += source, source = ''; + } + } + return result; + }, + + sub: function(pattern, replacement, count) { + replacement = this.gsub.prepareReplacement(replacement); + count = count === undefined ? 1 : count; + + return this.gsub(pattern, function(match) { + if (--count < 0) return match[0]; + return replacement(match); + }); + }, + + scan: function(pattern, iterator) { + this.gsub(pattern, iterator); + return this; + }, + + truncate: function(length, truncation) { + length = length || 30; + truncation = truncation === undefined ? '...' : truncation; + return this.length > length ? + this.slice(0, length - truncation.length) + truncation : this; + }, + + strip: function() { + return this.replace(/^\s+/, '').replace(/\s+$/, ''); + }, + + stripTags: function() { + return this.replace(/<\/?[^>]+>/gi, ''); + }, + + stripScripts: function() { + return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); + }, + + extractScripts: function() { + var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); + var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); + return (this.match(matchAll) || []).map(function(scriptTag) { + return (scriptTag.match(matchOne) || ['', ''])[1]; + }); + }, + + evalScripts: function() { + return this.extractScripts().map(function(script) { return eval(script) }); + }, + + escapeHTML: function() { + var self = arguments.callee; + self.text.data = this; + return self.div.innerHTML; + }, + + unescapeHTML: function() { + var div = document.createElement('div'); + div.innerHTML = this.stripTags(); + return div.childNodes[0] ? (div.childNodes.length > 1 ? + $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) : + div.childNodes[0].nodeValue) : ''; + }, + + toQueryParams: function(separator) { + var match = this.strip().match(/([^?#]*)(#.*)?$/); + if (!match) return {}; + + return match[1].split(separator || '&').inject({}, function(hash, pair) { + if ((pair = pair.split('='))[0]) { + var key = decodeURIComponent(pair.shift()); + var value = pair.length > 1 ? pair.join('=') : pair[0]; + if (value != undefined) value = decodeURIComponent(value); + + if (key in hash) { + if (hash[key].constructor != Array) hash[key] = [hash[key]]; + hash[key].push(value); + } + else hash[key] = value; + } + return hash; + }); + }, + + toArray: function() { + return this.split(''); + }, + + succ: function() { + return this.slice(0, this.length - 1) + + String.fromCharCode(this.charCodeAt(this.length - 1) + 1); + }, + + times: function(count) { + var result = ''; + for (var i = 0; i < count; i++) result += this; + return result; + }, + + camelize: function() { + var parts = this.split('-'), len = parts.length; + if (len == 1) return parts[0]; + + var camelized = this.charAt(0) == '-' + ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1) + : parts[0]; + + for (var i = 1; i < len; i++) + camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1); + + return camelized; + }, + + capitalize: function() { + return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); + }, + + underscore: function() { + return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase(); + }, + + dasherize: function() { + return this.gsub(/_/,'-'); + }, + + inspect: function(useDoubleQuotes) { + var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) { + var character = String.specialChar[match[0]]; + return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16); + }); + if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; + return "'" + escapedString.replace(/'/g, '\\\'') + "'"; + }, + + toJSON: function() { + return this.inspect(true); + }, + + unfilterJSON: function(filter) { + return this.sub(filter || Prototype.JSONFilter, '#{1}'); + }, + + evalJSON: function(sanitize) { + var json = this.unfilterJSON(); + try { + if (!sanitize || (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(json))) + return eval('(' + json + ')'); + } catch (e) { } + throw new SyntaxError('Badly formed JSON string: ' + this.inspect()); + }, + + include: function(pattern) { + return this.indexOf(pattern) > -1; + }, + + startsWith: function(pattern) { + return this.indexOf(pattern) === 0; + }, + + endsWith: function(pattern) { + var d = this.length - pattern.length; + return d >= 0 && this.lastIndexOf(pattern) === d; + }, + + empty: function() { + return this == ''; + }, + + blank: function() { + return /^\s*$/.test(this); + } +}); + +if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, { + escapeHTML: function() { + return this.replace(/&/g,'&').replace(//g,'>'); + }, + unescapeHTML: function() { + return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); + } +}); + +String.prototype.gsub.prepareReplacement = function(replacement) { + if (typeof replacement == 'function') return replacement; + var template = new Template(replacement); + return function(match) { return template.evaluate(match) }; +} + +String.prototype.parseQuery = String.prototype.toQueryParams; + +Object.extend(String.prototype.escapeHTML, { + div: document.createElement('div'), + text: document.createTextNode('') +}); + +with (String.prototype.escapeHTML) div.appendChild(text); + +var Template = Class.create(); +Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; +Template.prototype = { + initialize: function(template, pattern) { + this.template = template.toString(); + this.pattern = pattern || Template.Pattern; + }, + + evaluate: function(object) { + return this.template.gsub(this.pattern, function(match) { + var before = match[1]; + if (before == '\\') return match[2]; + return before + String.interpret(object[match[3]]); + }); + } +} + +var $break = new Object(); +var $continue = new Object(); + +var Enumerable = { + each: function(iterator) { + var index = 0; + try { + this._each(function(value) { + iterator(value, index++); + }); + } catch (e) { + if (e != $break) throw e; + } + return this; + }, + + eachSlice: function(number, iterator) { + var index = -number, slices = [], array = this.toArray(); + while ((index += number) < array.length) + slices.push(array.slice(index, index+number)); + return slices.map(iterator); + }, + + all: function(iterator) { + var result = true; + this.each(function(value, index) { + result = result && !!(iterator || Prototype.K)(value, index); + if (!result) throw $break; + }); + return result; + }, + + any: function(iterator) { + var result = false; + this.each(function(value, index) { + if (result = !!(iterator || Prototype.K)(value, index)) + throw $break; + }); + return result; + }, + + collect: function(iterator) { + var results = []; + this.each(function(value, index) { + results.push((iterator || Prototype.K)(value, index)); + }); + return results; + }, + + detect: function(iterator) { + var result; + this.each(function(value, index) { + if (iterator(value, index)) { + result = value; + throw $break; + } + }); + return result; + }, + + findAll: function(iterator) { + var results = []; + this.each(function(value, index) { + if (iterator(value, index)) + results.push(value); + }); + return results; + }, + + grep: function(pattern, iterator) { + var results = []; + this.each(function(value, index) { + var stringValue = value.toString(); + if (stringValue.match(pattern)) + results.push((iterator || Prototype.K)(value, index)); + }) + return results; + }, + + include: function(object) { + var found = false; + this.each(function(value) { + if (value == object) { + found = true; + throw $break; + } + }); + return found; + }, + + inGroupsOf: function(number, fillWith) { + fillWith = fillWith === undefined ? null : fillWith; + return this.eachSlice(number, function(slice) { + while(slice.length < number) slice.push(fillWith); + return slice; + }); + }, + + inject: function(memo, iterator) { + this.each(function(value, index) { + memo = iterator(memo, value, index); + }); + return memo; + }, + + invoke: function(method) { + var args = $A(arguments).slice(1); + return this.map(function(value) { + return value[method].apply(value, args); + }); + }, + + max: function(iterator) { + var result; + this.each(function(value, index) { + value = (iterator || Prototype.K)(value, index); + if (result == undefined || value >= result) + result = value; + }); + return result; + }, + + min: function(iterator) { + var result; + this.each(function(value, index) { + value = (iterator || Prototype.K)(value, index); + if (result == undefined || value < result) + result = value; + }); + return result; + }, + + partition: function(iterator) { + var trues = [], falses = []; + this.each(function(value, index) { + ((iterator || Prototype.K)(value, index) ? + trues : falses).push(value); + }); + return [trues, falses]; + }, + + pluck: function(property) { + var results = []; + this.each(function(value, index) { + results.push(value[property]); + }); + return results; + }, + + reject: function(iterator) { + var results = []; + this.each(function(value, index) { + if (!iterator(value, index)) + results.push(value); + }); + return results; + }, + + sortBy: function(iterator) { + return this.map(function(value, index) { + return {value: value, criteria: iterator(value, index)}; + }).sort(function(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }).pluck('value'); + }, + + toArray: function() { + return this.map(); + }, + + zip: function() { + var iterator = Prototype.K, args = $A(arguments); + if (typeof args.last() == 'function') + iterator = args.pop(); + + var collections = [this].concat(args).map($A); + return this.map(function(value, index) { + return iterator(collections.pluck(index)); + }); + }, + + size: function() { + return this.toArray().length; + }, + + inspect: function() { + return '#'; + } +} + +Object.extend(Enumerable, { + map: Enumerable.collect, + find: Enumerable.detect, + select: Enumerable.findAll, + member: Enumerable.include, + entries: Enumerable.toArray +}); +var $A = Array.from = function(iterable) { + if (!iterable) return []; + if (iterable.toArray) { + return iterable.toArray(); + } else { + var results = []; + for (var i = 0, length = iterable.length; i < length; i++) + results.push(iterable[i]); + return results; + } +} + +if (Prototype.Browser.WebKit) { + $A = Array.from = function(iterable) { + if (!iterable) return []; + if (!(typeof iterable == 'function' && iterable == '[object NodeList]') && + iterable.toArray) { + return iterable.toArray(); + } else { + var results = []; + for (var i = 0, length = iterable.length; i < length; i++) + results.push(iterable[i]); + return results; + } + } +} + +Object.extend(Array.prototype, Enumerable); + +if (!Array.prototype._reverse) + Array.prototype._reverse = Array.prototype.reverse; + +Object.extend(Array.prototype, { + _each: function(iterator) { + for (var i = 0, length = this.length; i < length; i++) + iterator(this[i]); + }, + + clear: function() { + this.length = 0; + return this; + }, + + first: function() { + return this[0]; + }, + + last: function() { + return this[this.length - 1]; + }, + + compact: function() { + return this.select(function(value) { + return value != null; + }); + }, + + flatten: function() { + return this.inject([], function(array, value) { + return array.concat(value && value.constructor == Array ? + value.flatten() : [value]); + }); + }, + + without: function() { + var values = $A(arguments); + return this.select(function(value) { + return !values.include(value); + }); + }, + + indexOf: function(object) { + for (var i = 0, length = this.length; i < length; i++) + if (this[i] == object) return i; + return -1; + }, + + reverse: function(inline) { + return (inline !== false ? this : this.toArray())._reverse(); + }, + + reduce: function() { + return this.length > 1 ? this : this[0]; + }, + + uniq: function(sorted) { + return this.inject([], function(array, value, index) { + if (0 == index || (sorted ? array.last() != value : !array.include(value))) + array.push(value); + return array; + }); + }, + + clone: function() { + return [].concat(this); + }, + + size: function() { + return this.length; + }, + + inspect: function() { + return '[' + this.map(Object.inspect).join(', ') + ']'; + }, + + toJSON: function() { + var results = []; + this.each(function(object) { + var value = Object.toJSON(object); + if (value !== undefined) results.push(value); + }); + return '[' + results.join(', ') + ']'; + } +}); + +Array.prototype.toArray = Array.prototype.clone; + +function $w(string) { + string = string.strip(); + return string ? string.split(/\s+/) : []; +} + +if (Prototype.Browser.Opera){ + Array.prototype.concat = function() { + var array = []; + for (var i = 0, length = this.length; i < length; i++) array.push(this[i]); + for (var i = 0, length = arguments.length; i < length; i++) { + if (arguments[i].constructor == Array) { + for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++) + array.push(arguments[i][j]); + } else { + array.push(arguments[i]); + } + } + return array; + } +} +var Hash = function(object) { + if (object instanceof Hash) this.merge(object); + else Object.extend(this, object || {}); +}; + +Object.extend(Hash, { + toQueryString: function(obj) { + var parts = []; + parts.add = arguments.callee.addPair; + + this.prototype._each.call(obj, function(pair) { + if (!pair.key) return; + var value = pair.value; + + if (value && typeof value == 'object') { + if (value.constructor == Array) value.each(function(value) { + parts.add(pair.key, value); + }); + return; + } + parts.add(pair.key, value); + }); + + return parts.join('&'); + }, + + toJSON: function(object) { + var results = []; + this.prototype._each.call(object, function(pair) { + var value = Object.toJSON(pair.value); + if (value !== undefined) results.push(pair.key.toJSON() + ': ' + value); + }); + return '{' + results.join(', ') + '}'; + } +}); + +Hash.toQueryString.addPair = function(key, value, prefix) { + key = encodeURIComponent(key); + if (value === undefined) this.push(key); + else this.push(key + '=' + (value == null ? '' : encodeURIComponent(value))); +} + +Object.extend(Hash.prototype, Enumerable); +Object.extend(Hash.prototype, { + _each: function(iterator) { + for (var key in this) { + var value = this[key]; + if (value && value == Hash.prototype[key]) continue; + + var pair = [key, value]; + pair.key = key; + pair.value = value; + iterator(pair); + } + }, + + keys: function() { + return this.pluck('key'); + }, + + values: function() { + return this.pluck('value'); + }, + + merge: function(hash) { + return $H(hash).inject(this, function(mergedHash, pair) { + mergedHash[pair.key] = pair.value; + return mergedHash; + }); + }, + + remove: function() { + var result; + for(var i = 0, length = arguments.length; i < length; i++) { + var value = this[arguments[i]]; + if (value !== undefined){ + if (result === undefined) result = value; + else { + if (result.constructor != Array) result = [result]; + result.push(value) + } + } + delete this[arguments[i]]; + } + return result; + }, + + toQueryString: function() { + return Hash.toQueryString(this); + }, + + inspect: function() { + return '#'; + }, + + toJSON: function() { + return Hash.toJSON(this); + } +}); + +function $H(object) { + if (object instanceof Hash) return object; + return new Hash(object); +}; + +// Safari iterates over shadowed properties +if (function() { + var i = 0, Test = function(value) { this.key = value }; + Test.prototype.key = 'foo'; + for (var property in new Test('bar')) i++; + return i > 1; +}()) Hash.prototype._each = function(iterator) { + var cache = []; + for (var key in this) { + var value = this[key]; + if ((value && value == Hash.prototype[key]) || cache.include(key)) continue; + cache.push(key); + var pair = [key, value]; + pair.key = key; + pair.value = value; + iterator(pair); + } +}; +ObjectRange = Class.create(); +Object.extend(ObjectRange.prototype, Enumerable); +Object.extend(ObjectRange.prototype, { + initialize: function(start, end, exclusive) { + this.start = start; + this.end = end; + this.exclusive = exclusive; + }, + + _each: function(iterator) { + var value = this.start; + while (this.include(value)) { + iterator(value); + value = value.succ(); + } + }, + + include: function(value) { + if (value < this.start) + return false; + if (this.exclusive) + return value < this.end; + return value <= this.end; + } +}); + +var $R = function(start, end, exclusive) { + return new ObjectRange(start, end, exclusive); +} + +var Ajax = { + getTransport: function() { + return Try.these( + function() {return new XMLHttpRequest()}, + function() {return new ActiveXObject('Msxml2.XMLHTTP')}, + function() {return new ActiveXObject('Microsoft.XMLHTTP')} + ) || false; + }, + + activeRequestCount: 0 +} + +Ajax.Responders = { + responders: [], + + _each: function(iterator) { + this.responders._each(iterator); + }, + + register: function(responder) { + if (!this.include(responder)) + this.responders.push(responder); + }, + + unregister: function(responder) { + this.responders = this.responders.without(responder); + }, + + dispatch: function(callback, request, transport, json) { + this.each(function(responder) { + if (typeof responder[callback] == 'function') { + try { + responder[callback].apply(responder, [request, transport, json]); + } catch (e) {} + } + }); + } +}; + +Object.extend(Ajax.Responders, Enumerable); + +Ajax.Responders.register({ + onCreate: function() { + Ajax.activeRequestCount++; + }, + onComplete: function() { + Ajax.activeRequestCount--; + } +}); + +Ajax.Base = function() {}; +Ajax.Base.prototype = { + setOptions: function(options) { + this.options = { + method: 'post', + asynchronous: true, + contentType: 'application/x-www-form-urlencoded', + encoding: 'UTF-8', + parameters: '' + } + Object.extend(this.options, options || {}); + + this.options.method = this.options.method.toLowerCase(); + if (typeof this.options.parameters == 'string') + this.options.parameters = this.options.parameters.toQueryParams(); + } +} + +Ajax.Request = Class.create(); +Ajax.Request.Events = + ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; + +Ajax.Request.prototype = Object.extend(new Ajax.Base(), { + _complete: false, + + initialize: function(url, options) { + this.transport = Ajax.getTransport(); + this.setOptions(options); + this.request(url); + }, + + request: function(url) { + this.url = url; + this.method = this.options.method; + var params = Object.clone(this.options.parameters); + + if (!['get', 'post'].include(this.method)) { + // simulate other verbs over post + params['_method'] = this.method; + this.method = 'post'; + } + + this.parameters = params; + + if (params = Hash.toQueryString(params)) { + // when GET, append parameters to URL + if (this.method == 'get') + this.url += (this.url.include('?') ? '&' : '?') + params; + else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) + params += '&_='; + } + + try { + if (this.options.onCreate) this.options.onCreate(this.transport); + Ajax.Responders.dispatch('onCreate', this, this.transport); + + this.transport.open(this.method.toUpperCase(), this.url, + this.options.asynchronous); + + if (this.options.asynchronous) + setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10); + + this.transport.onreadystatechange = this.onStateChange.bind(this); + this.setRequestHeaders(); + + this.body = this.method == 'post' ? (this.options.postBody || params) : null; + this.transport.send(this.body); + + /* Force Firefox to handle ready state 4 for synchronous requests */ + if (!this.options.asynchronous && this.transport.overrideMimeType) + this.onStateChange(); + + } + catch (e) { + this.dispatchException(e); + } + }, + + onStateChange: function() { + var readyState = this.transport.readyState; + if (readyState > 1 && !((readyState == 4) && this._complete)) + this.respondToReadyState(this.transport.readyState); + }, + + setRequestHeaders: function() { + var headers = { + 'X-Requested-With': 'XMLHttpRequest', + 'X-Prototype-Version': Prototype.Version, + 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' + }; + + if (this.method == 'post') { + headers['Content-type'] = this.options.contentType + + (this.options.encoding ? '; charset=' + this.options.encoding : ''); + + /* Force "Connection: close" for older Mozilla browsers to work + * around a bug where XMLHttpRequest sends an incorrect + * Content-length header. See Mozilla Bugzilla #246651. + */ + if (this.transport.overrideMimeType && + (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005) + headers['Connection'] = 'close'; + } + + // user-defined headers + if (typeof this.options.requestHeaders == 'object') { + var extras = this.options.requestHeaders; + + if (typeof extras.push == 'function') + for (var i = 0, length = extras.length; i < length; i += 2) + headers[extras[i]] = extras[i+1]; + else + $H(extras).each(function(pair) { headers[pair.key] = pair.value }); + } + + for (var name in headers) + this.transport.setRequestHeader(name, headers[name]); + }, + + success: function() { + return !this.transport.status + || (this.transport.status >= 200 && this.transport.status < 300); + }, + + respondToReadyState: function(readyState) { + var state = Ajax.Request.Events[readyState]; + var transport = this.transport, json = this.evalJSON(); + + if (state == 'Complete') { + try { + this._complete = true; + (this.options['on' + this.transport.status] + || this.options['on' + (this.success() ? 'Success' : 'Failure')] + || Prototype.emptyFunction)(transport, json); + } catch (e) { + this.dispatchException(e); + } + + var contentType = this.getHeader('Content-type'); + if (contentType && contentType.strip(). + match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i)) + this.evalResponse(); + } + + try { + (this.options['on' + state] || Prototype.emptyFunction)(transport, json); + Ajax.Responders.dispatch('on' + state, this, transport, json); + } catch (e) { + this.dispatchException(e); + } + + if (state == 'Complete') { + // avoid memory leak in MSIE: clean up + this.transport.onreadystatechange = Prototype.emptyFunction; + } + }, + + getHeader: function(name) { + try { + return this.transport.getResponseHeader(name); + } catch (e) { return null } + }, + + evalJSON: function() { + try { + var json = this.getHeader('X-JSON'); + return json ? json.evalJSON() : null; + } catch (e) { return null } + }, + + evalResponse: function() { + try { + return eval((this.transport.responseText || '').unfilterJSON()); + } catch (e) { + this.dispatchException(e); + } + }, + + dispatchException: function(exception) { + (this.options.onException || Prototype.emptyFunction)(this, exception); + Ajax.Responders.dispatch('onException', this, exception); + } +}); + +Ajax.Updater = Class.create(); + +Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { + initialize: function(container, url, options) { + this.container = { + success: (container.success || container), + failure: (container.failure || (container.success ? null : container)) + } + + this.transport = Ajax.getTransport(); + this.setOptions(options); + + var onComplete = this.options.onComplete || Prototype.emptyFunction; + this.options.onComplete = (function(transport, param) { + this.updateContent(); + onComplete(transport, param); + }).bind(this); + + this.request(url); + }, + + updateContent: function() { + var receiver = this.container[this.success() ? 'success' : 'failure']; + var response = this.transport.responseText; + + if (!this.options.evalScripts) response = response.stripScripts(); + + if (receiver = $(receiver)) { + if (this.options.insertion) + new this.options.insertion(receiver, response); + else + receiver.update(response); + } + + if (this.success()) { + if (this.onComplete) + setTimeout(this.onComplete.bind(this), 10); + } + } +}); + +Ajax.PeriodicalUpdater = Class.create(); +Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), { + initialize: function(container, url, options) { + this.setOptions(options); + this.onComplete = this.options.onComplete; + + this.frequency = (this.options.frequency || 2); + this.decay = (this.options.decay || 1); + + this.updater = {}; + this.container = container; + this.url = url; + + this.start(); + }, + + start: function() { + this.options.onComplete = this.updateComplete.bind(this); + this.onTimerEvent(); + }, + + stop: function() { + this.updater.options.onComplete = undefined; + clearTimeout(this.timer); + (this.onComplete || Prototype.emptyFunction).apply(this, arguments); + }, + + updateComplete: function(request) { + if (this.options.decay) { + this.decay = (request.responseText == this.lastText ? + this.decay * this.options.decay : 1); + + this.lastText = request.responseText; + } + this.timer = setTimeout(this.onTimerEvent.bind(this), + this.decay * this.frequency * 1000); + }, + + onTimerEvent: function() { + this.updater = new Ajax.Updater(this.container, this.url, this.options); + } +}); +function $(element) { + if (arguments.length > 1) { + for (var i = 0, elements = [], length = arguments.length; i < length; i++) + elements.push($(arguments[i])); + return elements; + } + if (typeof element == 'string') + element = document.getElementById(element); + return Element.extend(element); +} + +if (Prototype.BrowserFeatures.XPath) { + document._getElementsByXPath = function(expression, parentElement) { + var results = []; + var query = document.evaluate(expression, $(parentElement) || document, + null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); + for (var i = 0, length = query.snapshotLength; i < length; i++) + results.push(query.snapshotItem(i)); + return results; + }; + + document.getElementsByClassName = function(className, parentElement) { + var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]"; + return document._getElementsByXPath(q, parentElement); + } + +} else document.getElementsByClassName = function(className, parentElement) { + var children = ($(parentElement) || document.body).getElementsByTagName('*'); + var elements = [], child; + for (var i = 0, length = children.length; i < length; i++) { + child = children[i]; + if (Element.hasClassName(child, className)) + elements.push(Element.extend(child)); + } + return elements; +}; + +/*--------------------------------------------------------------------------*/ + +if (!window.Element) var Element = {}; + +Element.extend = function(element) { + var F = Prototype.BrowserFeatures; + if (!element || !element.tagName || element.nodeType == 3 || + element._extended || F.SpecificElementExtensions || element == window) + return element; + + var methods = {}, tagName = element.tagName, cache = Element.extend.cache, + T = Element.Methods.ByTag; + + // extend methods for all tags (Safari doesn't need this) + if (!F.ElementExtensions) { + Object.extend(methods, Element.Methods), + Object.extend(methods, Element.Methods.Simulated); + } + + // extend methods for specific tags + if (T[tagName]) Object.extend(methods, T[tagName]); + + for (var property in methods) { + var value = methods[property]; + if (typeof value == 'function' && !(property in element)) + element[property] = cache.findOrStore(value); + } + + element._extended = Prototype.emptyFunction; + return element; +}; + +Element.extend.cache = { + findOrStore: function(value) { + return this[value] = this[value] || function() { + return value.apply(null, [this].concat($A(arguments))); + } + } +}; + +Element.Methods = { + visible: function(element) { + return $(element).style.display != 'none'; + }, + + toggle: function(element) { + element = $(element); + Element[Element.visible(element) ? 'hide' : 'show'](element); + return element; + }, + + hide: function(element) { + $(element).style.display = 'none'; + return element; + }, + + show: function(element) { + $(element).style.display = ''; + return element; + }, + + remove: function(element) { + element = $(element); + element.parentNode.removeChild(element); + return element; + }, + + update: function(element, html) { + html = typeof html == 'undefined' ? '' : html.toString(); + $(element).innerHTML = html.stripScripts(); + setTimeout(function() {html.evalScripts()}, 10); + return element; + }, + + replace: function(element, html) { + element = $(element); + html = typeof html == 'undefined' ? '' : html.toString(); + if (element.outerHTML) { + element.outerHTML = html.stripScripts(); + } else { + var range = element.ownerDocument.createRange(); + range.selectNodeContents(element); + element.parentNode.replaceChild( + range.createContextualFragment(html.stripScripts()), element); + } + setTimeout(function() {html.evalScripts()}, 10); + return element; + }, + + inspect: function(element) { + element = $(element); + var result = '<' + element.tagName.toLowerCase(); + $H({'id': 'id', 'className': 'class'}).each(function(pair) { + var property = pair.first(), attribute = pair.last(); + var value = (element[property] || '').toString(); + if (value) result += ' ' + attribute + '=' + value.inspect(true); + }); + return result + '>'; + }, + + recursivelyCollect: function(element, property) { + element = $(element); + var elements = []; + while (element = element[property]) + if (element.nodeType == 1) + elements.push(Element.extend(element)); + return elements; + }, + + ancestors: function(element) { + return $(element).recursivelyCollect('parentNode'); + }, + + descendants: function(element) { + return $A($(element).getElementsByTagName('*')).each(Element.extend); + }, + + firstDescendant: function(element) { + element = $(element).firstChild; + while (element && element.nodeType != 1) element = element.nextSibling; + return $(element); + }, + + immediateDescendants: function(element) { + if (!(element = $(element).firstChild)) return []; + while (element && element.nodeType != 1) element = element.nextSibling; + if (element) return [element].concat($(element).nextSiblings()); + return []; + }, + + previousSiblings: function(element) { + return $(element).recursivelyCollect('previousSibling'); + }, + + nextSiblings: function(element) { + return $(element).recursivelyCollect('nextSibling'); + }, + + siblings: function(element) { + element = $(element); + return element.previousSiblings().reverse().concat(element.nextSiblings()); + }, + + match: function(element, selector) { + if (typeof selector == 'string') + selector = new Selector(selector); + return selector.match($(element)); + }, + + up: function(element, expression, index) { + element = $(element); + if (arguments.length == 1) return $(element.parentNode); + var ancestors = element.ancestors(); + return expression ? Selector.findElement(ancestors, expression, index) : + ancestors[index || 0]; + }, + + down: function(element, expression, index) { + element = $(element); + if (arguments.length == 1) return element.firstDescendant(); + var descendants = element.descendants(); + return expression ? Selector.findElement(descendants, expression, index) : + descendants[index || 0]; + }, + + previous: function(element, expression, index) { + element = $(element); + if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element)); + var previousSiblings = element.previousSiblings(); + return expression ? Selector.findElement(previousSiblings, expression, index) : + previousSiblings[index || 0]; + }, + + next: function(element, expression, index) { + element = $(element); + if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element)); + var nextSiblings = element.nextSiblings(); + return expression ? Selector.findElement(nextSiblings, expression, index) : + nextSiblings[index || 0]; + }, + + getElementsBySelector: function() { + var args = $A(arguments), element = $(args.shift()); + return Selector.findChildElements(element, args); + }, + + getElementsByClassName: function(element, className) { + return document.getElementsByClassName(className, element); + }, + + readAttribute: function(element, name) { + element = $(element); + if (Prototype.Browser.IE) { + if (!element.attributes) return null; + var t = Element._attributeTranslations; + if (t.values[name]) return t.values[name](element, name); + if (t.names[name]) name = t.names[name]; + var attribute = element.attributes[name]; + return attribute ? attribute.nodeValue : null; + } + return element.getAttribute(name); + }, + + getHeight: function(element) { + return $(element).getDimensions().height; + }, + + getWidth: function(element) { + return $(element).getDimensions().width; + }, + + classNames: function(element) { + return new Element.ClassNames(element); + }, + + hasClassName: function(element, className) { + if (!(element = $(element))) return; + var elementClassName = element.className; + if (elementClassName.length == 0) return false; + if (elementClassName == className || + elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) + return true; + return false; + }, + + addClassName: function(element, className) { + if (!(element = $(element))) return; + Element.classNames(element).add(className); + return element; + }, + + removeClassName: function(element, className) { + if (!(element = $(element))) return; + Element.classNames(element).remove(className); + return element; + }, + + toggleClassName: function(element, className) { + if (!(element = $(element))) return; + Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className); + return element; + }, + + observe: function() { + Event.observe.apply(Event, arguments); + return $A(arguments).first(); + }, + + stopObserving: function() { + Event.stopObserving.apply(Event, arguments); + return $A(arguments).first(); + }, + + // removes whitespace-only text node children + cleanWhitespace: function(element) { + element = $(element); + var node = element.firstChild; + while (node) { + var nextNode = node.nextSibling; + if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) + element.removeChild(node); + node = nextNode; + } + return element; + }, + + empty: function(element) { + return $(element).innerHTML.blank(); + }, + + descendantOf: function(element, ancestor) { + element = $(element), ancestor = $(ancestor); + while (element = element.parentNode) + if (element == ancestor) return true; + return false; + }, + + scrollTo: function(element) { + element = $(element); + var pos = Position.cumulativeOffset(element); + window.scrollTo(pos[0], pos[1]); + return element; + }, + + getStyle: function(element, style) { + element = $(element); + style = style == 'float' ? 'cssFloat' : style.camelize(); + var value = element.style[style]; + if (!value) { + var css = document.defaultView.getComputedStyle(element, null); + value = css ? css[style] : null; + } + if (style == 'opacity') return value ? parseFloat(value) : 1.0; + return value == 'auto' ? null : value; + }, + + getOpacity: function(element) { + return $(element).getStyle('opacity'); + }, + + setStyle: function(element, styles, camelized) { + element = $(element); + var elementStyle = element.style; + + for (var property in styles) + if (property == 'opacity') element.setOpacity(styles[property]) + else + elementStyle[(property == 'float' || property == 'cssFloat') ? + (elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') : + (camelized ? property : property.camelize())] = styles[property]; + + return element; + }, + + setOpacity: function(element, value) { + element = $(element); + element.style.opacity = (value == 1 || value === '') ? '' : + (value < 0.00001) ? 0 : value; + return element; + }, + + getDimensions: function(element) { + element = $(element); + var display = $(element).getStyle('display'); + if (display != 'none' && display != null) // Safari bug + return {width: element.offsetWidth, height: element.offsetHeight}; + + // All *Width and *Height properties give 0 on elements with display none, + // so enable the element temporarily + var els = element.style; + var originalVisibility = els.visibility; + var originalPosition = els.position; + var originalDisplay = els.display; + els.visibility = 'hidden'; + els.position = 'absolute'; + els.display = 'block'; + var originalWidth = element.clientWidth; + var originalHeight = element.clientHeight; + els.display = originalDisplay; + els.position = originalPosition; + els.visibility = originalVisibility; + return {width: originalWidth, height: originalHeight}; + }, + + makePositioned: function(element) { + element = $(element); + var pos = Element.getStyle(element, 'position'); + if (pos == 'static' || !pos) { + element._madePositioned = true; + element.style.position = 'relative'; + // Opera returns the offset relative to the positioning context, when an + // element is position relative but top and left have not been defined + if (window.opera) { + element.style.top = 0; + element.style.left = 0; + } + } + return element; + }, + + undoPositioned: function(element) { + element = $(element); + if (element._madePositioned) { + element._madePositioned = undefined; + element.style.position = + element.style.top = + element.style.left = + element.style.bottom = + element.style.right = ''; + } + return element; + }, + + makeClipping: function(element) { + element = $(element); + if (element._overflow) return element; + element._overflow = element.style.overflow || 'auto'; + if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') + element.style.overflow = 'hidden'; + return element; + }, + + undoClipping: function(element) { + element = $(element); + if (!element._overflow) return element; + element.style.overflow = element._overflow == 'auto' ? '' : element._overflow; + element._overflow = null; + return element; + } +}; + +Object.extend(Element.Methods, { + childOf: Element.Methods.descendantOf, + childElements: Element.Methods.immediateDescendants +}); + +if (Prototype.Browser.Opera) { + Element.Methods._getStyle = Element.Methods.getStyle; + Element.Methods.getStyle = function(element, style) { + switch(style) { + case 'left': + case 'top': + case 'right': + case 'bottom': + if (Element._getStyle(element, 'position') == 'static') return null; + default: return Element._getStyle(element, style); + } + }; +} +else if (Prototype.Browser.IE) { + Element.Methods.getStyle = function(element, style) { + element = $(element); + style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize(); + var value = element.style[style]; + if (!value && element.currentStyle) value = element.currentStyle[style]; + + if (style == 'opacity') { + if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/)) + if (value[1]) return parseFloat(value[1]) / 100; + return 1.0; + } + + if (value == 'auto') { + if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none')) + return element['offset'+style.capitalize()] + 'px'; + return null; + } + return value; + }; + + Element.Methods.setOpacity = function(element, value) { + element = $(element); + var filter = element.getStyle('filter'), style = element.style; + if (value == 1 || value === '') { + style.filter = filter.replace(/alpha\([^\)]*\)/gi,''); + return element; + } else if (value < 0.00001) value = 0; + style.filter = filter.replace(/alpha\([^\)]*\)/gi, '') + + 'alpha(opacity=' + (value * 100) + ')'; + return element; + }; + + // IE is missing .innerHTML support for TABLE-related elements + Element.Methods.update = function(element, html) { + element = $(element); + html = typeof html == 'undefined' ? '' : html.toString(); + var tagName = element.tagName.toUpperCase(); + if (['THEAD','TBODY','TR','TD'].include(tagName)) { + var div = document.createElement('div'); + switch (tagName) { + case 'THEAD': + case 'TBODY': + div.innerHTML = '' + html.stripScripts() + '
'; + depth = 2; + break; + case 'TR': + div.innerHTML = '' + html.stripScripts() + '
'; + depth = 3; + break; + case 'TD': + div.innerHTML = '
' + html.stripScripts() + '
'; + depth = 4; + } + $A(element.childNodes).each(function(node) { element.removeChild(node) }); + depth.times(function() { div = div.firstChild }); + $A(div.childNodes).each(function(node) { element.appendChild(node) }); + } else { + element.innerHTML = html.stripScripts(); + } + setTimeout(function() { html.evalScripts() }, 10); + return element; + } +} +else if (Prototype.Browser.Gecko) { + Element.Methods.setOpacity = function(element, value) { + element = $(element); + element.style.opacity = (value == 1) ? 0.999999 : + (value === '') ? '' : (value < 0.00001) ? 0 : value; + return element; + }; +} + +Element._attributeTranslations = { + names: { + colspan: "colSpan", + rowspan: "rowSpan", + valign: "vAlign", + datetime: "dateTime", + accesskey: "accessKey", + tabindex: "tabIndex", + enctype: "encType", + maxlength: "maxLength", + readonly: "readOnly", + longdesc: "longDesc" + }, + values: { + _getAttr: function(element, attribute) { + return element.getAttribute(attribute, 2); + }, + _flag: function(element, attribute) { + return $(element).hasAttribute(attribute) ? attribute : null; + }, + style: function(element) { + return element.style.cssText.toLowerCase(); + }, + title: function(element) { + var node = element.getAttributeNode('title'); + return node.specified ? node.nodeValue : null; + } + } +}; + +(function() { + Object.extend(this, { + href: this._getAttr, + src: this._getAttr, + disabled: this._flag, + checked: this._flag, + readonly: this._flag, + multiple: this._flag + }); +}).call(Element._attributeTranslations.values); + +Element.Methods.Simulated = { + hasAttribute: function(element, attribute) { + var t = Element._attributeTranslations, node; + attribute = t.names[attribute] || attribute; + node = $(element).getAttributeNode(attribute); + return node && node.specified; + } +}; + +Element.Methods.ByTag = {}; + +Object.extend(Element, Element.Methods); + +if (!Prototype.BrowserFeatures.ElementExtensions && + document.createElement('div').__proto__) { + window.HTMLElement = {}; + window.HTMLElement.prototype = document.createElement('div').__proto__; + Prototype.BrowserFeatures.ElementExtensions = true; +} + +Element.hasAttribute = function(element, attribute) { + if (element.hasAttribute) return element.hasAttribute(attribute); + return Element.Methods.Simulated.hasAttribute(element, attribute); +}; + +Element.addMethods = function(methods) { + var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag; + if (arguments.length == 2) { + var tagName = methods; + methods = arguments[1]; + } + + if (!tagName) Object.extend(Element.Methods, methods || {}); + else { + if (tagName.constructor == Array) tagName.each(extend); + else extend(tagName); + } + + function extend(tagName) { + tagName = tagName.toUpperCase(); + if (!Element.Methods.ByTag[tagName]) + Element.Methods.ByTag[tagName] = {}; + Object.extend(Element.Methods.ByTag[tagName], methods); + } + + function copy(methods, destination, onlyIfAbsent) { + onlyIfAbsent = onlyIfAbsent || false; + var cache = Element.extend.cache; + for (var property in methods) { + var value = methods[property]; + if (!onlyIfAbsent || !(property in destination)) + destination[property] = cache.findOrStore(value); + } + } + + function findDOMClass(tagName) { + var klass; + var trans = { + "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph", + "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList", + "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading", + "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote", + "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION": + "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD": + "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR": + "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET": + "FrameSet", "IFRAME": "IFrame" + }; + if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element'; + if (window[klass]) return window[klass]; + klass = 'HTML' + tagName + 'Element'; + if (window[klass]) return window[klass]; + klass = 'HTML' + tagName.capitalize() + 'Element'; + if (window[klass]) return window[klass]; + + window[klass] = {}; + window[klass].prototype = document.createElement(tagName).__proto__; + return window[klass]; + } + + if (F.ElementExtensions) { + copy(Element.Methods, HTMLElement.prototype); + copy(Element.Methods.Simulated, HTMLElement.prototype, true); + } + + if (F.SpecificElementExtensions) { + for (var tag in Element.Methods.ByTag) { + var klass = findDOMClass(tag); + if (typeof klass == "undefined") continue; + copy(T[tag], klass.prototype); + } + } + + Object.extend(Element, Element.Methods); + delete Element.ByTag; +}; + +var Toggle = { display: Element.toggle }; + +/*--------------------------------------------------------------------------*/ + +Abstract.Insertion = function(adjacency) { + this.adjacency = adjacency; +} + +Abstract.Insertion.prototype = { + initialize: function(element, content) { + this.element = $(element); + this.content = content.stripScripts(); + + if (this.adjacency && this.element.insertAdjacentHTML) { + try { + this.element.insertAdjacentHTML(this.adjacency, this.content); + } catch (e) { + var tagName = this.element.tagName.toUpperCase(); + if (['TBODY', 'TR'].include(tagName)) { + this.insertContent(this.contentFromAnonymousTable()); + } else { + throw e; + } + } + } else { + this.range = this.element.ownerDocument.createRange(); + if (this.initializeRange) this.initializeRange(); + this.insertContent([this.range.createContextualFragment(this.content)]); + } + + setTimeout(function() {content.evalScripts()}, 10); + }, + + contentFromAnonymousTable: function() { + var div = document.createElement('div'); + div.innerHTML = '' + this.content + '
'; + return $A(div.childNodes[0].childNodes[0].childNodes); + } +} + +var Insertion = new Object(); + +Insertion.Before = Class.create(); +Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), { + initializeRange: function() { + this.range.setStartBefore(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.parentNode.insertBefore(fragment, this.element); + }).bind(this)); + } +}); + +Insertion.Top = Class.create(); +Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), { + initializeRange: function() { + this.range.selectNodeContents(this.element); + this.range.collapse(true); + }, + + insertContent: function(fragments) { + fragments.reverse(false).each((function(fragment) { + this.element.insertBefore(fragment, this.element.firstChild); + }).bind(this)); + } +}); + +Insertion.Bottom = Class.create(); +Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), { + initializeRange: function() { + this.range.selectNodeContents(this.element); + this.range.collapse(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.appendChild(fragment); + }).bind(this)); + } +}); + +Insertion.After = Class.create(); +Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), { + initializeRange: function() { + this.range.setStartAfter(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.parentNode.insertBefore(fragment, + this.element.nextSibling); + }).bind(this)); + } +}); + +/*--------------------------------------------------------------------------*/ + +Element.ClassNames = Class.create(); +Element.ClassNames.prototype = { + initialize: function(element) { + this.element = $(element); + }, + + _each: function(iterator) { + this.element.className.split(/\s+/).select(function(name) { + return name.length > 0; + })._each(iterator); + }, + + set: function(className) { + this.element.className = className; + }, + + add: function(classNameToAdd) { + if (this.include(classNameToAdd)) return; + this.set($A(this).concat(classNameToAdd).join(' ')); + }, + + remove: function(classNameToRemove) { + if (!this.include(classNameToRemove)) return; + this.set($A(this).without(classNameToRemove).join(' ')); + }, + + toString: function() { + return $A(this).join(' '); + } +}; + +Object.extend(Element.ClassNames.prototype, Enumerable); +/* Portions of the Selector class are derived from Jack Slocum’s DomQuery, + * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style + * license. Please see http://www.yui-ext.com/ for more information. */ + +var Selector = Class.create(); + +Selector.prototype = { + initialize: function(expression) { + this.expression = expression.strip(); + this.compileMatcher(); + }, + + compileMatcher: function() { + // Selectors with namespaced attributes can't use the XPath version + if (Prototype.BrowserFeatures.XPath && !(/\[[\w-]*?:/).test(this.expression)) + return this.compileXPathMatcher(); + + var e = this.expression, ps = Selector.patterns, h = Selector.handlers, + c = Selector.criteria, le, p, m; + + if (Selector._cache[e]) { + this.matcher = Selector._cache[e]; return; + } + this.matcher = ["this.matcher = function(root) {", + "var r = root, h = Selector.handlers, c = false, n;"]; + + while (e && le != e && (/\S/).test(e)) { + le = e; + for (var i in ps) { + p = ps[i]; + if (m = e.match(p)) { + this.matcher.push(typeof c[i] == 'function' ? c[i](m) : + new Template(c[i]).evaluate(m)); + e = e.replace(m[0], ''); + break; + } + } + } + + this.matcher.push("return h.unique(n);\n}"); + eval(this.matcher.join('\n')); + Selector._cache[this.expression] = this.matcher; + }, + + compileXPathMatcher: function() { + var e = this.expression, ps = Selector.patterns, + x = Selector.xpath, le, m; + + if (Selector._cache[e]) { + this.xpath = Selector._cache[e]; return; + } + + this.matcher = ['.//*']; + while (e && le != e && (/\S/).test(e)) { + le = e; + for (var i in ps) { + if (m = e.match(ps[i])) { + this.matcher.push(typeof x[i] == 'function' ? x[i](m) : + new Template(x[i]).evaluate(m)); + e = e.replace(m[0], ''); + break; + } + } + } + + this.xpath = this.matcher.join(''); + Selector._cache[this.expression] = this.xpath; + }, + + findElements: function(root) { + root = root || document; + if (this.xpath) return document._getElementsByXPath(this.xpath, root); + return this.matcher(root); + }, + + match: function(element) { + return this.findElements(document).include(element); + }, + + toString: function() { + return this.expression; + }, + + inspect: function() { + return "#"; + } +}; + +Object.extend(Selector, { + _cache: {}, + + xpath: { + descendant: "//*", + child: "/*", + adjacent: "/following-sibling::*[1]", + laterSibling: '/following-sibling::*', + tagName: function(m) { + if (m[1] == '*') return ''; + return "[local-name()='" + m[1].toLowerCase() + + "' or local-name()='" + m[1].toUpperCase() + "']"; + }, + className: "[contains(concat(' ', @class, ' '), ' #{1} ')]", + id: "[@id='#{1}']", + attrPresence: "[@#{1}]", + attr: function(m) { + m[3] = m[5] || m[6]; + return new Template(Selector.xpath.operators[m[2]]).evaluate(m); + }, + pseudo: function(m) { + var h = Selector.xpath.pseudos[m[1]]; + if (!h) return ''; + if (typeof h === 'function') return h(m); + return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m); + }, + operators: { + '=': "[@#{1}='#{3}']", + '!=': "[@#{1}!='#{3}']", + '^=': "[starts-with(@#{1}, '#{3}')]", + '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']", + '*=': "[contains(@#{1}, '#{3}')]", + '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]", + '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]" + }, + pseudos: { + 'first-child': '[not(preceding-sibling::*)]', + 'last-child': '[not(following-sibling::*)]', + 'only-child': '[not(preceding-sibling::* or following-sibling::*)]', + 'empty': "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]", + 'checked': "[@checked]", + 'disabled': "[@disabled]", + 'enabled': "[not(@disabled)]", + 'not': function(m) { + var e = m[6], p = Selector.patterns, + x = Selector.xpath, le, m, v; + + var exclusion = []; + while (e && le != e && (/\S/).test(e)) { + le = e; + for (var i in p) { + if (m = e.match(p[i])) { + v = typeof x[i] == 'function' ? x[i](m) : new Template(x[i]).evaluate(m); + exclusion.push("(" + v.substring(1, v.length - 1) + ")"); + e = e.replace(m[0], ''); + break; + } + } + } + return "[not(" + exclusion.join(" and ") + ")]"; + }, + 'nth-child': function(m) { + return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m); + }, + 'nth-last-child': function(m) { + return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m); + }, + 'nth-of-type': function(m) { + return Selector.xpath.pseudos.nth("position() ", m); + }, + 'nth-last-of-type': function(m) { + return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m); + }, + 'first-of-type': function(m) { + m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m); + }, + 'last-of-type': function(m) { + m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m); + }, + 'only-of-type': function(m) { + var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m); + }, + nth: function(fragment, m) { + var mm, formula = m[6], predicate; + if (formula == 'even') formula = '2n+0'; + if (formula == 'odd') formula = '2n+1'; + if (mm = formula.match(/^(\d+)$/)) // digit only + return '[' + fragment + "= " + mm[1] + ']'; + if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b + if (mm[1] == "-") mm[1] = -1; + var a = mm[1] ? Number(mm[1]) : 1; + var b = mm[2] ? Number(mm[2]) : 0; + predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " + + "((#{fragment} - #{b}) div #{a} >= 0)]"; + return new Template(predicate).evaluate({ + fragment: fragment, a: a, b: b }); + } + } + } + }, + + criteria: { + tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;', + className: 'n = h.className(n, r, "#{1}", c); c = false;', + id: 'n = h.id(n, r, "#{1}", c); c = false;', + attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;', + attr: function(m) { + m[3] = (m[5] || m[6]); + return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m); + }, + pseudo: function(m) { + if (m[6]) m[6] = m[6].replace(/"/g, '\\"'); + return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m); + }, + descendant: 'c = "descendant";', + child: 'c = "child";', + adjacent: 'c = "adjacent";', + laterSibling: 'c = "laterSibling";' + }, + + patterns: { + // combinators must be listed first + // (and descendant needs to be last combinator) + laterSibling: /^\s*~\s*/, + child: /^\s*>\s*/, + adjacent: /^\s*\+\s*/, + descendant: /^\s/, + + // selectors follow + tagName: /^\s*(\*|[\w\-]+)(\b|$)?/, + id: /^#([\w\-\*]+)(\b|$)/, + className: /^\.([\w\-\*]+)(\b|$)/, + pseudo: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|\s)/, + attrPresence: /^\[([\w]+)\]/, + attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\]]*?)\4|([^'"][^\]]*?)))?\]/ + }, + + handlers: { + // UTILITY FUNCTIONS + // joins two collections + concat: function(a, b) { + for (var i = 0, node; node = b[i]; i++) + a.push(node); + return a; + }, + + // marks an array of nodes for counting + mark: function(nodes) { + for (var i = 0, node; node = nodes[i]; i++) + node._counted = true; + return nodes; + }, + + unmark: function(nodes) { + for (var i = 0, node; node = nodes[i]; i++) + node._counted = undefined; + return nodes; + }, + + // mark each child node with its position (for nth calls) + // "ofType" flag indicates whether we're indexing for nth-of-type + // rather than nth-child + index: function(parentNode, reverse, ofType) { + parentNode._counted = true; + if (reverse) { + for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) { + node = nodes[i]; + if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++; + } + } else { + for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++) + if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++; + } + }, + + // filters out duplicates and extends all nodes + unique: function(nodes) { + if (nodes.length == 0) return nodes; + var results = [], n; + for (var i = 0, l = nodes.length; i < l; i++) + if (!(n = nodes[i])._counted) { + n._counted = true; + results.push(Element.extend(n)); + } + return Selector.handlers.unmark(results); + }, + + // COMBINATOR FUNCTIONS + descendant: function(nodes) { + var h = Selector.handlers; + for (var i = 0, results = [], node; node = nodes[i]; i++) + h.concat(results, node.getElementsByTagName('*')); + return results; + }, + + child: function(nodes) { + var h = Selector.handlers; + for (var i = 0, results = [], node; node = nodes[i]; i++) { + for (var j = 0, children = [], child; child = node.childNodes[j]; j++) + if (child.nodeType == 1 && child.tagName != '!') results.push(child); + } + return results; + }, + + adjacent: function(nodes) { + for (var i = 0, results = [], node; node = nodes[i]; i++) { + var next = this.nextElementSibling(node); + if (next) results.push(next); + } + return results; + }, + + laterSibling: function(nodes) { + var h = Selector.handlers; + for (var i = 0, results = [], node; node = nodes[i]; i++) + h.concat(results, Element.nextSiblings(node)); + return results; + }, + + nextElementSibling: function(node) { + while (node = node.nextSibling) + if (node.nodeType == 1) return node; + return null; + }, + + previousElementSibling: function(node) { + while (node = node.previousSibling) + if (node.nodeType == 1) return node; + return null; + }, + + // TOKEN FUNCTIONS + tagName: function(nodes, root, tagName, combinator) { + tagName = tagName.toUpperCase(); + var results = [], h = Selector.handlers; + if (nodes) { + if (combinator) { + // fastlane for ordinary descendant combinators + if (combinator == "descendant") { + for (var i = 0, node; node = nodes[i]; i++) + h.concat(results, node.getElementsByTagName(tagName)); + return results; + } else nodes = this[combinator](nodes); + if (tagName == "*") return nodes; + } + for (var i = 0, node; node = nodes[i]; i++) + if (node.tagName.toUpperCase() == tagName) results.push(node); + return results; + } else return root.getElementsByTagName(tagName); + }, + + id: function(nodes, root, id, combinator) { + var targetNode = $(id), h = Selector.handlers; + if (!nodes && root == document) return targetNode ? [targetNode] : []; + if (nodes) { + if (combinator) { + if (combinator == 'child') { + for (var i = 0, node; node = nodes[i]; i++) + if (targetNode.parentNode == node) return [targetNode]; + } else if (combinator == 'descendant') { + for (var i = 0, node; node = nodes[i]; i++) + if (Element.descendantOf(targetNode, node)) return [targetNode]; + } else if (combinator == 'adjacent') { + for (var i = 0, node; node = nodes[i]; i++) + if (Selector.handlers.previousElementSibling(targetNode) == node) + return [targetNode]; + } else nodes = h[combinator](nodes); + } + for (var i = 0, node; node = nodes[i]; i++) + if (node == targetNode) return [targetNode]; + return []; + } + return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : []; + }, + + className: function(nodes, root, className, combinator) { + if (nodes && combinator) nodes = this[combinator](nodes); + return Selector.handlers.byClassName(nodes, root, className); + }, + + byClassName: function(nodes, root, className) { + if (!nodes) nodes = Selector.handlers.descendant([root]); + var needle = ' ' + className + ' '; + for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) { + nodeClassName = node.className; + if (nodeClassName.length == 0) continue; + if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle)) + results.push(node); + } + return results; + }, + + attrPresence: function(nodes, root, attr) { + var results = []; + for (var i = 0, node; node = nodes[i]; i++) + if (Element.hasAttribute(node, attr)) results.push(node); + return results; + }, + + attr: function(nodes, root, attr, value, operator) { + if (!nodes) nodes = root.getElementsByTagName("*"); + var handler = Selector.operators[operator], results = []; + for (var i = 0, node; node = nodes[i]; i++) { + var nodeValue = Element.readAttribute(node, attr); + if (nodeValue === null) continue; + if (handler(nodeValue, value)) results.push(node); + } + return results; + }, + + pseudo: function(nodes, name, value, root, combinator) { + if (nodes && combinator) nodes = this[combinator](nodes); + if (!nodes) nodes = root.getElementsByTagName("*"); + return Selector.pseudos[name](nodes, value, root); + } + }, + + pseudos: { + 'first-child': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) { + if (Selector.handlers.previousElementSibling(node)) continue; + results.push(node); + } + return results; + }, + 'last-child': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) { + if (Selector.handlers.nextElementSibling(node)) continue; + results.push(node); + } + return results; + }, + 'only-child': function(nodes, value, root) { + var h = Selector.handlers; + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (!h.previousElementSibling(node) && !h.nextElementSibling(node)) + results.push(node); + return results; + }, + 'nth-child': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, formula, root); + }, + 'nth-last-child': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, formula, root, true); + }, + 'nth-of-type': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, formula, root, false, true); + }, + 'nth-last-of-type': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, formula, root, true, true); + }, + 'first-of-type': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, "1", root, false, true); + }, + 'last-of-type': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, "1", root, true, true); + }, + 'only-of-type': function(nodes, formula, root) { + var p = Selector.pseudos; + return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root); + }, + + // handles the an+b logic + getIndices: function(a, b, total) { + if (a == 0) return b > 0 ? [b] : []; + return $R(1, total).inject([], function(memo, i) { + if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i); + return memo; + }); + }, + + // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type + nth: function(nodes, formula, root, reverse, ofType) { + if (nodes.length == 0) return []; + if (formula == 'even') formula = '2n+0'; + if (formula == 'odd') formula = '2n+1'; + var h = Selector.handlers, results = [], indexed = [], m; + h.mark(nodes); + for (var i = 0, node; node = nodes[i]; i++) { + if (!node.parentNode._counted) { + h.index(node.parentNode, reverse, ofType); + indexed.push(node.parentNode); + } + } + if (formula.match(/^\d+$/)) { // just a number + formula = Number(formula); + for (var i = 0, node; node = nodes[i]; i++) + if (node.nodeIndex == formula) results.push(node); + } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b + if (m[1] == "-") m[1] = -1; + var a = m[1] ? Number(m[1]) : 1; + var b = m[2] ? Number(m[2]) : 0; + var indices = Selector.pseudos.getIndices(a, b, nodes.length); + for (var i = 0, node, l = indices.length; node = nodes[i]; i++) { + for (var j = 0; j < l; j++) + if (node.nodeIndex == indices[j]) results.push(node); + } + } + h.unmark(nodes); + h.unmark(indexed); + return results; + }, + + 'empty': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) { + // IE treats comments as element nodes + if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue; + results.push(node); + } + return results; + }, + + 'not': function(nodes, selector, root) { + var h = Selector.handlers, selectorType, m; + var exclusions = new Selector(selector).findElements(root); + h.mark(exclusions); + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (!node._counted) results.push(node); + h.unmark(exclusions); + return results; + }, + + 'enabled': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (!node.disabled) results.push(node); + return results; + }, + + 'disabled': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (node.disabled) results.push(node); + return results; + }, + + 'checked': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (node.checked) results.push(node); + return results; + } + }, + + operators: { + '=': function(nv, v) { return nv == v; }, + '!=': function(nv, v) { return nv != v; }, + '^=': function(nv, v) { return nv.startsWith(v); }, + '$=': function(nv, v) { return nv.endsWith(v); }, + '*=': function(nv, v) { return nv.include(v); }, + '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); }, + '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); } + }, + + matchElements: function(elements, expression) { + var matches = new Selector(expression).findElements(), h = Selector.handlers; + h.mark(matches); + for (var i = 0, results = [], element; element = elements[i]; i++) + if (element._counted) results.push(element); + h.unmark(matches); + return results; + }, + + findElement: function(elements, expression, index) { + if (typeof expression == 'number') { + index = expression; expression = false; + } + return Selector.matchElements(elements, expression || '*')[index || 0]; + }, + + findChildElements: function(element, expressions) { + var exprs = expressions.join(','), expressions = []; + exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) { + expressions.push(m[1].strip()); + }); + var results = [], h = Selector.handlers; + for (var i = 0, l = expressions.length, selector; i < l; i++) { + selector = new Selector(expressions[i].strip()); + h.concat(results, selector.findElements(element)); + } + return (l > 1) ? h.unique(results) : results; + } +}); + +function $$() { + return Selector.findChildElements(document, $A(arguments)); +} +var Form = { + reset: function(form) { + $(form).reset(); + return form; + }, + + serializeElements: function(elements, getHash) { + var data = elements.inject({}, function(result, element) { + if (!element.disabled && element.name) { + var key = element.name, value = $(element).getValue(); + if (value != null) { + if (key in result) { + if (result[key].constructor != Array) result[key] = [result[key]]; + result[key].push(value); + } + else result[key] = value; + } + } + return result; + }); + + return getHash ? data : Hash.toQueryString(data); + } +}; + +Form.Methods = { + serialize: function(form, getHash) { + return Form.serializeElements(Form.getElements(form), getHash); + }, + + getElements: function(form) { + return $A($(form).getElementsByTagName('*')).inject([], + function(elements, child) { + if (Form.Element.Serializers[child.tagName.toLowerCase()]) + elements.push(Element.extend(child)); + return elements; + } + ); + }, + + getInputs: function(form, typeName, name) { + form = $(form); + var inputs = form.getElementsByTagName('input'); + + if (!typeName && !name) return $A(inputs).map(Element.extend); + + for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) { + var input = inputs[i]; + if ((typeName && input.type != typeName) || (name && input.name != name)) + continue; + matchingInputs.push(Element.extend(input)); + } + + return matchingInputs; + }, + + disable: function(form) { + form = $(form); + Form.getElements(form).invoke('disable'); + return form; + }, + + enable: function(form) { + form = $(form); + Form.getElements(form).invoke('enable'); + return form; + }, + + findFirstElement: function(form) { + return $(form).getElements().find(function(element) { + return element.type != 'hidden' && !element.disabled && + ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); + }); + }, + + focusFirstElement: function(form) { + form = $(form); + form.findFirstElement().activate(); + return form; + }, + + request: function(form, options) { + form = $(form), options = Object.clone(options || {}); + + var params = options.parameters; + options.parameters = form.serialize(true); + + if (params) { + if (typeof params == 'string') params = params.toQueryParams(); + Object.extend(options.parameters, params); + } + + if (form.hasAttribute('method') && !options.method) + options.method = form.method; + + return new Ajax.Request(form.readAttribute('action'), options); + } +} + +Object.extend(Form, Form.Methods); + +/*--------------------------------------------------------------------------*/ + +Form.Element = { + focus: function(element) { + $(element).focus(); + return element; + }, + + select: function(element) { + $(element).select(); + return element; + } +} + +Form.Element.Methods = { + serialize: function(element) { + element = $(element); + if (!element.disabled && element.name) { + var value = element.getValue(); + if (value != undefined) { + var pair = {}; + pair[element.name] = value; + return Hash.toQueryString(pair); + } + } + return ''; + }, + + getValue: function(element) { + element = $(element); + var method = element.tagName.toLowerCase(); + return Form.Element.Serializers[method](element); + }, + + clear: function(element) { + $(element).value = ''; + return element; + }, + + present: function(element) { + return $(element).value != ''; + }, + + activate: function(element) { + element = $(element); + try { + element.focus(); + if (element.select && (element.tagName.toLowerCase() != 'input' || + !['button', 'reset', 'submit'].include(element.type))) + element.select(); + } catch (e) {} + return element; + }, + + disable: function(element) { + element = $(element); + element.blur(); + element.disabled = true; + return element; + }, + + enable: function(element) { + element = $(element); + element.disabled = false; + return element; + } +} + +Object.extend(Form.Element, Form.Element.Methods); +Object.extend(Element.Methods.ByTag, { + "FORM": Object.clone(Form.Methods), + "INPUT": Object.clone(Form.Element.Methods), + "SELECT": Object.clone(Form.Element.Methods), + "TEXTAREA": Object.clone(Form.Element.Methods) +}); + +/*--------------------------------------------------------------------------*/ + +var Field = Form.Element; +var $F = Form.Element.getValue; + +/*--------------------------------------------------------------------------*/ + +Form.Element.Serializers = { + input: function(element) { + switch (element.type.toLowerCase()) { + case 'checkbox': + case 'radio': + return Form.Element.Serializers.inputSelector(element); + default: + return Form.Element.Serializers.textarea(element); + } + }, + + inputSelector: function(element) { + return element.checked ? element.value : null; + }, + + textarea: function(element) { + return element.value; + }, + + select: function(element) { + return this[element.type == 'select-one' ? + 'selectOne' : 'selectMany'](element); + }, + + selectOne: function(element) { + var index = element.selectedIndex; + return index >= 0 ? this.optionValue(element.options[index]) : null; + }, + + selectMany: function(element) { + var values, length = element.length; + if (!length) return null; + + for (var i = 0, values = []; i < length; i++) { + var opt = element.options[i]; + if (opt.selected) values.push(this.optionValue(opt)); + } + return values; + }, + + optionValue: function(opt) { + // extend element because hasAttribute may not be native + return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text; + } +} + +/*--------------------------------------------------------------------------*/ + +Abstract.TimedObserver = function() {} +Abstract.TimedObserver.prototype = { + initialize: function(element, frequency, callback) { + this.frequency = frequency; + this.element = $(element); + this.callback = callback; + + this.lastValue = this.getValue(); + this.registerCallback(); + }, + + registerCallback: function() { + setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); + }, + + onTimerEvent: function() { + var value = this.getValue(); + var changed = ('string' == typeof this.lastValue && 'string' == typeof value + ? this.lastValue != value : String(this.lastValue) != String(value)); + if (changed) { + this.callback(this.element, value); + this.lastValue = value; + } + } +} + +Form.Element.Observer = Class.create(); +Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.Observer = Class.create(); +Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { + getValue: function() { + return Form.serialize(this.element); + } +}); + +/*--------------------------------------------------------------------------*/ + +Abstract.EventObserver = function() {} +Abstract.EventObserver.prototype = { + initialize: function(element, callback) { + this.element = $(element); + this.callback = callback; + + this.lastValue = this.getValue(); + if (this.element.tagName.toLowerCase() == 'form') + this.registerFormCallbacks(); + else + this.registerCallback(this.element); + }, + + onElementEvent: function() { + var value = this.getValue(); + if (this.lastValue != value) { + this.callback(this.element, value); + this.lastValue = value; + } + }, + + registerFormCallbacks: function() { + Form.getElements(this.element).each(this.registerCallback.bind(this)); + }, + + registerCallback: function(element) { + if (element.type) { + switch (element.type.toLowerCase()) { + case 'checkbox': + case 'radio': + Event.observe(element, 'click', this.onElementEvent.bind(this)); + break; + default: + Event.observe(element, 'change', this.onElementEvent.bind(this)); + break; + } + } + } +} + +Form.Element.EventObserver = Class.create(); +Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.EventObserver = Class.create(); +Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { + getValue: function() { + return Form.serialize(this.element); + } +}); +if (!window.Event) { + var Event = new Object(); +} + +Object.extend(Event, { + KEY_BACKSPACE: 8, + KEY_TAB: 9, + KEY_RETURN: 13, + KEY_ESC: 27, + KEY_LEFT: 37, + KEY_UP: 38, + KEY_RIGHT: 39, + KEY_DOWN: 40, + KEY_DELETE: 46, + KEY_HOME: 36, + KEY_END: 35, + KEY_PAGEUP: 33, + KEY_PAGEDOWN: 34, + + element: function(event) { + return $(event.target || event.srcElement); + }, + + isLeftClick: function(event) { + return (((event.which) && (event.which == 1)) || + ((event.button) && (event.button == 1))); + }, + + pointerX: function(event) { + return event.pageX || (event.clientX + + (document.documentElement.scrollLeft || document.body.scrollLeft)); + }, + + pointerY: function(event) { + return event.pageY || (event.clientY + + (document.documentElement.scrollTop || document.body.scrollTop)); + }, + + stop: function(event) { + if (event.preventDefault) { + event.preventDefault(); + event.stopPropagation(); + } else { + event.returnValue = false; + event.cancelBubble = true; + } + }, + + // find the first node with the given tagName, starting from the + // node the event was triggered on; traverses the DOM upwards + findElement: function(event, tagName) { + var element = Event.element(event); + while (element.parentNode && (!element.tagName || + (element.tagName.toUpperCase() != tagName.toUpperCase()))) + element = element.parentNode; + return element; + }, + + observers: false, + + _observeAndCache: function(element, name, observer, useCapture) { + if (!this.observers) this.observers = []; + if (element.addEventListener) { + this.observers.push([element, name, observer, useCapture]); + element.addEventListener(name, observer, useCapture); + } else if (element.attachEvent) { + this.observers.push([element, name, observer, useCapture]); + element.attachEvent('on' + name, observer); + } + }, + + unloadCache: function() { + if (!Event.observers) return; + for (var i = 0, length = Event.observers.length; i < length; i++) { + Event.stopObserving.apply(this, Event.observers[i]); + Event.observers[i][0] = null; + } + Event.observers = false; + }, + + observe: function(element, name, observer, useCapture) { + element = $(element); + useCapture = useCapture || false; + + if (name == 'keypress' && + (Prototype.Browser.WebKit || element.attachEvent)) + name = 'keydown'; + + Event._observeAndCache(element, name, observer, useCapture); + }, + + stopObserving: function(element, name, observer, useCapture) { + element = $(element); + useCapture = useCapture || false; + + if (name == 'keypress' && + (Prototype.Browser.WebKit || element.attachEvent)) + name = 'keydown'; + + if (element.removeEventListener) { + element.removeEventListener(name, observer, useCapture); + } else if (element.detachEvent) { + try { + element.detachEvent('on' + name, observer); + } catch (e) {} + } + } +}); + +/* prevent memory leaks in IE */ +if (Prototype.Browser.IE) + Event.observe(window, 'unload', Event.unloadCache, false); +var Position = { + // set to true if needed, warning: firefox performance problems + // NOT neeeded for page scrolling, only if draggable contained in + // scrollable elements + includeScrollOffsets: false, + + // must be called before calling withinIncludingScrolloffset, every time the + // page is scrolled + prepare: function() { + this.deltaX = window.pageXOffset + || document.documentElement.scrollLeft + || document.body.scrollLeft + || 0; + this.deltaY = window.pageYOffset + || document.documentElement.scrollTop + || document.body.scrollTop + || 0; + }, + + realOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.scrollTop || 0; + valueL += element.scrollLeft || 0; + element = element.parentNode; + } while (element); + return [valueL, valueT]; + }, + + cumulativeOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + } while (element); + return [valueL, valueT]; + }, + + positionedOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + if (element) { + if(element.tagName=='BODY') break; + var p = Element.getStyle(element, 'position'); + if (p == 'relative' || p == 'absolute') break; + } + } while (element); + return [valueL, valueT]; + }, + + offsetParent: function(element) { + if (element.offsetParent) return element.offsetParent; + if (element == document.body) return element; + + while ((element = element.parentNode) && element != document.body) + if (Element.getStyle(element, 'position') != 'static') + return element; + + return document.body; + }, + + // caches x/y coordinate pair to use with overlap + within: function(element, x, y) { + if (this.includeScrollOffsets) + return this.withinIncludingScrolloffsets(element, x, y); + this.xcomp = x; + this.ycomp = y; + this.offset = this.cumulativeOffset(element); + + return (y >= this.offset[1] && + y < this.offset[1] + element.offsetHeight && + x >= this.offset[0] && + x < this.offset[0] + element.offsetWidth); + }, + + withinIncludingScrolloffsets: function(element, x, y) { + var offsetcache = this.realOffset(element); + + this.xcomp = x + offsetcache[0] - this.deltaX; + this.ycomp = y + offsetcache[1] - this.deltaY; + this.offset = this.cumulativeOffset(element); + + return (this.ycomp >= this.offset[1] && + this.ycomp < this.offset[1] + element.offsetHeight && + this.xcomp >= this.offset[0] && + this.xcomp < this.offset[0] + element.offsetWidth); + }, + + // within must be called directly before + overlap: function(mode, element) { + if (!mode) return 0; + if (mode == 'vertical') + return ((this.offset[1] + element.offsetHeight) - this.ycomp) / + element.offsetHeight; + if (mode == 'horizontal') + return ((this.offset[0] + element.offsetWidth) - this.xcomp) / + element.offsetWidth; + }, + + page: function(forElement) { + var valueT = 0, valueL = 0; + + var element = forElement; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + + // Safari fix + if (element.offsetParent == document.body) + if (Element.getStyle(element,'position')=='absolute') break; + + } while (element = element.offsetParent); + + element = forElement; + do { + if (!window.opera || element.tagName=='BODY') { + valueT -= element.scrollTop || 0; + valueL -= element.scrollLeft || 0; + } + } while (element = element.parentNode); + + return [valueL, valueT]; + }, + + clone: function(source, target) { + var options = Object.extend({ + setLeft: true, + setTop: true, + setWidth: true, + setHeight: true, + offsetTop: 0, + offsetLeft: 0 + }, arguments[2] || {}) + + // find page position of source + source = $(source); + var p = Position.page(source); + + // find coordinate system to use + target = $(target); + var delta = [0, 0]; + var parent = null; + // delta [0,0] will do fine with position: fixed elements, + // position:absolute needs offsetParent deltas + if (Element.getStyle(target,'position') == 'absolute') { + parent = Position.offsetParent(target); + delta = Position.page(parent); + } + + // correct by body offsets (fixes Safari) + if (parent == document.body) { + delta[0] -= document.body.offsetLeft; + delta[1] -= document.body.offsetTop; + } + + // set position + if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; + if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; + if(options.setWidth) target.style.width = source.offsetWidth + 'px'; + if(options.setHeight) target.style.height = source.offsetHeight + 'px'; + }, + + absolutize: function(element) { + element = $(element); + if (element.style.position == 'absolute') return; + Position.prepare(); + + var offsets = Position.positionedOffset(element); + var top = offsets[1]; + var left = offsets[0]; + var width = element.clientWidth; + var height = element.clientHeight; + + element._originalLeft = left - parseFloat(element.style.left || 0); + element._originalTop = top - parseFloat(element.style.top || 0); + element._originalWidth = element.style.width; + element._originalHeight = element.style.height; + + element.style.position = 'absolute'; + element.style.top = top + 'px'; + element.style.left = left + 'px'; + element.style.width = width + 'px'; + element.style.height = height + 'px'; + }, + + relativize: function(element) { + element = $(element); + if (element.style.position == 'relative') return; + Position.prepare(); + + element.style.position = 'relative'; + var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); + var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); + + element.style.top = top + 'px'; + element.style.left = left + 'px'; + element.style.height = element._originalHeight; + element.style.width = element._originalWidth; + } +} + +// Safari returns margins on body which is incorrect if the child is absolutely +// positioned. For performance reasons, redefine Position.cumulativeOffset for +// KHTML/WebKit only. +if (Prototype.Browser.WebKit) { + Position.cumulativeOffset = function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + if (element.offsetParent == document.body) + if (Element.getStyle(element, 'position') == 'absolute') break; + + element = element.offsetParent; + } while (element); + + return [valueL, valueT]; + } +} + +Element.addMethods(); \ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/rico.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/rico.js new file mode 100644 index 0000000..00e187e --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/rico.js @@ -0,0 +1,214 @@ +/** + * + * Copyright 2005 Sabre Airline Solutions + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + **/ + + +// This module does NOT depend on prototype.js + +var Rico = { + Version: '2.0 beta2', + loadRequested: 1, + loadComplete: 2, + init : function() { + try { // fix IE background image flicker (credit: www.mister-pixel.com) + document.execCommand("BackgroundImageCache", false, true); + } catch(err) {} + this.preloadMsgs=''; + var elements = document.getElementsByTagName('script'); + this.baseHref= location.protocol + "//" + location.host; + this.loadedFiles={}; + this.loadQueue=[]; + this.windowIsLoaded=false; + this.onLoadCallbacks=[]; + for (var i=0; i 0) { + var callback=this.onLoadCallbacks.pop(); + if (callback) callback(); + } + } + }, + + onLoad: function(callback) { + this.onLoadCallbacks.push(callback); + this.checkIfComplete(); + }, + + isKonqueror : navigator.userAgent.toLowerCase().indexOf("konqueror") >= 0, + + // logging funtions + + startTime : new Date(), + + timeStamp: function() { + var stamp = new Date(); + return (stamp.getTime()-this.startTime.getTime())+": "; + }, + + setDebugArea: function(id, forceit) { + if (!this.debugArea || forceit) { + var newarea=document.getElementById(id); + if (!newarea) return; + this.debugArea=newarea; + newarea.value=''; + } + }, + + addPreloadMsg: function(msg) { + this.preloadMsgs+=Rico.timeStamp()+msg+"\n"; + }, + + writeDebugMsg: function(msg, resetFlag) { + if (this.debugArea) { + if (resetFlag) this.debugArea.value=''; + this.debugArea.value+=this.timeStamp()+msg+"\n"; + } + } + +} + +Rico.init(); diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoAjaxEngine.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoAjaxEngine.js new file mode 100644 index 0000000..5363991 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoAjaxEngine.js @@ -0,0 +1,178 @@ +//-------------------- ricoAjaxEngine.js +Rico.AjaxEngine = Class.create(); + +Rico.AjaxEngine.prototype = { + + initialize: function() { + this.ajaxElements = new Array(); + this.ajaxObjects = new Array(); + this.requestURLS = new Array(); + this.options = {}; + }, + + registerAjaxElement: function( anId, anElement ) { + if ( !anElement ) + anElement = $(anId); + this.ajaxElements[anId] = anElement; + }, + + registerAjaxObject: function( anId, anObject ) { + this.ajaxObjects[anId] = anObject; + }, + + registerRequest: function (requestLogicalName, requestURL) { + this.requestURLS[requestLogicalName] = requestURL; + }, + + sendRequest: function(requestName, options) { + // Allow for backwards Compatibility + if ( arguments.length >= 2 ) + if (typeof arguments[1] == 'string') + options = {parameters: this._createQueryString(arguments, 1)}; + this.sendRequestWithData(requestName, null, options); + }, + + sendRequestWithData: function(requestName, xmlDocument, options) { + var requestURL = this.requestURLS[requestName]; + if ( requestURL == null ) + return; + + // Allow for backwards Compatibility + if ( arguments.length >= 3 ) + if (typeof arguments[2] == 'string') + options.parameters = this._createQueryString(arguments, 2); + + new Ajax.Request(requestURL, this._requestOptions(options,xmlDocument)); + }, + + sendRequestAndUpdate: function(requestName,container,options) { + // Allow for backwards Compatibility + if ( arguments.length >= 3 ) + if (typeof arguments[2] == 'string') + options.parameters = this._createQueryString(arguments, 2); + + this.sendRequestWithDataAndUpdate(requestName, null, container, options); + }, + + sendRequestWithDataAndUpdate: function(requestName,xmlDocument,container,options) { + var requestURL = this.requestURLS[requestName]; + if ( requestURL == null ) + return; + + // Allow for backwards Compatibility + if ( arguments.length >= 4 ) + if (typeof arguments[3] == 'string') + options.parameters = this._createQueryString(arguments, 3); + + var updaterOptions = this._requestOptions(options,xmlDocument); + + new Ajax.Updater(container, requestURL, updaterOptions); + }, + + // Private -- not part of intended engine API -------------------------------------------------------------------- + + _requestOptions: function(options,xmlDoc) { + var requestHeaders = ['X-Rico-Version', Rico.Version ]; + var sendMethod = 'post'; + if ( xmlDoc == null ) + if (Rico.prototypeVersion < 1.4) + requestHeaders.push( 'Content-type', 'text/xml' ); + else + sendMethod = 'get'; + (!options) ? options = {} : ''; + + if (!options._RicoOptionsProcessed){ + // Check and keep any user onComplete functions + if (options.onComplete) + options.onRicoComplete = options.onComplete; + // Fix onComplete + if (options.overrideOnComplete) + options.onComplete = options.overrideOnComplete; + else + options.onComplete = this._onRequestComplete.bind(this); + options._RicoOptionsProcessed = true; + } + + // Set the default options and extend with any user options + this.options = { + requestHeaders: requestHeaders, + parameters: options.parameters, + postBody: xmlDoc, + method: sendMethod, + onComplete: options.onComplete + }; + // Set any user options: + Object.extend(this.options, options); + return this.options; + }, + + _createQueryString: function( theArgs, offset ) { + var queryString = "" + for ( var i = offset ; i < theArgs.length ; i++ ) { + if ( i != offset ) + queryString += "&"; + + var anArg = theArgs[i]; + + if ( anArg.name != undefined && anArg.value != undefined ) { + queryString += anArg.name + "=" + escape(anArg.value); + } + else { + var ePos = anArg.indexOf('='); + var argName = anArg.substring( 0, ePos ); + var argValue = anArg.substring( ePos + 1 ); + queryString += argName + "=" + escape(argValue); + } + } + return queryString; + }, + + _onRequestComplete : function(request) { + if(!request) + return; + // User can set an onFailure option - which will be called by prototype + if (request.status != 200) + return; + + var response = request.responseXML.getElementsByTagName("ajax-response"); + if (response == null || response.length != 1) + return; + this._processAjaxResponse( response[0].childNodes ); + + // Check if user has set a onComplete function + var onRicoComplete = this.options.onRicoComplete; + if (onRicoComplete != null) + onRicoComplete(); + }, + + _processAjaxResponse: function( xmlResponseElements ) { + for ( var i = 0 ; i < xmlResponseElements.length ; i++ ) { + var responseElement = xmlResponseElements[i]; + + // only process nodes of type element..... + if ( responseElement.nodeType != 1 ) + continue; + + var responseType = responseElement.getAttribute("type"); + var responseId = responseElement.getAttribute("id"); + + if ( responseType == "object" ) + this._processAjaxObjectUpdate( this.ajaxObjects[ responseId ], responseElement ); + else if ( responseType == "element" ) + this._processAjaxElementUpdate( this.ajaxElements[ responseId ], responseElement ); + else + alert('unrecognized AjaxResponse type : ' + responseType ); + } + }, + + _processAjaxObjectUpdate: function( ajaxObject, responseElement ) { + ajaxObject.ajaxUpdate( responseElement ); + }, + + _processAjaxElementUpdate: function( ajaxElement, responseElement ) { + ajaxElement.innerHTML = RicoUtil.getContentAsString(responseElement); + } + +} + +Rico.includeLoaded('ricoAjaxEngine.js'); \ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoBehaviors.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoBehaviors.js new file mode 100644 index 0000000..ed5d572 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoBehaviors.js @@ -0,0 +1,188 @@ +/** + * (c) 2005-2007 Richard Cowin (http://openrico.org) + * + * Rico is licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + **/ + + +Rico.selectionSet = function(set, options){ + new Rico.SelectionSet(set, options) +} + +Rico.SelectionSet = Class.create(); +Rico.SelectionSet.prototype = { + initialize: function(selectionSet, options){ + this.options = options || {} + if (typeof selectionSet == 'string') + selectionSet = $$(selectionSet) + this.previouslySelected = []; + this.selectionSet = selectionSet; + this.selectedClassName = this.options.selectedClass || "selected"; + this.selectNode = this.options.selectNode || function(e){return e}; + this.onSelect = this.options.onSelect; + this.onFirstSelect = this.options.onFirstSelect; + this.clickHandler = this.click.bind(this); + selectionSet.each(function(e) {Event.observe(e, "click", new Rico.EventWrapper(this.clickHandler,e).wrapper);}.bind(this)) + if (!this.options.noDefault) + this.selectIndex(this.options.selectedIndex || 0) + }, + reset: function(){ + this.previouslySelected = []; + this.notifySelected(this.selected); + }, + select: function(element){ + if (this.selected == element) + return; + + if (this.selected) + new Element.ClassNames(this.selectNode(this.selected)).remove(this.selectedClassName) + + this.notifySelected(element) + + this.selected = element; + new Element.ClassNames(this.selectNode(this.selected)).add(this.selectedClassName) + }, + notifySelected: function(element){ + var index = this.selectionSet.indexOf(element) + if (this.onFirstSelect && !this.previouslySelected[index]){ + this.onFirstSelect(element, index) + this.previouslySelected[index] = true; + } + if (this.onSelect) + try{ + this.onSelect(element, index) + } catch (e) {} + }, + selectIndex: function(index){ + this.select(this.selectionSet[index]) + }, + nextSelectItem: function(index){ + var index = this.selectionSet.indexOf(this.selected) + if (index + 1 >= this.selectionSet.length) + return this.selectionSet[index - 1]; + else + return this.selectionSet[index + 1]; + }, + selectNext: function(){ + var index = this.selectionSet.indexOf(this.selected) + if (index >= this.selectionSet.length) + this.selectIndex(index - 1) + else + this.selectIndex(index + 1) + }, + click: function(event,target) { + this.select(target); + }, + add: function(item){ + // this.selectionSet.push(item) + if (item.constructur == Array) + item.each(function(e){ + Event.observe(e, "click", new Rico.EventWrapper(this.clickHandler,item).wrapper); + }.bind(this)) + else + Event.observe(item, "click", new Rico.EventWrapper(this.clickHandler,item).wrapper); + }, + remove: function(item){ + this.selectionSet = this.selectionSet.without(item) + //Todo: need to cleanup all events on item - need to keep track of eventwrappers + }, + removeAll: function(){ + + } + } + +Rico.HoverSet = Class.create(); +Rico.HoverSet.prototype = { + initialize: function(hoverSet, options){ + options = options || []; + this.hoverSet = hoverSet; + this.hoverClassName = options.hoverClass || "hover"; + this.hoverNodes = options.hoverNodes || function(e){return [e]}; + this.listenerHover = this._onHover.bind(this) + this.listenerEndHover = this._onUnHover.bind(this) + + this.hoverSet.each((function(e) {Event.observe(e, "mousemove", new Rico.EventWrapper(this.listenerHover,e).wrapper);}).bind(this)) + this.hoverSet.each((function(e) {Event.observe(e, "mouseout", new Rico.EventWrapper(this.listenerEndHover,e).wrapper);}).bind(this)) + }, + _onHover: function(event,target) { + this.hover(target); + }, + _onUnHover: function(event,target) { + this.unHover(target); + }, + hover: function(target) { + this.hoverNodes(target).each((function(t){Element.classNames(t).add(this.hoverClassName)}).bind(this)); + }, + unHover: function(target) { + this.hoverNodes(target).each((function(t){Element.classNames(t).remove(this.hoverClassName)}).bind(this)); + }, + add: function(item){ + Event.observe(item, "mousemove", new Rico.EventWrapper(this.listenerHover,item).wrapper); + Event.observe(item, "mouseout", new Rico.EventWrapper(this.listenerEndHover,item).wrapper); + }, + remove: function(item){ + //Todo: need to cleanup all events on item - need to keep terack of eventwrappers + //stopObserving + //Event.stopObserving(e, "mousemove", new Rico.EventWrapper(this.listenerHover,e).wrapper);}).bind(this)) + //this.hoverSet.each((function(e) {Event.observe(e, "mouseout", new Rico.EventWrapper(this.listenerEndHover,e).wrapper);}).bind(this)) + //hoverSet + }, + removeAll: function(item){ + } +} + + +Rico.Hover = { + groups: {}, + clearCurrent: function(group) { + var last_hover = Rico.Hover.groups[group]; + if(!last_hover) return + clearTimeout(last_hover[0]) + last_hover[1].end() + Rico.Hover.groups[group] = null; + }, + end: function(group) { + Rico.Hover.groups[group][1].end(); + }, + endWith: function(hover, group) { + var timer = setTimeout('Rico.Hover.end("'+ group + '")', hover.exitDelay) + Rico.Hover.groups[group] = [timer, hover] + } +} + +Rico.HoverDisplay = Class.create(); +Rico.HoverDisplay.prototype = { + initialize: function(element, options) { + this.element = element; + this.options = options || {}; + this.group = this.options.group; + this.exitDelay = this.options.delay || 1000; + }, + begin: function() { + Rico.Hover.clearCurrent(this.group) + Element.show(this.element) + }, + end: function(delay) { + if(delay) + Rico.Hover.endWith(this, this.group); + else + Element.hide(this.element) + } +} + + +Rico.EventWrapper = Class.create(); +Rico.EventWrapper.prototype = { + initialize: function(handler, target){ + this.handler = handler; + this.target = target; + this.wrapper = this.wrapperCall.bindAsEventListener(this) + }, + wrapperCall: function(event){ + this.handler(event, this.target) + } +} + +Rico.includeLoaded('ricoBehaviors.js'); diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoCalendar.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoCalendar.js new file mode 100644 index 0000000..8aa596c --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoCalendar.js @@ -0,0 +1,443 @@ +// By Matt Brown +// June-October 2006 +// email: dowdybrown@yahoo.com +// Implements a pop-up Gregorian calendar. +// Dates of adoption of the Gregorian calendar vary by country - accurate as a US & British calendar from 14 Sept 1752 to present. +// Mark special dates with calls to addHoliday() +// Inspired by code originally written by Tan Ling Wee on 2 Dec 2001 + +// Requires prototype.js and ricoCommon.js + +Rico.CalendarControl = Class.create(); + +Rico.CalendarControl.prototype = { + + initialize: function(id,options) { + this.id=id; + var today=new Date(); + Object.extend(this, new Rico.Popup({ignoreClicks:true})); + Object.extend(this.options, { + startAt : 0, // week starts with 0=sunday, 1=monday + showWeekNumber : 0, // show week number in first column? + showToday : 1, // show "Today is..." in footer? + cursorColor: '#FDD', // color used to highlight dates as the user moves their mouse + repeatInterval : 100, // when left/right arrow is pressed, repeat action every x milliseconds + dateFmt : 'ISO8601', // default is ISO-8601, 'rico'=use format stored in ricoTranslate object + selectedDateBorder : "#666666", // border to indicate currently selected date + minDate : new Date(today.getFullYear()-50,0,1), // default to +-50 yrs from current date + maxDate : new Date(today.getFullYear()+50,11,31) + }); + Object.extend(this.options, options || {}); + this.close=this.closePopup; + this.bPageLoaded=false; + this.img=new Array(); + this.Holidays={}; + this.todayString=RicoTranslate.getPhrase("Today is "); + this.weekString=RicoTranslate.getPhrase("Wk"); + if (this.options.dateFmt=='rico') this.options.dateFmt=RicoTranslate.dateFmt; + this.dateParts=new Array(); + this.re=/^\s*(\w+)(\W)(\w+)(\W)(\w+)/i; + if (this.re.exec(this.options.dateFmt)) { + this.dateParts[RegExp.$1]=0; + this.dateParts[RegExp.$3]=1; + this.dateParts[RegExp.$5]=2; + } + }, + + + // y=0 implies a repeating holiday + addHoliday : function(d, m, y, desc, bgColor, txtColor) { + this.Holidays[this.holidayKey(y,m-1,d)]={desc:desc, txtColor:txtColor, bgColor:bgColor || '#DDF'}; + }, + + holidayKey : function(y,m,d) { + return 'h'+y.toPaddedString(4)+m.toPaddedString(2)+d.toPaddedString(2); + }, + + atLoad : function() { + this.container=document.createElement("div"); + this.container.style.display="none" + this.container.id=this.id; + this.container.className='ricoCalContainer'; + + this.maintab=document.createElement("table"); + this.maintab.cellSpacing=0; + this.maintab.cellPadding=0; + this.maintab.border=0; + this.maintab.className='ricoCalTab'; + + for (var i=0; i<7; i++) { + var r=this.maintab.insertRow(-1); + r.className='row'+i; + for (var c=0; c<8; c++) + r.insertCell(-1); + } + this.tbody=this.maintab.tBodies[0]; + var r=this.tbody.rows[0]; + r.className='ricoCalDayNames'; + if (this.options.showWeekNumber) { + r.cells[0].innerHTML=this.weekString; + for (var i=0; i<7; i++) + this.tbody.rows[i].cells[0].className='ricoCalWeekNum'; + } + this.styles=[]; + for (var i=0; i<7; i++) { + var dow=(i+this.options.startAt) % 7; + r.cells[i+1].innerHTML=RicoTranslate.dayNames[dow].substring(0,3); + this.styles[i+1]='ricoCal'+dow; + } + + // table header (navigation controls) + this.thead=this.maintab.createTHead() + var r=this.thead.insertRow(-1); + var c=r.insertCell(-1); + c.colSpan=8; + var img=this.createNavArrow('decMonth','left'); + c.appendChild(document.createElement("a")).appendChild(img); + this.titleMonth=document.createElement("a"); + c.appendChild(this.titleMonth); + Event.observe(this.titleMonth,"click", this.popUpMonth.bindAsEventListener(this), false); + var img=this.createNavArrow('incMonth','right'); + c.appendChild(document.createElement("a")).appendChild(img); + var s=document.createElement("span"); + s.innerHTML=' '; + s.style.paddingLeft='3em'; + c.appendChild(s); + + var img=this.createNavArrow('decYear','left'); + c.appendChild(document.createElement("a")).appendChild(img); + this.titleYear=document.createElement("a"); + Event.observe(this.titleYear,"click", this.popUpYear.bindAsEventListener(this), false); + c.appendChild(this.titleYear); + var img=this.createNavArrow('incYear','right'); + c.appendChild(document.createElement("a")).appendChild(img); + + // table footer (today) + if (this.options.showToday) { + this.tfoot=this.maintab.createTFoot() + var r=this.tfoot.insertRow(-1); + this.todayCell=r.insertCell(-1); + this.todayCell.colSpan=8; + Event.observe(this.todayCell,"click", this.selectNow.bindAsEventListener(this), false); + } + + + this.container.appendChild(this.maintab); + + // close icon (upper right) + var img=document.createElement("img"); + img.src=Rico.imgDir+'close.gif'; + img.onclick=this.close.bind(this); + img.style.cursor='pointer'; + img.style.position='absolute'; + img.style.top='1px'; /* assumes a 1px border */ + img.style.right='1px'; + this.container.appendChild(img); + + // month selector + this.monthSelect=document.createElement("table"); + this.monthSelect.className='ricoCalMenu'; + this.monthSelect.cellPadding=2; + this.monthSelect.cellSpacing=0; + this.monthSelect.border=0; + for (var i=0; i<4; i++) { + var r=this.monthSelect.insertRow(-1); + for (var j=0; j<3; j++) { + var c=r.insertCell(-1); + var a=document.createElement("a"); + a.innerHTML=RicoTranslate.monthNames[i*3+j].substring(0,3); + a.name=i*3+j; + c.appendChild(a); + Event.observe(a,"click", this.selectMonth.bindAsEventListener(this), false); + } + } + this.monthSelect.style.display='none'; + this.container.appendChild(this.monthSelect); + + // fix anchors so they work in IE6 + var a=this.container.getElementsByTagName('a'); + for (var i=0; i this.options.maxDate.getFullYear()) return false; + if (yr == this.options.maxDate.getFullYear() && mo > this.options.maxDate.getMonth()) return false; + return true; + }, + + incMonth : function() { + var newMonth=this.monthSelected+1; + var newYear=this.yearSelected; + if (newMonth>11) { + newMonth=0; + newYear++; + } + if (!this.isValidMonth(newYear,newMonth)) return; + this.monthSelected=newMonth; + this.yearSelected=newYear; + this.constructCalendar() + }, + + decMonth : function() { + var newMonth=this.monthSelected-1; + var newYear=this.yearSelected; + if (newMonth<0) { + newMonth=11; + newYear--; + } + if (!this.isValidMonth(newYear,newMonth)) return; + this.monthSelected=newMonth; + this.yearSelected=newYear; + this.constructCalendar() + }, + + selectMonth : function(e) { + var el=Event.element(e); + this.monthSelected=parseInt(el.name); + this.constructCalendar(); + Event.stop(e); + }, + + popUpMonth : function() { + this.monthSelect.style.display=this.monthSelect.style.display=='none' ? 'block' : 'none'; + }, + + popDownMonth : function() { + this.monthSelect.style.display='none'; + }, + + /*** Year Pulldown ***/ + + popUpYear : function() { + var newYear=prompt(RicoTranslate.getPhrase("Year ("+this.options.minDate.getFullYear()+"-"+this.options.maxDate.getFullYear()+")"),this.yearSelected); + if (newYear==null) return; + newYear=parseInt(newYear); + if (isNaN(newYear) || newYearthis.options.maxDate.getFullYear()) { + alert(RicoTranslate.getPhrase("Invalid year")); + } else { + this.yearSelected=newYear; + this.constructCalendar(); + } + }, + + incYear : function() { + if (this.yearSelected>=this.options.maxDate.getFullYear()) return; + this.yearSelected++; + this.constructCalendar(); + }, + + decYear : function() { + if (this.yearSelected<=this.options.minDate.getFullYear()) return; + this.yearSelected--; + this.constructCalendar(); + }, + + // tried a number of different week number functions posted on the net + // this is the only one that produced consistent results when comparing week numbers for December and the following January + WeekNbr : function(year,month,day) { + var when = new Date(year,month,day); + var newYear = new Date(year,0,1); + var offset = 7 + 1 - newYear.getDay(); + if (offset == 8) offset = 1; + var daynum = ((Date.UTC(year,when.getMonth(),when.getDate(),0,0,0) - Date.UTC(year,0,1,0,0,0)) /1000/60/60/24) + 1; + var weeknum = Math.floor((daynum-offset+7)/7); + if (weeknum == 0) { + year--; + var prevNewYear = new Date(year,0,1); + var prevOffset = 7 + 1 - prevNewYear.getDay(); + if (prevOffset == 2 || prevOffset == 8) weeknum = 53; else weeknum = 52; + } + return weeknum; + }, + + constructCalendar : function() { + var aNumDays = Array (31,0,31,30,31,30,31,31,30,31,30,31) + var startDate = new Date (this.yearSelected,this.monthSelected,1) + var endDate,numDaysInMonth + + if (typeof this.monthSelected!='number' || this.monthSelected>=12 || this.monthSelected<0) { + alert('ERROR in calendar: monthSelected='+this.monthSelected); + return; + } + var today = new Date(); + this.dateNow = today.getDate(); + this.monthNow = today.getMonth(); + this.yearNow = today.getFullYear(); + + if (this.monthSelected==1) { + endDate = new Date (this.yearSelected,this.monthSelected+1,1); + endDate = new Date (endDate - (24*60*60*1000)); + numDaysInMonth = endDate.getDate() + } else { + numDaysInMonth = aNumDays[this.monthSelected]; + } + var dayPointer = startDate.getDay() - this.options.startAt + if (dayPointer<0) dayPointer+=7; + this.popDownMonth(); + + this.bgcolor=Element.getStyle(this.tbody,'background-color'); + this.bgcolor=this.bgcolor.replace(/\"/g,''); + if (this.options.showWeekNumber) { + for (var i=1; i<7; i++) + this.tbody.rows[i].cells[0].innerHTML=' '; + } + for ( var i=1; i<=dayPointer; i++ ) + this.resetCell(this.tbody.rows[1].cells[i]); + + for ( var datePointer=1,r=1; datePointer<=numDaysInMonth; datePointer++,dayPointer++ ) { + var colnum=dayPointer % 7 + 1; + if (this.options.showWeekNumber==1 && colnum==1) + this.tbody.rows[r].cells[0].innerHTML=this.WeekNbr(this.yearSelected,this.monthSelected,datePointer); + var dateClass=this.styles[colnum]; + if ((datePointer==this.dateNow)&&(this.monthSelected==this.monthNow)&&(this.yearSelected==this.yearNow)) + dateClass='ricoCalToday'; + var c=this.tbody.rows[r].cells[colnum]; + c.innerHTML=" " + datePointer + " "; + c.className=dateClass; + var bordercolor=(datePointer==this.odateSelected) && (this.monthSelected==this.omonthSelected) && (this.yearSelected==this.oyearSelected) ? this.options.selectedDateBorder : this.bgcolor; + c.style.border='1px solid '+bordercolor; + var h=this.Holidays[this.holidayKey(this.yearSelected,this.monthSelected,datePointer)]; + if (!h) h=this.Holidays[this.holidayKey(0,this.monthSelected,datePointer)]; + c.style.color=h ? h.txtColor : ''; + c.style.backgroundColor=h ? h.bgColor : ''; + c.title=h ? h.desc : ''; + if (colnum==7) r++; + } + while (dayPointer<42) { + var colnum=dayPointer % 7 + 1; + this.resetCell(this.tbody.rows[r].cells[colnum]); + dayPointer++; + if (colnum==7) r++; + } + + this.titleMonth.innerHTML = RicoTranslate.monthNames[this.monthSelected].substring(0,3); + this.titleYear.innerHTML = this.yearSelected; + if (this.options.showToday) + this.todayCell.innerHTML=this.todayString+''+this.dateNow + " " + RicoTranslate.monthNames[this.monthNow].substring(0,3) + " " + this.yearNow+''; + this.monthSelect.style.top=this.thead.offsetHeight+'px'; + this.monthSelect.style.left=this.titleMonth.offsetLeft+'px'; + }, + + resetCell: function(c) { + c.innerHTML=" "; + c.className='ricoCalEmpty'; + c.style.border='1px solid '+this.bgcolor; + c.style.color=''; + c.style.backgroundColor=''; + c.title=''; + }, + + saveAndClose : function(e) { + Event.stop(e); + var el=Event.element(e); + var s=el.innerHTML.replace(/ /g,''); + if (s=='' || el.className=='ricoCalWeekNum') return; + var day=parseInt(s); + if (isNaN(day)) return; + var d=new Date(this.yearSelected,this.monthSelected,day); + var dateStr=d.formatDate(this.options.dateFmt=='ISO8601' ? 'yyyy-mm-dd' : this.options.dateFmt); + if (this.returnValue) this.returnValue(dateStr); + this.close(); + }, + + open : function(curval) { + if (!this.bPageLoaded) return; + if (typeof curval=='object') { + this.dateSelected = curval.getDate(); + this.monthSelected = curval.getMonth(); + this.yearSelected = curval.getFullYear(); + } else if (this.options.dateFmt=='ISO8601') { + var d=new Date; + d.setISO8601(curval); + this.dateSelected = d.getDate(); + this.monthSelected = d.getMonth(); + this.yearSelected = d.getFullYear(); + } else if (this.re.exec(curval)) { + var aDate=new Array(RegExp.$1,RegExp.$3,RegExp.$5); + this.dateSelected = parseInt(aDate[this.dateParts['dd']], 10); + this.monthSelected = parseInt(aDate[this.dateParts['mm']], 10) - 1; + this.yearSelected = parseInt(aDate[this.dateParts['yyyy']], 10); + } else { + if (curval) alert('ERROR: invalid date passed to calendar ('+curval+')'); + this.dateSelected = this.dateNow + this.monthSelected = this.monthNow + this.yearSelected = this.yearNow + } + this.odateSelected=this.dateSelected + this.omonthSelected=this.monthSelected + this.oyearSelected=this.yearSelected + this.constructCalendar(); + this.openPopup(); + } +} + +Rico.includeLoaded('ricoCalendar.js'); diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoColor.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoColor.js new file mode 100644 index 0000000..84c3b98 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoColor.js @@ -0,0 +1,29 @@ +function attachValueChangeListeners() { + $('red').onkeypress = colorChangedDeffered; + $('green').onkeypress = colorChangedDeffered; + $('blue').onkeypress = colorChangedDeffered; +} + +function colorChangedDeffered() { + setTimeout( colorChanged, 1 ); +} + +function colorChanged() { + var red = Math.min( parseInt($('red').value) || 0, 255); + var green = Math.min( parseInt($('green').value) || 0, 255); + var blue = Math.min( parseInt($('blue').value) || 0, 255); + + var color = new Rico.Color( red, green, blue ); + + var newIllustrateString = " var color = new Rico.Color( "; + newIllustrateString += red + ", "; + newIllustrateString += green + ", "; + newIllustrateString += blue + " ); // color.asHex() = "; + newIllustrateString += color.asHex(); + + $('rgbCode').innerHTML = newIllustrateString; + $('colorBox').style.backgroundColor = color.asHex(); + //$('colorBox').innerHTML = color.asHex(); +} + +Rico.includeLoaded('ricoColor.js'); diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoColorPicker.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoColorPicker.js new file mode 100644 index 0000000..86ab657 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoColorPicker.js @@ -0,0 +1,75 @@ +// =================================================================== +// Original author: Matt Kruse +// WWW: http://www.mattkruse.com/ +// +// Adapted to Rico by Matt Brown +// =================================================================== + + +Rico.ColorPicker = Class.create(); + +Rico.ColorPicker.prototype = { + + initialize: function(id,options) { + this.id=id; + this.currentValue = "#FFFFFF"; + Object.extend(this, new Rico.Popup()); + Object.extend(this.options, { + showColorCode : false, + cellsPerRow : 18, + palette : [] + }); + var hexvals=['00','33','66','99','CC','FF']; + for (var g=0; g '; + if ( ((i+1)>=this.options.palette.length) || (((i+1) % width) == 0)) + cp_contents += ""; + } + var halfwidth = Math.floor(width/2); + if (this.options.showColorCode) + cp_contents += " #FFFFFF"; + else + cp_contents += " "; + cp_contents += ""; + this.container.innerHTML=cp_contents; + document.body.appendChild(this.container); + this.setDiv(this.container); + this.open=this.openPopup; + this.close=this.closePopup; + Event.observe(this.container,"mouseover", this.highlightColor.bindAsEventListener(this), false); + Event.observe(this.container,"click", this.selectColor.bindAsEventListener(this), false); + this.close(); + }, + + selectColor: function(e) { + if (this.returnValue) this.returnValue(this.currentValue); + this.close(); + }, + + // This function runs when you move your mouse over a color block, if you have a newer browser + highlightColor: function(e) { + var elem = Event.element(e); + if (!elem.tagName || elem.tagName.toLowerCase() != 'td') return; + var c=Rico.Color.createColorFromBackground(elem).toString(); + this.currentValue = c; + Element.setStyle('colorPickerSelectedColor',{'background-color':c}); + d = $("colorPickerSelectedColorValue"); + if (d) d.innerHTML = c; + } +} + +Rico.includeLoaded('ricoColorPicker.js'); diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoCommon.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoCommon.js new file mode 100644 index 0000000..0e6f4ea --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoCommon.js @@ -0,0 +1,739 @@ +/** + * + * Copyright 2005 Sabre Airline Solutions + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + **/ + +if (typeof Rico=='undefined') + throw("Cannot find the Rico object"); +if (typeof Prototype=='undefined') + throw("Rico requires the Prototype JavaScript framework"); +Rico.prototypeVersion = parseFloat(Prototype.Version.split(".")[0] + "." + Prototype.Version.split(".")[1]); +if (Rico.prototypeVersion < 1.3) + throw("Rico requires Prototype JavaScript framework version 1.3 or greater"); + +/** @singleton */ +var RicoUtil = { + + getDirectChildrenByTag: function(e, tagName) { + var kids = new Array(); + var allKids = e.childNodes; + tagName=tagName.toLowerCase(); + for( var i = 0 ; i < allKids.length ; i++ ) + if ( allKids[i] && allKids[i].tagName && allKids[i].tagName.toLowerCase() == tagName ) + kids.push(allKids[i]); + return kids; + }, + + createXmlDocument : function() { + if (document.implementation && document.implementation.createDocument) { + var doc = document.implementation.createDocument("", "", null); + + if (doc.readyState == null) { + doc.readyState = 1; + doc.addEventListener("load", function () { + doc.readyState = 4; + if (typeof doc.onreadystatechange == "function") + doc.onreadystatechange(); + }, false); + } + + return doc; + } + + if (window.ActiveXObject) + return Try.these( + function() { return new ActiveXObject('MSXML2.DomDocument') }, + function() { return new ActiveXObject('Microsoft.DomDocument')}, + function() { return new ActiveXObject('MSXML.DomDocument') }, + function() { return new ActiveXObject('MSXML3.DomDocument') } + ) || false; + + return null; + }, + + getInnerText: function(el) { + if (typeof el == "string") return el; + if (typeof el == "undefined") { return el }; + var cs = el.childNodes; + var l = cs.length; + var str = ""; + for (var i = 0; i < l; i++) { + switch (cs[i].nodeType) { + case 1: //ELEMENT_NODE + if (Element.getStyle(cs[i],'display')=='none') continue; + switch (cs[i].tagName.toLowerCase()) { + case 'img': str += cs[i].alt || cs[i].title || cs[i].src; break; + case 'input': if (cs[i].type=='hidden') continue; + case 'select': + case 'textarea': str += $F(cs[i]) || ''; break; + default: str += this.getInnerText(cs[i]); break; + } + break; + case 3: //TEXT_NODE + str += cs[i].nodeValue; + break; + } + } + return str; + }, + + // For Konqueror 3.5, isEncoded must be true + getContentAsString: function( parentNode, isEncoded ) { + if (isEncoded) return this._getEncodedContent(parentNode); + if (typeof parentNode.xml != 'undefined') return this._getContentAsStringIE(parentNode); + return this._getContentAsStringMozilla(parentNode); + }, + + _getEncodedContent: function(parentNode) { + if (parentNode.innerHTML) return parentNode.innerHTML; + switch (parentNode.childNodes.length) { + case 0: return ""; + case 1: return parentNode.firstChild.nodeValue; + default: return parentNode.childNodes[1].nodeValue; + } + }, + + _getContentAsStringIE: function(parentNode) { + var contentStr = ""; + for ( var i = 0 ; i < parentNode.childNodes.length ; i++ ) { + var n = parentNode.childNodes[i]; + if (n.nodeType == 4) { + contentStr += n.nodeValue; + } + else { + contentStr += n.xml; + } + } + return contentStr; + }, + + _getContentAsStringMozilla: function(parentNode) { + var xmlSerializer = new XMLSerializer(); + var contentStr = ""; + for ( var i = 0 ; i < parentNode.childNodes.length ; i++ ) { + var n = parentNode.childNodes[i]; + if (n.nodeType == 4) { // CDATA node + contentStr += n.nodeValue; + } + else { + contentStr += xmlSerializer.serializeToString(n); + } + } + return contentStr; + }, + + docElement: function() { + return (document.compatMode && document.compatMode.indexOf("CSS")!=-1) ? document.documentElement : document.getElementsByTagName("body")[0]; + }, + +/** + * return available height - excludes scrollbar & margin + */ + windowHeight: function() { + return window.innerHeight? window.innerHeight : this.docElement().clientHeight; + //return this.docElement().clientHeight; + }, + +/** + * return available width - excludes scrollbar & margin + */ + windowWidth: function() { + return this.docElement().clientWidth; + }, + + docScrollLeft: function() { + if ( window.pageXOffset ) + return window.pageXOffset; + else if ( document.documentElement && document.documentElement.scrollLeft ) + return document.documentElement.scrollLeft; + else if ( document.body ) + return document.body.scrollLeft; + else + return 0; + }, + + docScrollTop: function() { + if ( window.pageYOffset ) + return window.pageYOffset; + else if ( document.documentElement && document.documentElement.scrollTop ) + return document.documentElement.scrollTop; + else if ( document.body ) + return document.body.scrollTop; + else + return 0; + }, + + nan2zero: function(n) { + if (typeof(n)=='string') n=parseInt(n); + return isNaN(n) || typeof(n)=='undefined' ? 0 : n; + }, + + eventKey: function(e) { + if( typeof( e.keyCode ) == 'number' ) { + return e.keyCode; //DOM + } else if( typeof( e.which ) == 'number' ) { + return e.which; //NS 4 compatible + } else if( typeof( e.charCode ) == 'number' ) { + return e.charCode; //also NS 6+, Mozilla 0.9+ + } + return -1; //total failure, we have no way of obtaining the key code + }, + +/** + * Return the previous sibling that has the specified tagName + */ + getPreviosSiblingByTagName: function(el,tagName) { + var sib=el.previousSibling; + while (sib) { + if ((sib.tagName==tagName) && (sib.style.display!='none')) return sib; + sib=sib.previousSibling; + } + return null; + }, + +/** + * Return the parent HTML element that has the specified tagName. + * @param className optional + */ + getParentByTagName: function(el,tagName,className) { + var par=el; + tagName=tagName.toLowerCase(); + while (par) { + if (par.tagName && par.tagName.toLowerCase()==tagName) + if (!className || par.className.indexOf(className)>=0) return par; + par=par.parentNode; + } + return null; + }, + +/** + * Wrap the children of a DOM element in a new element + * @param el the element whose children are to be wrapped + * @param cls class name of the wrapper (optional) + * @param id id of the wrapper (optional) + * @param wrapperTag type of wrapper element to be created (optional, defaults to DIV) + */ + wrapChildren: function(el,cls,id,wrapperTag) { + var tag=wrapperTag || 'div'; + var wrapper = document.createElement(tag); + if (id) wrapper.id=id; + if (cls) wrapper.className=cls; + while (el.firstChild) + wrapper.appendChild(el.firstChild); + el.appendChild(wrapper); + return wrapper; + }, + +/** + * Format a positive number + * @param decPlaces the number of digits to display after the decimal point + * @param thouSep the character to use as the thousands separator + * @param decPoint the character to use as the decimal point + */ + formatPosNumber: function(posnum,decPlaces,thouSep,decPoint) { + var a=posnum.toFixed(decPlaces).split(/\./); + if (thouSep) { + var rgx = /(\d+)(\d{3})/; + while (rgx.test(a[0])) + a[0]=a[0].replace(rgx, '$1'+thouSep+'$2'); + } + return a.join(decPoint); + }, + +/** + * Post condition - if childNodes[n] is refChild, than childNodes[n+1] is newChild. + */ + DOMNode_insertAfter: function(newChild,refChild) { + var parentx=refChild.parentNode; + if(parentx.lastChild==refChild) { return parentx.appendChild(newChild);} + else {return parentx.insertBefore(newChild,refChild.nextSibling);} + }, + + positionCtlOverIcon: function(ctl,icon) { + if (ctl.style.display=='none') ctl.style.display='block'; + var offsets=Position.page(icon); + var correction=Prototype.Browser.IE ? 1 : 2; // based on a 1px border + var lpad=this.nan2zero(Element.getStyle(icon,'padding-left')) + ctl.style.left = (offsets[0]+lpad+correction)+'px'; + var scrTop=this.docScrollTop(); + var newTop=offsets[1] + correction + scrTop; + var ctlht=ctl.offsetHeight; + var iconht=icon.offsetHeight; + if (newTop+iconht+ctlht < this.windowHeight()+scrTop) + newTop+=iconht; // display below icon + else + newTop=Math.max(newTop-ctlht,scrTop); // display above icon + ctl.style.top = newTop+'px'; + }, + + createFormField: function(parent,elemTag,elemType,id,name) { + if (typeof name!='string') name=id; + if (Prototype.Browser.IE) { + // IE cannot set NAME attribute on dynamically created elements + var s=elemTag+' id="'+id+'"'; + if (elemType) s+=' type="'+elemType+'"'; + if (elemTag.match(/^(form|input|select|textarea|object|button|img)$/)) s+=' name="'+name+'"'; + var field=document.createElement('<'+s+' />'); + } else { + var field=document.createElement(elemTag); + if (elemType) field.type=elemType; + field.id=id; + if (typeof field.name=='string') field.name=name; + } + parent.appendChild(field); + return field; + }, + +/** + * Gets the value of the specified cookie + */ + getCookie: function(itemName) { + var arg = itemName+'='; + var alen = arg.length; + var clen = document.cookie.length; + var i = 0; + while (i < clen) { + var j = i + alen; + if (document.cookie.substring(i, j) == arg) { + var endstr = document.cookie.indexOf (';', j); + if (endstr == -1) endstr=document.cookie.length; + return unescape(document.cookie.substring(j, endstr)); + } + i = document.cookie.indexOf(' ', i) + 1; + if (i == 0) break; + } + return null; + }, + +/** + * Write information to cookie. + * For cookies to be retained for the current session only, set daysToKeep=null. + * To erase a cookie, pass a negative daysToKeep value. + */ + setCookie: function(itemName,itemValue,daysToKeep,cookiePath,cookieDomain) { + var c = itemName+"="+escape(itemValue); + if (typeof(daysToKeep)=='number') { + var date = new Date(); + date.setTime(date.getTime()+(daysToKeep*24*60*60*1000)); + c+="; expires="+date.toGMTString(); + } + if (typeof(cookiePath)=='string') c+="; path="+cookiePath; + if (typeof(cookieDomain)=='string') c+="; domain="+cookieDomain; + document.cookie = c; + } + +}; + + +// Translation helper object +/** @singleton */ +var RicoTranslate = { + phrases : {}, + thouSep : ",", + decPoint: ".", + langCode: "en", + re : /^(\W*)\b(.*)\b(\W*)$/, + dateFmt : "mm/dd/yyyy", + timeFmt : "hh:nn:ss a/pm", + monthNames: ['January','February','March','April','May','June', + 'July','August','September','October','November','December'], + dayNames: ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'], + + addPhrase: function(fromPhrase, toPhrase) { + this.phrases[fromPhrase]=toPhrase; + }, + +/** + * fromPhrase may contain multiple words/phrases separated by tabs + * and each portion will be looked up separately. + * Punctuation & spaces at the beginning or + * ending of a phrase are ignored. + */ + getPhrase: function(fromPhrase) { + var words=fromPhrase.split(/\t/); + var transWord,translated = ''; + for (var i=0; iformat is an integer in the range 1-6:
+ *
1 (year)
+ *
YYYY (eg 1997)
+ *
2 (year and month)
+ *
YYYY-MM (eg 1997-07)
+ *
3 (complete date)
+ *
YYYY-MM-DD (eg 1997-07-16)
+ *
4 (complete date plus hours and minutes)
+ *
YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)
+ *
5 (complete date plus hours, minutes and seconds)
+ *
YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)
+ *
6 (complete date plus hours, minutes, seconds and a decimal + * fraction of a second)
+ *
YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)
+ *
+ * Based on: http://www.codeproject.com/jscript/dateformat.asp + */ + Date.prototype.toISO8601String = function (format, offset) { + if (!format) { var format = 6; } + if (!offset) { + var offset = 'Z'; + var date = this; + } else { + var d = offset.match(/([-+])([0-9]{2}):([0-9]{2})/); + var offsetnum = (Number(d[2]) * 60) + Number(d[3]); + offsetnum *= ((d[1] == '-') ? -1 : 1); + var date = new Date(Number(Number(this) + (offsetnum * 60000))); + } + + var zeropad = function (num) { return ((num < 10) ? '0' : '') + num; } + + var str = ""; + str += date.getUTCFullYear(); + if (format > 1) { str += "-" + zeropad(date.getUTCMonth() + 1); } + if (format > 2) { str += "-" + zeropad(date.getUTCDate()); } + if (format > 3) { + str += "T" + zeropad(date.getUTCHours()) + + ":" + zeropad(date.getUTCMinutes()); + } + if (format > 5) { + var secs = Number(date.getUTCSeconds() + "." + + ((date.getUTCMilliseconds() < 100) ? '0' : '') + + zeropad(date.getUTCMilliseconds())); + str += ":" + zeropad(secs); + } else if (format > 4) { str += ":" + zeropad(date.getUTCSeconds()); } + + if (format > 3) { str += offset; } + return str; + } +} + +if (!String.prototype.formatDate) { + String.prototype.formatDate = function(fmt) { + var s=this.replace(/-/g,'/'); + var d = new Date(s); + return isNaN(d) ? this : d.formatDate(fmt); + } +} + +if (!Number.prototype.formatNumber) { +/** + * Format a number according to the specs in assoc array 'fmt'. + * Result is a string, wrapped in a span element with a class of: negNumber, zeroNumber, posNumber + * These classes can be set in CSS to display negative numbers in red, for example. + * + *

fmt may contain:

+ *
multiplier
the original number is multiplied by this amount before formatting
+ *
decPlaces
number of digits to the right of the decimal point
+ *
decPoint
character to be used as the decimal point
+ *
thouSep
character to use as the thousands separator
+ *
prefix
string added to the beginning of the result (e.g. a currency symbol)
+ *
suffix
string added to the end of the result (e.g. % symbol)
+ *
negSign
specifies format for negative numbers: L=leading minus, T=trailing minus, P=parens
+ *
+ */ + Number.prototype.formatNumber = function(fmt) { + if (isNaN(this)) return 'NaN'; + var n=this; + if (typeof fmt.multiplier=='number') n*=fmt.multiplier; + var decPlaces=typeof fmt.decPlaces=='number' ? fmt.decPlaces : 0; + var thouSep=typeof fmt.thouSep=='string' ? fmt.thouSep : RicoTranslate.thouSep; + var decPoint=typeof fmt.decPoint=='string' ? fmt.decPoint : RicoTranslate.decPoint; + var prefix=fmt.prefix || ""; + var suffix=fmt.suffix || ""; + var negSign=typeof fmt.negSign=='string' ? fmt.negSign : "L"; + negSign=negSign.toUpperCase(); + var s,cls; + if (n<0.0) { + s=RicoUtil.formatPosNumber(-n,decPlaces,thouSep,decPoint); + if (negSign=="P") s="("+s+")"; + s=prefix+s; + if (negSign=="L") s="-"+s; + if (negSign=="T") s+="-"; + cls='negNumber'; + } else { + cls=n==0.0 ? 'zeroNumber' : 'posNumber'; + s=prefix+RicoUtil.formatPosNumber(n,decPlaces,thouSep,decPoint); + } + return ""+s+suffix+""; + } +} + +if (!String.prototype.formatNumber) { +/** + * Take a string that can be converted via parseFloat + * and format it according to the specs in assoc array 'fmt'. + */ + String.prototype.formatNumber = function(fmt) { + var n=parseFloat(this); + return isNaN(n) ? this : n.formatNumber(fmt); + } +} + +/** + * Fix select control bleed-thru on floating divs in IE. + * Based on technique published by Joe King at: + * http://dotnetjunkies.com/WebLog/jking/archive/2003/10/30/2975.aspx + */ +Rico.Shim = Class.create(); + +if (Prototype.Browser.IE) { + Rico.Shim.prototype = { + + initialize: function(DivRef) { + this.ifr = document.createElement('iframe'); + this.ifr.style.position="absolute"; + this.ifr.style.display = "none"; + this.ifr.src="javascript:false;"; + DivRef.parentNode.appendChild(this.ifr); + this.DivRef=DivRef; + }, + + hide: function() { + this.ifr.style.display = "none"; + }, + + show: function() { + this.ifr.style.width = this.DivRef.offsetWidth; + this.ifr.style.height = this.DivRef.offsetHeight; + this.ifr.style.top = this.DivRef.style.top; + this.ifr.style.left = this.DivRef.style.left; + this.ifr.style.zIndex = this.DivRef.currentStyle.zIndex - 1; + this.ifr.style.display = "block"; + } + } +} else { + Rico.Shim.prototype = { + initialize: function() {}, + hide: function() {}, + show: function() {} + } +} + + +/** + * Rico.Shadow is intended for positioned elements. + * Uses blur filter in IE, and alpha-transparent png images for all other browsers. + * Based on: http://www.positioniseverything.net/articles/dropshadows.html + */ +Rico.Shadow = Class.create(); + +Rico.Shadow.prototype = { + + initialize: function(DivRef) { + this.div = document.createElement('div'); + this.div.style.position="absolute"; + if (typeof this.div.style.filter=='undefined') { + new Image().src = Rico.imgDir+"shadow.png"; + new Image().src = Rico.imgDir+"shadow_ur.png"; + new Image().src = Rico.imgDir+"shadow_ll.png"; + this.createShadow(); + this.offset=5; + } else { + this.div.style.backgroundColor='#888'; + this.div.style.filter='progid:DXImageTransform.Microsoft.Blur(makeShadow=1, shadowOpacity=0.3, pixelRadius=3)'; + this.offset=0; // MS blur filter already does offset + } + this.div.style.display = "none"; + DivRef.parentNode.appendChild(this.div); + this.DivRef=DivRef; + }, + + createShadow: function() { + var tab = document.createElement('table'); + tab.style.height='100%'; + tab.style.width='100%'; + tab.cellSpacing=0; + tab.dir='ltr'; + + var tr1=tab.insertRow(-1); + tr1.style.height='8px'; + var td11=tr1.insertCell(-1); + td11.style.width='8px'; + var td12=tr1.insertCell(-1); + td12.style.background="transparent url("+Rico.imgDir+"shadow_ur.png"+") no-repeat right bottom" + + var tr2=tab.insertRow(-1); + var td21=tr2.insertCell(-1); + td21.style.background="transparent url("+Rico.imgDir+"shadow_ll.png"+") no-repeat right bottom" + var td22=tr2.insertCell(-1); + td22.style.background="transparent url("+Rico.imgDir+"shadow.png"+") no-repeat right bottom" + + this.div.appendChild(tab); + }, + + hide: function() { + this.div.style.display = "none"; + }, + + show: function() { + this.div.style.width = this.DivRef.offsetWidth + 'px'; + this.div.style.height= this.DivRef.offsetHeight + 'px'; + this.div.style.top = (parseInt(this.DivRef.style.top)+this.offset)+'px'; + this.div.style.left = (parseInt(this.DivRef.style.left)+this.offset)+'px'; + this.div.style.zIndex= parseInt(Element.getStyle(this.DivRef,'z-index')) - 1; + this.div.style.display = "block"; + } +} + + +Rico.Popup = Class.create(); + +Rico.Popup.prototype = { + + initialize: function(options,DivRef) { + this.options = { + hideOnEscape : true, + hideOnClick : true, + ignoreClicks : false, + position : 'absolute', + shadow : true + } + Object.extend(this.options, options || {}); + if (DivRef) this.setDiv(DivRef); + }, + + setDiv: function(DivRef,closeFunc) { + this.divPopup=$(DivRef); + var position=this.options.position == 'auto' ? Element.getStyle(this.divPopup,'position').toLowerCase() : this.options.position; + if (!this.divPopup || position != 'absolute') return; + this.closeFunc=closeFunc || this.closePopup.bindAsEventListener(this); + this.shim=new Rico.Shim(this.divPopup); + if (this.options.shadow) + this.shadow=new Rico.Shadow(this.divPopup); + if (this.options.hideOnClick) + Event.observe(document,"click", this.closeFunc); + if (this.options.hideOnEscape) + Event.observe(document,"keyup", this._checkKey.bindAsEventListener(this)); + if (this.options.ignoreClicks) this.ignoreClicks(); + }, + + ignoreClicks: function() { + Event.observe(this.divPopup,"click", this._ignoreClick.bindAsEventListener(this)); + }, + + _ignoreClick: function(e) { + if (e.stopPropagation) + e.stopPropagation(); + else + e.cancelBubble = true; + return true; + }, + + // event handler to process keyup events (hide menu on escape key) + _checkKey: function(e) { + if (RicoUtil.eventKey(e)==27) this.closeFunc(); + return true; + }, + + openPopup: function(left,top) { + if (typeof left=='number') this.divPopup.style.left=left+'px'; + if (typeof top=='number') this.divPopup.style.top=top+'px'; + this.divPopup.style.display="block"; + if (this.shim) this.shim.show(); + if (this.shadow) this.shadow.show(); + }, + + closePopup: function() { + if (this.shim) this.shim.hide(); + if (this.shadow) this.shadow.hide(); + this.divPopup.style.display="none" + } + +} + +Rico.includeLoaded('ricoCommon.js'); diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoComponents.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoComponents.js new file mode 100644 index 0000000..1db5830 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoComponents.js @@ -0,0 +1,194 @@ +/** + * (c) 2005-2007 Richard Cowin (http://openrico.org) + * (c) 2005-2007 Matt Brown (http://dowdybrown.com) + * + * Rico is licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + **/ + + +Rico.ContentTransitionBase = function() {} +Rico.ContentTransitionBase.prototype = { + initialize: function(titles, contents, options) { + if (typeof titles == 'string') + titles = $$(titles) + if (typeof contents == 'string') + contents = $$(contents) + + this.titles = titles; + this.contents = contents; + this.options = Object.extend({ + duration:200, + steps:8, + rate:Rico.Effect.easeIn + }, options || {}); + this.hoverSet = new Rico.HoverSet(titles, options); + contents.each(function(p){ if (p) Element.hide(p)}) + this.selectionSet = new Rico.SelectionSet(titles, Object.extend(this.options, {onSelect: this.select.bind(this)})); + if (this.initContent) this.initContent(); + }, + reset: function(){ + this.selectionSet.reset(); + }, + select: function(title) { + if ( this.selected == this.contentOf(title)) return + var panel = this.contentOf(title); + if (this.transition){ + if (this.selected){ + var effect = this.transition(panel) + if (effect) Rico.animate(effect, this.options) + } + else + Element.show(panel); + }else{ + if (this.selected) + Element.hide(this.selected) + Element.show(panel); + } + this.selected = panel; + }, + add: function(title, content){ + this.titles.push(title); + this.contents.push(content); + this.hoverSet.add(title); + this.selectionSet.add(title); + this.selectionSet.select(title); + }, + remove: function(title){}, + removeAll: function(){ + this.hoverSet.removeAll(); + this.selectionSet.removeAll(); + }, + openByIndex: function(index){this.selectionSet.selectIndex(index)}, + contentOf: function(title){ return this.contents[this.titles.indexOf(title)]} +} + +Rico.ContentTransition = Class.create(); +Rico.ContentTransition.prototype = Object.extend(new Rico.ContentTransitionBase(),{}); + +Rico.SlidingPanel = Class.create(); +Rico.SlidingPanel.prototype = { + initialize: function(panel) { + this.panel = panel; + this.options = arguments[1] || {}; + this.closed = true; + this.showing = false + this.openEffect = this.options.openEffect; + this.closeEffect = this.options.closeEffect; + this.animator = new Rico.Effect.Animator(); + Element.makeClipping(this.panel) + }, + toggle: function () { + if(!this.showing){ + this.open(); + } else { + this.close(); + } + }, + open: function () { + if (this.closed){ + this.showing = true; + Element.show(this.panel); + this.options.disabler.disableNative(); + } + /*this.animator.stop();*/ + this.animator.play(this.openEffect, + { onFinish:function(){ Element.undoClipping($(this.panel))}.bind(this), + rate:Rico.Effect.easeIn}); + }, + close: function () { + Element.makeClipping(this.panel) + this.animator.stop(); + this.showing = false; + this.animator.play(this.closeEffect, + { onFinish:function(){ Element.hide(this.panel); + this.options.disabler.enableNative()}.bind(this), + rate:Rico.Effect.easeOut}); + } +} + + +//------------------------------------------- +// Example components +//------------------------------------------- + +Rico.Accordion = Class.create(); +Rico.Accordion.prototype = Object.extend(new Rico.ContentTransitionBase(), { + initContent: function() { + this.selected.style.height = this.options.panelHeight + "px"; + }, + transition: function(p){ + if (!this.options.noAnimate) + return new Rico.AccordionEffect(this.selected, p, this.options.panelHeight); + else{ + p.style.height = this.options.panelHeight + "px"; + if (this.selected) Element.hide(this.selected); + Element.show(p); + } + } +}) + + +Rico.TabbedPanel = Class.create(); +Rico.TabbedPanel.prototype = Object.extend(new Rico.ContentTransitionBase(), { + initContent: function() { + if (false && (this.options.panelHeight=='auto' || this.options.panelWidth=='auto')) { + // 'auto' is not working yet + var maxwi=0, maxht=0; + for (var i=0; i=0; i--) { + if (x >= Position.positionedOffset(this.cols[i])[0]) + return this.cols[i]; + } + return this.cols[0]; + }, + + destroy: function() { + try{ + for (var i=0; i= Position.positionedOffset(panels[insertPos+1])[1]) { + if (panels[insertPos + 2]) + newCol.insertBefore(this.insertionOutline, panels[insertPos+2]); + else + newCol.appendChild(this.insertionOutline); + } + this.insertionColumn = newCol; + }, + + _moveInsertion: function(column){ + if (this.insertionColumn != column) { + this.insertionColumn.removeChild(this.insertionOutline) + this.insertionColumn = column; + column.appendChild(this.insertionOutline); + } + }, + + columnPanels: function(column){ + var panels = []; + for (var i=0; i 0; + }, + + setStartDragFromElement: function( e, mouseDownElement ) { + this.origPos = RicoUtil.toDocumentPosition(mouseDownElement); + this.startx = e.screenX - this.origPos.x + this.starty = e.screenY - this.origPos.y + //this.startComponentX = e.layerX ? e.layerX : e.offsetX; + //this.startComponentY = e.layerY ? e.layerY : e.offsetY; + //this.adjustedForDraggableSize = false; + + this.interestedInMotionEvents = this.hasSelection(); + this._terminateEvent(e); + }, + + updateSelection: function( draggable, extendSelection ) { + if ( ! extendSelection ) + this.clearSelection(); + + if ( draggable.isSelected() ) { + this.currentDragObjects.removeItem(draggable); + draggable.deselect(); + if ( draggable == this.lastSelectedDraggable ) + this.lastSelectedDraggable = null; + } + else { + this.currentDragObjects[ this.currentDragObjects.length ] = draggable; + draggable.select(); + this.lastSelectedDraggable = draggable; + } + }, + + _mouseDownHandler: function(e) { + if ( arguments.length == 0 ) + e = event; + + // if not button 1 ignore it... + var nsEvent = e.which != undefined; + if ( (nsEvent && e.which != 1) || (!nsEvent && e.button != 1)) + return; + + var eventTarget = e.target ? e.target : e.srcElement; + var draggableObject = eventTarget.draggable; + + var candidate = eventTarget; + while (draggableObject == null && candidate.parentNode) { + candidate = candidate.parentNode; + draggableObject = candidate.draggable; + } + + if ( draggableObject == null ) + return; + + this.updateSelection( draggableObject, e.ctrlKey ); + + // clear the drop zones postion cache... + if ( this.hasSelection() ) + for ( var i = 0 ; i < this.dropZones.length ; i++ ) + this.dropZones[i].clearPositionCache(); + + this.setStartDragFromElement( e, draggableObject.getMouseDownHTMLElement() ); + }, + + + _mouseMoveHandler: function(e) { + var nsEvent = e.which != undefined; + if ( !this.interestedInMotionEvents ) { + //this._terminateEvent(e); + return; + } + + if ( ! this.hasSelection() ) + return; + + if ( ! this.currentDragObjectVisible ) + this._startDrag(e); + + if ( !this.activatedDropZones ) + this._activateRegisteredDropZones(); + + //if ( !this.adjustedForDraggableSize ) + // this._adjustForDraggableSize(e); + + this._updateDraggableLocation(e); + this._updateDropZonesHover(e); + + this._terminateEvent(e); + }, + + _makeDraggableObjectVisible: function(e) + { + if ( !this.hasSelection() ) + return; + + var dragElement; + if ( this.currentDragObjects.length > 1 ) + dragElement = this.currentDragObjects[0].getMultiObjectDragGUI(this.currentDragObjects); + else + dragElement = this.currentDragObjects[0].getSingleObjectDragGUI(); + + // go ahead and absolute position it... + if ( RicoUtil.getElementsComputedStyle(dragElement, "position") != "absolute" ) +/* if (Element.getStyle(dragElement,'position')=='absolute')*/ + dragElement.style.position = "absolute"; + + // need to parent him into the document... + if ( dragElement.parentNode == null || dragElement.parentNode.nodeType == 11 ) + document.body.appendChild(dragElement); + + this.dragElement = dragElement; + this._updateDraggableLocation(e); + + this.currentDragObjectVisible = true; + }, + + /** + _adjustForDraggableSize: function(e) { + var dragElementWidth = this.dragElement.offsetWidth; + var dragElementHeight = this.dragElement.offsetHeight; + if ( this.startComponentX > dragElementWidth ) + this.startx -= this.startComponentX - dragElementWidth + 2; + if ( e.offsetY ) { + if ( this.startComponentY > dragElementHeight ) + this.starty -= this.startComponentY - dragElementHeight + 2; + } + this.adjustedForDraggableSize = true; + }, + **/ + + _leftOffset: function(e) { + return e.offsetX ? document.body.scrollLeft : 0 + }, + + _topOffset: function(e) { + return e.offsetY ? document.body.scrollTop:0 + }, + + + _updateDraggableLocation: function(e) { + var dragObjectStyle = this.dragElement.style; + dragObjectStyle.left = (e.screenX + this._leftOffset(e) - this.startx) + "px" + dragObjectStyle.top = (e.screenY + this._topOffset(e) - this.starty) + "px"; + }, + + _updateDropZonesHover: function(e) { + var n = this.dropZones.length; + for ( var i = 0 ; i < n ; i++ ) { + if ( ! this._mousePointInDropZone( e, this.dropZones[i] ) ) + this.dropZones[i].hideHover(); + } + + for ( var i = 0 ; i < n ; i++ ) { + if ( this._mousePointInDropZone( e, this.dropZones[i] ) ) { + if ( this.dropZones[i].canAccept(this.currentDragObjects) ) + this.dropZones[i].showHover(); + } + } + }, + + _startDrag: function(e) { + for ( var i = 0 ; i < this.currentDragObjects.length ; i++ ) + this.currentDragObjects[i].startDrag(); + + this._makeDraggableObjectVisible(e); + }, + + _mouseUpHandler: function(e) { + if ( ! this.hasSelection() ) + return; + + var nsEvent = e.which != undefined; + if ( (nsEvent && e.which != 1) || (!nsEvent && e.button != 1)) + return; + + this.interestedInMotionEvents = false; + + if ( this.dragElement == null ) { + this._terminateEvent(e); + return; + } + + if ( this._placeDraggableInDropZone(e) ) + this._completeDropOperation(e); + else { + this._terminateEvent(e); + Rico.animate(new Rico.Effect.Position( this.dragElement, this.origPos.x, this.origPos.y), + {duration: 200, + steps: 20, + onFinish : this._doCancelDragProcessing.bind(this) } ); + } + + Event.stopObserving(document.body, "mousemove", this._mouseMove); + Event.stopObserving(document.body, "mouseup", this._mouseUp); + }, + + _retTrue: function () { + return true; + }, + + _completeDropOperation: function(e) { + if ( this.dragElement != this.currentDragObjects[0].getMouseDownHTMLElement() ) { + if ( this.dragElement.parentNode != null ) + this.dragElement.parentNode.removeChild(this.dragElement); + } + + this._deactivateRegisteredDropZones(); + this._endDrag(); + this.clearSelection(); + this.dragElement = null; + this.currentDragObjectVisible = false; + this._terminateEvent(e); + }, + + _doCancelDragProcessing: function() { + this._cancelDrag(); + + if ( this.dragElement != this.currentDragObjects[0].getMouseDownHTMLElement() && this.dragElement) + if ( this.dragElement.parentNode != null ) + this.dragElement.parentNode.removeChild(this.dragElement); + + + this._deactivateRegisteredDropZones(); + this.dragElement = null; + this.currentDragObjectVisible = false; + }, + + _placeDraggableInDropZone: function(e) { + var foundDropZone = false; + var n = this.dropZones.length; + for ( var i = 0 ; i < n ; i++ ) { + if ( this._mousePointInDropZone( e, this.dropZones[i] ) ) { + if ( this.dropZones[i].canAccept(this.currentDragObjects) ) { + this.dropZones[i].hideHover(); + this.dropZones[i].accept(this.currentDragObjects); + foundDropZone = true; + break; + } + } + } + + return foundDropZone; + }, + + _cancelDrag: function() { + for ( var i = 0 ; i < this.currentDragObjects.length ; i++ ) + this.currentDragObjects[i].cancelDrag(); + }, + + _endDrag: function() { + for ( var i = 0 ; i < this.currentDragObjects.length ; i++ ) + this.currentDragObjects[i].endDrag(); + }, + + _mousePointInDropZone: function( e, dropZone ) { + + var absoluteRect = dropZone.getAbsoluteRect(); + + return e.clientX > absoluteRect.left + this._leftOffset(e) && + e.clientX < absoluteRect.right + this._leftOffset(e) && + e.clientY > absoluteRect.top + this._topOffset(e) && + e.clientY < absoluteRect.bottom + this._topOffset(e); + }, + + _addMouseDownHandler: function( aDraggable ) + { + htmlElement = aDraggable.getMouseDownHTMLElement(); + if ( htmlElement != null ) { + htmlElement.draggable = aDraggable; + Event.observe(htmlElement , "mousedown", this._onmousedown.bindAsEventListener(this)); + Event.observe(htmlElement, "mousedown", this._mouseDown); + } + }, + + _activateRegisteredDropZones: function() { + var n = this.dropZones.length; + for ( var i = 0 ; i < n ; i++ ) { + var dropZone = this.dropZones[i]; + if ( dropZone.canAccept(this.currentDragObjects) ) + dropZone.activate(); + } + + this.activatedDropZones = true; + }, + + _deactivateRegisteredDropZones: function() { + var n = this.dropZones.length; + for ( var i = 0 ; i < n ; i++ ) + this.dropZones[i].deactivate(); + this.activatedDropZones = false; + }, + + _onmousedown: function () { + Event.observe(document.body, "mousemove", this._mouseMove); + Event.observe(document.body, "mouseup", this._mouseUp); + }, + + _terminateEvent: function(e) { + if ( e.stopPropagation != undefined ) + e.stopPropagation(); + else if ( e.cancelBubble != undefined ) + e.cancelBubble = true; + + if ( e.preventDefault != undefined ) + e.preventDefault(); + else + e.returnValue = false; + }, + + + initializeEventHandlers: function() { + if ( typeof document.implementation != "undefined" && + document.implementation.hasFeature("HTML", "1.0") && + document.implementation.hasFeature("Events", "2.0") && + document.implementation.hasFeature("CSS", "2.0") ) { + document.addEventListener("mouseup", this._mouseUpHandler.bindAsEventListener(this), false); + document.addEventListener("mousemove", this._mouseMoveHandler.bindAsEventListener(this), false); + } + else { + document.attachEvent( "onmouseup", this._mouseUpHandler.bindAsEventListener(this) ); + document.attachEvent( "onmousemove", this._mouseMoveHandler.bindAsEventListener(this) ); + } + } + } + + var dndMgr = new Rico.DragAndDrop(); + dndMgr.initializeEventHandlers(); + + +//-------------------- ricoDraggable.js +Rico.Draggable = Class.create(); + +Rico.Draggable.prototype = { + + initialize: function( type, htmlElement ) { + this.type = type; + this.htmlElement = $(htmlElement); + this.selected = false; + }, + + /** + * Returns the HTML element that should have a mouse down event + * added to it in order to initiate a drag operation + * + **/ + getMouseDownHTMLElement: function() { + return this.htmlElement; + }, + + select: function() { + this.selected = true; + + if ( this.showingSelected ) + return; + + var htmlElement = this.getMouseDownHTMLElement(); + + var color = Rico.Color.createColorFromBackground(htmlElement); + color.isBright() ? color.darken(0.033) : color.brighten(0.033); + + this.saveBackground = RicoUtil.getElementsComputedStyle(htmlElement, "backgroundColor", "background-color"); +// this.saveBackground = Element.getStyle(htmlElement,'backgroundColor') || Element.getStyle(htmlElement,'background-color') + htmlElement.style.backgroundColor = color.asHex(); + this.showingSelected = true; + }, + + deselect: function() { + this.selected = false; + if ( !this.showingSelected ) + return; + + var htmlElement = this.getMouseDownHTMLElement(); + + htmlElement.style.backgroundColor = this.saveBackground; + this.showingSelected = false; + }, + + isSelected: function() { + return this.selected; + }, + + startDrag: function() { + }, + + cancelDrag: function() { + }, + + endDrag: function() { + }, + + getSingleObjectDragGUI: function() { + return this.htmlElement; + }, + + getMultiObjectDragGUI: function( draggables ) { + return this.htmlElement; + }, + + getDroppedGUI: function() { + return this.htmlElement; + }, + + toString: function() { + return this.type + ":" + this.htmlElement + ":"; + } + +} + + +//-------------------- ricoDropzone.js +Rico.Dropzone = Class.create(); + +Rico.Dropzone.prototype = { + + initialize: function( htmlElement ) { + this.htmlElement = $(htmlElement); + this.absoluteRect = null; + }, + + getHTMLElement: function() { + return this.htmlElement; + }, + + clearPositionCache: function() { + this.absoluteRect = null; + }, + + getAbsoluteRect: function() { + if ( this.absoluteRect == null ) { + var htmlElement = this.getHTMLElement(); + var pos = RicoUtil.toViewportPosition(htmlElement); + + this.absoluteRect = { + top: pos.y, + left: pos.x, + bottom: pos.y + htmlElement.offsetHeight, + right: pos.x + htmlElement.offsetWidth + }; + } + return this.absoluteRect; + }, + + activate: function() { + var htmlElement = this.getHTMLElement(); + if (htmlElement == null || this.showingActive) + return; + + this.showingActive = true; + this.saveBackgroundColor = htmlElement.style.backgroundColor; + + var fallbackColor = "#ffea84"; + var currentColor = Rico.Color.createColorFromBackground(htmlElement); + if ( currentColor == null ) + htmlElement.style.backgroundColor = fallbackColor; + else { + currentColor.isBright() ? currentColor.darken(0.2) : currentColor.brighten(0.2); + htmlElement.style.backgroundColor = currentColor.asHex(); + } + }, + + deactivate: function() { + var htmlElement = this.getHTMLElement(); + if (htmlElement == null || !this.showingActive) + return; + + htmlElement.style.backgroundColor = this.saveBackgroundColor; + this.showingActive = false; + this.saveBackgroundColor = null; + }, + + showHover: function() { + var htmlElement = this.getHTMLElement(); + if ( htmlElement == null || this.showingHover ) + return; + + this.saveBorderWidth = htmlElement.style.borderWidth; + this.saveBorderStyle = htmlElement.style.borderStyle; + this.saveBorderColor = htmlElement.style.borderColor; + + this.showingHover = true; + htmlElement.style.borderWidth = "1px"; + htmlElement.style.borderStyle = "solid"; + //htmlElement.style.borderColor = "#ff9900"; + htmlElement.style.borderColor = "#ffff00"; + }, + + hideHover: function() { + var htmlElement = this.getHTMLElement(); + if ( htmlElement == null || !this.showingHover ) + return; + + htmlElement.style.borderWidth = this.saveBorderWidth; + htmlElement.style.borderStyle = this.saveBorderStyle; + htmlElement.style.borderColor = this.saveBorderColor; + this.showingHover = false; + }, + + canAccept: function(draggableObjects) { + return true; + }, + + accept: function(draggableObjects) { + var htmlElement = this.getHTMLElement(); + if ( htmlElement == null ) + return; + + n = draggableObjects.length; + for ( var i = 0 ; i < n ; i++ ) + { + var theGUI = draggableObjects[i].getDroppedGUI(); +/* if (Element.getStyle(theGUI,'position')=='absolute')*/ + if ( RicoUtil.getElementsComputedStyle( theGUI, "position" ) == "absolute" ) + { + theGUI.style.position = "static"; + theGUI.style.top = ""; + theGUI.style.top = ""; + } + htmlElement.appendChild(theGUI); + } + } +} + +RicoUtil = Object.extend(RicoUtil, { + getElementsComputedStyle: function ( htmlElement, cssProperty, mozillaEquivalentCSS) { + if ( arguments.length == 2 ) + mozillaEquivalentCSS = cssProperty; + + var el = $(htmlElement); + if ( el.currentStyle ) + return el.currentStyle[cssProperty]; + else + return document.defaultView.getComputedStyle(el, null).getPropertyValue(mozillaEquivalentCSS); + }, + + createXmlDocument : function() { + if (document.implementation && document.implementation.createDocument) { + var doc = document.implementation.createDocument("", "", null); + + if (doc.readyState == null) { + doc.readyState = 1; + doc.addEventListener("load", function () { + doc.readyState = 4; + if (typeof doc.onreadystatechange == "function") + doc.onreadystatechange(); + }, false); + } + + return doc; + } + + if (window.ActiveXObject) + return Try.these( + function() { return new ActiveXObject('MSXML2.DomDocument') }, + function() { return new ActiveXObject('Microsoft.DomDocument')}, + function() { return new ActiveXObject('MSXML.DomDocument') }, + function() { return new ActiveXObject('MSXML3.DomDocument') } + ) || false; + + return null; + }, + + getContentAsString: function( parentNode ) { + return parentNode.xml != undefined ? + this._getContentAsStringIE(parentNode) : + this._getContentAsStringMozilla(parentNode); + }, + + _getContentAsStringIE: function(parentNode) { + var contentStr = ""; + for ( var i = 0 ; i < parentNode.childNodes.length ; i++ ) { + var n = parentNode.childNodes[i]; + if (n.nodeType == 4) { + contentStr += n.nodeValue; + } + else { + contentStr += n.xml; + } + } + return contentStr; + }, + + _getContentAsStringMozilla: function(parentNode) { + var xmlSerializer = new XMLSerializer(); + var contentStr = ""; + for ( var i = 0 ; i < parentNode.childNodes.length ; i++ ) { + var n = parentNode.childNodes[i]; + if (n.nodeType == 4) { // CDATA node + contentStr += n.nodeValue; + } + else { + contentStr += xmlSerializer.serializeToString(n); + } + } + return contentStr; + }, + + toViewportPosition: function(element) { + return this._toAbsolute(element,true); + }, + + toDocumentPosition: function(element) { + return this._toAbsolute(element,false); + }, + + /** + * Compute the elements position in terms of the window viewport + * so that it can be compared to the position of the mouse (dnd) + * This is additions of all the offsetTop,offsetLeft values up the + * offsetParent hierarchy, ...taking into account any scrollTop, + * scrollLeft values along the way... + * + * IE has a bug reporting a correct offsetLeft of elements within a + * a relatively positioned parent!!! + **/ + _toAbsolute: function(element,accountForDocScroll) { + + if ( navigator.userAgent.toLowerCase().indexOf("msie") == -1 ) + return this._toAbsoluteMozilla(element,accountForDocScroll); + + var x = 0; + var y = 0; + var parent = element; + while ( parent ) { + + var borderXOffset = 0; + var borderYOffset = 0; + if ( parent != element ) { + var borderXOffset = parseInt(this.getElementsComputedStyle(parent, "borderLeftWidth" )); + var borderYOffset = parseInt(this.getElementsComputedStyle(parent, "borderTopWidth" )); + borderXOffset = isNaN(borderXOffset) ? 0 : borderXOffset; + borderYOffset = isNaN(borderYOffset) ? 0 : borderYOffset; + } + + x += parent.offsetLeft - parent.scrollLeft + borderXOffset; + y += parent.offsetTop - parent.scrollTop + borderYOffset; + parent = parent.offsetParent; + } + + if ( accountForDocScroll ) { + x -= this.docScrollLeft(); + y -= this.docScrollTop(); + } + + return { x:x, y:y }; + }, + + /** + * Mozilla did not report all of the parents up the hierarchy via the + * offsetParent property that IE did. So for the calculation of the + * offsets we use the offsetParent property, but for the calculation of + * the scrollTop/scrollLeft adjustments we navigate up via the parentNode + * property instead so as to get the scroll offsets... + * + **/ + _toAbsoluteMozilla: function(element,accountForDocScroll) { + var x = 0; + var y = 0; + var parent = element; + while ( parent ) { + x += parent.offsetLeft; + y += parent.offsetTop; + parent = parent.offsetParent; + } + + parent = element; + while ( parent && + parent != document.body && + parent != document.documentElement ) { + if ( parent.scrollLeft ) + x -= parent.scrollLeft; + if ( parent.scrollTop ) + y -= parent.scrollTop; + parent = parent.parentNode; + } + + if ( accountForDocScroll ) { + x -= this.docScrollLeft(); + y -= this.docScrollTop(); + } + + return { x:x, y:y }; + }, + + docScrollLeft: function() { + if ( window.pageXOffset ) + return window.pageXOffset; + else if ( document.documentElement && document.documentElement.scrollLeft ) + return document.documentElement.scrollLeft; + else if ( document.body ) + return document.body.scrollLeft; + else + return 0; + }, + + docScrollTop: function() { + if ( window.pageYOffset ) + return window.pageYOffset; + else if ( document.documentElement && document.documentElement.scrollTop ) + return document.documentElement.scrollTop; + else if ( document.body ) + return document.body.scrollTop; + else + return 0; + } +}); + +Rico.includeLoaded('ricoDragDrop.js'); diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoEffects.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoEffects.js new file mode 100644 index 0000000..608bb60 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoEffects.js @@ -0,0 +1,389 @@ + /** + * (c) 2005-2007 Richard Cowin (http://openrico.org) + * + * Rico is licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + **/ + +Rico.animate = function(effect){ + new Rico.Effect.Animator().play(effect, arguments[1]); +} + +Rico.Effect = {} +Rico.Effect.easeIn = function(step){ + return Math.sqrt(step) +} +Rico.Effect.easeOut = function(step){ + return step*step +} +Rico.Stepping = {} +Rico.Stepping.easeIn = Rico.Effect.easeIn; +Rico.Stepping.easeOut = Rico.Effect.easeOut; + +Rico.Effect.Animator = Class.create(); +Rico.Effect.Animator.prototype = { + initialize : function(effect) { + this.animateMethod = this.animate.bind(this); + this.options = arguments[1] || {}; + this.stepsLeft = 0; + if (!effect) return; + this.reset(effect, arguments[1]); + }, + reset: function(effect){ + this.effect = effect; + if (arguments[1]) this.setOptions(arguments[1]); + this.stepsLeft = this.options.steps; + this.duration = this.options.duration; + }, + setOptions: function(options){ + this.options = Object.extend({ + steps: 10, + duration: 200, + rate: function(steps){ return steps;} + }, options|| {}); + }, + play: function(effect) { + this.setOptions(arguments[1]) + if (effect) + if (effect.step) + this.reset(effect, arguments[1]); + else{ + $H(effect).keys().each((function(e){ + var effectClass = {fadeOut:Rico.Effect.FadeOut}[e]; + this.reset(new effectClass(effect[e])); + }).bind(this)) + } + this.animate(); + }, + stop: function() { + this.stepsLeft = this.options.steps; + }, + pause: function() { + this.interupt = true; + }, + resume: function() { + this.interupt = false; + if (this.stepsLeft >0) + this.animate(); + }, + animate: function() { + if (this.interupt) + return; + if (this.stepsLeft <=0) { + if (this.effect.finish) this.effect.finish(); + if (this.options.onFinish) this.options.onFinish(); + return; + } + if (this.timer) + clearTimeout(this.timer); + this.effect.step(this.options.rate(this.stepsLeft)); + this.startNextStep(); + }, + startNextStep: function() { + var stepDuration = Math.round(this.duration/this.stepsLeft) ; + this.duration -= stepDuration; + this.stepsLeft--; + this.timer = setTimeout(this.animateMethod, stepDuration); + }, + isPlaying: function(){ + return this.stepsLeft != 0 && !this.interupt; + } +} + +Rico.Effect.Group = Class.create(); +Rico.Effect.Group.prototype = { + initialize: function(effects){ + this.effects = effects; + }, + step: function(stepsToGo){ + this.effects.each(function(e){e.step(stepsToGo)}); + }, + finish: function(){ + this.effects.each(function(e){if (e.finish) e.finish()}); + } +} + +Rico.Effect.SizeAndPosition = Class.create(); +Rico.Effect.SizeAndPosition.prototype = { + initialize: function(element, x, y, w, h) { + this.element = $(element); + this.x = x || this.element.offsetLeft; + this.y = y || this.element.offsetTop; + this.w = w || this.element.offsetWidth; + this.h = h || this.element.offsetHeight; + }, + step: function(stepsToGo) { + var left = this.element.offsetLeft + ((this.x - this.element.offsetLeft)/stepsToGo) + "px" + var top = this.element.offsetTop + ((this.y - this.element.offsetTop)/stepsToGo) + "px" + var width = this.element.offsetWidth + ((this.w - this.element.offsetWidth)/stepsToGo) + "px" + var height = this.element.offsetHeight + ((this.h - this.element.offsetHeight)/stepsToGo) + "px" + var style = this.element.style; + style.left = left; + style.top = top; + style.width = width; + style.height = height; + } +} + +Rico.AccordionEffect = Class.create(); +Rico.AccordionEffect.prototype = { + initialize: function(toClose, toOpen, height) { + this.toClose = toClose; + this.toOpen = toOpen; +/* if (!navigator.appVersion.match(/\bMSIE\b/)) {*/ + Element.makeClipping(toOpen); + Element.makeClipping(toClose); +/* }*/ + Rico.Controls.disableNativeControls(toClose); + Element.show(toOpen); + this.toOpen.style.height = "0px"; + this.endHeight = height; + }, + step: function(framesLeft) { + var cHeight = Math.max(1,this.toClose.offsetHeight - parseInt((parseInt(this.toClose.offsetHeight))/framesLeft)); + var closeHeight = cHeight + "px"; + var openHeight = (this.endHeight - cHeight) + "px" + this.toClose.style.height = closeHeight; + this.toOpen.style.height = openHeight; + }, + finish: function(){ + Element.hide(this.toClose) + this.toOpen.style.height = this.endHeight + "px"; + this.toClose.style.height = "0px"; +/* if (!navigator.appVersion.match(/\bMSIE\b/)) {*/ + Element.undoClipping(this.toOpen); + Element.undoClipping(this.toClose); +/* }*/ + + Rico.Controls.enableNativeControls(this.toOpen); + } +}; + +Rico.Effect.SizeFromBottom = Class.create() +Rico.Effect.SizeFromBottom.prototype = { + initialize: function(element, y, h) { + this.element = $(element); + this.y = y || this.element.offsetTop; + this.h = h || this.element.offsetHeight; + this.options = arguments[3] || {}; + }, + step: function(framesToGo) { + var top = this.element.offsetTop + ((this.y - this.element.offsetTop)/framesToGo) + "px" + var height = this.element.offsetHeight + ((this.h - this.element.offsetHeight)/framesToGo) + "px" + var style = this.element.style; + style.height = height; + style.top = top; + } +} + +Rico.Effect.Position = Class.create(); +Rico.Effect.Position.prototype = { + initialize: function(element, x, y) { + this.element = $(element); + this.x = x || this.element.offsetLeft; + this.destTop = y || this.element.offsetTop; + }, + step: function(stepsToGo) { + var left = this.element.offsetLeft + ((this.x - this.element.offsetLeft)/stepsToGo) + "px" + var top = this.element.offsetTop + ((this.destTop - this.element.offsetTop)/stepsToGo) + "px" + var style = this.element.style; + style.left = left; + style.top = top; + } +} + +Rico.Effect.FadeTo = Class.create() +Rico.Effect.FadeTo.prototype = { + initialize: function(element, value){ + this.element = element; + this.opacity = Element.getStyle(this.element, 'opacity') || 1.0; + this.target = Math.min(value, 1.0); + }, + step: function(framesLeft) { + var curOpacity = Element.getStyle(this.element, 'opacity'); + var newOpacity = curOpacity + (this.target - curOpacity)/framesLeft + Rico.Effect.setOpacity(this.element, Math.min(Math.max(0,newOpacity),1.0)); + } +} + +Rico.Effect.FadeOut = Class.create() +Rico.Effect.FadeOut.prototype = { + initialize: function(element){ + this.effect = new Rico.Effect.FadeTo(element, 0.0) + }, + step: function(framesLeft) { + this.effect.step(framesLeft); + } +} + +Rico.Effect.FadeIn = Class.create() +Rico.Effect.FadeIn.prototype = { + initialize: function(element){ + var options = arguments[1] || {} + var startValue = options.startValue || 0 + Element.setStyle(element, 'opacity', startValue); + this.effect = new Rico.Effect.FadeTo(element, 1.0) + }, + step: function(framesLeft) { + this.effect.step(framesLeft); + } +} + +Rico.Effect.setOpacity= function(element, value) { + element.style.filter = "alpha(opacity:"+Math.round(value*100)+")"; + element.style.opacity = value; +} + +Rico.Effect.SizeFromTop = Class.create() +Rico.Effect.SizeFromTop.prototype = { + initialize: function(element, scrollElement, y, h) { + this.element = $(element); + this.h = h || this.element.offsetHeight; + // element.style.top = y; + this.scrollElement = scrollElement; + this.options = arguments[4] || {}; + this.baseHeight = this.options.baseHeight || Math.max(this.h, this.element.offsetHeight) + }, + step: function(framesToGo) { + var rawHeight = this.element.offsetHeight + ((this.h - this.element.offsetHeight)/framesToGo); + var height = rawHeight + "px" + var scroll = (rawHeight - this.baseHeight) + "px"; + this.scrollElement.style.top = scroll; + this.element.style.height = height; + } +} + + +Rico.Effect.Height = Class.create() +Rico.Effect.Height.prototype = { + initialize: function(element, endHeight) { + this.element = element + this.endHeight = endHeight + }, + step: function(stepsLeft) { + if (this.element.constructor != Array){ + var height = this.element.offsetHeight + ((this.endHeight - this.element.offsetHeight)/stepsLeft) + "px" + this.element.style.height = height; + } else { + var height = this.element[0].offsetHeight + ((this.endHeight - this.element[0].offsetHeight)/stepsLeft) + "px" + this.element.each(function(e){e.style.height = height}) + } + } +} + +Rico.Effect.SizeWidth = Class.create(); +Rico.Effect.SizeWidth.prototype = { + initialize: function(element, endWidth) { + this.element = element + this.endWidth = endWidth + }, + step: function(stepsLeft) { + delta = Math.abs(this.endWidth - parseInt(this.element.offsetWidth))/(stepsLeft); + this.element.style.width = (this.element.offsetWidth - delta) + "px"; + } +} + +//these are to support non Safari browsers and keep controls from bleeding through on absolute positioned element. +Rico.Controls = { + editors: [], + scrollSelectors: [], + + disableNativeControls: function(element) { + Rico.Controls.defaultDisabler.disableNative(element); + }, + enableNativeControls: function(element){ + Rico.Controls.defaultDisabler.enableNative(element); + }, + prepareForSizing: function(element){ + Element.makeClipping(element) + Rico.Controls.disableNativeControls(element) + }, + resetSizing: function(element){ + Element.undoClipping(element) + Rico.Controls.enableNativeControls(element) + }, + registerScrollSelectors: function(selectorSet) { + selectorSet.each(function(s){Rico.Controls.scrollSelectors.push(Rico.selector(s))}); + } +} + +Rico.Controls.Disabler = Class.create(); +Rico.Controls.Disabler.prototype = { + initialize: function(){ + this.options = Object.extend({ + excludeSet: [], + hidables: Rico.Controls.editors + }, arguments[0] || {}); + }, + disableNative: function(element) { + if (!(/Konqueror|Safari|KHTML/.test(navigator.userAgent))){ + if (!navigator.appVersion.match(/\bMSIE\b/)) + this.blockControls(element).each(function(e){Element.makeClipping(e)}); + else + this.hidableControls(element).each(function(e){e.disable()}); + } + }, + enableNative: function(element){ + if (!(/Konqueror|Safari|KHTML/.test(navigator.userAgent))){ + if (!navigator.appVersion.match(/\bMSIE\b/)) + this.blockControls(element).each(function(e){Element.undoClipping(e)}); + else + this.hidableControls(element).each(function(e){e.enable()}); + } + }, + blockControls: function(element){ + try{ + var includes = []; + if (this.options.includeSet) + includes = this.options.includeSet; + else{ + var selectors = this.options.includeSelectors || Rico.Controls.scrollSelectors; + includes = selectors.map(function(s){return s.findAll(element)}).flatten(); + } + return includes.select(function(e){return (Element.getStyle(e, 'display') != 'none') && !this.options.excludeSet.include(e)}.bind(this)); + }catch(e) { return []} + }, + hidableControls: function(element){ + if (element) + return this.options.hidables.select(function(e){return Element.childOf(e, element)}); + else + return this.options.hidables; + } +} + +Rico.Controls.defaultDisabler = new Rico.Controls.Disabler(); +Rico.Controls.blankDisabler = new Rico.Controls.Disabler({includeSet:[],hidables:[]}); + +Rico.Controls.HidableInput = Class.create(); +Rico.Controls.HidableInput.prototype = { + initialize: function(field, view){ + this.field = field; + this.view = view; + this.enable(); + Rico.Controls.editors.push(this); + }, + enable: function(){ + Element.hide(this.view); + Element.show(this.field); + }, + disable: function(){ + this.view.value = $F(this.field); + if (this.field.offsetWidth > 1) { + this.view.style.width = parseInt(this.field.offsetWidth) + "px"; + Element.hide(this.field); + Element.show(this.view); + } + } +} + + + +Element.forceRefresh = function(item) { + try { + var n = document.createTextNode(' ') + item.appendChild(n); item.removeChild(n); + } catch(e) { } +}; + +Rico.includeLoaded('ricoEffects.js'); diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoGridCommon.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoGridCommon.js new file mode 100644 index 0000000..01f7392 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoGridCommon.js @@ -0,0 +1,685 @@ +/** + * (c) 2005-2007 Richard Cowin (http://openrico.org) + * (c) 2005-2007 Matt Brown (http://dowdybrown.com) + * + * Rico is licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + **/ + + +if(typeof Rico=='undefined') throw("GridCommon requires the Rico JavaScript framework"); +if(typeof RicoUtil=='undefined') throw("GridCommon requires the RicoUtil Library"); + + +/** + * Define methods that are common to both SimpleGrid and LiveGrid + */ +Rico.GridCommon = function() {}; + +Rico.GridCommon.prototype = { + + baseInit: function() { + this.options = { + resizeBackground : 'resize.gif', + saveColumnInfo : {width:true, filter:false, sort:false}, // save info in cookies? + allowColResize : true, // allow user to resize columns + windowResize : true, // Resize grid on window.resize event? Set to false when embedded in an accordian. + click : null, + dblclick : null, + contextmenu : null, + useUnformattedColWidth : true, + menuEvent : 'dblclick', // event that triggers menus - click, dblclick, contextmenu, or none (no menus) + defaultWidth : 100, // in the absence of any other width info, columns will be this many pixels wide + scrollBarWidth : 19, // this is the value used in positioning calculations, it does not actually change the width of the scrollbar + minScrollWidth : 100, // min scroll area width when width of frozen columns exceeds window width + columnSpecs : [] + } + this.colWidths = new Array(); + this.hdrCells=new Array(); + this.headerColCnt=0; + this.headerRowIdx=0; + this.tabs=new Array(2); + this.thead=new Array(2); + this.tbody=new Array(2); + }, + + attachMenuEvents: function() { + if (!this.options.menuEvent || this.options.menuEvent=='none') return; + this.hideScroll=navigator.userAgent.match(/Macintosh\b.*\b(Firefox|Camino)\b/i) || Prototype.Browser.Opera; + this.options[this.options.menuEvent]=this.handleMenuClick.bindAsEventListener(this); + if (this.highlightDiv) { + switch (this.options.highlightElem) { + case 'cursorRow': + this.attachMenu(this.highlightDiv); + break; + case 'cursorCell': + for (var i=0; i<2; i++) + this.attachMenu(this.highlightDiv[i]); + break; + } + } + for (var i=0; i<2; i++) + this.attachMenu(this.tbody[i]); + }, + + attachMenu: function(elem) { + if (this.options.click) + Event.observe(elem, 'click', this.options.click, false); + if (this.options.dblclick) { + if (Prototype.Browser.WebKit || Prototype.Browser.Opera) + Event.observe(elem, 'click', this.handleDblClick.bindAsEventListener(this), false); + else + Event.observe(elem, 'dblclick', this.options.dblclick, false); + } + if (this.options.contextmenu) { + if (Prototype.Browser.Opera) + Event.observe(elem, 'click', this.handleContextMenu.bindAsEventListener(this), false); + else + Event.observe(elem, 'contextmenu', this.options.contextmenu, false); + } + }, + + // implement double-click for browsers that don't support a double-click event (e.g. Safari) + handleDblClick: function(e) { + var elem=Event.element(e); + if (this.dblClickElem == elem) { + this.options.dblclick(e); + } else { + this.dblClickElem = elem; + this.safariTimer=setTimeout(this.clearDblClick.bind(this),300); + } + }, + + clearDblClick: function() { + this.dblClickElem=null; + }, + + // implement right-click for browsers that don't support contextmenu event (e.g. Opera) + // use control-click instead + handleContextMenu: function(e) { + if( typeof( e.which ) == 'number' ) + var b = e.which; //Netscape compatible + else if( typeof( e.button ) == 'number' ) + var b = e.button; //DOM + else + return; + if (b==1 && e.ctrlKey) + this.options.contextmenu(e); + }, + + cancelMenu: function() { + if (this.menu && this.menu.isVisible()) this.menu.cancelmenu(); + }, + + // gather info from original headings + getColumnInfo: function(hdrSrc) { + Rico.writeDebugMsg("getColumnInfo start"); + //alert(hdrSrc.tagName+' '+hdrSrc.id+' len='+hdrSrc.length); + if (hdrSrc.length == 0) return; + this.headerRowCnt=hdrSrc.length; + var colcnt; + for (r=0; r= this.hdrCells.length) this.hdrCells[r]=new Array(); + for (c=0; c=0) ? this.columns[c].cell(r) : null; + }, + + availHt: function() { + var divPos=Position.page(this.outerDiv); + return RicoUtil.windowHeight()-divPos[1]-2*this.options.scrollBarWidth-15; // allow for scrollbar and some margin + }, + + handleScroll: function(e) { + var newTop=(this.hdrHt-this.scrollDiv.scrollTop)+'px'; + this.tabs[0].style.top=newTop; + this.setHorizontalScroll(); + }, + + setHorizontalScroll: function() { + var newLeft=(-this.scrollDiv.scrollLeft)+'px'; + this.hdrTabs[1].style.left=newLeft; + }, + + pluginScroll: function() { + if (this.scrollPluggedIn) return; + Event.observe(this.scrollDiv,"scroll",this.scrollEventFunc, false); + this.scrollPluggedIn=true; + }, + + unplugScroll: function() { + Event.stopObserving(this.scrollDiv,"scroll", this.scrollEventFunc , false); + this.scrollPluggedIn=false; + }, + + printVisible: function(exportType) { + this.exportStart(); + var limit=this.pageSize; + if (this.buffer && this.buffer.totalRows < limit) limit=this.buffer.totalRows; + for(var r=0; r < limit; r++) { + this.exportText+=""; + for (var c=0; c"+this.columns[c].getFormattedValue(r)+""; + } + this.exportText+=""; + } + this.exportFinish(exportType); + }, + + exportStart: function() { + this.exportText=""; + + for (var r=0; r 0) { + var divs=Element.getElementsByClassName(hdrcell.cell,'ricoLG_cell'); + var cell=divs && divs.length>0 ? divs[0] : hdrcell.cell; + this.exportText+=""; + } + } + this.exportText+=""; + } + + for (var c=0; c= this.columns.length) continue; + var col=this.columns[colnum]; + switch (v[0].charAt(0)) { + case 'w': + col.setColWidth(v[1]); + col.customWidth=true; + break; + case 'h': + if (v[1].toLowerCase()=='true') + col.showColumn(true); + else + col.hideColumn(true); + break; + case 's': + col.setSorted(v[1]); + break; + case 'f': + var filterTemp=v[1].split('~'); + col.filterOp=filterTemp.shift(); + col.filterValues = []; + col.filterType = Rico.TableColumn.USERFILTER; + for (var j=0; j 0) + RicoUtil.setCookie(this.tableId, cookieVals.join(','), this.options.cookieDays, this.options.cookiePath, this.options.cookieDomain); + } + +} + +Rico.TableColumn = Class.create(); + +Rico.TableColumn.UNFILTERED = 0; +Rico.TableColumn.SYSTEMFILTER = 1; /* system-generated filter, not shown to user */ +Rico.TableColumn.USERFILTER = 2; + +Rico.TableColumn.UNSORTED = 0; +Rico.TableColumn.SORT_ASC = "ASC"; +Rico.TableColumn.SORT_DESC = "DESC"; +Rico.TableColumn.MINWIDTH = 10; // min column width when user is resizing + +Rico.TableColumn.DOLLAR = {type:'number', prefix:'$', decPlaces:2, ClassName:'alignright'}; +Rico.TableColumn.EURO = {type:'number', prefix:'€', decPlaces:2, ClassName:'alignright'}; +Rico.TableColumn.PERCENT = {type:'number', suffix:'%', decPlaces:2, multiplier:100, ClassName:'alignright'}; +Rico.TableColumn.QTY = {type:'number', decPlaces:0, ClassName:'alignright'}; +Rico.TableColumn.DEFAULT = {type:"raw"}; + +Rico.TableColumn.prototype = { + + baseInit: function(liveGrid,colIdx,hdrInfo,tabIdx) { + Rico.writeDebugMsg("TableColumn.init index="+colIdx+" tabIdx="+tabIdx); + this.liveGrid = liveGrid; + this.index = colIdx; + this.hideWidth = Rico.isKonqueror || Prototype.Browser.WebKit || liveGrid.headerRowCnt>1 ? 5 : 2; // column width used for "hidden" columns. Anything less than 5 causes problems with Konqueror. Best to keep this greater than padding used inside cell. + this.options = liveGrid.options; + this.tabIdx = tabIdx; + this.hdrCell = hdrInfo.cell; + this.body = document.getElementsByTagName("body")[0]; // work around FireFox bug (document.body doesn't exist after XSLT) + this.displayName = this.getDisplayName(this.hdrCell); + var divs=this.hdrCell.getElementsByTagName('div'); + this.hdrColDiv=(divs.length<1) ? RicoUtil.wrapChildren(this.hdrCell,'ricoLG_col') : divs[0]; + this.hdrCellDiv=(divs.length<2) ? RicoUtil.wrapChildren(this.hdrColDiv,'ricoLG_cell') : divs[1]; + var sectionIndex= tabIdx==0 ? colIdx : colIdx-liveGrid.options.frozenColumns; + this.dataCell = liveGrid.tbody[tabIdx].rows[0].cells[sectionIndex]; + var divs=this.dataCell.getElementsByTagName('div'); + this.dataColDiv=(divs.length<1) ? RicoUtil.wrapChildren(this.dataCell,'ricoLG_col') : divs[0]; + + this.mouseDownHandler= this.handleMouseDown.bindAsEventListener(this); + this.mouseMoveHandler= this.handleMouseMove.bindAsEventListener(this); + this.mouseUpHandler = this.handleMouseUp.bindAsEventListener(this); + this.mouseOutHandler = this.handleMouseOut.bindAsEventListener(this); + + this.fieldName = 'col'+this.index; + var spec = liveGrid.options.columnSpecs[colIdx]; + this.format=Object.extend( {}, Rico.TableColumn.DEFAULT); + switch (typeof spec) { + case 'object': + if (typeof spec.format=='string') Object.extend(this.format, Rico.TableColumn[spec.format.toUpperCase()]); + Object.extend(this.format, spec); + break; + case 'string': + if (spec.slice(0,4)=='spec') spec=spec.slice(4).toUpperCase(); // for backwards compatibility + this.format=typeof Rico.TableColumn[spec]=='object' ? Rico.TableColumn[spec] : Rico.TableColumn.DEFAULT; + break; + } + this.dataColDiv.className += (this.format.ClassName) ? ' '+this.format.ClassName : ' '+liveGrid.tableId+'_col'+colIdx; + this.visible=true; + if (typeof this.format.visible=='boolean') this.visible=this.format.visible; + if (typeof this.format.type!='string') this.format.type='raw'; + Rico.writeDebugMsg("TableColumn.init index="+colIdx+" fieldName="+this.fieldName+' type='+this.format.type); + this.sortable = typeof this.format.canSort=='boolean' ? this.format.canSort : liveGrid.options.canSortDefault; + this.currentSort = Rico.TableColumn.UNSORTED; + this.filterable = typeof this.format.canFilter=='boolean' ? this.format.canFilter : liveGrid.options.canFilterDefault; + this.filterType = Rico.TableColumn.UNFILTERED; + this.hideable = typeof this.format.canHide=='boolean' ? this.format.canHide : liveGrid.options.canHideDefault; + if (typeof this.isNullable!='boolean') this.isNullable = /number|date/.test(this.format.type); + this.isText = /raw|text/.test(this.format.type); + + var wi=(typeof(this.format.width)=='number') ? this.format.width : hdrInfo.initWidth; + wi=(typeof(wi)=='number') ? Math.max(wi,Rico.TableColumn.MINWIDTH) : liveGrid.options.defaultWidth; + this.setColWidth(wi); + if (!this.visible) this.setDisplayNone(); + if (this.options.allowColResize && !this.format.noResize) this.insertResizer(); + }, + + insertResizer: function() { + this.hdrCell.style.width=''; + var resizer=this.hdrCellDiv.appendChild(document.createElement('div')); + resizer.className='ricoLG_Resize'; + resizer.style[this.liveGrid.align[1]]='0px'; + if (this.options.resizeBackground) { + var resizePath=Rico.imgDir+this.options.resizeBackground; + if (Prototype.Browser.IE) resizePath=location.protocol+resizePath; + resizer.style.backgroundImage='url('+resizePath+')'; + } + Event.observe(resizer,"mousedown", this.mouseDownHandler, false); + }, + + // get the display name of a column + getDisplayName: function(el) { + var anchors=el.getElementsByTagName("A"); + //Check the existance of A tags + if (anchors.length > 0) + return anchors[0].innerHTML; + else + return el.innerHTML.stripTags(); + }, + + _clear: function(gridCell) { + gridCell.innerHTML=' '; + }, + + clearCell: function(rowIndex) { + var gridCell=this.cell(rowIndex); + this._clear(gridCell,rowIndex); + if (!this.liveGrid.buffer) return; + var acceptAttr=this.liveGrid.buffer.options.acceptAttr; + for (var k=0; k0) this.edge+=RicoUtil.nan2zero(this.liveGrid.tabs[0].offsetWidth)-this.liveGrid.scrollDiv.scrollLeft; + } + this.liveGrid.resizeDiv.style.left=this.edge+"px"; + this.liveGrid.resizeDiv.style.display=""; + this.liveGrid.outerDiv.style.cursor='e-resize'; + this.tmpHighlight=this.liveGrid.highlightEnabled; + this.liveGrid.highlightEnabled=false; + this.pluginMouseEvents(); + Event.stop(e); + }, + + handleMouseMove: function(e) { + var delta=e.clientX-this.resizeStart; + var newWidth=(this.liveGrid.direction=='rtl') ? this.origWidth-delta : this.origWidth+delta; + if (newWidth < Rico.TableColumn.MINWIDTH) return; + this.liveGrid.resizeDiv.style.left=(this.edge+delta)+"px"; + this.colWidth=newWidth; + Event.stop(e); + }, + + handleMouseUp: function(e) { + this.unplugMouseEvents(); + Rico.writeDebugMsg('handleMouseUp '+this.liveGrid.tableId); + this.liveGrid.outerDiv.style.cursor=''; + this.liveGrid.resizeDiv.style.display="none"; + this.setColWidth(this.colWidth); + this.customWidth=true; + this.liveGrid.setCookie(); + this.liveGrid.highlightEnabled=this.tmpHighlight; + this.liveGrid.sizeDivs(); + Event.stop(e); + }, + + handleMouseOut: function(e) { + var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement; + while (reltg != null && reltg.nodeName.toLowerCase() != 'body') + reltg=reltg.parentNode; + if (reltg!=null && reltg.nodeName.toLowerCase() == 'body') return true; + this.handleMouseUp(e); + return true; + }, + + setDisplayNone: function() { + this.hdrCell.style.display='none'; + this.hdrColDiv.style.display='none'; + this.dataCell.style.display='none'; + this.dataColDiv.style.display='none'; + }, + + // recalcTableWidth defaults to true + hideColumn: function(noresize) { + Rico.writeDebugMsg('hideColumn '+this.liveGrid.tableId); + this.setDisplayNone(); + this.liveGrid.cancelMenu(); + this.visible=false; + this.customVisible=true; + if (noresize) return; + this.liveGrid.setCookie(); + this.liveGrid.sizeDivs(); + }, + + showColumn: function(noresize) { + Rico.writeDebugMsg('showColumn '+this.liveGrid.tableId); + this.hdrCell.style.display=''; + this.hdrColDiv.style.display=''; + this.dataCell.style.display=''; + this.dataColDiv.style.display=''; + this.liveGrid.cancelMenu(); + this.visible=true; + this.customVisible=true; + if (noresize) return; + this.liveGrid.setCookie(); + this.liveGrid.sizeDivs(); + }, + + setImage: function() { + if ( this.currentSort == Rico.TableColumn.SORT_ASC ) { + this.imgSort.style.display=''; + this.imgSort.src=Rico.imgDir+this.options.sortAscendImg; + } else if ( this.currentSort == Rico.TableColumn.SORT_DESC ) { + this.imgSort.style.display=''; + this.imgSort.src=Rico.imgDir+this.options.sortDescendImg; + } else { + this.imgSort.style.display='none'; + } + if (this.filterType == Rico.TableColumn.USERFILTER) { + this.imgFilter.style.display=''; + this.imgFilter.title=this.getFilterText(); + } else { + this.imgFilter.style.display='none'; + } + }, + + canHideShow: function() { + return this.hideable; + } + +}; + +Rico.includeLoaded('ricoGridCommon.js'); diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoLiveGrid.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoLiveGrid.js new file mode 100644 index 0000000..bc2af62 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoLiveGrid.js @@ -0,0 +1,1806 @@ +/** + * (c) 2005-2007 Richard Cowin (http://openrico.org) + * (c) 2005-2007 Matt Brown (http://dowdybrown.com) + * + * Rico is licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + **/ + + +if(typeof Rico=='undefined') throw("LiveGrid requires the Rico JavaScript framework"); +if(typeof RicoUtil=='undefined') throw("LiveGrid requires the RicoUtil Library"); +if(typeof RicoTranslate=='undefined') throw("LiveGrid requires the RicoTranslate Library"); +if(typeof Rico.TableColumn=='undefined') throw("LiveGrid requires ricoGridCommon.js"); + + +Rico.Buffer = {}; + +/** + * Loads buffer with data that already exists in the document as an HTML table (no AJAX). + * Also serves as a base class for AJAX-enabled buffers. + */ +Rico.Buffer.Base = Class.create(); + +Rico.Buffer.Base.prototype = { + + initialize: function(dataTable, options) { + this.clear(); + this.updateInProgress = false; + this.lastOffset = 0; + this.rcvdRowCount = false; // true if an eof element was included in the last xml response + this.foundRowCount = false; // true if an xml response is ever received with eof true + this.totalRows = 0; + this.rowcntContent = ""; + this.rcvdOffset = -1; + this.options = { + fixedHdrRows : 0, + canFilter : false, // does buffer object support filtering? + isEncoded : true, // is the data received via ajax html encoded? + acceptAttr : [] // attributes that can be copied from original/ajax data (e.g. className, style, id) + } + Object.extend(this.options, options || {}); + if (dataTable) { + this.loadRowsFromTable(dataTable); + } else { + this.clear(); + } + }, + + registerGrid: function(liveGrid) { + this.liveGrid = liveGrid; + }, + + setTotalRows: function( newTotalRows ) { + if (this.totalRows == newTotalRows) return; + this.totalRows = newTotalRows; + if (this.liveGrid) { + Rico.writeDebugMsg("setTotalRows, newTotalRows="+newTotalRows); + if (this.liveGrid.sizeTo=='data') this.liveGrid.resizeWindow(); + this.liveGrid.updateHeightDiv(); + } + }, + + loadRowsFromTable: function(tableElement) { + this.rows = this.dom2jstable(tableElement,this.options.fixedHdrRows); + this.startPos = 0; + this.size = this.rows.length; + this.setTotalRows(this.size); + this.rowcntContent = this.size.toString(); + this.rcvdRowCount = true; + this.foundRowCount = true; + }, + + dom2jstable: function(rowsElement,firstRow) { + var newRows = new Array(); + var trs = rowsElement.getElementsByTagName("tr"); + var acceptAttr=this.options.acceptAttr; + for ( var i=firstRow || 0; i < trs.length; i++ ) { + var row = new Array(); + var cells = trs[i].getElementsByTagName("td"); + for ( var j=0; j < cells.length ; j++ ) { + row[j]={}; + row[j].content=RicoUtil.getContentAsString(cells[j],this.options.isEncoded); + for (var k=0; k= this.startPos) && (lastRow <= this.endPos()); // && (this.size != 0); + }, + + endPos: function() { + return this.startPos + this.rows.length; + }, + + fetch: function(offset) { + this.liveGrid.refreshContents(offset); + return; + }, + + exportAllRows: function(populate,finish) { + populate(this.getRows(0,this.totalRows)); + finish(); + }, + + setWindow: function(start, count) { + this.windowStart = start - this.startPos; + this.windowEnd = Math.min(this.windowStart + count,this.size); + this.windowPos = start; + }, + + isVisible: function(bufRow) { + return bufRow < this.rows.length && bufRow >= this.windowStart && bufRow < this.windowEnd; + }, + + getWindowCell: function(windowRow,col) { + var bufrow=this.windowStart+windowRow; + return this.isVisible(bufrow) && col < this.rows[bufrow].length ? this.rows[bufrow][col] : null; + }, + + getWindowValue: function(windowRow,col) { + var cell=this.getWindowCell(windowRow,col); + return cell ? cell.content : null; + }, + + setWindowValue: function(windowRow,col,newval) { + var bufRow=this.windowStart+windowRow; + if (bufRow >= this.windowEnd) return false; + return this.setValue(bufRow,col,newval); + }, + + getCell: function(bufRow,col) { + return bufRow < this.size ? this.rows[bufRow][col] : null; + }, + + getValue: function(bufRow,col) { + var cell=this.getCell(bufRow,col); + return cell ? cell.content : null; + }, + + setValue: function(bufRow,col,newval,newstyle) { + if (bufRow>=this.size) return false; + if (!this.rows[bufRow][col]) this.rows[bufRow][col]={}; + this.rows[bufRow][col].content=newval; + if (typeof newstyle=='string') this.rows[bufRow][col]._style=newstyle; + this.rows[bufRow][col].modified=true; + return true; + }, + + getRows: function(start, count) { + var begPos = start - this.startPos; + var endPos = Math.min(begPos + count,this.size); + var results = new Array(); + for ( var i=begPos; i < endPos; i++ ) + results.push(this.rows[i]); + return results + } + +}; + + +// Rico.LiveGrid ----------------------------------------------------- + +Rico.LiveGrid = Class.create(); + +Rico.LiveGrid.prototype = { + + initialize: function( tableId, buffer, options ) { + Object.extend(this, new Rico.GridCommon); + Object.extend(this, new Rico.LiveGridMethods); + this.baseInit(); + this.tableId = tableId; + this.buffer = buffer; + Rico.setDebugArea(tableId+"_debugmsgs"); // if used, this should be a textarea + + Object.extend(this.options, { + visibleRows : -1, // -1 or 'window'=size grid to client window; -2 or 'data'=size grid to min(window,data); -3 or 'body'=size so body does not have a scrollbar + frozenColumns : 0, + offset : 0, // first row to be displayed + prefetchBuffer : true, // load table on page load? + minPageRows : 1, + maxPageRows : 50, + canSortDefault : true, // can be overridden in the column specs + canFilterDefault : buffer.options.canFilter, // can be overridden in the column specs + canHideDefault : true, // can be overridden in the column specs + cookiePrefix : 'liveGrid.'+tableId, + + // highlight & selection parameters + highlightElem : 'none',// what gets highlighted/selected (cursorRow, cursorCell, menuRow, menuCell, selection, or none) + highlightSection : 3, // which section gets highlighted (frozen=1, scrolling=2, all=3, none=0) + highlightMethod : 'class', // outline, class, both (outline is less CPU intensive on the client) + highlightClass : 'ricoLG_selection', + + // export/print parameters + maxPrint : 1000, // max # of rows that can be printed/exported, 0=disable print/export feature + exportWindow : "height=300,width=500,scrollbars=1,menubar=1,resizable=1", + + // heading parameters + headingSort : 'link', // link: make headings a link that will sort column, hover: make headings a hoverset, none: events on headings are disabled + hdrIconsFirst : true, // true: put sort & filter icons before header text, false: after + sortAscendImg : 'sort_asc.gif', + sortDescendImg : 'sort_desc.gif', + filterImg : 'filtercol.gif' + }); + // other options: + // sortCol: initial sort column + + this.options.sortHandler = this.sortHandler.bind(this); + this.options.filterHandler = this.filterHandler.bind(this); + this.options.onRefreshComplete = this.bookmarkHandler.bind(this); + this.options.rowOverHandler = this.rowMouseOver.bindAsEventListener(this); + this.options.mouseDownHandler = this.selectMouseDown.bindAsEventListener(this); + this.options.mouseOverHandler = this.selectMouseOver.bindAsEventListener(this); + this.options.mouseUpHandler = this.selectMouseUp.bindAsEventListener(this); + Object.extend(this.options, options || {}); + + switch (typeof this.options.visibleRows) { + case 'string': + this.sizeTo=this.options.visibleRows; + this.options.visibleRows=-1; + break; + case 'number': + switch (this.options.visibleRows) { + case -1: this.sizeTo='window'; break; + case -2: this.sizeTo='data'; break; + case -3: this.sizeTo='body'; break; + } + break; + default: + this.sizeTo='window'; + this.options.visibleRows=-1; + } + this.highlightEnabled=this.options.highlightSection>0; + this.pageSize=0; + this.createTables(); + if (this.headerColCnt==0) { + alert('ERROR: no columns found in "'+this.tableId+'"'); + return; + } + this.createColumnArray(); + if (this.options.headingSort=='hover') + this.createHoverSet(); + + this.bookmark=$(this.tableId+"_bookmark"); + this.sizeDivs(); + this.createDataCells(this.options.visibleRows); + if (this.pageSize == 0) return; + this.buffer.registerGrid(this); + if (this.buffer.setBufferSize) this.buffer.setBufferSize(this.pageSize); + this.scrollTimeout = null; + this.lastScrollPos = 0; + this.attachMenuEvents(); + + // preload the images... + new Image().src = Rico.imgDir+this.options.filterImg; + new Image().src = Rico.imgDir+this.options.sortAscendImg; + new Image().src = Rico.imgDir+this.options.sortDescendImg; + Rico.writeDebugMsg("images preloaded"); + + this.setSortUI( this.options.sortCol, this.options.sortDir ); + this.setImages(); + if (this.listInvisible().length==this.columns.length) + this.columns[0].showColumn(); + this.sizeDivs(); + this.scrollDiv.style.display=""; + if (this.buffer.totalRows>0) + this.updateHeightDiv(); + if (this.options.prefetchBuffer) { + if (this.bookmark) this.bookmark.innerHTML = RicoTranslate.getPhrase("Loading..."); + if (this.options.canFilterDefault && this.options.getQueryParms) + this.checkForFilterParms(); + this.buffer.fetch(this.options.offset); + } + this.scrollEventFunc=this.handleScroll.bindAsEventListener(this); + this.wheelEventFunc=this.handleWheel.bindAsEventListener(this); + this.wheelEvent=(Prototype.Browser.IE || Prototype.Browser.Opera || Prototype.Browser.WebKit) ? 'mousewheel' : 'DOMMouseScroll'; + if (this.options.offset && this.options.offset < this.buffer.totalRows) + setTimeout(this.scrollToRow.bind(this,this.options.offset),50); // Safari requires a delay + this.pluginScroll(); + this.setHorizontalScroll(); + if (this.options.windowResize) + setTimeout(this.pluginWindowResize.bind(this),100); + } +}; + +Rico.LiveGridMethods = function() {}; + +Rico.LiveGridMethods.prototype = { + + createHoverSet: function() { + var hdrs=[]; + for( var c=0; c < this.headerColCnt; c++ ) + hdrs.push(this.columns[c].hdrCellDiv); + this.hoverSet = new Rico.HoverSet(hdrs); + }, + + checkForFilterParms: function() { + var s=window.location.search; + if (s.charAt(0)=='?') s=s.substring(1); + var pairs = s.split('&'); + for (var i=0; i 0; c++) + this.thead[c 0; c++) { + if (cells[0].className=='ricoFrozen') { + this.thead[0].rows[r].appendChild(cells[0]); + if (r==this.headerRowIdx) this.options.frozenColumns=c+1; + } else { + this.thead[1].rows[r].appendChild(cells[0]); + } + } + } + } + Rico.writeDebugMsg('loadHdrSrc end'); + }, + + sizeDivs: function() { + Rico.writeDebugMsg('sizeDivs: '+this.tableId); + this.cancelMenu(); + this.unhighlight(); + this.baseSizeDivs(); + if (this.pageSize == 0) return; + this.rowHeight = Math.round(this.dataHt/this.pageSize); + var scrHt=this.dataHt; + if (this.scrWi>0 || Prototype.Browser.IE || Prototype.Browser.WebKit) + scrHt+=this.options.scrollBarWidth; + this.scrollDiv.style.height=scrHt+'px'; + this.innerDiv.style.width=(this.scrWi-this.options.scrollBarWidth+1)+'px'; + this.resizeDiv.style.height=this.frozenTabs.style.height=this.innerDiv.style.height=(this.hdrHt+this.dataHt+1)+'px'; + Rico.writeDebugMsg('sizeDivs scrHt='+scrHt+' innerHt='+this.innerDiv.style.height+' rowHt='+this.rowHeight+' pageSize='+this.pageSize); + pad=(this.scrWi-this.scrTabWi < this.options.scrollBarWidth) ? 2 : 0; + this.shadowDiv.style.width=(this.scrTabWi+pad)+'px'; + this.outerDiv.style.height=(this.hdrHt+scrHt)+'px'; + this.setHorizontalScroll(); + }, + + setHorizontalScroll: function() { + var scrleft=this.scrollDiv.scrollLeft; + this.scrollTabs.style.left=(-scrleft)+'px'; + }, + + remainingHt: function() { + var winHt=RicoUtil.windowHeight(); + var margin=Prototype.Browser.IE ? 15 : 10; + switch (this.sizeTo) { + case 'window': + case 'data': + var divPos=Position.page(this.outerDiv); + var tabHt=Math.max(this.tabs[0].offsetHeight,this.tabs[1].offsetHeight); + Rico.writeDebugMsg("remainingHt, winHt="+winHt+' tabHt='+tabHt+' gridY='+divPos[1]); + return winHt-divPos[1]-tabHt-this.options.scrollBarWidth-margin; // allow for scrollbar and some margin + case 'body': + //Rico.writeDebugMsg("remainingHt, document.height="+document.height); + //Rico.writeDebugMsg("remainingHt, body.offsetHeight="+document.body.offsetHeight); + //Rico.writeDebugMsg("remainingHt, body.scrollHeight="+document.body.scrollHeight); + //Rico.writeDebugMsg("remainingHt, documentElement.scrollHeight="+document.documentElement.scrollHeight); + var bodyHt=Prototype.Browser.IE ? document.body.scrollHeight : document.body.offsetHeight; + var remHt=winHt-bodyHt-margin; + if (!Prototype.Browser.WebKit) remHt-=this.options.scrollBarWidth; + Rico.writeDebugMsg("remainingHt, winHt="+winHt+' pageHt='+bodyHt+' remHt='+remHt); + return remHt; + } + }, + + adjustPageSize: function() { + var remHt=this.remainingHt(); + Rico.writeDebugMsg('adjustPageSize remHt='+remHt+' lastRow='+this.lastRowPos); + if (remHt > this.rowHeight) + this.autoAppendRows(remHt); + else if (remHt < 0 || this.sizeTo=='data') + this.autoRemoveRows(-remHt); + }, + + pluginWindowResize: function() { + Event.observe(window, "resize", this.resizeWindow.bindAsEventListener(this), false); + }, + + resizeWindow: function() { + Rico.writeDebugMsg('resizeWindow '+this.tableId+' lastRow='+this.lastRowPos); + if (!this.sizeTo) { + this.sizeDivs(); + return; + } + var oldSize=this.pageSize; + this.adjustPageSize(); + if (this.pageSize > oldSize) { + this.isPartialBlank=true; + var adjStart=this.adjustRow(this.lastRowPos); + this.buffer.fetch(adjStart); + } + if (oldSize != this.pageSize) + setTimeout(this.finishResize.bind(this),50); + else + this.sizeDivs(); + Rico.writeDebugMsg('resizeWindow complete. old size='+oldSize+' new size='+this.pageSize); + }, + + finishResize: function() { + this.sizeDivs(); + this.updateHeightDiv(); + }, + + topOfLastPage: function() { + return Math.max(this.buffer.totalRows-this.pageSize,0); + }, + + updateHeightDiv: function() { + var notdisp=this.topOfLastPage(); + var ht = this.scrollDiv.clientHeight + this.rowHeight * notdisp; + //if (Prototype.Browser.Opera) ht+=this.options.scrollBarWidth-3; + Rico.writeDebugMsg("updateHeightDiv, ht="+ht+' scrollDiv.clientHeight='+this.scrollDiv.clientHeight+' rowsNotDisplayed='+notdisp); + this.shadowDiv.style.height=ht+'px'; + }, + + autoRemoveRows: function(overage) { + var removeCnt=Math.ceil(overage / this.rowHeight); + if (this.sizeTo=='data') + removeCnt=Math.max(removeCnt,this.pageSize-this.buffer.totalRows); + Rico.writeDebugMsg("autoRemoveRows overage="+overage+" removeCnt="+removeCnt); + for (var i=0; i= this.buffer.size) idx.onBlankRow=true; + return idx; + }, + + attachHighlightEvents: function(tBody) { + switch (this.options.highlightElem) { + case 'selection': + Event.observe(tBody,"mousedown", this.options.mouseDownHandler, false); + tBody.ondrag = function () { return false; }; + tBody.onselectstart = function () { return false; }; + break; + case 'cursorRow': + case 'cursorCell': + Event.observe(tBody,"mouseover", this.options.rowOverHandler, false); + break; + } + }, + + getVisibleSelection: function() { + var cellList=[]; + if (this.SelectIdxStart && this.SelectIdxEnd) { + var r1=Math.max(Math.min(this.SelectIdxEnd.row,this.SelectIdxStart.row),this.buffer.windowPos); + var r2=Math.min(Math.max(this.SelectIdxEnd.row,this.SelectIdxStart.row),this.buffer.windowEnd-1); + var c1=Math.min(this.SelectIdxEnd.column,this.SelectIdxStart.column); + var c2=Math.max(this.SelectIdxEnd.column,this.SelectIdxStart.column); + for (var r=r1; r<=r2; r++) + for (var c=c1; c<=c2; c++) + cellList.push({row:r-this.buffer.windowPos,column:c}); + } + if (this.SelectCtrl) { + for (var i=0; i=this.buffer.windowPos && this.SelectCtrl[i].row r2) { + this.HideSelection(); + return; + } + var c1=Math.min(this.SelectIdxEnd.column,this.SelectIdxStart.column); + var c2=Math.max(this.SelectIdxEnd.column,this.SelectIdxStart.column); + var top1=this.columns[c1].cell(r1-this.buffer.windowStart).offsetTop; + var cell2=this.columns[c1].cell(r2-this.buffer.windowStart); + var bottom2=cell2.offsetTop+cell2.offsetHeight; + var left1=this.columns[c1].dataCell.offsetLeft; + var left2=this.columns[c2].dataCell.offsetLeft; + var right2=left2+this.columns[c2].dataCell.offsetWidth; + //window.status='updateSelectOutline: '+r1+' '+r2+' top='+top1+' bot='+bottom2; + this.highlightDiv[0].style.top=this.highlightDiv[3].style.top=this.highlightDiv[1].style.top=(this.hdrHt+top1-1) + 'px'; + this.highlightDiv[2].style.top=(this.hdrHt+bottom2-1)+'px'; + this.highlightDiv[3].style.left=(left1-2)+'px'; + this.highlightDiv[0].style.left=this.highlightDiv[2].style.left=(left1-1)+'px'; + this.highlightDiv[1].style.left=(right2-1)+'px'; + this.highlightDiv[0].style.width=this.highlightDiv[2].style.width=(right2-left1-1) + 'px'; + this.highlightDiv[1].style.height=this.highlightDiv[3].style.height=(bottom2-top1) + 'px'; + //this.highlightDiv[0].style.right=this.highlightDiv[2].style.right=this.highlightDiv[1].style.right=()+'px'; + //this.highlightDiv[2].style.bottom=this.highlightDiv[3].style.bottom=this.highlightDiv[1].style.bottom=(this.hdrHt+bottom2) + 'px'; + for (var i=0; i<4; i++) + this.highlightDiv[i].style.display=''; + }, + + HideSelection: function(cellList) { + if (this.options.highlightMethod!='class') { + for (var i=0; i<4; i++) + this.highlightDiv[i].style.display='none'; + } + if (this.options.highlightMethod!='outline') { + var cellList=this.getVisibleSelection(); + for (var i=0; i= 0) { + sortDirection=this.columns[colnum].getSortDirection(); + } else { + if (typeof sortDirection!='string') { + sortDirection=Rico.TableColumn.SORT_ASC; + } else { + sortDirection=sortDirection.toUpperCase(); + if (sortDirection != Rico.TableColumn.SORT_DESC) sortDirection=Rico.TableColumn.SORT_ASC; + } + switch (typeof columnNameOrNum) { + case 'string': + colnum=this.findColumnName(columnNameOrNum); + break; + case 'number': + colnum=columnNameOrNum; + break; + } + } + if (typeof(colnum)!='number' || colnum < 0) return; + this.clearSort(); + this.columns[colnum].setSorted(sortDirection); + this.buffer.sortBuffer(colnum,sortDirection,this.columns[colnum].format.type,this.columns[colnum]._sortfunc); + }, + +/** + * clear sort flag on all columns + */ + clearSort: function() { + for (var x=0;x"; + for (var c=0; c"; + } + this.exportText+=""; + } + } + +}; + + +Object.extend(Rico.TableColumn.prototype, { + +initialize: function(liveGrid,colIdx,hdrInfo,tabIdx) { + this.baseInit(liveGrid,colIdx,hdrInfo,tabIdx); + Rico.writeDebugMsg(" sortable="+this.sortable+" filterable="+this.filterable+" hideable="+this.hideable+" isNullable="+this.isNullable+' isText='+this.isText); + this.fixHeaders(this.liveGrid.tableId, this.options.hdrIconsFirst); + if (this.format.type=='control' && this.format.control) { + // copy all properties/methods that start with '_' + if (typeof this.format.control=='string') + this.format.control=eval(this.format.control); + for (var property in this.format.control) + if (property.charAt(0)=='_') { + Rico.writeDebugMsg("Copying control property "+property); + this[property] = this.format.control[property]; + } + } else if (this['format_'+this.format.type]) { + this._format=this['format_'+this.format.type].bind(this); + } +}, + +sortAsc: function() { + this.setColumnSort(Rico.TableColumn.SORT_ASC); +}, + +sortDesc: function() { + this.setColumnSort(Rico.TableColumn.SORT_DESC); +}, + +setColumnSort: function(direction) { + this.liveGrid.clearSort(); + this.setSorted(direction); + if (this.liveGrid.options.saveColumnInfo.sort) + this.liveGrid.setCookie(); + if (this.options.sortHandler) + this.options.sortHandler(); +}, + +isSortable: function() { + return this.sortable; +}, + +isSorted: function() { + return this.currentSort != Rico.TableColumn.UNSORTED; +}, + +getSortDirection: function() { + return this.currentSort; +}, + +toggleSort: function() { + if (this.liveGrid.buffer && this.liveGrid.buffer.totalRows==0) return; + if (this.currentSort == Rico.TableColumn.SORT_ASC) + this.sortDesc(); + else + this.sortAsc(); +}, + +setUnsorted: function() { + this.setSorted(Rico.TableColumn.UNSORTED); +}, + +/** + * direction must be one of Rico.TableColumn.UNSORTED, .SORT_ASC, or .SORT_DESC + */ +setSorted: function(direction) { + this.currentSort = direction; +}, + +canFilter: function() { + return this.filterable; +}, + +getFilterText: function() { + var vals=[]; + for (var i=0; i(.*)<\/span>/i)) + vals.push(RegExp.leftContext); + else + vals.push(v); + } + switch (this.filterOp) { + case 'EQ': return vals[0]; + case 'NE': return 'not: '+vals.join(', '); + case 'LE': return '<= '+vals[0]; + case 'GE': return '>= '+vals[0]; + case 'LIKE': return 'like: '+vals[0]; + case 'NULL': return ''; + case 'NOTNULL': return ''; + } + return '?'; +}, + +getFilterQueryParm: function() { + if (this.filterType == Rico.TableColumn.UNFILTERED) return ''; + var retval='&f['+this.index+'][op]='+this.filterOp; + retval+='&f['+this.index+'][len]='+this.filterValues.length + for (var i=0; i/g,'>'); +}, + +format_number: function(v) { + if (typeof v=='undefined' || v=='' || v==null) + return ' '; + else + return v.formatNumber(this.format); +}, + +format_datetime: function(v) { + if (typeof v=='undefined' || v=='' || v==null) + return ' '; + else { + var d=new Date; + d.setISO8601(v); + return d.formatDate(this.format.dateFmt || 'translateDateTime'); + } +}, + +format_date: function(v) { + if (typeof v=='undefined' || v==null || v=='') + return ' '; + else { + var d=new Date; + if (!d.setISO8601(v)) return v; + return d.formatDate(this.format.dateFmt || 'translateDate'); + } +}, + +fixHeaders: function(prefix, iconsfirst) { + if (this.sortable) { + switch (this.options.headingSort) { + case 'link': + var a=RicoUtil.wrapChildren(this.hdrCellDiv,'ricoSort',undefined,'a') + a.href = "#"; + a.onclick = this.toggleSort.bindAsEventListener(this); + break; + case 'hover': + this.hdrCellDiv.onclick = this.toggleSort.bindAsEventListener(this); + break; + } + } + this.imgFilter = document.createElement('img'); + this.imgFilter.style.display='none'; + this.imgFilter.src=Rico.imgDir+this.options.filterImg; + this.imgFilter.className='ricoLG_HdrIcon'; + this.imgSort = document.createElement('img'); + this.imgSort.style.display='none'; + this.imgSort.className='ricoLG_HdrIcon'; + if (iconsfirst) { + this.hdrCellDiv.insertBefore(this.imgSort,this.hdrCellDiv.firstChild); + this.hdrCellDiv.insertBefore(this.imgFilter,this.hdrCellDiv.firstChild); + } else { + this.hdrCellDiv.appendChild(this.imgFilter); + this.hdrCellDiv.appendChild(this.imgSort); + } +}, + +getValue: function(windowRow) { + return this.liveGrid.buffer.getWindowValue(windowRow,this.index); +}, + +getFormattedValue: function(windowRow) { + return this._format(this.getValue(windowRow)); +}, + +getBufferCell: function(windowRow) { + return this.liveGrid.buffer.getWindowCell(windowRow,this.index); +}, + +setValue: function(windowRow,newval) { + this.liveGrid.buffer.setWindowValue(windowRow,this.index,newval); +}, + +_format: function(v) { + return v; +}, + +_display: function(v,gridCell) { + gridCell.innerHTML=this._format(v); +}, + +displayValue: function(windowRow) { + var bufCell=this.getBufferCell(windowRow); + if (!bufCell) { + this.clearCell(windowRow); + return; + } + var gridCell=this.cell(windowRow); + this._display(bufCell.content,gridCell,windowRow); + var acceptAttr=this.liveGrid.buffer.options.acceptAttr; + for (var k=0; k').replace(/ /g,' '); + }, + + _getdesc: function(v) { + var desc=this._map[v]; + return (typeof desc=='string') ? desc : this._defaultDesc; + }, + + _display: function(v,gridCell,windowRow) { + this._codes[windowRow].value=v; + this._descriptions[windowRow].innerHTML=this._getdesc(v); + } + +} + +Rico.includeLoaded('ricoLiveGrid.js'); diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoLiveGridAjax.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoLiveGridAjax.js new file mode 100644 index 0000000..ab193ff --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoLiveGridAjax.js @@ -0,0 +1,412 @@ +if(typeof Rico=='undefined') throw("LiveGridAjax requires the Rico JavaScript framework"); +if(typeof RicoUtil=='undefined') throw("LiveGridAjax requires the RicoUtil object"); +if(typeof Rico.Buffer=='undefined') throw("LiveGridAjax requires the Rico.Buffer object"); + + +/** + * Data source is a static XML file located on the server + */ +Rico.Buffer.AjaxXML = Class.create(); + +Rico.Buffer.AjaxXML.prototype = { + + initialize: function(url,options,ajaxOptions) { + Object.extend(this, new Rico.Buffer.Base()); + Object.extend(this, new Rico.Buffer.AjaxXMLMethods); + this.dataSource=url; + this.options.bufferTimeout = 20000; // time to wait for ajax response (milliseconds) + this.options.requestParameters = []; + Object.extend(this.options, options || {}); + this.ajaxOptions = { parameters: null, method : 'get' }; + Object.extend(this.ajaxOptions, ajaxOptions || {}); + this.requestCount=0; + this.processingRequest=false; + this.pendingRequest=-1; + } +} + +Rico.Buffer.AjaxXMLMethods = function() {}; + +Rico.Buffer.AjaxXMLMethods.prototype = { + + fetch: function(offset) { + if ( this.isInRange(offset) ) { + Rico.writeDebugMsg("AjaxXML fetch: in buffer"); + this.liveGrid.refreshContents(offset); + return; + } + this.processingRequest=true + Rico.writeDebugMsg("AjaxXML fetch, offset="+offset); + this.liveGrid.showMsg("Waiting for data..."); + this.timeoutHandler = setTimeout( this.handleTimedOut.bind(this), this.options.bufferTimeout); + this.sendAjaxRequest(offset,0,this.ajaxUpdate.bind(this,offset)); + }, + +/** + * Server did not respond in time... assume that there could have been + * an error, and allow requests to be processed again. + */ + handleTimedOut: function() { + Rico.writeDebugMsg("Request Timed Out"); + this.liveGrid.showMsg("Request for data timed out!"); + }, + + formQueryHash: function(startPos,fetchSize) { + if (typeof fetchSize!='number') fetchSize=this.totalRows; + var queryHash= { + id: this.liveGrid.tableId, + page_size: fetchSize, + offset: startPos + }; + if (!this.foundRowCount) queryHash['get_total']='true'; + if (this.options.requestParameters) { + for ( var i=0; i < this.options.requestParameters.length; i++ ) { + var anArg = this.options.requestParameters[i]; + if ( anArg.name != undefined && anArg.value != undefined ) { + queryHash[anArg.name]=anArg.value; + } else { + var ePos = anArg.indexOf('='); + var argName = anArg.substring( 0, ePos ); + var argValue = anArg.substring( ePos + 1 ); + queryHash[argName]=argValue; + } + } + } + + // sort + Object.extend(queryHash,this.sortParm); + + // filters + for (n=0; n=0) { + var offset=this.pendingRequest; + Rico.writeDebugMsg("ajaxUpdate: found pending request for offset="+offset); + this.pendingRequest=-1; + this.fetch(offset); + } + }, + + CheckRowCount: function(ajaxResponse,offset) { + //try { + Rico.writeDebugMsg("CheckRowCount, size="+this.size+' rcv cnt type='+typeof(this.rowcntContent)); + if (this.rcvdRowCount==true) { + Rico.writeDebugMsg("found row cnt: "+this.rowcntContent); + var eofrow=parseInt(this.rowcntContent); + var lastTotalRows=this.totalRows; + if (!isNaN(eofrow) && eofrow!=lastTotalRows) { + this.setTotalRows(eofrow); + var newpos=Math.min(this.liveGrid.topOfLastPage(),offset); + Rico.writeDebugMsg("CheckRowCount: new rowcnt="+eofrow+" newpos="+newpos); + if (lastTotalRows==0 && this.liveGrid.sizeTo=='data') + this.liveGrid.adjustPageSize(); + //this.lastRowPos=-1; + this.liveGrid.scrollToRow(newpos); + if ( this.isInRange(newpos) ) { + this.liveGrid.refreshContents(newpos); + } else { + this.fetch(newpos); + } + return; + } + } else { + var lastbufrow=offset+this.rcvdRows; + if (lastbufrow>this.totalRows) { + var newcnt=lastbufrow; + Rico.writeDebugMsg("extending totrows to "+newcnt); + this.setTotalRows(newcnt); + } + } + var newpos=this.liveGrid.pixeltorow(this.liveGrid.scrollDiv.scrollTop); + Rico.writeDebugMsg("CheckRowCount: newpos="+newpos); + this.liveGrid.refreshContents(newpos); + //} + //catch(err) { + // alert("Error in CheckRowCount:"+err.message); + //} + }, + + updateBuffer: function(ajaxResponse, start) { + Rico.writeDebugMsg("updateBuffer: "+start); + this.rcvdRows = 0; + var newRows = this.loadRows(ajaxResponse); + if (newRows==null) return; + this.rcvdRows = newRows.length; + Rico.writeDebugMsg("updateBuffer: # of rows="+this.rcvdRows); + if (this.rows.length == 0) { // initial load + this.rows = newRows; + this.startPos = start; + } else if (start > this.startPos) { //appending + if (this.startPos + this.rows.length < start) { + this.rows = newRows; + this.startPos = start;// + } else { + this.rows = this.rows.concat( newRows.slice(0, newRows.length)); + if (this.rows.length > this.maxBufferSize) { + var fullSize = this.rows.length; + this.rows = this.rows.slice(this.rows.length - this.maxBufferSize, this.rows.length) + this.startPos = this.startPos + (fullSize - this.rows.length); + } + } + } else { //prepending + if (start + newRows.length < this.startPos) { + this.rows = newRows; + } else { + this.rows = newRows.slice(0, this.startPos).concat(this.rows); + if (this.maxBufferSize && this.rows.length > this.maxBufferSize) + this.rows = this.rows.slice(0, this.maxBufferSize) + } + this.startPos = start; + } + this.size = this.rows.length; + }, + + loadRows: function(ajaxResponse) { + Rico.writeDebugMsg("loadRows"); + this.rcvdRowCount = false; + var debugtags = ajaxResponse.getElementsByTagName('debug'); + for (var i=0; i 0) { + var msg=RicoUtil.getContentAsString(error[0],this.options.isEncoded); + alert("Data provider returned an error:\n"+msg); + Rico.writeDebugMsg("Data provider returned an error:\n"+msg); + return null; + } + var rowsElement = ajaxResponse.getElementsByTagName('rows')[0]; + var rowcnttags = ajaxResponse.getElementsByTagName('rowcount'); + if (rowcnttags && rowcnttags.length==1) { + this.rowcntContent = RicoUtil.getContentAsString(rowcnttags[0],this.options.isEncoded); + this.rcvdRowCount = true; + this.foundRowCount = true; + Rico.writeDebugMsg("loadRows, found RowCount="+this.rowcntContent); + } + this.updateUI = rowsElement.getAttribute("update_ui") == "true"; + this.rcvdOffset = rowsElement.getAttribute("offset"); + Rico.writeDebugMsg("loadRows, rcvdOffset="+this.rcvdOffset); + return this.dom2jstable(rowsElement); + } + +}; + + + +Rico.Buffer.AjaxSQL = Class.create(); + +Rico.Buffer.AjaxSQL.prototype = { + + initialize: function(url,options,ajaxOptions) { + Object.extend(this, new Rico.Buffer.AjaxXML()); + Object.extend(this, new Rico.Buffer.AjaxSQLMethods()); + this.dataSource=url; + this.options.canFilter=true; + this.options.largeBufferSize = 7.0; // 7 pages + this.options.nearLimitFactor = 1.0; // 1 page + Object.extend(this.options, options || {}); + Object.extend(this.ajaxOptions, ajaxOptions || {}); + this.sortParm={}; + } +} + +Rico.Buffer.AjaxSQLMethods = function() {}; + +Rico.Buffer.AjaxSQLMethods.prototype = { + + registerGrid: function(liveGrid) { + this.liveGrid = liveGrid; + this.sessionExpired=false; + this.timerMsg=$(liveGrid.tableId+'_timer'); + if (this.options.TimeOut && this.timerMsg) { + if (!this.timerMsg.title) this.timerMsg.title=RicoTranslate.getPhrase("minutes before your session expires") + this.restartSessionTimer(); + } + }, + + setBufferSize: function(pageSize) { + this.maxFetchSize = Math.max(50,parseInt(this.options.largeBufferSize * pageSize)); + this.nearLimit = parseInt(this.options.nearLimitFactor * pageSize); + this.maxBufferSize = this.maxFetchSize * 3; + }, + + restartSessionTimer: function() { + if (this.sessionExpired==true) return; + this.timeRemaining=this.options.TimeOut+1; + if (this.sessionTimer) clearTimeout(this.sessionTimer); + this.updateSessionTimer(); + }, + + updateSessionTimer: function() { + if (--this.timeRemaining<=0) { + this.displaySessionTimer(RicoTranslate.getPhrase("EXPIRED")); + this.timerMsg.style.backgroundColor="red"; + this.sessionExpired=true; + } else { + this.displaySessionTimer(this.timeRemaining); + this.sessionTimer=setTimeout(this.updateSessionTimer.bind(this),60000); + } + }, + + displaySessionTimer: function(msg) { + this.timerMsg.innerHTML=' '+msg+' '; + }, + + refresh: function() { + this.fetch(this.lastOffset); + }, + + /** + * Fetch data from database. + * @param offset position (row) within the dataset (-1=clear existing buffer before issuing request) + */ + fetch: function(offset) { + Rico.writeDebugMsg("AjaxSQL fetch, offset="+offset+' lastOffset='+this.lastOffset); + if (this.processingRequest) { + Rico.writeDebugMsg("AjaxSQL fetch: queue request"); + this.pendingRequest=offset; + return; + } + if (offset < 0) { + this.clear(); + this.setTotalRows(0); + this.foundRowCount = false; + offset=0; + } + var lastOffset = this.lastOffset; + this.lastOffset = offset; + var inRange=this.isInRange(offset); + if (inRange) { + Rico.writeDebugMsg("AjaxSQL fetch: in buffer"); + this.liveGrid.refreshContents(offset); + if (offset > lastOffset) { + if (offset+this.liveGrid.pageSize < this.endPos()-this.nearLimit) return; + if (this.endPos()==this.totalRows && this.foundRowCount) return; + } else if (offset < lastOffset) { + if (offset > this.startPos+this.nearLimit) return; + if (this.startPos==0) return; + } else return; + } + if (offset >= this.totalRows && this.foundRowCount) return; + + this.processingRequest=true + Rico.writeDebugMsg("AjaxSQL fetch, processing offset="+offset); + var bufferStartPos = this.getFetchOffset(offset); + var fetchSize = this.getFetchSize(bufferStartPos); + var partialLoaded = false; + + if (!inRange) this.liveGrid.showMsg("Waiting for data..."); + this.timeoutHandler = setTimeout( this.handleTimedOut.bind(this), this.options.bufferTimeout); + this.sendAjaxRequest(bufferStartPos,fetchSize,this.ajaxUpdate.bind(this,bufferStartPos)); + }, + + getFetchSize: function(adjustedOffset) { + var adjustedSize = 0; + if (adjustedOffset >= this.startPos) { //appending + var endFetchOffset = this.maxFetchSize + adjustedOffset; + adjustedSize = endFetchOffset - adjustedOffset; + if(adjustedOffset == 0 && adjustedSize < this.maxFetchSize) + adjustedSize = this.maxFetchSize; + Rico.writeDebugMsg("getFetchSize/append, adjustedSize="+adjustedSize+" adjustedOffset="+adjustedOffset+' endFetchOffset='+endFetchOffset); + } else { //prepending + adjustedSize = Math.min(this.startPos - adjustedOffset,this.maxFetchSize); + } + return adjustedSize; + }, + + getFetchOffset: function(offset) { + var adjustedOffset = offset; + if (offset > this.startPos) + adjustedOffset = Math.max(offset, this.endPos()); //appending + else if (offset + this.maxFetchSize >= this.startPos) + adjustedOffset = Math.max(this.startPos - this.maxFetchSize, 0); //prepending + return adjustedOffset; + }, + + sortBuffer: function(colnum,sortdir,coltype) { + this.sortParm={}; + if (this.options.sortParmFmt && this.options.sortParmFmt=='displayName') { + this.sortParm['sort_col']=this.liveGrid.columns[colnum].displayName.toLowerCase(); + this.sortParm['sort_dir']=sortdir; + }else{ + this.sortParm['s'+colnum]=sortdir; + } + this.clear(); + }, + + exportAllRows: function(populate,finish) { + this.exportPopulate=populate; + this.exportFinish=finish; + this.liveGrid.showMsg("Waiting for data..."); + this.sendExportRequest(0); + }, + +/** + * Make ajax request for print window data + */ + sendExportRequest: function(offset) { + this.timeoutHandler = setTimeout(this.exportTimedOut.bind(this), this.options.bufferTimeout); + this.sendAjaxRequest(offset,200,this.exportAppend.bind(this,offset)); + }, + + exportTimedOut: function() { + Rico.writeDebugMsg("Print Request Timed Out"); + this.liveGrid.showMsg("Request for data timed out!"); + this.exportFinish(); + }, + + exportAppend: function(startPos,request) { + this.clearTimer(); + var response = request.responseXML.getElementsByTagName("ajax-response"); + if (response == null || response.length != 1) return; + var rowsElement = response[0].getElementsByTagName('rows')[0]; + var rows=this.dom2jstable(rowsElement); + this.exportPopulate(rows); + if (rows.length==0) + this.exportFinish(); + else + this.sendExportRequest(startPos+rows.length); + } + +}; + +Rico.includeLoaded('ricoLiveGridAjax.js'); diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoLiveGridForms.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoLiveGridForms.js new file mode 100644 index 0000000..3e60c45 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoLiveGridForms.js @@ -0,0 +1,830 @@ +if(typeof Rico=='undefined') throw("LiveGridForms requires the Rico JavaScript framework"); +if(typeof RicoUtil=='undefined') throw("LiveGridForms requires the RicoUtil object"); +if(typeof RicoTranslate=='undefined') throw("LiveGridForms requires the RicoTranslate object"); + + +Rico.TableEdit = Class.create(); + +Rico.TableEdit.prototype = { + + initialize: function(liveGrid) { + Rico.writeDebugMsg('Rico.TableEdit initialize: '+liveGrid.tableId); + this.grid=liveGrid; + this.options = { + maxDisplayLen : 20, // max displayed text field length + panelHeight : 200, // size of tabbed panels + panelWidth : 500, + hoverClass : 'tabHover', + selectedClass : 'tabSelected', + compact : false, // compact corners + RecordName : 'record', + readOnlyColor : '#AAA', // read-only fields displayed using this color + showSaveMsg : 'errors' // disposition of database update responses (full - show full response, errors - show full response for errors and short response otherwise) + } + Object.extend(this.options, liveGrid.options); + this.menu=liveGrid.menu; + this.menu.options.dataMenuHandler=this.editMenu.bind(this); + this.menu.ignoreClicks(); + RicoEditControls.atLoad(); + this.createEditDiv(); + this.saveMsg=$(liveGrid.tableId+'_savemsg'); + Event.observe(document,"click", this.clearSaveMsg.bindAsEventListener(this), false); + this.TEerror=false; + this.extraMenuItems=new Array(); + this.responseHandler=this.processResponse.bind(this); + }, + + createEditDiv: function() { + + // create editDiv (form) + + this.requestCount=1; + this.editDiv = this.grid.createDiv('edit',document.body); + this.editDiv.style.display='none'; + if (this.options.canEdit || this.options.canAdd) { + this.startForm(); + this.createForm(this.form); + } else { + var button=this.createButton("Close"); + Event.observe(button,"click", this.cancelEdit.bindAsEventListener(this), false); + this.createForm(this.editDiv); + } + this.editDivCreated=true; + this.formPopup=new Rico.Popup({ignoreClicks:true},this.editDiv); + + // create responseDialog + + this.responseDialog = this.grid.createDiv('editResponse',document.body); + this.responseDialog.style.display='none'; + + var button = document.createElement('button'); + button.appendChild(document.createTextNode('OK')); + button.onclick=this.ackResponse.bindAsEventListener(this); + this.responseDialog.appendChild(button); + + this.responseDiv = this.grid.createDiv('editResponseText',this.responseDialog); + + if (this.panelGroup) { + Rico.writeDebugMsg("createEditDiv complete, requestCount="+this.requestCount); + setTimeout(this.initPanelGroup.bind(this),50); + } + }, + + initPanelGroup: function() { + this.requestCount--; + Rico.writeDebugMsg("initPanelGroup: "+this.requestCount); + if (this.requestCount>0) return; + var wi=parseInt(this.options.panelWidth); + this.form.style.width=(wi+10)+'px'; + if (Prototype.Browser.WebKit) this.editDiv.style.display='block'; // this causes display to flash briefly + this.options.bgColor = Rico.Color.createColorFromBackground(this.form); + this.editDiv.style.display='none'; + this.options.panelHdrWidth=(Math.floor(wi / this.options.panels.length)-4)+'px'; + this.Accordion=new Rico.TabbedPanel(this.panelHdr.findAll(this.notEmpty), this.panelContent.findAll(this.notEmpty), this.options); + }, + + notEmpty: function(v) { + return typeof(v)!='undefined'; + }, + + startForm: function() { + this.form = document.createElement('form'); + this.form.onsubmit=function() {return false;}; + this.editDiv.appendChild(this.form); + + var tab = document.createElement('table'); + var row = tab.insertRow(-1); + var cell = row.insertCell(-1); + var button=cell.appendChild(this.createButton("Save \t"+this.options.RecordName)); + Event.observe(button,"click", this.TESubmit.bindAsEventListener(this), false); + var cell = row.insertCell(-1); + var button=cell.appendChild(this.createButton("Cancel")); + Event.observe(button,"click", this.cancelEdit.bindAsEventListener(this), false); + this.form.appendChild(tab); + + // hidden fields + this.hiddenFields = document.createElement('div'); + this.hiddenFields.style.display='none'; + this.action = this.appendHiddenField(this.grid.tableId+'__action',''); + for (var i=0; i"+buttonLabel.substr(1); + button.accessKey=buttonLabel.charAt(0); + return button; + }, + + createPanel: function(i) { + var hasFields=false; + for (var j=0; j=0; i--) + if (this.createPanel(i)) + tables[i]=this.createFormTable(this.panelContent[i],'tabContent'); + } else { + for (var i=0; i 0) { + Rico.writeDebugMsg("Data provider returned an error:\n"+RicoUtil.getContentAsString(error[0],this.grid.buffer.isEncoded)); + alert(RicoTranslate.getPhrase("The request returned an error")+":\n"+RicoUtil.getContentAsString(error[0],this.grid.buffer.isEncoded)); + return null; + } + response=response.getElementsByTagName('response')[0]; + var id = response.getAttribute("id").slice(0,-8); + var rowsElement = response.getElementsByTagName('rows')[0]; + var rows = this.grid.buffer.dom2jstable(rowsElement); + var elem=$(id); + //alert('selectValuesUpdate:'+id+' '+elem.tagName); + Rico.writeDebugMsg("selectValuesUpdate: id="+id+' rows='+rows.length); + for (var i=0; i0) { + var c0=rows[i][0].content; + var c1=(rows[i].length>1) ? rows[i][1].content : c0; + this.addSelectOption(elem,c0,c1,i); + } + } + if ($('textnew__'+id)) + this.addSelectOption(elem,this.options.TableSelectNew,"(new value)"); + if (this.panelGroup) + setTimeout(this.initPanelGroup.bind(this),50); + }, + + addSelectOption: function(elem,value,text,idx) { + switch (elem.tagName.toLowerCase()) { + case 'div': + var opt=RicoUtil.createFormField(elem,'input','radio',elem.id+'_'+idx,elem.id); + opt.value=value; + var lbl=document.createElement('label'); + lbl.innerHTML=text; + lbl.htmlFor=opt.id; + elem.appendChild(lbl); + break; + case 'select': + var opt=document.createElement('option'); + opt.value=value; + opt.text=text; + //elem.options.add(opt); + if (Prototype.Browser.IE) + elem.add(opt); + else + elem.add(opt,null); + break; + } + }, + + clearSaveMsg: function() { + if (this.saveMsg) this.saveMsg.innerHTML=""; + }, + + addMenuItem: function(menuText,menuAction,enabled) { + this.extraMenuItems.push({menuText:menuText,menuAction:menuAction,enabled:enabled}); + }, + + editMenu: function(grid,r,c,onBlankRow) { + this.clearSaveMsg(); + if (this.grid.buffer.sessionExpired==true || this.grid.buffer.startPos<0) return; + this.rowIdx=r; + var elemTitle=$('pageTitle'); + var pageTitle=elemTitle ? elemTitle.innerHTML : document.title; + this.menu.addMenuHeading(pageTitle); + for (var i=0; i(.*)<\/span>/i)) + return [RegExp.$2,RegExp.leftContext]; + else + return [value,value]; + }, + + // use with care: Prototype 1.5 does not include disabled fields in the post-back + setReadOnly: function(addFlag) { + for (var i=0; i=0; i--) { + if (ch[i].nodeType==1 && ch[i].nodeName!='P' && ch[i].nodeName!='DIV' && ch[i].nodeName!='BR') + this.responseDiv.removeChild(ch[i]); + } + var responseText=this.responseDiv.innerHTML; + if (responseText.toLowerCase().indexOf('error')==-1 && this.options.showSaveMsg!='full') { + this.hideResponse(''); + this.grid.resetContents(); + this.grid.buffer.foundRowCount = false; + this.grid.buffer.fetch(this.grid.lastRowPos || 0); + if (this.saveMsg) this.saveMsg.innerHTML=' '+responseText.stripTags()+' '; + } + this.processCallback(this.options.onSubmitResponse); + }, + + processCallback: function(callback) { + switch (typeof callback) { + case 'string': eval(callback); break; + case 'function': callback(); break; + } + }, + + // called when ok pressed on error response message + ackResponse: function() { + this.hideResponse(''); + this.grid.highlightEnabled=true; + }, + + editRecord: function(e) { + this.grid.highlightEnabled=false; + this.menu.hidemenu(); + this.hideResponse('Saving...'); + this.grid.outerDiv.style.cursor = 'auto'; + this.action.value="upd"; + for (var i=0; i winWi) + this.editDiv.style.left=(winWi-editWi)+'px'; + else + this.editDiv.style.left=(odOffset[0]+1)+'px'; + + // set top position + var scrTop=RicoUtil.docScrollTop(); + var editHt=this.editDiv.offsetHeight; + var newTop=odOffset[1]+this.grid.hdrHt+scrTop; + var bottom=RicoUtil.windowHeight()+scrTop; + if (row >= 0) { + newTop+=(row+1)*this.grid.rowHeight; + if (newTop+editHt>bottom) newTop-=(editHt+this.grid.rowHeight); + } else { + if (newTop+editHt>bottom) newTop=bottom-editHt; + } + this.processCallback(this.options.formOpen); + this.formPopup.openPopup(null,Math.max(newTop,scrTop)); + this.editDiv.style.visibility='visible'; + if (this.initialized) return; + for (i = 0; i < this.grid.columns.length; i++) { + spec=this.grid.columns[i].format; + if (!spec || !spec.EntryType || !spec.FieldName) continue; + switch (spec.EntryType) { + case 'tinyMCE': + if (typeof tinyMCE!='undefined') tinyMCE.execCommand('mceAddControl', true, spec.FieldName); + break; + } + } + this.formPopup.openPopup(); // tinyMCE may have changed the dimensions of the form + this.initialized=true; + }, + + makeFormInvisible: function() { + this.editDiv.style.visibility='hidden'; + this.formPopup.closePopup(); + this.processCallback(this.options.formClose); + }, + + getConfirmDesc: function(rowIdx) { + var desc=this.grid.columns[this.options.ConfirmDeleteCol].cell(rowIdx).innerHTML; + desc=this.getLookupValue(desc)[1]; + return desc.stripTags(); + }, + + deleteRecord: function() { + this.menu.hidemenu(); + var desc; + if (this.options.ConfirmDeleteCol < 0) { + desc=RicoTranslate.getPhrase("this "+this.options.RecordName); + } else { + desc=this.getConfirmDesc(this.rowIdx); + if (desc.length>50) desc=desc.substring(0,50)+'...'; + desc='\"' + desc + '\"' + } + if (!this.options.ConfirmDelete.valueOf || confirm(RicoTranslate.getPhrase("Are you sure you want to delete ") + desc + " ?")) { + this.hideResponse('Deleting...'); + this.showResponse(); + var parms=this.action.name+"=del"+this.getKey(); + //alert(parms); + new Ajax.Updater(this.responseDiv, window.location.pathname, {parameters:parms,onComplete:this.processResponse.bind(this)}); + } + this.menu.cancelmenu(); + }, + + getKey: function() { + var key=''; + for (var i=0; i= totrows; + var column=this.liveGrid.columns[c]; + if (this.options.dataMenuHandler) { + var showMenu=this.options.dataMenuHandler(this.liveGrid,r,c,onBlankRow); + if (!showMenu) return false; + } + + // menu items for sorting + if (column.sortable && totrows>0) { + this.sortmenu.clearMenu(); + this.addSubMenuItem(RicoTranslate.getPhrase("Sort by")+": "+column.displayName, this.sortmenu, false); + this.sortmenu.addMenuItem("Ascending", column.sortAsc.bind(column), true); + this.sortmenu.addMenuItem("Descending", column.sortDesc.bind(column), true); + } + + // menu items for filtering + if (column.canFilter() && (!onBlankRow || column.filterType == Rico.TableColumn.USERFILTER)) { + this.filtermenu.clearMenu(); + this.addSubMenuItem(RicoTranslate.getPhrase("Filter by")+": "+column.displayName, this.filtermenu, false); + column.userFilter=column.getValue(r); + if (column.filterType == Rico.TableColumn.USERFILTER) { + this.filtermenu.addMenuItem("Remove filter", column.setUnfiltered.bind(column), true); + this.filtermenu.addMenuItem("Refresh", this.liveGrid.filterHandler.bind(this.liveGrid), true); + if (column.filterOp=='LIKE') + this.filtermenu.addMenuItem("Change keyword...", column.setFilterKW.bind(column), true); + if (column.filterOp=='NE' && !onBlankRow) + this.filtermenu.addMenuItem("Exclude this value also", column.addFilterNE.bind(column), true); + } else if (!onBlankRow) { + this.filtermenu.addMenuItem("Include only this value", column.setFilterEQ.bind(column), true); + this.filtermenu.addMenuItem("Greater than or equal to this value", column.setFilterGE.bind(column), column.userFilter!=''); + this.filtermenu.addMenuItem("Less than or equal to this value", column.setFilterLE.bind(column), column.userFilter!=''); + if (column.isText) + this.filtermenu.addMenuItem("Contains keyword...", column.setFilterKW.bind(column), true); + this.filtermenu.addMenuItem("Exclude this value", column.setFilterNE.bind(column), true); + } + if (this.liveGrid.filterCount() > 0) + this.filtermenu.addMenuItem("Remove all filters", this.liveGrid.clearFilters.bind(this.liveGrid), true); + } + + // menu items for Print/Export + if (this.liveGrid.options.maxPrint > 0 && totrows>0) { + this.exportmenu.clearMenu(); + this.addSubMenuItem('Print\t/Export',this.exportmenu); + this.exportmenu.addMenuItem("Visible rows to web page", this.liveGrid.printVisible.bind(this.liveGrid,'plain'), true); + this.exportmenu.addMenuItem("All rows to web page", this.liveGrid.printAll.bind(this.liveGrid,'plain'), this.liveGrid.buffer.totalRows <= this.liveGrid.options.maxPrint); + if (Prototype.Browser.IE) { + this.exportmenu.addMenuBreak(); + this.exportmenu.addMenuItem("Visible rows to spreadsheet", this.liveGrid.printVisible.bind(this.liveGrid,'owc'), true); + this.exportmenu.addMenuItem("All rows to spreadsheet", this.liveGrid.printAll.bind(this.liveGrid,'owc'), this.liveGrid.buffer.totalRows <= this.liveGrid.options.maxPrint); + } + } + + // menu items for hide/unhide + var hiddenCols=this.liveGrid.listInvisible(); + for (var showableCnt=0,x=0; x 0 || column.canHideShow()) { + this.hideshowmenu.clearMenu(); + this.addSubMenuItem('Hide\t/Show',this.hideshowmenu); + var visibleCnt=this.liveGrid.columns.length-hiddenCols.length; + var enabled=(visibleCnt>1 && column.visible && column.canHideShow()); + this.hideshowmenu.addMenuItem(RicoTranslate.getPhrase('Hide')+': '+column.displayName, column.hideColumn.bind(column), enabled); + for (var cnt=0,x=0; x 1) + this.hideshowmenu.addMenuItem(RicoTranslate.getPhrase('Show All'), this.liveGrid.showAll.bind(this.liveGrid)); + } + return true; +} + +} + +Rico.includeLoaded('ricoLiveGridMenu.js'); diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoMenu.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoMenu.js new file mode 100644 index 0000000..544d3e8 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoMenu.js @@ -0,0 +1,197 @@ +Rico.Menu = Class.create(); + +Rico.Menu.prototype = { + + initialize: function(options) { + Object.extend(this, new Rico.Popup()); + Object.extend(this.options, { + width : "15em", + margin : 6 // account for shadow + }); + if (typeof options=='string') + this.options.width=options; + else + Object.extend(this.options, options || {}); + this.hideFunc=null; + this.highlightElem=null; + new Image().src = Rico.imgDir+'left.gif'; + new Image().src = Rico.imgDir+'right.gif'; + }, + + createDiv: function(parentNode) { + if (this.div) return; + this.div = document.createElement('div'); + this.div.className = Prototype.Browser.WebKit ? 'ricoMenuSafari' : 'ricoMenu'; + this.div.style.position="absolute"; + this.div.style.width=this.options.width; + if (!parentNode) parentNode = document.getElementsByTagName("body")[0]; + parentNode.appendChild(this.div); + this.width=this.div.offsetWidth + this.setDiv(this.div,this.cancelmenu.bindAsEventListener(this)); + this.direction=Element.getStyle(this.div,'direction') || 'ltr'; + this.direction=this.direction.toLowerCase(); // ltr or rtl + this.hidemenu(); + this.itemCount=0; + }, + + showmenu: function(e,hideFunc){ + Event.stop(e); + this.hideFunc=hideFunc; + if (this.div.childNodes.length==0) { + this.cancelmenu(); + return false; + } + this.openmenu(e.clientX,e.clientY,0,0); + }, + + openmenu: function(x,y,clickItemWi,clickItemHt) { + var newLeft=RicoUtil.docScrollLeft()+x; + //window.status='openmenu: newLeft='+newLeft+' width='+this.width+' windowWi='+RicoUtil.windowWidth(); + if (this.direction == 'rtl') { + if (newLeft > this.width+clickItemWi) newLeft-=this.width+clickItemWi; + } else { + if (x+this.width+this.options.margin > RicoUtil.windowWidth()) newLeft-=this.width+clickItemWi; + } + var newTop=RicoUtil.docScrollTop()+y; + this.div.style.visibility="hidden"; + this.div.style.display="block"; + var contentHt=this.div.offsetHeight; + if (y+contentHt+this.options.margin > RicoUtil.windowHeight()) + newTop=Math.max(newTop-contentHt+clickItemHt,0); + this.openPopup(newLeft,newTop); + this.div.style.visibility ="visible"; + return false; + }, + + clearMenu: function() { + this.div.innerHTML=""; + this.defaultAction=null; + this.itemCount=0; + }, + + addMenuHeading: function(hdg,translate) { + var el=document.createElement('div') + el.innerHTML =(translate==null || translate==true) ? RicoTranslate.getPhrase(hdg) : hdg; + el.className='ricoMenuHeading'; + this.div.appendChild(el); + }, + + addMenuBreak: function() { + var brk=document.createElement('div'); + brk.className="ricoMenuBreak"; + this.div.appendChild(brk); + }, + + addSubMenuItem: function(menutext, submenu, translate) { + var dir=this.direction=='rtl' ? 'left' : 'right'; + var a=this.addMenuItem(menutext,null,true,null,translate); + a.className='ricoSubMenu'; + a.style.backgroundImage='url('+Rico.imgDir+dir+'.gif)'; + a.style.backgroundRepeat='no-repeat'; + a.style.backgroundPosition=dir; + a.onmouseover=this.showSubMenu.bind(this,a,submenu); + a.onmouseout=this.subMenuOut.bindAsEventListener(this); + }, + + showSubMenu: function(a,submenu) { + if (this.openSubMenu) this.hideSubMenu(); + this.openSubMenu=submenu; + this.openMenuAnchor=a; + var pos=Position.page(a); + if (a.className=='ricoSubMenu') a.className='ricoSubMenuOpen'; + submenu.openmenu(pos[0]+a.offsetWidth, pos[1], a.offsetWidth-2, a.offsetHeight+2); + }, + + subMenuOut: function(e) { + if (!this.openSubMenu) return; + Event.stop(e); + var elem=Event.element(e); + var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement; + try { + while (reltg != null && reltg != this.openSubMenu.div) + reltg=reltg.parentNode; + } catch(err) {} + if (reltg == this.openSubMenu.div) return; + this.hideSubMenu(); + }, + + hideSubMenu: function() { + if (this.openMenuAnchor) { + this.openMenuAnchor.className='ricoSubMenu'; + this.openMenuAnchor=null; + } + if (this.openSubMenu) { + this.openSubMenu.hidemenu(); + this.openSubMenu=null; + } + }, + + addMenuItem: function(menutext,action,enabled,title,translate,target) { + this.itemCount++; + if (translate==null) translate=true; + var a = document.createElement(typeof action=='string' ? 'a' : 'div'); + if ( arguments.length < 3 || enabled ) { + switch (typeof action) { + case 'function': + a.onclick = action; + break; + case 'string' : + a.href = action; + if (target) a.target = target; + break + } + a.className = 'enabled'; + if (this.defaultAction==null) this.defaultAction=action; + } else { + a.disabled = true; + a.className = 'disabled'; + } + a.innerHTML = translate ? RicoTranslate.getPhrase(menutext) : menutext; + if (typeof title=='string') + a.title = translate ? RicoTranslate.getPhrase(title) : title; + a=this.div.appendChild(a); + Event.observe(a,"mouseover", this.mouseOver.bindAsEventListener(this)); + Event.observe(a,"mouseout", this.mouseOut.bindAsEventListener(this)); + return a; + }, + + mouseOver: function(e) { + if (this.highlightElem && this.highlightElem.className=='enabled-hover') { + // required for Safari + this.highlightElem.className='enabled'; + this.highlightElem=null; + } + var elem=Event.element(e); + if (this.openMenuAnchor && this.openMenuAnchor!=elem) + this.hideSubMenu(); + if (elem.className=='enabled') { + elem.className='enabled-hover'; + this.highlightElem=elem; + } + }, + + mouseOut: function(e) { + var elem=Event.element(e); + if (elem.className=='enabled-hover') elem.className='enabled'; + if (this.highlightElem==elem) this.highlightElem=null; + }, + + isVisible: function() { + return this.div && Element.visible(this.div); + }, + + cancelmenu: function() { + if (this.hideFunc) this.hideFunc(); + this.hideFunc=null; + this.hidemenu(); + }, + + hidemenu: function() { + if (!this.div) return; + if (this.openSubMenu) this.openSubMenu.hidemenu(); + this.closePopup(); + } + +}; + +Rico.includeLoaded('ricoMenu.js'); diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoSheet.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoSheet.js new file mode 100644 index 0000000..97faef6 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoSheet.js @@ -0,0 +1,1577 @@ +Object.extend(Rico.SimpleGrid.prototype, { + +initSheet: function() { + this.highlightDiv=[]; + for (var i=0; i<4; i++) { + this.highlightDiv[i] = this.createDiv("highlight",this.scrollDiv); + this.highlightDiv[i].style.display="none"; + this.highlightDiv[i].id+=i; + this.highlightDiv[i].style[i % 2==0 ? 'height' : 'width']="0px"; + } + for (var c=1; c s.r2) { + this.HideSelection(); + return; + } + var top1=this.columns[s.c1].cell(s.r1).offsetTop; + var cell2=this.columns[s.c1].cell(s.r2); + var bottom2=cell2.offsetTop+cell2.offsetHeight; + var left1=this.columns[s.c1].dataCell.offsetLeft; + var left2=this.columns[s.c2].dataCell.offsetLeft; + var right2=left2+this.columns[s.c2].dataCell.offsetWidth; + //window.status='updateSelectOutline: '+s.r1+' '+s.r2+' top='+top1+' bot='+bottom2; + this.highlightDiv[0].style.top=this.highlightDiv[3].style.top=this.highlightDiv[1].style.top=(top1-3) + 'px'; + this.highlightDiv[2].style.top=(bottom2-2)+'px'; + this.highlightDiv[3].style.left=(left1-2)+'px'; + this.highlightDiv[0].style.left=this.highlightDiv[2].style.left=(left1-1)+'px'; + this.highlightDiv[1].style.left=(right2-1)+'px'; + this.highlightDiv[0].style.width=this.highlightDiv[2].style.width=(right2-left1-1) + 'px'; + this.highlightDiv[1].style.height=this.highlightDiv[3].style.height=(bottom2-top1) + 'px'; + for (var i=0; i<4; i++) + this.highlightDiv[i].style.display=''; +}, + +isSelected: function(r,c) { + var s=this.getSelection(); + return s ? (s.r1 <= r) && (r <= s.r2) && (s.c1 <= c) && (c <= s.c2) : false; +}, + +HideSelection: function(cellList) { + for (var i=0; i<4; i++) + this.highlightDiv[i].style.display='none'; +}, + +ShowSelection: function() { + this.updateSelectOutline(); +}, + +/* + * @param what valid values are: null, 'all', 'formats', 'formulas', 'values' + */ +clearSelection: function() { + var s=this.getSelection(); + if (!s) return; + var args=$A(arguments); + var what=args.shift(); + if (typeof what=='object') what=args.shift(); // in case first arg is an event object + var v=(!what || what=='all') ? 1 : 0; + var whatobj={formats:v,formulas:v,values:v}; + if (typeof what=='string') whatobj[what]=1; + if (whatobj.values) whatobj.formulas=1; + for (var r=s.r1; r<=s.r2; r++) { + for (var c=s.c1; c<=s.c2; c++) { + var gridcell=this.columns[c].cell(r); + if (whatobj.formats) { + gridcell.style.cssText=''; + gridcell.RicoFormat={}; + } + if (whatobj.formulas) gridcell.RicoFormula=null; + if (whatobj.values) gridcell.RicoValue=null; + this.formatCell(gridcell); + } + } +}, + +selectCellRC: function(r,c,adjFlag) { + if (r < 0 || r >= this.columns[0].numRows()) return; + this.HideSelection(); + if (adjFlag) { + if (this.SelectIdxStart.tabIdx == this.columns[c].tabIdx) + this.SelectIdxEnd={row:r, column:c, tabIdx:this.columns[c].tabIdx}; + } else { + this.SelectIdxStart=this.SelectIdxEnd={row:r, column:c, tabIdx:this.columns[c].tabIdx}; + this.columns[c].cell(r).focus(); // causes IE to scroll cell into view (but not FF) + } + this.ShowSelection(); +}, + +moveSelection: function(dr,dc,adjFlag,e) { + var selIdx=adjFlag ? this.SelectIdxEnd : this.SelectIdxStart; + var newr=selIdx.row+dr; + var newc=selIdx.column+dc; + if (newr>=0 && newr=1 && newcs.c1) clipstr+="\t"; + clipstr+=this.columns[c].cell(r).RicoValue; + } + clipstr+="\r\n"; + } + this.clipBox.style.display='block'; + this.clipBox.value=clipstr; + this.clipBox.select(); +}, + +copySelection: function() { + var s=this.getSelection(); + if (!s) return; + var clipArray=[]; + for (var r=s.r1; r<=s.r2; r++) { + var cliprow=[]; + for (var c=s.c1; c<=s.c2; c++) { + var clipcell={}; + var gridcell=this.columns[c].cell(r); + clipcell.value=gridcell.RicoValue; + clipcell.style=gridcell.style.cssText; + if (gridcell.RicoFormat) + clipcell.format=Object.extend({}, gridcell.RicoFormat || {}); + if (gridcell.RicoFormula) + clipcell.formula=Object.extend({}, gridcell.RicoFormula); + cliprow[c-s.c1]=clipcell; + } + clipArray[r-s.r1]=cliprow; + } + return clipArray; +}, + +pasteSelection: function(clipArray,pasteType) { + var s=this.getSelection(); + if (!s || !clipArray) return; + pasteType=pasteType || 'all'; + var clipclen=clipArray[0].length; + if (s.r1==s.r2 && s.c1==s.c2) { + s.r2=Math.min(s.r1+clipArray.length,this.columns[0].numRows())-1; + s.c2=Math.min(s.c1+clipclen,this.columns.length)-1; + } + for (var r=s.r1,clipr=0; r<=s.r2; r++) { + var arow=clipArray[clipr]; + for (var c=s.c1,clipc=0; c<=s.c2; c++) { + var clipcell=arow[clipc]; + var gridcell=this.columns[c].cell(r); + this.updateDependencies(gridcell,'remove'); + gridcell.RicoFormula=null; + if (clipcell.formula) { + gridcell.RicoFormula=Object.extend({}, clipcell.formula); + gridcell.RicoFormula.cell=gridcell; + gridcell.RicoValue = gridcell.RicoFormula.eval(); + this.updateDependencies(gridcell,'add'); + } else { + gridcell.RicoValue=clipcell.value; + } + gridcell.style.cssText=clipcell.style; + if (clipcell.format) + gridcell.RicoFormat=Object.extend({}, clipcell.format); + this.formatCell(gridcell); + this.checkDependencies(gridcell); + clipc=(clipc+1) % clipclen; + } + clipr=(clipr+1) % clipArray.length; + } +}, + +formatSelection: function(newFormat) { + var s=this.getSelection(); + if (!s) return; + for (var r=s.r1; r<=s.r2; r++) { + for (var c=s.c1; c<=s.c2; c++) { + var gridcell=this.cell(r,c); + gridcell.RicoFormat=newFormat; + this.formatCell(gridcell); + } + } +}, + +handleCtrlKey: function(e) { + switch (e.keyCode) { + // Ctrl-C + case 67: + this.clip=this.copySelection(); + window.status='copy: '+this.clip.length; + Event.stop(e); + break; + + // Ctrl-X + case 88: + this.clip=this.copySelection(); + this.clearSelection(); + Event.stop(e); + break; + + // Ctrl-V + case 86: + window.status='paste: '+this.clip.length; + this.pasteSelection(this.clip); + Event.stop(e); + break; + + // Ctrl-B + case 66: + this.toggleAttr('font-weight','normal','bold'); + Event.stop(e); + break; + + // Ctrl-I + case 73: + this.toggleAttr('font-style','normal','italic'); + Event.stop(e); + break; + } +}, + +handleNormalKey: function(e) { + switch (e.keyCode) { + case 91: + case 16: + case 17: + case 18: + case 20: + case 27: return; + + // tab + case 9: this.moveSelection(0,e.shiftKey ? -1 : 1,false,e); break; + // enter/return + case 13: this.moveSelection(1,0,false,e); break; + // arrow keys + case 37: this.moveSelection(0,-1,e.shiftKey,e); break; + case 38: this.moveSelection(-1,0,e.shiftKey,e); break; + case 39: this.moveSelection(0,1,e.shiftKey,e); break; + case 40: this.moveSelection(1,0,e.shiftKey,e); break; + // home + case 36: this.selectCellRC(this.SelectIdxStart.row,1); Event.stop(e); break; + // F2 + case 113: this.showInputArea(false,e); break; + + default: this.showInputArea(true,e); break; + } + return false; +}, + +gridKeydown: function(e) { + if (e.altKey) return; + var elem=Event.element(e); + if (elem.id=='inputArea') return true; + //window.status='gridKeydown keyCode='+e.keyCode; + if (e.ctrlKey) + this.handleCtrlKey(e); + else + this.handleNormalKey(e); +}, + +toggleAttr: function(attr,v1,v2) { + var v=this.getStyle(this.SelectIdxStart.row,this.SelectIdxStart.column,attr); + v=v==v2 ? v1 : v2; + this.updateSelectionStyle(attr,v); +}, + +getStyle: function(row,col,attr) { + var csstxt=this.columns[col].cell(row).style.cssText; + if (!csstxt) return; + if (csstxt.charAt(csstxt.length-1)!=';') csstxt+=';'; // opera + csstxt=' '+csstxt; + var re=new RegExp("[ ;]"+attr+"\\s*:\\s*([^ ;]*)\\s*;","i"); + if (re.test(csstxt)) + return RegExp.$1; + else + return; +}, + +updateStyleText: function(csstxt,attr,value) { + var newval=attr+':'+value+';'; + if (!csstxt) return newval; + csstxt=' '+csstxt.strip(); + if (csstxt.charAt(csstxt.length-1)!=';') csstxt+=';'; // opera + var re=new RegExp("([ ;])"+attr+"\\s*:\\s*([^ ;]*)\\s*;","i"); + // safari must process the regexp twice, everyone else can run it once + if (re.test(csstxt)) + return Prototype.Browser.WebKit ? csstxt.replace(re,"$1"+newval) : RegExp.leftContext+RegExp.$1+newval+RegExp.rightContext; + else + return csstxt+newval; +}, + +updateSelectionStyle: function(attr,newVal) { + var s=this.getSelection(); + if (!s) return; + for (var c=s.c1; c<=s.c2; c++) { + var col=this.columns[c]; + for (var r=s.r1; r<=s.r2; r++) + col.cell(r).style.cssText=this.updateStyleText(col.cell(r).style.cssText,attr,newVal); + } +}, + +showHelp: function() { + var msg="Rico Spreadsheet\n\n"; + msg+="Ctrl-C = copy, Ctrl-X = cut, Ctrl-V = paste (only from/to cells on this grid)\n\n"; + msg+="Formulas starting with '=' are supported\n"; + msg+="Formulas may contain parentheses and the following operators: + - * / & % = > < <= >= <>\n"; + msg+="'+' follows javascript rules regarding type conversion (which are slightly different from Excel)\n"; + msg+="Formulas may refer to cells using 'A1' notation (and 'A1:B2' for ranges).\n"; + msg+="The following functions are supported in formulas:\n\n"; + var funclist=[]; + for (var funcname in Rico.Formula.prototype) + if (funcname.substring(0,5)=='eval_') funclist.push(funcname.substring(5)); + funclist.sort(); + var funcstr=funclist.join(', '); + var i=funcstr.indexOf(' ',Math.floor(funcstr.length/2)); + msg+=funcstr.substring(0,i)+"\n"+funcstr.substring(i+1); + msg+="\n\nFormula parsing based on code originally published by E. W. Bachtal at http://ewbi.blogs.com/develops/"; + msg+="\nFuture functionality may include copy/paste from external applications, load/save, number & date formatting, and support for additional functions."; + alert(msg); +} + +}); + + +Rico.Formula = Class.create(); + +Rico.Formula.TOK_TYPE_NOOP = "noop"; +Rico.Formula.TOK_TYPE_OPERAND = "operand"; +Rico.Formula.TOK_TYPE_FUNCTION = "function"; +Rico.Formula.TOK_TYPE_SUBEXPR = "subexpression"; +Rico.Formula.TOK_TYPE_ARGUMENT = "argument"; +Rico.Formula.TOK_TYPE_OP_PRE = "operator-prefix"; +Rico.Formula.TOK_TYPE_OP_IN = "operator-infix"; +Rico.Formula.TOK_TYPE_OP_POST = "operator-postfix"; +Rico.Formula.TOK_TYPE_WSPACE = "white-space"; +Rico.Formula.TOK_TYPE_UNKNOWN = "unknown"; + +Rico.Formula.TOK_SUBTYPE_START = "start"; +Rico.Formula.TOK_SUBTYPE_STOP = "stop"; + +Rico.Formula.TOK_SUBTYPE_TEXT = "text"; +Rico.Formula.TOK_SUBTYPE_NUMBER = "number"; +Rico.Formula.TOK_SUBTYPE_LOGICAL = "logical"; +Rico.Formula.TOK_SUBTYPE_ERROR = "error"; +Rico.Formula.TOK_SUBTYPE_RANGE = "range"; + +Rico.Formula.TOK_SUBTYPE_MATH = "math"; +Rico.Formula.TOK_SUBTYPE_CONCAT = "concatenate"; +Rico.Formula.TOK_SUBTYPE_INTERSECT = "intersect"; +Rico.Formula.TOK_SUBTYPE_UNION = "union"; + +Rico.Formula.prototype = { + +initialize: function(grid,cell) { + this.grid=grid; + this.cell=cell; +}, + +// 'A' -> 1, 'AA' -> 27 +colLetter2Num: function(colstr) { + colstr=colstr.toUpperCase(); + switch (colstr.length) { + case 1: return colstr.charCodeAt(0)-64; + case 2: return (colstr.charCodeAt(0)-64) * 26 + colstr.charCodeAt(1)-64; + default: return -1; + } +}, + +// 1 -> 'A', 27 -> 'AA' +colNum2Letter: function(colnum) { + if (colnum <= 26) return String.fromCharCode(64+colnum); + colnum-=1; + return String.fromCharCode(64+Math.floor(colnum / 26),65+(colnum % 26)); +}, + + +toHTML: function() { + var indentCount = 0; + + var indent = function() { + var s = "|"; + for (var i = 0; i < indentCount; i++) { + s += "   |"; + } + return s; + }; + + var tokensHtml = "
1) this.exportText+=" colspan='"+newSpan+"'"; + this.exportText+=">"+RicoUtil.getInnerText(cell)+"
"; + tokensHtml += ""; + tokensHtml += ""; + tokensHtml += ""; + tokensHtml += ""; + tokensHtml += ""; + tokensHtml += ""; + + this.tokens.reset(); + while (this.tokens.moveNext()) { + + var token = this.tokens.current(); + + if (token.subtype == Rico.Formula.TOK_SUBTYPE_STOP) + indentCount -= ((indentCount > 0) ? 1 : 0); + + tokensHtml += ""; + + tokensHtml += ""; + tokensHtml += ""; + tokensHtml += ""; + tokensHtml += ""; + tokensHtml += ""; + + tokensHtml += ""; + + if (token.subtype == Rico.Formula.TOK_SUBTYPE_START) indentCount++; + } + tokensHtml += "
indextypesubtypetokentoken tree
" + (this.tokens.index + 1) + "" + token.type + "" + ((token.subtype.length == 0) ? " " : token.subtype) + "" + ((token.value.length == 0) ? " " : token.value).split(" ").join(" ") + "" + indent() + ((token.value.length == 0) ? " " : token.value).split(" ").join(" ") + "
"; + return tokensHtml; +}, + + +parseCellRef: function(refString) { + if (!refString) return null; + if (!refString.match(/^(\$?)([a-z]*)(\$?)(\d*)$/i)) return null; + var abscol=(RegExp.$1=='$'); + var absrow=(RegExp.$3=='$'); + var r=null,c=null; + if (RegExp.$2) { + c=this.colLetter2Num(RegExp.$2); + if (c<0 || c>=this.grid.columns.length) return null; + if (!abscol) c-=this.cell.RicoCol; + } + if (RegExp.$4) { + r=parseInt(RegExp.$4); + if (!absrow) r-=this.cell.RicoRow; + } + //alert('parseCellRef: '+refString+"\n"+'r='+r+' c='+c+' absrow='+absrow+' abscol='+abscol); + return {row:r, col:c, absRow:absrow, absCol:abscol}; +}, + + +resolveCellRef: function(cellRef) { + var r=cellRef.row; + var c=cellRef.col; + if (!cellRef.absRow) r+=this.cell.RicoRow; + if (!cellRef.absCol) c+=this.cell.RicoCol; + return {row:r, col:c}; +}, + + +resolveRange: function(token) { + if (!token.rangeStart) return null; + var a1=this.resolveCellRef(token.rangeStart); + var a2=this.resolveCellRef(token.rangeEnd); + //alert('resolveRange: '+a1.row+','+a1.col+' '+a2.row+','+a2.col); + var r1=Math.min(a1.row,a2.row); + var r2=Math.max(a1.row,a2.row); + var c1=Math.min(a1.col,a2.col) || 0; + var c2=Math.max(a1.col,a2.col) || this.grid.columns.length-1; + return [r1,c1,r2,c2]; +}, + + +range2evalstr: function(token) { + var rng=this.resolveRange(token); + return rng ? rng.join(',') : ''; +}, + + +cellref2str: function(cellRef) { + var ref=this.resolveCellRef(cellRef); + var c=this.colNum2Letter(ref.col); + if (cellRef.absCol) c='$'+c; + var r=ref.row.toString(); + if (cellRef.absRow) r='$'+r; + return c+r; +}, + + +range2str: function(token) { + var s1=this.cellref2str(token.rangeStart); + var s2=this.cellref2str(token.rangeEnd); + return (s1==s2) ? s1 : s1+':'+s2; +}, + + +GetRange: function(r1,c1,r2,c2) { + if (typeof r1=='undefined' || typeof c1=='undefined') return NaN; + if (r1==r2 && c1==c2) return this.grid.columns[c1].cell(r1-1).RicoValue; + var result=[]; + for (var r=r1; r<=r2; r++) { + var newRow=[]; + for (var c=c1; c<=c2; c++) + newRow.push(this.grid.columns[c].cell(r-1).RicoValue); + result.push(newRow); + } + return result; +}, + + +getRanges: function() { + var result=[]; + this.tokens.reset(); + while (this.tokens.moveNext()) { + var token = this.tokens.current(); + if (token.subtype=='range') result.push(this.resolveRange(token)); + } + return result; +}, + + +eval_sum: function() { + var result=0; + for (var i=0; i') + evalstr+='!='; + else + evalstr+=token.value; + break; + case 'operator-postfix': + if (token.value=='%') + evalstr+='/100'; + else + evalstr+=token.value; + break; + case 'operand': + if (token.subtype=='range') + evalstr+='this.GetRange('+this.range2evalstr(token)+')'; + else if (token.subtype=='text') + evalstr+='"'+token.value+'"'; + else + evalstr+=token.value; + break; + default: + evalstr+=token.value; + break; + } + } + this.lastEval=evalstr; + //window.status=evalstr; + try { + var result=eval(evalstr) + return result; + } catch(e) { alert(e.message); return '#ERROR'; } +}, + + +toEditString: function() { + var s='='; + this.tokens.reset(); + while (this.tokens.moveNext()) { + var token = this.tokens.current(); + switch (token.type) { + case 'function': + if (token.subtype=='start') + s+=token.value+'('; + else + s+=')'; + break; + case 'subexpression': + if (token.subtype=='start') + s+='('; + else + s+=')'; + break; + case 'operand': + if (token.subtype=='range') + s+=this.range2str(token); + else if (token.subtype=='text') + s+='"'+token.value+'"'; + else + s+=token.value; + break; + default: + s+=token.value; + } + } + return s; +}, + + +// Excel formula parser +// from http://ewbi.blogs.com/develops/2004/12/excel_formula_p.html +parse: function(formula) { + var tokens = new Rico.Formula.f_tokens(); + var tokenStack = new Rico.Formula.f_tokenStack(); + + var offset = 0; + + var currentChar = function() { return formula.substr(offset, 1); }; + var doubleChar = function() { return formula.substr(offset, 2); }; + var nextChar = function() { return formula.substr(offset + 1, 1); }; + var EOF = function() { return (offset >= formula.length); }; + + var token = ""; + + var inString = false; + var inPath = false; + var inRange = false; + var inError = false; + + while (formula.length > 0) { + if (formula.substr(0, 1) == " ") + formula = formula.substr(1); + else { + if (formula.substr(0, 1) == "=") + formula = formula.substr(1); + break; + } + } + + while (!EOF()) { + + // state-dependent character evaluation (order is important) + + // double-quoted strings + // embeds are doubled + // end marks token + + if (inString) { + if (currentChar() == "\"") { + if (nextChar() == "\"") { + token += "\""; + offset += 1; + } else { + inString = false; + tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND, Rico.Formula.TOK_SUBTYPE_TEXT); + token = ""; + } + } else { + token += currentChar(); + } + offset += 1; + continue; + } + + // single-quoted strings (links) + // embeds are double + // end does not mark a token + + if (inPath) { + if (currentChar() == "'") { + if (nextChar() == "'") { + token += "'"; + offset += 1; + } else { + inPath = false; + } + } else { + token += currentChar(); + } + offset += 1; + continue; + } + + // bracked strings (range offset or linked workbook name) + // no embeds (changed to "()" by Excel) + // end does not mark a token + + if (inRange) { + if (currentChar() == "]") { + inRange = false; + } + token += currentChar(); + offset += 1; + continue; + } + + // error values + // end marks a token, determined from absolute list of values + + if (inError) { + token += currentChar(); + offset += 1; + if ((",#NULL!,#DIV/0!,#VALUE!,#REF!,#NAME?,#NUM!,#N/A,").indexOf("," + token + ",") != -1) { + inError = false; + tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND, Rico.Formula.TOK_SUBTYPE_ERROR); + token = ""; + } + continue; + } + + // independent character evaulation (order not important) + + // establish state-dependent character evaluations + + if (currentChar() == "\"") { + if (token.length > 0) { + // not expected + tokens.add(token, Rico.Formula.TOK_TYPE_UNKNOWN); + token = ""; + } + inString = true; + offset += 1; + continue; + } + + if (currentChar() == "'") { + if (token.length > 0) { + // not expected + tokens.add(token, Rico.Formula.TOK_TYPE_UNKNOWN); + token = ""; + } + inPath = true; + offset += 1; + continue; + } + + if (currentChar() == "[") { + inRange = true; + token += currentChar(); + offset += 1; + continue; + } + + if (currentChar() == "#") { + if (token.length > 0) { + // not expected + tokens.add(token, Rico.Formula.TOK_TYPE_UNKNOWN); + token = ""; + } + inError = true; + token += currentChar(); + offset += 1; + continue; + } + + // mark start and end of arrays and array rows + + if (currentChar() == "{") { + if (token.length > 0) { + // not expected + tokens.add(token, Rico.Formula.TOK_TYPE_UNKNOWN); + token = ""; + } + tokenStack.push(tokens.add("ARRAY", Rico.Formula.TOK_TYPE_FUNCTION, Rico.Formula.TOK_SUBTYPE_START)); + tokenStack.push(tokens.add("ARRAYROW", Rico.Formula.TOK_TYPE_FUNCTION, Rico.Formula.TOK_SUBTYPE_START)); + offset += 1; + continue; + } + + if (currentChar() == ";") { + if (token.length > 0) { + tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND); + token = ""; + } + tokens.addRef(tokenStack.pop()); + tokens.add(",", Rico.Formula.TOK_TYPE_ARGUMENT); + tokenStack.push(tokens.add("ARRAYROW", Rico.Formula.TOK_TYPE_FUNCTION, Rico.Formula.TOK_SUBTYPE_START)); + offset += 1; + continue; + } + + if (currentChar() == "}") { + if (token.length > 0) { + tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND); + token = ""; + } + tokens.addRef(tokenStack.pop()); + tokens.addRef(tokenStack.pop()); + offset += 1; + continue; + } + + // trim white-space + + if (currentChar() == " ") { + if (token.length > 0) { + tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND); + token = ""; + } + tokens.add("", Rico.Formula.TOK_TYPE_WSPACE); + offset += 1; + while ((currentChar() == " ") && (!EOF())) { + offset += 1; + } + continue; + } + + // multi-character comparators + + if ((",>=,<=,<>,").indexOf("," + doubleChar() + ",") != -1) { + if (token.length > 0) { + tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND); + token = ""; + } + tokens.add(doubleChar(), Rico.Formula.TOK_TYPE_OP_IN, Rico.Formula.TOK_SUBTYPE_LOGICAL); + offset += 2; + continue; + } + + // standard infix operators + + if (("+-*/^&=><").indexOf(currentChar()) != -1) { + if (token.length > 0) { + tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND); + token = ""; + } + tokens.add(currentChar(), Rico.Formula.TOK_TYPE_OP_IN); + offset += 1; + continue; + } + + // standard postfix operators + + if (("%").indexOf(currentChar()) != -1) { + if (token.length > 0) { + tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND); + token = ""; + } + tokens.add(currentChar(), Rico.Formula.TOK_TYPE_OP_POST); + offset += 1; + continue; + } + + // start subexpression or function + + if (currentChar() == "(") { + if (token.length > 0) { + tokenStack.push(tokens.add(token, Rico.Formula.TOK_TYPE_FUNCTION, Rico.Formula.TOK_SUBTYPE_START)); + token = ""; + } else { + tokenStack.push(tokens.add("", Rico.Formula.TOK_TYPE_SUBEXPR, Rico.Formula.TOK_SUBTYPE_START)); + } + offset += 1; + continue; + } + + // function, subexpression, array parameters + + if (currentChar() == ",") { + if (token.length > 0) { + tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND); + token = ""; + } + if (!(tokenStack.type() == Rico.Formula.TOK_TYPE_FUNCTION)) { + tokens.add(currentChar(), Rico.Formula.TOK_TYPE_OP_IN, Rico.Formula.TOK_SUBTYPE_UNION); + } else { + tokens.add(currentChar(), Rico.Formula.TOK_TYPE_ARGUMENT); + } + offset += 1; + continue; + } + + // stop subexpression + + if (currentChar() == ")") { + if (token.length > 0) { + tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND); + token = ""; + } + tokens.addRef(tokenStack.pop()); + offset += 1; + continue; + } + + // token accumulation + + token += currentChar(); + offset += 1; + + } + + // dump remaining accumulation + + if (token.length > 0) tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND); + + // move all tokens to a new collection, excluding all unnecessary white-space tokens + + var tokens2 = new Rico.Formula.f_tokens(); + + while (tokens.moveNext()) { + + token = tokens.current(); + + if (token.type == Rico.Formula.TOK_TYPE_WSPACE) { + if ((tokens.BOF()) || (tokens.EOF())) {} + else if (!( + ((tokens.previous().type == Rico.Formula.TOK_TYPE_FUNCTION) && (tokens.previous().subtype == Rico.Formula.TOK_SUBTYPE_STOP)) || + ((tokens.previous().type == Rico.Formula.TOK_TYPE_SUBEXPR) && (tokens.previous().subtype == Rico.Formula.TOK_SUBTYPE_STOP)) || + (tokens.previous().type == Rico.Formula.TOK_TYPE_OPERAND) + ) + ) {} + else if (!( + ((tokens.next().type == Rico.Formula.TOK_TYPE_FUNCTION) && (tokens.next().subtype == Rico.Formula.TOK_SUBTYPE_START)) || + ((tokens.next().type == Rico.Formula.TOK_TYPE_SUBEXPR) && (tokens.next().subtype == Rico.Formula.TOK_SUBTYPE_START)) || + (tokens.next().type == Rico.Formula.TOK_TYPE_OPERAND) + ) + ) {} + else + tokens2.add(token.value, Rico.Formula.TOK_TYPE_OP_IN, Rico.Formula.TOK_SUBTYPE_INTERSECT); + continue; + } + + tokens2.addRef(token); + + } + + // switch infix "-" operator to prefix when appropriate, switch infix "+" operator to noop when appropriate, identify operand + // and infix-operator subtypes, pull "@" from in front of function names + + while (tokens2.moveNext()) { + + token = tokens2.current(); + + if ((token.type == Rico.Formula.TOK_TYPE_OP_IN) && (token.value == "-")) { + if (tokens2.BOF()) + token.type = Rico.Formula.TOK_TYPE_OP_PRE; + else if ( + ((tokens2.previous().type == Rico.Formula.TOK_TYPE_FUNCTION) && (tokens2.previous().subtype == Rico.Formula.TOK_SUBTYPE_STOP)) || + ((tokens2.previous().type == Rico.Formula.TOK_TYPE_SUBEXPR) && (tokens2.previous().subtype == Rico.Formula.TOK_SUBTYPE_STOP)) || + (tokens2.previous().type == Rico.Formula.TOK_TYPE_OP_POST) || + (tokens2.previous().type == Rico.Formula.TOK_TYPE_OPERAND) + ) + token.subtype = Rico.Formula.TOK_SUBTYPE_MATH; + else + token.type = Rico.Formula.TOK_TYPE_OP_PRE; + continue; + } + + if ((token.type == Rico.Formula.TOK_TYPE_OP_IN) && (token.value == "+")) { + if (tokens2.BOF()) + token.type = Rico.Formula.TOK_TYPE_NOOP; + else if ( + ((tokens2.previous().type == Rico.Formula.TOK_TYPE_FUNCTION) && (tokens2.previous().subtype == Rico.Formula.TOK_SUBTYPE_STOP)) || + ((tokens2.previous().type == Rico.Formula.TOK_TYPE_SUBEXPR) && (tokens2.previous().subtype == Rico.Formula.TOK_SUBTYPE_STOP)) || + (tokens2.previous().type == Rico.Formula.TOK_TYPE_OP_POST) || + (tokens2.previous().type == Rico.Formula.TOK_TYPE_OPERAND) + ) + token.subtype = Rico.Formula.TOK_SUBTYPE_MATH; + else + token.type = Rico.Formula.TOK_TYPE_NOOP; + continue; + } + + if ((token.type == Rico.Formula.TOK_TYPE_OP_IN) && (token.subtype.length == 0)) { + if (("<>=").indexOf(token.value.substr(0, 1)) != -1) + token.subtype = Rico.Formula.TOK_SUBTYPE_LOGICAL; + else if (token.value == "&") + token.subtype = Rico.Formula.TOK_SUBTYPE_CONCAT; + else + token.subtype = Rico.Formula.TOK_SUBTYPE_MATH; + continue; + } + + if ((token.type == Rico.Formula.TOK_TYPE_OPERAND) && (token.subtype.length == 0)) { + if (isNaN(parseFloat(token.value))) + if ((token.value == 'TRUE') || (token.value == 'FALSE')) + token.subtype = Rico.Formula.TOK_SUBTYPE_LOGICAL; + else { + token.subtype = Rico.Formula.TOK_SUBTYPE_RANGE; + var a=token.value.split(':'); + token.rangeStart=this.parseCellRef(a[0]); + token.rangeEnd=a.length>1 ? this.parseCellRef(a[1]) : token.rangeStart; + } + else + token.subtype = Rico.Formula.TOK_SUBTYPE_NUMBER; + continue; + } + + if (token.type == Rico.Formula.TOK_TYPE_FUNCTION) { + if (token.value.substr(0, 1) == "@") + token.value = token.value.substr(1); + continue; + } + + } + + tokens2.reset(); + + // move all tokens to a new collection, excluding all noops + + this.tokens = new Rico.Formula.f_tokens(); + + while (tokens2.moveNext()) { + if (tokens2.current().type != Rico.Formula.TOK_TYPE_NOOP) + this.tokens.addRef(tokens2.current()); + } +} + +} + + +Rico.Formula.f_token = Class.create(); +Rico.Formula.f_token.prototype = { + initialize: function(value, type, subtype) { + this.value = value; + this.type = type; + this.subtype = subtype; + } +} + + +Rico.Formula.f_tokens = Class.create(); +Rico.Formula.f_tokens.prototype = { + initialize: function() { + this.items = new Array(); + this.index = -1; + }, + + addRef: function(token) { + this.items.push(token); + }, + + add: function(value, type, subtype) { + if (!subtype) subtype = ""; + var token = new Rico.Formula.f_token(value, type, subtype); + this.addRef(token); + return token; + }, + + reset: function() { + this.index = -1; + }, + + BOF: function() { + return (this.index <= 0); + }, + + EOF: function() { + return (this.index >= (this.items.length - 1)); + }, + + moveNext: function() { + if (this.EOF()) return false; this.index++; return true; + }, + + current: function() { + if (this.index == -1) return null; return (this.items[this.index]); + }, + + next: function() { + if (this.EOF()) return null; return (this.items[this.index + 1]); + }, + + previous: function() { + if (this.index < 1) return null; return (this.items[this.index - 1]); + } +} + + +Rico.Formula.f_tokenStack = Class.create(); +Rico.Formula.f_tokenStack.prototype = { + initialize: function() { + this.items = new Array(); + }, + + push: function(token) { + this.items.push(token); + }, + + pop: function() { + var token = this.items.pop(); + return (new Rico.Formula.f_token("", token.type, Rico.Formula.TOK_SUBTYPE_STOP)); + }, + + token: function() { + return ((this.items.length > 0) ? this.items[this.items.length - 1] : null); + }, + + value: function() { + return ((this.token()) ? this.token().value : ""); + }, + + type: function() { + return ((this.token()) ? this.token().type : ""); + }, + + subtype: function() { + return ((this.token()) ? this.token().subtype : ""); + } +} + + +Rico.Formula.f_dependencies = Class.create(); +Rico.Formula.f_dependencies.prototype = { + initialize: function() { + this.items = []; + }, + + add: function(cell) { + if (!this.items.include(cell)) this.items.push(cell); + }, + + remove: function(cell) { + this.items=this.items.select(function(item) { return (item != cell); }); + }, + + find: function(cell) { + return this.items.detect(function(item) { return (item==cell); }); + }, + + clear: function() { + this.items.clear(); + } +} + + +Object.extend(Rico.Menu.prototype, { + +showSheetMenu: function(e,hideFunc) { + var elem=this.showSimpleMenu(e,hideFunc); + if (!this.grid) return; + var newIdx=this.grid.cellIndex(elem); + if (!this.grid.isSelected(newIdx.row,newIdx.column)) + this.grid.selectCellRC(newIdx.row,newIdx.column,false); +} + +}); + + +Rico.includeLoaded('ricoSheet.js'); diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoSimpleGrid.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoSimpleGrid.js new file mode 100644 index 0000000..a6b407e --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoSimpleGrid.js @@ -0,0 +1,160 @@ +/** + * (c) 2005-2007 Richard Cowin (http://openrico.org) + * (c) 2005-2007 Matt Brown (http://dowdybrown.com) + * + * Rico is licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + **/ + + +if(typeof Rico=='undefined') throw("SimpleGrid requires the Rico JavaScript framework"); +if(typeof RicoUtil=='undefined') throw("SimpleGrid requires the RicoUtil Library"); +if(typeof RicoTranslate=='undefined') throw("SimpleGrid requires the RicoTranslate Library"); + +Rico.SimpleGrid = Class.create(); + +Rico.SimpleGrid.prototype = { + + initialize: function( tableId, options ) { + Object.extend(this, new Rico.GridCommon); + this.baseInit(tableId); + Rico.setDebugArea(tableId+"_debugmsgs"); // if used, this should be a textarea + Object.extend(this.options, options || {}); + this.tableId = tableId; + this.createDivs(); + this.hdrTabs=new Array(2); + for (var i=0; i<2; i++) { + this.tabs[i]=$(tableId+'_tab'+i); + this.hdrTabs[i]=$(tableId+'_tab'+i+'h'); + if (i==0) this.tabs[i].style.position='absolute'; + if (i==0) this.tabs[i].style.left='0px'; + this.hdrTabs[i].style.position='absolute'; + this.hdrTabs[i].style.top='0px'; + this.hdrTabs[i].style.zIndex=1; + this.thead[i]=this.hdrTabs[i]; + this.tbody[i]=this.tabs[i]; + this.headerColCnt = this.getColumnInfo(this.hdrTabs[i].rows); + if (i==0) this.options.frozenColumns=this.headerColCnt; + } + if (this.headerColCnt==0) { + alert('ERROR: no columns found in "'+this.tableId+'"'); + return; + } + this.hdrHt=Math.max(RicoUtil.nan2zero(this.hdrTabs[0].offsetHeight),this.hdrTabs[1].offsetHeight); + for (var i=0; i<2; i++) + if (i==0) this.tabs[i].style.top=this.hdrHt+'px'; + this.createColumnArray(); + this.pageSize=this.columns[0].dataColDiv.childNodes.length; + this.sizeDivs(); + this.attachMenuEvents(); + this.scrollEventFunc=this.handleScroll.bindAsEventListener(this); + this.pluginScroll(); + if (this.options.windowResize) + Event.observe(window,"resize", this.sizeDivs.bindAsEventListener(this), false); + }, + + /** + * Register a menu that will only be used in the scrolling part of the grid. + * If submenus are used, they must be registered after the main menu. + */ + registerScrollMenu: function(menu) { + if (!this.menu) this.menu=menu; + menu.grid=this; + menu.showmenu=menu.showSimpleMenu; + menu.showSubMenu=menu.showSimpleSubMenu; + menu.createDiv(this.scrollDiv); + }, + + handleMenuClick: function(e) { + this.cancelMenu(); + this.menuCell=RicoUtil.getParentByTagName(Event.element(e),'div'); + this.highlightEnabled=false; + if (this.hideScroll) this.scrollDiv.style.overflow="hidden"; + if (this.menu.buildGridMenu) this.menu.buildGridMenu(this.menuCell); + this.menu.showmenu(e,this.closeMenu.bind(this)); + }, + + closeMenu: function() { + if (this.hideScroll) this.scrollDiv.style.overflow=""; + this.highlightEnabled=true; + }, + + sizeDivs: function() { + if (this.outerDiv.offsetParent.style.display=='none') return; + this.baseSizeDivs(); + var maxHt=Math.max(this.options.maxHt || this.availHt(), 50); + var totHt=Math.min(this.hdrHt+this.dataHt, maxHt); + Rico.writeDebugMsg('sizeDivs '+this.tableId+': hdrHt='+this.hdrHt+' dataHt='+this.dataHt); + this.dataHt=totHt-this.hdrHt; + if (this.scrWi>0) this.dataHt+=this.options.scrollBarWidth; + this.scrollDiv.style.height=this.dataHt+'px'; + var divAdjust=2; + this.innerDiv.style.width=(this.scrWi-this.options.scrollBarWidth+divAdjust)+'px'; + this.innerDiv.style.height=this.hdrHt+'px'; + totHt+=divAdjust; + this.resizeDiv.style.height=this.frozenTabs.style.height=totHt+'px'; + this.outerDiv.style.height=(totHt+this.options.scrollBarWidth)+'px'; + this.setHorizontalScroll(); + } + +}; + +if (Rico.Menu) { +Object.extend(Rico.Menu.prototype, { + +showSimpleMenu: function(e,hideFunc) { + Event.stop(e); + this.hideFunc=hideFunc; + if (this.div.childNodes.length==0) { + this.cancelmenu(); + return false; + } + this.clientX=Event.pointerX(e); + this.clientY=Event.pointerY(e); + var elem=Event.element(e); + while (elem && !Element.hasClassName(elem,'ricoLG_cell')) + elem=elem.parentNode; + if (!elem) return false; + var td=RicoUtil.getParentByTagName(elem,'td'); + + var newLeft=Math.floor(td.offsetLeft+td.offsetWidth/2); + if (this.direction == 'rtl') { + if (newLeft > this.width) newLeft-=this.width; + } else { + if (newLeft+this.width+this.options.margin > this.grid.scrollDiv.scrollLeft+this.grid.scrollDiv.clientWidth) newLeft-=this.width; + } + this.div.style.visibility="hidden"; + this.div.style.display="block"; + var contentHt=this.div.offsetHeight; + var newTop=Math.floor(elem.offsetTop+elem.offsetHeight/2); + if (newTop+contentHt+this.options.margin > this.grid.scrollDiv.scrollTop+this.grid.scrollDiv.clientHeight) + newTop=Math.max(newTop-contentHt,0); + this.openPopup(newLeft,newTop); + this.div.style.visibility ="visible"; + return elem; +}, + +showSimpleSubMenu: function(a,submenu) { + if (this.openSubMenu) this.hideSubMenu(); + this.openSubMenu=submenu; + this.openMenuAnchor=a; + if (a.className=='ricoSubMenu') a.className='ricoSubMenuOpen'; + var top=parseInt(this.div.style.top); + var left=parseInt(this.div.style.left); + submenu.openPopup(left+a.offsetWidth,top+a.offsetTop); + submenu.div.style.visibility ="visible"; +} + +}); +} + +Object.extend(Rico.TableColumn.prototype, { + +initialize: function(grid,colIdx,hdrInfo,tabIdx) { + this.baseInit(grid,colIdx,hdrInfo,tabIdx); +} + +}); + +Rico.includeLoaded('ricoSimpleGrid.js'); diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoSimpleGrid.xsl b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoSimpleGrid.xsl new file mode 100644 index 0000000..f3c0dc2 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoSimpleGrid.xsl @@ -0,0 +1,285 @@ + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +ricoLG_outerDiv + + + + + + +ricoLG_frozenTabsDiv + + + + + + + + + + + + + + + + + + + +ricoLG_innerDiv + + + +ricoLG_scrollTabsDiv + + + + + + + + + + + + + +ricoLG_scrollDiv + + + + + + + + + + + + + + + + + + + + + + + +ricoLG_table ricoLG_top +ricoLG_left +ricoLG_right + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ricoLG_hdg + + + +
+ + ricoLG_cell + + +
+
+
+
+
+ + + + + + + + + + + +ricoLG_table ricoLG_bottom +ricoLG_left +ricoLG_right + + + + + + + +
+ + + ricoLG_cell + + + +
+ +
+
+ +
+
+
+ +
diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoSimpleGrid2xl.xsl b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoSimpleGrid2xl.xsl new file mode 100644 index 0000000..f04b2e1 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoSimpleGrid2xl.xsl @@ -0,0 +1,160 @@ + + + + + + + progid="Excel.Sheet" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + + + + + + + + + + s22 + + + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoStyles.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoStyles.js new file mode 100644 index 0000000..34af1aa --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoStyles.js @@ -0,0 +1,469 @@ +/** + * + * Copyright 2005 Sabre Airline Solutions + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + **/ + +//-------------------- ricoColor.js +Rico.Color = Class.create(); + +Rico.Color.prototype = { + + initialize: function(red, green, blue) { + this.rgb = { r: red, g : green, b : blue }; + }, + + setRed: function(r) { + this.rgb.r = r; + }, + + setGreen: function(g) { + this.rgb.g = g; + }, + + setBlue: function(b) { + this.rgb.b = b; + }, + + setHue: function(h) { + + // get an HSB model, and set the new hue... + var hsb = this.asHSB(); + hsb.h = h; + + // convert back to RGB... + this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, hsb.b); + }, + + setSaturation: function(s) { + // get an HSB model, and set the new hue... + var hsb = this.asHSB(); + hsb.s = s; + + // convert back to RGB and set values... + this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, hsb.b); + }, + + setBrightness: function(b) { + // get an HSB model, and set the new hue... + var hsb = this.asHSB(); + hsb.b = b; + + // convert back to RGB and set values... + this.rgb = Rico.Color.HSBtoRGB( hsb.h, hsb.s, hsb.b ); + }, + + darken: function(percent) { + var hsb = this.asHSB(); + this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, Math.max(hsb.b - percent,0)); + }, + + brighten: function(percent) { + var hsb = this.asHSB(); + this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, Math.min(hsb.b + percent,1)); + }, + + blend: function(other) { + this.rgb.r = Math.floor((this.rgb.r + other.rgb.r)/2); + this.rgb.g = Math.floor((this.rgb.g + other.rgb.g)/2); + this.rgb.b = Math.floor((this.rgb.b + other.rgb.b)/2); + }, + + isBright: function() { + var hsb = this.asHSB(); + return this.asHSB().b > 0.5; + }, + + isDark: function() { + return ! this.isBright(); + }, + + asRGB: function() { + return "rgb(" + this.rgb.r + "," + this.rgb.g + "," + this.rgb.b + ")"; + }, + + asHex: function() { + return "#" + this.rgb.r.toColorPart() + this.rgb.g.toColorPart() + this.rgb.b.toColorPart(); + }, + + asHSB: function() { + return Rico.Color.RGBtoHSB(this.rgb.r, this.rgb.g, this.rgb.b); + }, + + toString: function() { + return this.asHex(); + } + +}; + +Rico.Color.createFromHex = function(hexCode) { + if(hexCode.length==4) { + var shortHexCode = hexCode; + var hexCode = '#'; + for(var i=1;i<4;i++) + hexCode += (shortHexCode.charAt(i) + shortHexCode.charAt(i)); + } + if ( hexCode.indexOf('#') == 0 ) + hexCode = hexCode.substring(1); + var red = hexCode.substring(0,2); + var green = hexCode.substring(2,4); + var blue = hexCode.substring(4,6); + return new Rico.Color( parseInt(red,16), parseInt(green,16), parseInt(blue,16) ); +} + +/** + * Factory method for creating a color from the background of + * an HTML element. + */ +Rico.Color.createColorFromBackground = function(elem) { + + var actualColor = Element.getStyle(elem, "background-color"); + + // if color is tranparent, check parent + // Safari returns "rgba(0, 0, 0, 0)", which means transparent + if ( actualColor.match(/^(transparent|rgba\(0,\s*0,\s*0,\s*0\))$/i) && elem.parentNode ) + return Rico.Color.createColorFromBackground(elem.parentNode); + + if ( actualColor == null ) + return new Rico.Color(255,255,255); + + if ( actualColor.indexOf("rgb(") == 0 ) { + var colors = actualColor.substring(4, actualColor.length - 1 ); + var colorArray = colors.split(","); + return new Rico.Color( parseInt( colorArray[0] ), + parseInt( colorArray[1] ), + parseInt( colorArray[2] ) ); + + } + else if ( actualColor.indexOf("#") == 0 ) { + return Rico.Color.createFromHex(actualColor); + } + else + return new Rico.Color(255,255,255); +} + +Rico.Color.HSBtoRGB = function(hue, saturation, brightness) { + + var red = 0; + var green = 0; + var blue = 0; + + if (saturation == 0) { + red = parseInt(brightness * 255.0 + 0.5); + green = red; + blue = red; + } + else { + var h = (hue - Math.floor(hue)) * 6.0; + var f = h - Math.floor(h); + var p = brightness * (1.0 - saturation); + var q = brightness * (1.0 - saturation * f); + var t = brightness * (1.0 - (saturation * (1.0 - f))); + + switch (parseInt(h)) { + case 0: + red = (brightness * 255.0 + 0.5); + green = (t * 255.0 + 0.5); + blue = (p * 255.0 + 0.5); + break; + case 1: + red = (q * 255.0 + 0.5); + green = (brightness * 255.0 + 0.5); + blue = (p * 255.0 + 0.5); + break; + case 2: + red = (p * 255.0 + 0.5); + green = (brightness * 255.0 + 0.5); + blue = (t * 255.0 + 0.5); + break; + case 3: + red = (p * 255.0 + 0.5); + green = (q * 255.0 + 0.5); + blue = (brightness * 255.0 + 0.5); + break; + case 4: + red = (t * 255.0 + 0.5); + green = (p * 255.0 + 0.5); + blue = (brightness * 255.0 + 0.5); + break; + case 5: + red = (brightness * 255.0 + 0.5); + green = (p * 255.0 + 0.5); + blue = (q * 255.0 + 0.5); + break; + } + } + + return { r : parseInt(red), g : parseInt(green) , b : parseInt(blue) }; +} + +Rico.Color.RGBtoHSB = function(r, g, b) { + + var hue; + var saturation; + var brightness; + + var cmax = (r > g) ? r : g; + if (b > cmax) + cmax = b; + + var cmin = (r < g) ? r : g; + if (b < cmin) + cmin = b; + + brightness = cmax / 255.0; + if (cmax != 0) + saturation = (cmax - cmin)/cmax; + else + saturation = 0; + + if (saturation == 0) + hue = 0; + else { + var redc = (cmax - r)/(cmax - cmin); + var greenc = (cmax - g)/(cmax - cmin); + var bluec = (cmax - b)/(cmax - cmin); + + if (r == cmax) + hue = bluec - greenc; + else if (g == cmax) + hue = 2.0 + redc - bluec; + else + hue = 4.0 + greenc - redc; + + hue = hue / 6.0; + if (hue < 0) + hue = hue + 1.0; + } + + return { h : hue, s : saturation, b : brightness }; +} + +//-------------------- ricoCorner.js +Rico.Corner = { + + round: function(e, options) { + var e = $(e); + this._setOptions(options); + var color = this.options.color == "fromElement" ? this._background(e) : this.options.color; + var bgColor = this.options.bgColor == "fromParent" ? this._background(e.parentNode) : this.options.bgColor; + this._roundCornersImpl(e, color, bgColor); + }, + + _roundCornersImpl: function(e, color, bgColor) { + if(this.options.border) + this._renderBorder(e,bgColor); + if(this._isTopRounded()) + this._roundTopCorners(e,color,bgColor); + if(this._isBottomRounded()) + this._roundBottomCorners(e,color,bgColor); + }, + + _renderBorder: function(el,bgColor) { + var borderValue = "1px solid " + this._borderColor(bgColor); + var borderL = "border-left: " + borderValue; + var borderR = "border-right: " + borderValue; + var style = "style='" + borderL + ";" + borderR + "'"; + el.innerHTML = "
" + el.innerHTML + "
" + }, + + _roundTopCorners: function(el, color, bgColor) { + var corner = this._createCorner(bgColor); + for(var i=0 ; i < this.options.numSlices ; i++ ) + corner.appendChild(this._createCornerSlice(color,bgColor,i,"top")); + el.style.paddingTop = '0px'; + el.insertBefore(corner,el.firstChild); + }, + + _roundBottomCorners: function(el, color, bgColor) { + var corner = this._createCorner(bgColor); + for(var i=(this.options.numSlices-1) ; i >= 0 ; i-- ) + corner.appendChild(this._createCornerSlice(color,bgColor,i,"bottom")); + el.style.paddingBottom = 0; + el.appendChild(corner); + }, + + _createCorner: function(bgColor) { + var corner = document.createElement("div"); + corner.style.backgroundColor = (this._isTransparent() ? "transparent" : bgColor); + return corner; + }, + + _createCornerSlice: function(color,bgColor, n, position) { + var slice = document.createElement("span"); + + var inStyle = slice.style; + inStyle.backgroundColor = color; + inStyle.display = "block"; + inStyle.height = "1px"; + inStyle.overflow = "hidden"; + inStyle.fontSize = "1px"; + + var borderColor = this._borderColor(color,bgColor); + if ( this.options.border && n == 0 ) { + inStyle.borderTopStyle = "solid"; + inStyle.borderTopWidth = "1px"; + inStyle.borderLeftWidth = "0px"; + inStyle.borderRightWidth = "0px"; + inStyle.borderBottomWidth = "0px"; + inStyle.height = "0px"; // assumes css compliant box model + inStyle.borderColor = borderColor; + } + else if(borderColor) { + inStyle.borderColor = borderColor; + inStyle.borderStyle = "solid"; + inStyle.borderWidth = "0px 1px"; + } + + if ( !this.options.compact && (n == (this.options.numSlices-1)) ) + inStyle.height = "2px"; + + this._setMargin(slice, n, position); + this._setBorder(slice, n, position); + return slice; + }, + + _setOptions: function(options) { + this.options = { + corners : "all", + color : "fromElement", + bgColor : "fromParent", + blend : true, + border : false, + compact : false + } + Object.extend(this.options, options || {}); + + this.options.numSlices = this.options.compact ? 2 : 4; + if ( this._isTransparent() ) + this.options.blend = false; + }, + + _whichSideTop: function() { + if ( this._hasString(this.options.corners, "all", "top") ) + return ""; + + if ( this.options.corners.indexOf("tl") >= 0 && this.options.corners.indexOf("tr") >= 0 ) + return ""; + + if (this.options.corners.indexOf("tl") >= 0) + return "left"; + else if (this.options.corners.indexOf("tr") >= 0) + return "right"; + return ""; + }, + + _whichSideBottom: function() { + if ( this._hasString(this.options.corners, "all", "bottom") ) + return ""; + + if ( this.options.corners.indexOf("bl")>=0 && this.options.corners.indexOf("br")>=0 ) + return ""; + + if(this.options.corners.indexOf("bl") >=0) + return "left"; + else if(this.options.corners.indexOf("br")>=0) + return "right"; + return ""; + }, + + _borderColor : function(color,bgColor) { + if ( color == "transparent" ) + return bgColor; + else if ( this.options.border ) + return this.options.border; + else if ( this.options.blend ) + return this._blend( bgColor, color ); + else + return ""; + }, + + + _setMargin: function(el, n, corners) { + var marginSize = this._marginSize(n); + var whichSide = corners == "top" ? this._whichSideTop() : this._whichSideBottom(); + + if ( whichSide == "left" ) { + el.style.marginLeft = marginSize + "px"; el.style.marginRight = "0px"; + } + else if ( whichSide == "right" ) { + el.style.marginRight = marginSize + "px"; el.style.marginLeft = "0px"; + } + else { + el.style.marginLeft = marginSize + "px"; el.style.marginRight = marginSize + "px"; + } + }, + + _setBorder: function(el,n,corners) { + var borderSize = this._borderSize(n); + var whichSide = corners == "top" ? this._whichSideTop() : this._whichSideBottom(); + if ( whichSide == "left" ) { + el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = "0px"; + } + else if ( whichSide == "right" ) { + el.style.borderRightWidth = borderSize + "px"; el.style.borderLeftWidth = "0px"; + } + else { + el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = borderSize + "px"; + } + if (this.options.border != false) + el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = borderSize + "px"; + }, + + _marginSize: function(n) { + if ( this._isTransparent() ) + return 0; + + var marginSizes = [ 5, 3, 2, 1 ]; + var blendedMarginSizes = [ 3, 2, 1, 0 ]; + var compactMarginSizes = [ 2, 1 ]; + var smBlendedMarginSizes = [ 1, 0 ]; + + if ( this.options.compact && this.options.blend ) + return smBlendedMarginSizes[n]; + else if ( this.options.compact ) + return compactMarginSizes[n]; + else if ( this.options.blend ) + return blendedMarginSizes[n]; + else + return marginSizes[n]; + }, + + _borderSize: function(n) { + var transparentBorderSizes = [ 5, 3, 2, 1 ]; + var blendedBorderSizes = [ 2, 1, 1, 1 ]; + var compactBorderSizes = [ 1, 0 ]; + var actualBorderSizes = [ 0, 2, 0, 0 ]; + + if ( this.options.compact && (this.options.blend || this._isTransparent()) ) + return 1; + else if ( this.options.compact ) + return compactBorderSizes[n]; + else if ( this.options.blend ) + return blendedBorderSizes[n]; + else if ( this.options.border ) + return actualBorderSizes[n]; + else if ( this._isTransparent() ) + return transparentBorderSizes[n]; + return 0; + }, + + _hasString: function(str) { for(var i=1 ; i= 0) return true; return false; }, + _blend: function(c1, c2) { var cc1 = Rico.Color.createFromHex(c1); cc1.blend(Rico.Color.createFromHex(c2)); return cc1; }, + _background: function(el) { try { return Rico.Color.createColorFromBackground(el).asHex(); } catch(err) { return "#ffffff"; } }, + _isTransparent: function() { return this.options.color == "transparent"; }, + _isTopRounded: function() { return this._hasString(this.options.corners, "all", "top", "tl", "tr"); }, + _isBottomRounded: function() { return this._hasString(this.options.corners, "all", "bottom", "bl", "br"); }, + _hasSingleTextChild: function(el) { return el.childNodes.length == 1 && el.childNodes[0].nodeType == 3; } +} + +Rico.includeLoaded('ricoStyles.js'); diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoTree.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoTree.js new file mode 100644 index 0000000..45f7a95 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/ricoTree.js @@ -0,0 +1,318 @@ +// Rico Tree Control +// by Matt Brown +// Oct 2006 +// email: dowdybrown@yahoo.com + +// Requires prototype.js and ricoCommon.js + +// each node in nodeIndex is an Array with 6+n positions +// node[0] is 0/1 when the node is closed/open +// node[1] is 0/1 when the folder is closed/open +// node[2] is 1 if the node is a leaf node +// node[3] is the node id +// node[4] is the node description +// node[5] is 1 when the node is selectable, 0 otherwise +// node[6]...node[6+n] are the child nodes + +Rico.TreeControl = Class.create(); + +Rico.TreeControl.prototype = { + + initialize: function(id,url,options) { + Object.extend(this, new Rico.Popup({ignoreClicks:true})); + Object.extend(this.options, { + nodeIdDisplay:'none', // first, last, tooltip, or none + showCheckBox: false, + showFolders: false, + showPlusMinus: true, + defaultAction: this.nodeClick.bindAsEventListener(this), + height: '300px', + width: '300px', + leafIcon: Rico.imgDir+'doc.gif' + }); + Object.extend(this.options, options || {}); + this.img=[]; + this.FirstChildNode=6; + this.nodeIndex={}; + this.nodeCount=0; + this.foldersTree=0; + this.timeOutId=0; + this.id=id; + this.dataSource=url; + this.close=this.closePopup; + }, + + atLoad : function() { + var imgsrc = new Array("node.gif","nodelast.gif","folderopen.gif","folderclosed.gif"); + for (i=0;inot selectable, 1->selectable (use default action), otherwise the node is selectable and cells[4] contains the action + var content=[]; + for (var j=0; j0) { + var suffix=lastNode ? 'last' : ''; + if (this.options.showPlusMinus && foldersNode[2]) + this.showPlusMinus(row.insertCell(-1),foldersNode,suffix); + else + this.NodeImage(row.insertCell(-1),suffix) + newLeft.push(lastNode ? "nodeblank" : "nodeline") + } + if (this.options.showFolders) + this.showFolders(row.insertCell(-1),foldersNode); + if (this.options.showCheckBox && foldersNode[5]) + this.showCheckBox(row.insertCell(-1),foldersNode); + this.displayLabel(row,foldersNode) + this.treeDiv.appendChild(tab) + + if (foldersNode.length > this.FirstChildNode && foldersNode[0]) { + //there are sub-nodes and the folder is open + for (var i=this.FirstChildNode; i this.FirstChildNode) + img.onclick=this.openBranch.bindAsEventListener(this); + else + img.onclick=this.getChildren.bindAsEventListener(this); + var prefix=foldersNode[1] ? "nodem" : "nodep" + img.src=Rico.imgDir+prefix+suffix+".gif"; + td.appendChild(img) + }, + + showFolders: function(td,foldersNode) { + var img = document.createElement("img") + if (!foldersNode[2]) { + img.src=this.options.leafIcon; + } else { + img.name=foldersNode[3]; + img.style.cursor='pointer'; + if (foldersNode.length > this.FirstChildNode) + img.onclick=this.openBranch.bindAsEventListener(this); + else + img.onclick=this.getChildren.bindAsEventListener(this); + img.src=Rico.imgDir+(foldersNode[1] ? "folderopen.gif" : "folderclosed.gif"); + } + td.appendChild(img) + }, + + showCheckBox: function(td,foldersNode) { + var inp=document.createElement("input") + inp.type="checkbox" + inp.name=foldersNode[3] + td.appendChild(inp) + }, + + displayLabel: function(row,foldersNode) { + if (foldersNode[5]) { + var span=document.createElement('a'); + span.href='#'; + span.onclick=this.options.defaultAction; + } else { + var span=document.createElement('p'); + } + span.id=this.id+"__"+foldersNode[3]; + var desc=foldersNode[4]; + switch (this.options.nodeIdDisplay) { + case 'last': desc+=' ('+foldersNode[3]+')'; break; + case 'first': desc=foldersNode[3]+' - '+desc; break; + case 'tooltip': span.title=foldersNode[3]; break; + } + span.appendChild(document.createTextNode(desc)) + var td=row.insertCell(-1) + td.appendChild(span) + }, + + //when a parent is closed all children also are + closeFolders: function(foldersNode) { + var i=0 + if (foldersNode[2]) { + for (i=this.FirstChildNode; i< foldersNode.length; i++) + this.closeFolders(foldersNode[i]) + } + foldersNode[0] = 0 + foldersNode[1] = 0 + }, + + nodeClick: function(e) { + var node=Event.element(e); + if (this.returnValue) { + var v=node.id; + var i=v.indexOf('__'); + if (i>=0) v=v.substr(i+2); + this.returnValue(v,node.innerHTML); + } + this.close(); + }, + + //recurse over the tree structure + //called by openbranch + clickOnFolderRec: function(foldersNode, folderName) { + var i=0 + if (foldersNode[3] == folderName) { + if (foldersNode[0]) { + this.closeFolders(foldersNode) + } else { + foldersNode[0] = 1 + foldersNode[1] = 1 + } + } else if (foldersNode[2]) { + for (i=this.FirstChildNode; i< foldersNode.length; i++) + this.clickOnFolderRec(foldersNode[i], folderName) + } + }, + + openBranch: function(e) { + var node=Event.element(e); + this.clickOnFolderRec(this.foldersTree, node.name) + this.timeOutId = setTimeout(this.redrawTree.bind(this),100) + }, + + getChildren: function(e) { + var node=Event.element(e); + this.loadXMLDoc(node.name) + this.openBranch(e) + } + +} + +Rico.includeLoaded('ricoTree.js'); diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_de.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_de.js new file mode 100644 index 0000000..530820a --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_de.js @@ -0,0 +1,86 @@ +/***************************************************************** + Page : livegrid_DE.js + Description : LiveGrid text for German menus + Translator: rainer@langheiter@.com + Version 0.1 - please send corrections to dowdybrown@yahoo.com +******************************************************************/ +// 2007-02-09, made some improvements - debach@gmx.de + +RicoTranslate.addPhrase("Sort by","Sortiert nach") +RicoTranslate.addPhrase("Filter by","Gefiltert nach") +RicoTranslate.addPhrase("Hide","Verbergen") +RicoTranslate.addPhrase("Show","Zeige") +RicoTranslate.addPhrase("Show All","Alle zeigen") +RicoTranslate.addPhrase("Ascending","Aufsteigend") +RicoTranslate.addPhrase("Descending","Absteigend") + +RicoTranslate.addPhrase("Include only this value","Nur diesen Wert einbeziehen") +RicoTranslate.addPhrase("Exclude this value","Diesen Wert ausschließen") +RicoTranslate.addPhrase("Exclude this value also","Diesen Wert ebenfalls ausschließen") +RicoTranslate.addPhrase("Greater than or equal to this value","Größer oder gleich diesem Wert") +RicoTranslate.addPhrase("Less than or equal to this value","Kleiner oder gleich diesem wert") +RicoTranslate.addPhrase("Contains keyword","Enthält Schlüsselwort") +RicoTranslate.addPhrase("Change keyword","Schlüsselwort ändern ") +RicoTranslate.addPhrase("Enter keyword to search for","Schlüsselwort eintragen, nach dem gesucht werden soll") +RicoTranslate.addPhrase("use * as a wildcard","verwende * als Wildcard") +RicoTranslate.addPhrase("Remove filter","Entferne Filter") + +RicoTranslate.addPhrase("Waiting for data","Warte auf Daten") +RicoTranslate.addPhrase("Request for data timed out","Zeitüberschreitung") + +RicoTranslate.addPhrase("No matching records","Keine übereinstimmenden Einträge") +RicoTranslate.addPhrase("Listing records","Zeige Einträge") +RicoTranslate.addPhrase("of","von") +RicoTranslate.addPhrase("of about","von ungefähr") + +RicoTranslate.monthNames=["Januar", "Februar", "März", "April", "Mai","Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"] +RicoTranslate.dayNames=["Sonntag", "Montag","Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"] + +RicoTranslate.thouSep="." +RicoTranslate.decPoint="," +RicoTranslate.dateFmt="dd.mm.yyyy" + +// added for 22 August release + +RicoTranslate.addPhrase("Print","Druck") +RicoTranslate.addPhrase("Export","Exportiert") +RicoTranslate.addPhrase("Visible rows","Sichtbare Zeilen") +RicoTranslate.addPhrase("All rows","Alle Zeilen") + +// added for Feb 2007 release + +RicoTranslate.addPhrase("Loading","Lade") +RicoTranslate.addPhrase("minutes before your session expires","Minuten, bevor Ihre Sitzung abläuft") // formal +//RicoTranslate.addPhrase("minutes before your session expires","Minuten, bevor deine Sitzung abläuft") // informal +//RicoTranslate.addPhrase("minutes before your session expires","Minuten, bevor die Sitzung abläuft") // indirect +RicoTranslate.addPhrase("EXPIRED","ABGELAUFEN") +RicoTranslate.addPhrase("Close","Schließen") +RicoTranslate.addPhrase("Cancel","Abbrechen") +RicoTranslate.addPhrase("Save","Speichere") +RicoTranslate.addPhrase("Add","Erstelle") +RicoTranslate.addPhrase("Edit","Bearbeite") +RicoTranslate.addPhrase("Delete","Lösche") +RicoTranslate.addPhrase("Are you sure you want to delete","Möchten Sie dies wirklich löschen:") // formal +//RicoTranslate.addPhrase("Are you sure you want to delete","Möchtest du das wirklich löschen:") // informal +//RicoTranslate.addPhrase("Are you sure you want to delete","Wirklich löschen:") // indirect +RicoTranslate.addPhrase("record","Eintrag") +RicoTranslate.addPhrase("this record","diesen Eintrag") // "dieser"? +RicoTranslate.addPhrase("new record","neuen Eintrag") // "neuer"? +RicoTranslate.addPhrase("Please enter","Bitte eingeben") +RicoTranslate.addPhrase("a value for","einen Wert für") +RicoTranslate.addPhrase("an integer value for","einen ganzzahligen Wert für") +RicoTranslate.addPhrase("a positive integer value for","einen positiven ganzzahligen Wert für") +RicoTranslate.addPhrase("The request returned an error","Die Anfrage ergab einen Fehler") + +// for demo only: + +RicoTranslate.addPhrase("Show orders for","Zeige Bestellungen für") +RicoTranslate.addPhrase("Show order detail","Zeige Bestelldetails") +RicoTranslate.addPhrase("order","Bestellung") +RicoTranslate.addPhrase("this order","diese Bestellung") +RicoTranslate.addPhrase("new order","neue Bestellung") + +// add your own here: + +RicoTranslate.addPhrase("Visible rows to web page","Sichtbare Zeilen auf eine Webseite") +RicoTranslate.addPhrase("All rows to web page","Alle Zeilen auf eine Webseite") \ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_es.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_es.js new file mode 100644 index 0000000..dc5b8f6 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_es.js @@ -0,0 +1,79 @@ +/***************************************************************** + Page : livegrid_es.js + Description : LiveGrid text for Spanish menus + Version 0.2 (by Marco Scarnatto) + If you have better translations, or would like to include + translations for another language, please send them to dowdybrown@yahoo.com +******************************************************************/ + +RicoTranslate.addPhrase("Sort by","Ordenar por") +RicoTranslate.addPhrase("Filter by","Filtrar por") +RicoTranslate.addPhrase("Hide","Ocultar") +RicoTranslate.addPhrase("Show","Mostrar") +RicoTranslate.addPhrase("Show All","Mostrar todo") +RicoTranslate.addPhrase("Ascending","Ascendente") +RicoTranslate.addPhrase("Descending","Descendente") + +RicoTranslate.addPhrase("Include only this value","Incluir solo este valor") +RicoTranslate.addPhrase("Exclude this value","Excluir este valor") +RicoTranslate.addPhrase("Exclude this value also","Excluir este valor también") +RicoTranslate.addPhrase("Greater than or equal to this value","Mayor o igual a este valor") +RicoTranslate.addPhrase("Less than or equal to this value","Menor o igual a este valor") +RicoTranslate.addPhrase("Contains keyword","Contiene el texto") +RicoTranslate.addPhrase("Change keyword","Cambiar texto") +RicoTranslate.addPhrase("Enter keyword to search for","Ingrese texto a buscar") +RicoTranslate.addPhrase("use * as a wildcard","use * como un comodín") +RicoTranslate.addPhrase("Remove filter","Quitar filtro") + +RicoTranslate.addPhrase("Waiting for data","Esperando datos") +RicoTranslate.addPhrase("Request for data timed out","Tiempo excedido en recibir datos ") + +RicoTranslate.addPhrase("No matching records","No hay datos coincidentes") +RicoTranslate.addPhrase("Listing records","Mostrando datos") +RicoTranslate.addPhrase("of","de") +RicoTranslate.addPhrase("of about","de alrededor de") + +RicoTranslate.thouSep="," +RicoTranslate.decPoint="." +RicoTranslate.dateFmt="dd/mm/yyyy" + +RicoTranslate.monthNames=['Enero','Febrero', 'Marzo', 'Abril', 'Mayo','Junio', 'Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'] +RicoTranslate.dayNames=['Domingo','Lunes','Martes','Miércoles','Jueves','Viernes','Sábado'] + +// added for Aug 2006 release + +RicoTranslate.addPhrase("Print","Imprimir") +RicoTranslate.addPhrase("Export","Exportar") +RicoTranslate.addPhrase("Visible rows","Filas visibles") +RicoTranslate.addPhrase("All rows","Todas las filas") + +// added for Feb 2007 release + +RicoTranslate.addPhrase("Loading","Cargar") +RicoTranslate.addPhrase("minutes before your session expires","minutos antes de su sesión expiran") +RicoTranslate.addPhrase("EXPIRED","EXPIRADO") +RicoTranslate.addPhrase("Close","Cerrar") +RicoTranslate.addPhrase("Cancel","Cancelar") +RicoTranslate.addPhrase("Save","Guardar") +RicoTranslate.addPhrase("Add","Añadir") +RicoTranslate.addPhrase("Edit","Editar") +RicoTranslate.addPhrase("Delete","Borrar") +RicoTranslate.addPhrase("Are you sure you want to delete","¿Está seguro de que quiere borrar") +RicoTranslate.addPhrase("record","expediente") +RicoTranslate.addPhrase("this record","este expediente") +RicoTranslate.addPhrase("new record","expediente nuevo") +RicoTranslate.addPhrase("Please enter","Introduzca") +RicoTranslate.addPhrase("a value for","un valor para") +RicoTranslate.addPhrase("an integer value for","un valor del número entero para") +RicoTranslate.addPhrase("a positive integer value for","un valor positivo del número entero para") +RicoTranslate.addPhrase("The request returned an error","Un error ocurrió mientras que recibía datos") + +// for demo only: + +RicoTranslate.addPhrase("Show orders for","Mostrar las ordenes de") +RicoTranslate.addPhrase("Show order detail","Mostrar detalle de la orden") +RicoTranslate.addPhrase("order","la orden") +RicoTranslate.addPhrase("this order","esta orden") +RicoTranslate.addPhrase("new order","nueva orden") + +// add your own here: diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_fr.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_fr.js new file mode 100644 index 0000000..7f92442 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_fr.js @@ -0,0 +1,79 @@ +/***************************************************************** + Page : livegrid_FR.js + Description : LiveGrid text for French menus + Version 0.3 (revisions by Pierre Grellet) + If you have better translations, or would like to include + translations for another language, please send them to dowdybrown@yahoo.com +******************************************************************/ + +RicoTranslate.addPhrase("Sort by","Trier par") +RicoTranslate.addPhrase("Filter by","Filtrer par") +RicoTranslate.addPhrase("Hide","Masquer") +RicoTranslate.addPhrase("Show","Afficher") +RicoTranslate.addPhrase("Show All","Afficher tous") +RicoTranslate.addPhrase("Ascending","Croissant") +RicoTranslate.addPhrase("Descending","Décroissant") + +RicoTranslate.addPhrase("Include only this value","Inclure seulement cette valeur") +RicoTranslate.addPhrase("Exclude this value","Exclure cette valeur aussi") +RicoTranslate.addPhrase("Exclude this value also","Exclure cette valeur") +RicoTranslate.addPhrase("Greater than or equal to this value","Supérieur ou égal à cette valeur") +RicoTranslate.addPhrase("Less than or equal to this value","Inférieur ou égal à cette valeur") +RicoTranslate.addPhrase("Contains keyword","Contenant le mot-clé") +RicoTranslate.addPhrase("Change keyword","Changer le mot-clé") +RicoTranslate.addPhrase("Enter keyword to search for","Écrivez le mot-clé à rechercher") +RicoTranslate.addPhrase("use * as a wildcard","utiliser * comme caractère générique") +RicoTranslate.addPhrase("Remove filter","Enlever le filtre") + +RicoTranslate.addPhrase("Waiting for data","En attente des données") +RicoTranslate.addPhrase("Request for data timed out","La requête a atteint sa limite de temps ") + +RicoTranslate.addPhrase("No matching records","Aucun articles ne correspond") +RicoTranslate.addPhrase("Listing records","Résultats") +RicoTranslate.addPhrase("of","de") +RicoTranslate.addPhrase("of about","sur un total d'environ") + +RicoTranslate.thouSep="'" +RicoTranslate.decPoint="." +RicoTranslate.dateFmt="dd.mm.yyyy" + +RicoTranslate.monthNames=['Janvier','Février', 'Mars', 'Avril', 'Mai','Juin', 'Juillet','Août','Septembre','Octobre','Novembre','Décembre'] +RicoTranslate.dayNames=['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'] + +// added for 22 August release + +RicoTranslate.addPhrase("Print","Imprimer") +RicoTranslate.addPhrase("Export","Exporter") +RicoTranslate.addPhrase("Visible rows","Rangs visible") +RicoTranslate.addPhrase("All rows","Tous les rangs") + +// added for Feb 2007 release + +RicoTranslate.addPhrase("Loading","Chargement") +RicoTranslate.addPhrase("minutes before your session expires","minutes avant votre session expire") +RicoTranslate.addPhrase("EXPIRED","EXPIRÉ") +RicoTranslate.addPhrase("Close","Fermer") +RicoTranslate.addPhrase("Cancel","Annuler") +RicoTranslate.addPhrase("Save","Sauvegarder") +RicoTranslate.addPhrase("Add","Ajouter") +RicoTranslate.addPhrase("Edit","Éditer") +RicoTranslate.addPhrase("Delete","Supprimer") +RicoTranslate.addPhrase("Are you sure you want to delete","Êtes-vous sûr de vouloir supprimer") +RicoTranslate.addPhrase("record","enregistrement") +RicoTranslate.addPhrase("this record","cet enregistrement") +RicoTranslate.addPhrase("new record","nouvel enregistrement") +RicoTranslate.addPhrase("Please enter","Veuillez saisir") +RicoTranslate.addPhrase("a value for","une valeur pour") +RicoTranslate.addPhrase("an integer value for","un nombre entier pour") +RicoTranslate.addPhrase("a positive integer value for","un nombre positif pour") +RicoTranslate.addPhrase("The request returned an error","La requête a renvoyé une erreur") + +// for demo only: + +RicoTranslate.addPhrase("Show orders for","Montrer les commandes pour") +RicoTranslate.addPhrase("Show order detail","Montrer les détails de la commande") +RicoTranslate.addPhrase("order","la commande") +RicoTranslate.addPhrase("this order","cette commande") +RicoTranslate.addPhrase("new order","nouvelle commande") + +// add your own here: diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_it.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_it.js new file mode 100644 index 0000000..efc7124 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_it.js @@ -0,0 +1,80 @@ +/***************************************************************** + Page : livegrid_IT.js + Description : LiveGrid text for Italian menus + Version 0.1 (these are guesses based mostly on babelfish results) + If you have better translations, or would like to include + translations for another language, please send them to dowdybrown@yahoo.com +******************************************************************/ + +RicoTranslate.addPhrase("Sort by","Ordina per") +RicoTranslate.addPhrase("Filter by","Filtra per") +RicoTranslate.addPhrase("Hide","Nascondi") +RicoTranslate.addPhrase("Show","Mostra") +RicoTranslate.addPhrase("Show All","Mostra Tutte") +RicoTranslate.addPhrase("Ascending","Crescente") +RicoTranslate.addPhrase("Descending","Decrescente") + +RicoTranslate.addPhrase("Include only this value","Ritieni soltanto questo valore") +RicoTranslate.addPhrase("Exclude this value","Escludi questo valore") +RicoTranslate.addPhrase("Exclude this value also","Escludi questo valore anche") +RicoTranslate.addPhrase("Greater than or equal to this value","Superiore o uguale a questo valore") +RicoTranslate.addPhrase("Less than or equal to this value","Inferiore o uguale a questo valore") +RicoTranslate.addPhrase("Contains keyword","Contiene la parola chiave") +RicoTranslate.addPhrase("Change keyword","Cambia la parola chiave") +RicoTranslate.addPhrase("Enter keyword to search for","Entra la parola chiave da cercare") +RicoTranslate.addPhrase("use * as a wildcard","usa * come \"jolly\"") +RicoTranslate.addPhrase("Remove filter","Rimuovi filtro") + +RicoTranslate.addPhrase("Waiting for data","Attendere per i dati") +RicoTranslate.addPhrase("Request for data timed out","La richiesta dei dati ha raggiunto il limite di tempo") + +RicoTranslate.addPhrase("No matching records","Nessun articoli corrispondenti") +RicoTranslate.addPhrase("Listing records","Risultati") +RicoTranslate.addPhrase("of","di") +RicoTranslate.addPhrase("of about","di circa") + +RicoTranslate.monthNames=["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"] +RicoTranslate.dayNames=["Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato"] + +RicoTranslate.thouSep="." +RicoTranslate.decPoint="," +RicoTranslate.dateFmt="dd/mm/yyyy" + +// added for Feb 2007 release + +RicoTranslate.addPhrase("Loading","Caricamento") +RicoTranslate.addPhrase("minutes before your session expires","minuti prima che la vostra sessione termini") +RicoTranslate.addPhrase("EXPIRED","TERMINATA") +RicoTranslate.addPhrase("Close","Chiudi") +RicoTranslate.addPhrase("Cancel","Annulla") +RicoTranslate.addPhrase("Save","Salva") +RicoTranslate.addPhrase("Add","Aggiungi") +RicoTranslate.addPhrase("Edit","Modifica") +RicoTranslate.addPhrase("Delete","Cancella") +RicoTranslate.addPhrase("Are you sure you want to delete","Siete sicuri che volete cancellare") +RicoTranslate.addPhrase("record","registrazione") +RicoTranslate.addPhrase("this record","qesta registrazione") +RicoTranslate.addPhrase("new record","nuova registrazione") +RicoTranslate.addPhrase("Please enter","Per favore inserire") +RicoTranslate.addPhrase("a value for","un valore per") +RicoTranslate.addPhrase("an integer value for","un numero intero per") +RicoTranslate.addPhrase("a positive integer value for","un numero intero positivo per") +RicoTranslate.addPhrase("The request returned an error","La richiesta ha generato un errore") + +// for demo only: + +RicoTranslate.addPhrase("Show orders for","Mostra gli ordini per") +RicoTranslate.addPhrase("Show order detail","Mostra i dettagli dell'ordine") +RicoTranslate.addPhrase("order","ordine") +RicoTranslate.addPhrase("this order","questo ordine") +RicoTranslate.addPhrase("new order","nuovo ordine") + +// added for 22 August release + +RicoTranslate.addPhrase("Print","Stampa") +RicoTranslate.addPhrase("Export","Esporta") +RicoTranslate.addPhrase("Visible rows","Righe visibili") +RicoTranslate.addPhrase("All rows","Tutte le righe") + +// add your own here: + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_ja.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_ja.js new file mode 100644 index 0000000..479f9e2 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_ja.js @@ -0,0 +1,49 @@ +/***************************************************************** + Page : livegrid_ja.js + Description : LiveGrid text for Japanese menus + Translator: hsur +******************************************************************/ + +RicoTranslate.addPhrase("Sort by","ソート") +RicoTranslate.addPhrase("Filter by","絞込み") +RicoTranslate.addPhrase("Hide","隠す") +RicoTranslate.addPhrase("Show","表示") +RicoTranslate.addPhrase("Ascending","昇順") +RicoTranslate.addPhrase("Descending","降順") + +RicoTranslate.addPhrase("Include only this value","この値を含む") +RicoTranslate.addPhrase("Exclude this value","この値を除く") +RicoTranslate.addPhrase("Greater than or equal to this value","これ以上の値") +RicoTranslate.addPhrase("Less than or equal to this value","これ以下の値") +RicoTranslate.addPhrase("Contains keyword","このキーワードを含む") +RicoTranslate.addPhrase("Change keyword","キーワードを変更") +RicoTranslate.addPhrase("Enter keyword to search for","キーワードを入力してください") +RicoTranslate.addPhrase("use * as a wildcard","ワイルドカードとして*を使います") +RicoTranslate.addPhrase("also","も") +RicoTranslate.addPhrase("Remove filter","絞込みを削除") + +RicoTranslate.addPhrase("Waiting for data","データ取得中") +RicoTranslate.addPhrase("Request for data timed out","タイムアウトしました") + +RicoTranslate.addPhrase("No matching records","一致するレコードはありません") +RicoTranslate.addPhrase("Listing records","") +RicoTranslate.addPhrase("of","of") +RicoTranslate.addPhrase("of about","of about") + +RicoTranslate.monthNames=["1月", "2月", "3月", "4月", "5月","6月", "7月", "8月", "9月", "10月", "11月", "12月"] +RicoTranslate.dayNames=["月","火", "æ°´","木", "金", "土", "日"] + +RicoTranslate.thouSep="." +RicoTranslate.decPoint="," +RicoTranslate.dateFmt="yyyy/mm/dd" +RicoTranslate.timeFmt="HH:nn:ss" + +// added for 22 August release + +RicoTranslate.addPhrase("Print","印刷") +RicoTranslate.addPhrase("Export","抽出") +RicoTranslate.addPhrase("Visible rows","Visible rows") +RicoTranslate.addPhrase("All rows","全ての行") + +// add your own here: + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_pt.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_pt.js new file mode 100644 index 0000000..bdaa9d2 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_pt.js @@ -0,0 +1,55 @@ +/***************************************************************** + Page : livegrid_pt.js (brazilian) + Description : LiveGrid text for Brazilian Portuguese menus + Version 0.1 (by Adriano Accorsi - adriano@token.com.br) + If you have better translations, or would like to include + translations for another language, please send them to dowdybrown@yahoo.com +******************************************************************/ + +RicoTranslate.addPhrase("Sort by","Ordenar por") +RicoTranslate.addPhrase("Filter by","Filtrar por") +RicoTranslate.addPhrase("Hide","Ocultar") +RicoTranslate.addPhrase("Show","Exibir") +RicoTranslate.addPhrase("Show All","Exibir tudo") +RicoTranslate.addPhrase("Ascending","Ascendente") +RicoTranslate.addPhrase("Descending","Descendente") + +RicoTranslate.addPhrase("Include only this value","Incluir apenas este valor") +RicoTranslate.addPhrase("Exclude this value","Excluir este valor") +RicoTranslate.addPhrase("Greater than or equal to this value","Maior ou igual a este valor") +RicoTranslate.addPhrase("Less than or equal to this value","Menor ou igual a este valor") +RicoTranslate.addPhrase("Contains keyword","Contém texto") +RicoTranslate.addPhrase("Change keyword","Alterar texto") +RicoTranslate.addPhrase("Enter keyword to search for","Informe texto a ser pesquisado") +RicoTranslate.addPhrase("use * as a wildcard","use * como 'coringa'") +RicoTranslate.addPhrase("also","também") +RicoTranslate.addPhrase("Remove filter","Remover filtro") + +RicoTranslate.addPhrase("Waiting for data","Aguardando dados") +RicoTranslate.addPhrase("Request for data timed out","Tempo esgotado para espera de dados") + +RicoTranslate.addPhrase("No matching records","Nenhum registro encontrado.") +RicoTranslate.addPhrase("Listing records","Listar registros") +RicoTranslate.addPhrase("of","de") +RicoTranslate.addPhrase("of about","de aproximadamente") + +RicoTranslate.thouSep="." +RicoTranslate.decPoint="," +RicoTranslate.dateFmt="dd/mm/yyyy" + +RicoTranslate.monthNames=["Janeiro", "Fevereiro", "Março", "Abril", "Maio","Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"] +RicoTranslate.dayNames=["Domingo", "Segunda","Terça", "Quarta", "Quinta", "Sexta", "Sábado"] + +// added for 22 August release + +RicoTranslate.addPhrase("Print","Imprimir") +RicoTranslate.addPhrase("Export","Exportar") +RicoTranslate.addPhrase("Visible rows","Fileiras visíveis") +RicoTranslate.addPhrase("All rows","Todas as fileiras") + +// for demo only: + +RicoTranslate.addPhrase("Show orders for","Exibir pedidos de") +RicoTranslate.addPhrase("Show order detail","Exibir detalhes do pedido") + +// add your own here: diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_ru.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_ru.js new file mode 100644 index 0000000..c4ceea7 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_ru.js @@ -0,0 +1,82 @@ +/***************************************************************** + Page : livegrid_ru.js + Description : LiveGrid text for Russian menus + Version 0.2 (by Illiya Gannitskiy,Alexey Uvarov) + If you have better translations, or would like to include + translations for another language, please send them to dowdybrown@yahoo.com +******************************************************************/ + +RicoTranslate.addPhrase("Sort by","Ñîðòèðîâêà ïî") +RicoTranslate.addPhrase("Filter by","Ôèëüòðàöèÿ ïî") +RicoTranslate.addPhrase("Hide","Ñïðÿòàòü") +RicoTranslate.addPhrase("Show","Ïîêàçàòü") +RicoTranslate.addPhrase("Show All","Ïîêàçàòü âñå") +RicoTranslate.addPhrase("Ascending","Âîçðàñòàþùàÿ") +RicoTranslate.addPhrase("Descending","Óáûâàþùàÿ") + +RicoTranslate.addPhrase("Include only this value","Âêëþ÷èòü òîëüêî ýòî çíà÷åíèå") +RicoTranslate.addPhrase("Exclude this value","Èñêëþ÷èòü ýòî çíà÷åíèå") +RicoTranslate.addPhrase("Greater than or equal to this value","Áîëüøå èëè ðàâíî äàííîìó çíà÷åíèþ") +RicoTranslate.addPhrase("Less than or equal to this value","Ìåíüøå èëè ðàâíî äàííîìó çíà÷åíèþ") +RicoTranslate.addPhrase("Contains keyword","Ñîäåðæèò çíà÷åíèå") +RicoTranslate.addPhrase("Change keyword","Èçìåíèòü çíà÷åíèå") +RicoTranslate.addPhrase("Enter keyword to search for","Èñêàòü ïî êëþ÷ó") +RicoTranslate.addPhrase("use * as a wildcard","Èñïîëüçîâàòü * äëÿ âñåõ çàïèñåé") +RicoTranslate.addPhrase("also","òàêæå") +RicoTranslate.addPhrase("Remove filter","Óáðàòü ôèëüòð") + +RicoTranslate.addPhrase("Waiting for data","Îæèäàíèå äàííûõ") +RicoTranslate.addPhrase("Request for data timed out","Ïðåâûøåí èíòåðâàë îæèäàíèÿ äàííûõ") + +RicoTranslate.addPhrase("No matching records","Íåò ñîâïàäåíèé") +RicoTranslate.addPhrase("Listing records","Ïðîñìîòð çàïèñåé") +RicoTranslate.addPhrase("of","èç") +RicoTranslate.addPhrase("of about","èç î") + +RicoTranslate.thouSep="," +RicoTranslate.decPoint="." +RicoTranslate.dateFmt="dd/mm/yyyy" + +RicoTranslate.monthNames=['ßíâàðü','Ôåâðàëü', 'Ìàðò', 'Àïðåëü', 'Ìàé','Èþíü', 'Èþëü','Àâãóñò','Ñåíòÿáðü','Îòêòÿáðü','Íîÿáðü','Äåêàáðü'] +RicoTranslate.dayNames=['Ïîíåäåëüíèê','Âòîðíèê','Ñðåäà','×åòâåðã','Ïÿòíèöà','Ñóááîòà','Âîñêðåñåíüå'] + +// added for 22 August release + +RicoTranslate.addPhrase("Print","Ïå÷àòü") +RicoTranslate.addPhrase("Export","Ýêñïîðò") +RicoTranslate.addPhrase("Visible rows","Âèäèìûå çàïèñè") +RicoTranslate.addPhrase("All rows","Âñå çàïèñè") + +// added for Feb 2007 release + +RicoTranslate.addPhrase("Loading","Çàãðóçêà") +RicoTranslate.addPhrase("minutes before your session expires","ìèíóò äî èñòå÷åíèÿ ñåññèè") +RicoTranslate.addPhrase("EXPIRED","ÈÑÒÅÊËÎ") +RicoTranslate.addPhrase("Close","Çàêðûòî") +RicoTranslate.addPhrase("Cancel","Îòìåíà") +RicoTranslate.addPhrase("Save","Ñîõðàíèòü") +RicoTranslate.addPhrase("Add","Äîáàâèòü") +RicoTranslate.addPhrase("Edit","Ðåäàêòèðîâàòü") +RicoTranslate.addPhrase("Delete","Óäàëèòü") +RicoTranslate.addPhrase("Are you sure you want to delete","Âû óâåðåííû,÷òî õîòèòå óäàëèòü") +RicoTranslate.addPhrase("record","çàïèñü") +RicoTranslate.addPhrase("this record","ýòà çàïèñü") +RicoTranslate.addPhrase("new record","íîâàÿ çàïèñü") +RicoTranslate.addPhrase("Please enter","Ïîæàëóéñòà ââåäèòå") +RicoTranslate.addPhrase("a value for","çíà÷åíèå äëÿ") +RicoTranslate.addPhrase("an integer value for","öåëîå çíà÷åíèå äëÿ") +RicoTranslate.addPhrase("a positive integer value for","ïîëîæèòåëüíîå öåëîå çíà÷åíèå äëÿ") +RicoTranslate.addPhrase("The request returned an error","Çàïðîñ âîçâðàòèë îøèáêó") + + + +// for demo only: + +RicoTranslate.addPhrase("Show orders for","Ïîêàçàòü çíà÷åíèÿ äëÿ") +RicoTranslate.addPhrase("Show order detail","Ïîêàçàòü çíà÷åíèÿ ïîäðîáíî") +RicoTranslate.addPhrase("order","çíà÷åíèå") +RicoTranslate.addPhrase("this order","ýòî çíà÷åíèå") +RicoTranslate.addPhrase("new order","íîâîå çíà÷åíèå") + + +// add your own here: diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_ua.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_ua.js new file mode 100644 index 0000000..18206c8 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_ua.js @@ -0,0 +1,82 @@ +/***************************************************************** + Page : livegrid_ua.js + Description : LiveGrid text for Ukrainian menus + Version 0.1 (by Illiya Gannitskiy,Alexey Uvarov) + If you have better translations, or would like to include + translations for another language, please send them to dowdybrown@yahoo.com +******************************************************************/ + +RicoTranslate.addPhrase("Sort by","Cîðòóâàííÿ ïî") +RicoTranslate.addPhrase("Filter by","Ô³ëüòðàö³ÿ ïî") +RicoTranslate.addPhrase("Hide","Ñõîâàòè") +RicoTranslate.addPhrase("Show","Ïîêàçàòè") +RicoTranslate.addPhrase("Show All","Ïîêàçàòè âñå") +RicoTranslate.addPhrase("Ascending","Çðîñòàþ÷à") +RicoTranslate.addPhrase("Descending","Óáóâàþ÷à") + +RicoTranslate.addPhrase("Include only this value","Âêëþ÷èòè ò³ëüêè öå çíà÷åííÿ") +RicoTranslate.addPhrase("Exclude this value","Âèêëþ÷èòè öå çíà÷åííÿ") +RicoTranslate.addPhrase("Greater than or equal to this value","Á³ëüøå àáî ð³âíî äàíîìó çíà÷åííþ") +RicoTranslate.addPhrase("Less than or equal to this value","Ìåíøå àáî ð³âíî äàíîìó çíà÷åííþ") +RicoTranslate.addPhrase("Contains keyword","̳ñòèòü çíà÷åííÿ") +RicoTranslate.addPhrase("Change keyword","Çì³íèòè çíà÷åííÿ") +RicoTranslate.addPhrase("Enter keyword to search for","Øóêàòè ïî êëþ÷ó") +RicoTranslate.addPhrase("use * as a wildcard","Âèêîðèñòîâóâàòè * äëÿ âñ³õ çàïèñ³â") +RicoTranslate.addPhrase("also","òàêîæ") +RicoTranslate.addPhrase("Remove filter","Ïðèáðàòè ô³ëüòð") + +RicoTranslate.addPhrase("Waiting for data","Î÷³êóâàííÿ äàíèõ") +RicoTranslate.addPhrase("Request for data timed out","Ïåðåâèùåíèé ³íòåðâàë î÷³êóâàííÿ äàíèõ") + +RicoTranslate.addPhrase("No matching records","Íåìຠçá³ã³â") +RicoTranslate.addPhrase("Listing records","Ïåðåãëÿä çàïèñ³â") +RicoTranslate.addPhrase("of","ç") +RicoTranslate.addPhrase("of about","ç î") + +RicoTranslate.thouSep="," +RicoTranslate.decPoint="." +RicoTranslate.dateFmt="dd/mm/yyyy" + +RicoTranslate.monthNames=['ѳ÷åíü','Ëþòèé', 'Áåðåçåíü', 'Êâ³òåíü', 'Òðàâåíü','×åðâåíü', 'Ëèïåíü','Ñåðïåíü','Âåðåñåíü','Æîâòåíü','Ëèñòîïàä','Ãðóäåíü'] +RicoTranslate.dayNames=['Ïîíåä³ëîê','³âòîðîê','Ñåðåäà','×åòâåð','Ï'ÿòíèöÿ','Ñóáîòà','Íåä³ëÿ'] + +// added for 22 August release + +RicoTranslate.addPhrase("Print","Äðóê") +RicoTranslate.addPhrase("Export","Åêñïîðò") +RicoTranslate.addPhrase("Visible rows","Âèäèì³ çàïèñè") +RicoTranslate.addPhrase("All rows","Âñ³ çàïèñè") + +// added for Feb 2007 release + +RicoTranslate.addPhrase("Loading","Çàâàíòàæåííÿ") +RicoTranslate.addPhrase("minutes before your session expires","õâèëèí äî çàê³í÷åííÿ ñåñ³¿") +RicoTranslate.addPhrase("EXPIRED","ÇÀʲÍ×ÈËÎÑß") +RicoTranslate.addPhrase("Close","Çàêðèòî") +RicoTranslate.addPhrase("Cancel","³äì³íà") +RicoTranslate.addPhrase("Save","Çáåðåãòè") +RicoTranslate.addPhrase("Add","Äîäàòè") +RicoTranslate.addPhrase("Edit","Ðåäàãóâàòè") +RicoTranslate.addPhrase("Delete","Âèäàëèòè") +RicoTranslate.addPhrase("Are you sure you want to delete","Âè óïåâíåí³,ùî áàæàºòå âèäàëèòè") +RicoTranslate.addPhrase("record","çàïèñ") +RicoTranslate.addPhrase("this record","öåé çàïèñ") +RicoTranslate.addPhrase("new record","íîâèé çàïèñ") +RicoTranslate.addPhrase("Please enter","Áóäü ëàñêà, ââåä³òü") +RicoTranslate.addPhrase("a value for","çíà÷åííÿ äëÿ") +RicoTranslate.addPhrase("an integer value for","ö³ëå çíà÷åííÿ äëÿ") +RicoTranslate.addPhrase("a positive integer value for","ïîçèòèâíå ö³ëå çíà÷åííÿ äëÿ") +RicoTranslate.addPhrase("The request returned an error","Çàïèò ïîâåðíóâ ïîìèëêó") + + + +// for demo only: + +RicoTranslate.addPhrase("Show orders for","Ïîêàçàòè çíà÷åííÿ") +RicoTranslate.addPhrase("Show order detail","Ïîêàçàòè çíà÷åííÿ äåòàëüíî") +RicoTranslate.addPhrase("order","Çíà÷åííÿ") +RicoTranslate.addPhrase("this order","öå çíà÷åííÿ") +RicoTranslate.addPhrase("new order","íîâå çíà÷åííÿ") + + +// add your own here: diff --git a/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_zh.js b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_zh.js new file mode 100644 index 0000000..96b9a78 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/js/rico/translations/livegrid_zh.js @@ -0,0 +1,55 @@ +/***************************************************************** + Page : livegrid_zh.js + Description : LiveGrid text for CHINA menus + Translator: Sam Shan at gz_shanming@yahoo.com + Version 0.1 - please send corrections to dowdybrown@yahoo.com + Version 0.2 - Updated based on Xinjun liu's comments. +******************************************************************/ + +RicoTranslate.addPhrase("Sort by","排序") +RicoTranslate.addPhrase("Filter by","过滤") +RicoTranslate.addPhrase("Hide","隐藏") +RicoTranslate.addPhrase("Show","显示") +RicoTranslate.addPhrase("Ascending","升序") +RicoTranslate.addPhrase("Descending","降序") + +RicoTranslate.addPhrase("Include only this value","只包含此值") +RicoTranslate.addPhrase("Exclude this value","不包含此值") +RicoTranslate.addPhrase("Greater than or equal to this value","大于等于") +RicoTranslate.addPhrase("Less than or equal to this value","小于等于") +RicoTranslate.addPhrase("Contains keyword","包含关键字") +RicoTranslate.addPhrase("Change keyword","更改关键字") +RicoTranslate.addPhrase("Enter keyword to search for","输入关键字") +RicoTranslate.addPhrase("use * as a wildcard","使用*通配符") +RicoTranslate.addPhrase("also","也") +RicoTranslate.addPhrase("Remove filter","移除过滤器") + +RicoTranslate.addPhrase("Waiting for data","等待接收数据") +RicoTranslate.addPhrase("Request for data timed out","等待数据超时") + +RicoTranslate.addPhrase("No matching records","没有匹配的数据") +RicoTranslate.addPhrase("Listing records","列出纪录") +RicoTranslate.addPhrase("of","共") +RicoTranslate.addPhrase("of about","大约") + +RicoTranslate.monthNames=["一月", "二月", "三月", "四月", "五月","六月", "七月", "八月", "九月", "十月", "十一月", "十二月"] +RicoTranslate.dayNames=["星期日","星期一", "星期二","星期三", "星期四", "星期五", "星期六"] + +RicoTranslate.thouSep="." +RicoTranslate.decPoint="," +RicoTranslate.dateFmt="yyyy/mm/dd" + +// added for 22 August release + +RicoTranslate.addPhrase("Print","打印") +RicoTranslate.addPhrase("Export","输出") +RicoTranslate.addPhrase("Visible rows","当前显示记录") +RicoTranslate.addPhrase("All rows","所有记录") + +// for demo only: + +RicoTranslate.addPhrase("Show orders for","显示订单") +RicoTranslate.addPhrase("Show order detail","显示订单详情") + +// add your own here: + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/language/english.php b/NP_TrackBack/branches/DOM-branch/trackback/language/english.php new file mode 100644 index 0000000..b81e490 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/language/english.php @@ -0,0 +1,87 @@ + for ID <%tb_id%>. " + . "Below are the full details:\n\n" + . "URL:\t<%url%>\nTitle:\t<%title%>\nExcerpt:\t<%excerpt%>\nBlogname:\t<%blogname%>"); +define('_TB_NORTIFICATION_MAIL_TITLE', "New Trackback received for ID <%tb_id%>"); + +// template title +define('_TB_dateFormat', 'Date format'); +define('_TB_tplHeader', 'Header'); +define('_TB_tplEmpty', 'Empty'); +define('_TB_tplItem', 'Item'); +define('_TB_tplFooter', 'Footer'); +define('_TB_tplLocalHeader', 'Header (Local)'); +define('_TB_tplLocalEmpty', 'Empty (Local)'); +define('_TB_tplLocalItem', 'Item (Local)'); +define('_TB_tplLocalFooter', 'Footer (Local)'); +define('_TB_tplNO_ACCEPT', 'No accept message'); +define('_TB_tplTbNone', 'Trackback count (none)'); +define('_TB_tplTbOne', 'Trackback count (one)'); +define('_TB_tplTbMore', 'Trackback count (more)'); + +// template values +define('_TB_dateFormat_VAL', "%e/%m/%g"); +define('_TB_tplHeader_VAL', "
"); +define('_TB_tplLocalHeader_VAL', "
\n\t
Local Trackback
\n\n"); +define('_TB_tplLocalEmpty_VAL', ""); +define('_TB_tplLocalItem_VAL', "\t
\n\t\t
\n\t\t\t<%delete%> \">" + . "<%title%>: <%excerpt%>\n\t\t
\n\t\t
\n\t\t\t<%timestamp%>\n" + . "\t\t
\n\t
\n\n"); +define('_TB_tplLocalFooter_VAL', "\t
"); + +// error messages +define('_TB_msgNOTALLOWED_SEND', "You're not allowed to send pings"); +define('_TB_msgDISABLED_SEND', "Sending trackback pings is disabled"); +define('_TB_msgNO_SENDER_URL', "No ping URL"); +define('_TB_msgBAD_SENDER_URL', 'Bad ping URL'); +define('_TB_msgCOULDNOT_SEND_PING', 'Could not send ping: %s'); +define('_TB_msgRESP_HTTP_ERROR', 'An error occurred: HTTP Error: [%s] %s'); +define('_TB_msgAN_ERROR_OCCURRED', "An error occurred: %s"); +define('_TB_msgTBID_IS_MISSING', "TrackBack ID is missing (tb_id)"); +define('_TB_msgTB_COULDNOT_TB_UPDATE', 'Could not update trackback data: %s'); +define('_TB_msgDUPLICATED_TB_BLOCKED', "Trackback: Duplicated Blocked Trackback [ignore] (itemid:%d from: %s)"); +define('_TB_msgLINK_CHECK_OK', "Trackback: LinkCheck OK. (link: %s pat: %s )"); +define('_TB_msgLINK_CHECK_IGNORE', "Trackback: LinkCheck NG. [ignore] (itemid:%d from: %s cnt: %s pat: %s)"); +define('_TB_msgLINK_CHECK_BLOCK', "Trackback: LinkCheck NG. [block] (itemid:%d from: %s cnt: %s pat: %s)"); +define('_TB_msgCOULDNOT_SAVE_DOUBLE', 'Could not save trackback data, possibly because of a double entry: '); + + + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/language/japanese-euc.php b/NP_TrackBack/branches/DOM-branch/trackback/language/japanese-euc.php new file mode 100644 index 0000000..c7dd64a --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/language/japanese-euc.php @@ -0,0 +1,69 @@ + ¤«¤é ID:<%tb_id%> ¤Îµ­»ö¤ËÂФ·¤Æ¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤ò¼õ¿®¤·¤Þ¤·¤¿¡£ " + . "¾ÜºÙ¤Ï²¼µ­¤Î¤È¤ª¤ê¤Ç¤¹:\n\n" + . "URL:\t<%url%>\n¥¿¥¤¥È¥ë:\t<%title%>\n³µÍ×:\t<%excerpt%>\n¥Ö¥í¥°Ì¾:\t<%blogname%>"); +define('_TB_NORTIFICATION_MAIL_TITLE', "¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤ò¼õ¿®¤·¤Þ¤·¤¿ ID:<%tb_id%>"); + +// template title +define('_TB_dateFormat', 'ÆüÉդηÁ¼°'); +define('_TB_tplHeader', 'TB°ìÍ÷¥Æ¥ó¥×¥ì¡¼¥È(¥Ø¥Ã¥ÀÉô)'); +define('_TB_tplEmpty', 'TB°ìÍ÷¥Æ¥ó¥×¥ì¡¼¥È(0·ï¤Î¤È¤­)'); +define('_TB_tplItem', 'TB°ìÍ÷¥Æ¥ó¥×¥ì¡¼¥È(¥¢¥¤¥Æ¥àÉô)'); +define('_TB_tplFooter', 'TB°ìÍ÷¥Æ¥ó¥×¥ì¡¼¥È(¥Õ¥Ã¥¿Éô)'); +define('_TB_tplLocalHeader', '¥í¡¼¥«¥ëTB°ìÍ÷¥Æ¥ó¥×¥ì¡¼¥È(¥Ø¥Ã¥ÀÉô)'); +define('_TB_tplLocalEmpty', '¥í¡¼¥«¥ëTB°ìÍ÷¥Æ¥ó¥×¥ì¡¼¥È(0·ï¤Î¤È¤­)'); +define('_TB_tplLocalItem', '¥í¡¼¥«¥ëTB°ìÍ÷¥Æ¥ó¥×¥ì¡¼¥È(¥¢¥¤¥Æ¥àÉô)'); +define('_TB_tplLocalFooter', '¥í¡¼¥«¥ëTB°ìÍ÷¥Æ¥ó¥×¥ì¡¼¥È(¥Õ¥Ã¥¿Éô)'); +define('_TB_tplNO_ACCEPT', '¥È¥é¥Ã¥¯¥Ð¥Ã¥¯µñÈݤλþ¤Î¥á¥Ã¥»¡¼¥¸'); +define('_TB_tplTbNone', 'TB¿ôɽ¼¨·Á¼°(0·ï)'); +define('_TB_tplTbOne', 'TB¿ôɽ¼¨·Á¼°(1·ï)'); +define('_TB_tplTbMore', 'TB¿ôɽ¼¨·Á¼°(2·ï°Ê¾å)'); + +// template values +define('_TB_dateFormat_VAL', "%Y/%m/%d %H:%I"); +define('_TB_tplHeader_VAL', "
\n\t
¥È¥é¥Ã¥¯¥Ð¥Ã¥¯
<%admin%>\n\n"); +define('_TB_tplEmpty_VAL', "\t
\n\t\t¤³¤Î¥¨¥ó¥È¥ê¤Ë¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤Ï¤¢¤ê¤Þ¤»¤ó\n\t
\n\n"); + +define('_TB_tplItem_VAL', "\t
\n\t\t
<%name%>
\n" + . "\t\t
\n\t\t\t\"><%title%>: <%excerpt%>\n" + . "\t\t
\n\t\t
\n\t\t\t<%date%>\n\t\t
\n\t
\n\n"); +define('_TB_tplFooter_VAL', "\t
\n\t\t¤³¤Î\">¥È¥é¥Ã¥¯¥Ð¥Ã¥¯URL¤ò»È¤Ã¤Æ¤³¤Îµ­»ö¤Ë¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤òÁ÷¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£\n" + . "\t\t¤â¤·¤¢¤Ê¤¿¤Î¥Ö¥í¥°¤¬¥È¥é¥Ã¥¯¥Ð¥Ã¥¯Á÷¿®¤ËÂбþ¤·¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ë¤Ï" + . "\" onclick=\"window.open(this.href, 'trackback', 'scrollbars=yes,width=600,height=340,left=10,top=10,status=yes,resizable=yes'); return false;\">¤³¤Á¤é¤Î¥Õ¥©¡¼¥à" + . "¤«¤é¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤òÁ÷¿®¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£.\n\t
\n
"); +define('_TB_tplLocalHeader_VAL', "
\n\t
¥í¡¼¥«¥ë¥È¥é¥Ã¥¯¥Ð¥Ã¥¯
\n\n"); +define('_TB_tplLocalEmpty_VAL', ""); +define('_TB_tplLocalItem_VAL', "\t
\n\t\t
\n\t\t\t<%delete%> \"><%title%>: <%excerpt%>\n" + . "\t\t
\n\t\t
\n\t\t\t<%timestamp%>\n\t\t
\n\t
\n\n"); +define('_TB_tplLocalFooter_VAL', "\t
"); + + + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/language/japanese-utf8.php b/NP_TrackBack/branches/DOM-branch/trackback/language/japanese-utf8.php new file mode 100644 index 0000000..9ecea5c --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/language/japanese-utf8.php @@ -0,0 +1,84 @@ + から ID:<%tb_id%> の記事に対してトラックバックを受信しました。 " + . "詳細は下記のとおりです:\n\n" + . "URL:\t<%url%>\nタイトル:\t<%title%>\n概要:\t<%excerpt%>\nブログ名:\t<%blogname%>"); +define('_TB_NORTIFICATION_MAIL_TITLE', "トラックバックを受信しました ID:<%tb_id%>"); + +// template title +define('_TB_dateFormat', '日付の形式'); +define('_TB_tplHeader', 'TB一覧テンプレート(ヘッダ部)'); +define('_TB_tplEmpty', 'TB一覧テンプレート(0件のとき)'); +define('_TB_tplItem', 'TB一覧テンプレート(アイテム部)'); +define('_TB_tplFooter', 'TB一覧テンプレート(フッタ部)'); +define('_TB_tplLocalHeader', 'ローカルTB一覧テンプレート(ヘッダ部)'); +define('_TB_tplLocalEmpty', 'ローカルTB一覧テンプレート(0件のとき)'); +define('_TB_tplLocalItem', 'ローカルTB一覧テンプレート(アイテム部)'); +define('_TB_tplLocalFooter', 'ローカルTB一覧テンプレート(フッタ部)'); +define('_TB_tplNO_ACCEPT', 'トラックバック拒否の時のメッセージ'); +define('_TB_tplTbNone', 'TB数表示形式(0件)'); +define('_TB_tplTbOne', 'TB数表示形式(1件)'); +define('_TB_tplTbMore', 'TB数表示形式(2件以上)'); + +// template values +define('_TB_dateFormat_VAL', "%Y/%m/%d %H:%I"); +define('_TB_tplHeader_VAL', "
\n\t
トラックバック
<%admin%>\n\n"); +define('_TB_tplEmpty_VAL', "\t
\n\t\tこのエントリにトラックバックはありません\n\t
\n\n"); + +define('_TB_tplItem_VAL', "\t
\n\t\t
<%name%>
\n" + . "\t\t
\n\t\t\t\"><%title%>: <%excerpt%>\n" + . "\t\t
\n\t\t
\n\t\t\t<%date%>\n\t\t
\n\t
\n\n"); +define('_TB_tplFooter_VAL', "\t
\n\t\tこの\">トラックバックURLを使ってこの記事にトラックバックを送ることができます。\n" + . "\t\tもしあなたのブログがトラックバック送信に対応していない場合には" + . "\" onclick=\"window.open(this.href, 'trackback', 'scrollbars=yes,width=600,height=340,left=10,top=10,status=yes,resizable=yes'); return false;\">こちらのフォーム" + . "からトラックバックを送信することができます。.\n\t
\n
"); +define('_TB_tplLocalHeader_VAL', "
\n\t
ローカルトラックバック
\n\n"); +define('_TB_tplLocalEmpty_VAL', ""); +define('_TB_tplLocalItem_VAL', "\t
\n\t\t
\n\t\t\t<%delete%> \"><%title%>: <%excerpt%>\n" + . "\t\t
\n\t\t
\n\t\t\t<%timestamp%>\n\t\t
\n\t
\n\n"); +define('_TB_tplLocalFooter_VAL', "\t
"); + +// error messages +define('_TB_msgNOTALLOWED_SEND', "トラックバックの送信が許可されていません"); +define('_TB_msgDISABLED_SEND', "トラックバックの送信が無効に設定されています"); +define('_TB_msgNO_SENDER_URL', "トラックバック送信先のURLが空です"); +define('_TB_msgBAD_SENDER_URL', "トラックバック送信先のURLが正しくありません"); +define('_TB_msgCOULDNOT_SEND_PING', "エラーのためにトラックバックが送信出来ませんでした(エラー:%s)"); +define('_TB_msgRESP_HTTP_ERROR', "エラーが発生しました:HTTPエラー : [%s] %s"); +define('_TB_msgAN_ERROR_OCCURRED', "エラーが発生しました:%s"); +define('_TB_msgTBID_IS_MISSING', "トラックバックIDが指定されていません"); +define('_TB_msgTB_COULDNOT_TB_UPDATE', "トラックバックデータを更新できませんでした: %s"); +define('_TB_msgDUPLICATED_TB_BLOCKED', "Trackback: itemid:%dへの%sからのトラックバックをブロックしました[拒否]"); +define('_TB_msgLINK_CHECK_OK', "Trackback: リンクチェック OK. (link: %s pat: %s )"); +define('_TB_msgLINK_CHECK_IGNORE', "Trackback: リンクチェック NG. [拒否] (itemid:%d from: %s cnt: %s pat: %s)"); +define('_TB_msgLINK_CHECK_BLOCK', "Trackback: リンクチェック NG. [ブロック] (itemid:%d from: %s cnt: %s pat: %s); +define('_TB_msgCOULDNOT_SAVE_DOUBLE', 'データ重複のためトラックバックを保存できませんでした: '); + + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/mkeuc.sh b/NP_TrackBack/branches/DOM-branch/trackback/mkeuc.sh new file mode 100644 index 0000000..d9f44be --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/mkeuc.sh @@ -0,0 +1,11 @@ +#!/bin/bash -x + +FILES=`find japanese-utf8.templates -name '*ml'` + +for utf8file in $FILES +do + eucfile=`echo $utf8file | sed 's/japanese-utf8/japanese-euc/'` + nkf -e -W -d < $utf8file > $eucfile +done + +nkf -e -W -d < japanese-utf8.help.html > japanese-euc.help.html diff --git a/NP_TrackBack/branches/DOM-branch/trackback/silk/accept.png b/NP_TrackBack/branches/DOM-branch/trackback/silk/accept.png new file mode 100644 index 0000000000000000000000000000000000000000..f1037591430e75798fa9a175c7456c7cdd48af7c GIT binary patch literal 1012 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vk7#JAu2Ka=y z{{R2~@4vr){{H^*>(j@dAKrd{{qo1tm*1a0|N8LRm&Z>&J$(G};e&S%9=>__;Pr!R z?=IbZbLI5g1E=5YKk#Jd{>M8GKHj$P@wV*`*KdEgVc-3&8y?T!`f%Nr`)jt|U$g7> z)-88eZN0r>`^~Lu@6X;riPxd{U!OSZO7Hwj6XsuZ4uZL?0bPdU*)>v;RLykCv95%Bnn>U3Wac^GI3Q$;_hDp%eD>wI3=fJ&{pzBBSU;M)C2qi97oXj;Gcg z%*;QQ(!4J>?`U$#;grH7$$3YTGEaErA5N@1n38uSv36g2{-MN@LyyW>IQ+eo=O@f^UR^k%56pd)b=vKn<5XT^vIy<|HQ^V7sxzDLa~bi$y}s z!7DknqN0y~`2}*suQ(KV=fK^&4!4qGc3sh`KeJUMjEH=hL#+h=Vz=VsPso}3%H z>|D+QhuN)>lf;dg7Y92po%=duK||&4nyQui8+^UJw^qeV1T?HRkJ-9n4-@0|{q@6D|ZQ7Kv|Nq8~8#ip&Flo!Zb?erxUAs1J=l_)}SGKLayJE$PWy_W= zS+XQ()Bi<_7F935vvA?Us%3Y279N{Fe}2`H+f_?$RW71Xn%oz9tZGH=SMf{6!nCY{LWJDk>iAf;np za{J!I*4+uMyW*R7#x-t_soN4$w>7F}Q$+Q~h^h_YmFvRF)`pa>4k=v|T)Z;4cvWEG z%D|$Pi7m7C0KFer666=m0Q5gqLDuHJJfPv61s;*b3=CW!K$y{KjmZq4plXS0L`iUd zT1k0gQ7VIPVscS_ZfZ(qqJmpyQEGX9QFgI{Z-j!8fq_YT*_!h}4RbwR978JRq@K^_ zZ)A{Ydl;RidRo(sZ=vorjmfEgyu~M^p8fwXWg>s%>(_htZ1w*Hy_%M4Iq&&z#|<+y zF08AGZk#G~$e=WVTX~hoB%Rf(mSw&<_;ZWTBL+F&qMuGHm%Q#}Q=d_{X@bS!p15TZ z>m+qAzxlrNz?||k`#Kh#5S`Y;diO;MJM;C@orkTqK4$!;##6rgv0>MvA7z{W*Zuv@ Y67*g$Dk&_V3FuG;Pgg&ebxsLQ0J2wWE&u=k literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/silk/cross.png b/NP_TrackBack/branches/DOM-branch/trackback/silk/cross.png new file mode 100644 index 0000000000000000000000000000000000000000..2802c2cfea10ee6e559506f987070f1dff8798d9 GIT binary patch literal 820 zcmcgo`%h8<6uv%ZEYq#6X}QMQTxuDbEPp8l1Otu?pi)?@baK`G1UTn4^M(R{$=Ubv_0KhfEDzVF-F&UVgsQ4Q!X1A0P9}dlQ?Q*S+~s9$bF*9-JQs(%#m@Mf&fa3NH`7?I zE9rljmo}KGzZuCJiHz063(nZHq1LfLDtrT4m{)`x#{J*RHPv;Ry5NYGFV!OmZRfB9 zI9BE(Y8Z?1Bxq4{4QiC@)JU#escUXjtLo(R%sQRg*sQy%r{_xO7n72hy#}j|T6its zvc;`WmDQ|3t7zcCDbAj-kB!aGm(vGq(*-4wu62Tgp%<^aQ=Q^ r{5}5XkSDeR+Hy(~pR?t-t9ToT1leQe(lmp|sSgkVFONIKsqX#<5sL5?JIw-oc($E%(wIBf1W<_=lHJo zr;fcldHDUwqi;_h{&9HU^CLTd?OOM9=lUPpR(#mD?ZeisU$(4zy?OoD^-F)OU-D|h znonz2eOtZg*Xp_7S1b_5`dpD{7?c}}>6YIb9HU8)+``B0Y zuBY)sPx-s9(jRRF@7wC$wbXuSE%?@w^P#!=RdemPri_>M6_4v{9@W==u1tPeUGSo+ z^ig%`r}E@Sm6eYxDxXvo-m5IRTT%SEIQCIN+Qa;U$9c(D3RB-@#ofuvyqBHzI6LuL zUdo;9j8|zf@6v*9XQqBg344$l^D;U5WOmr`?2tF{A!jopp2tR>Neg`y6L2jdaof?h`YUXKktlH&6$((i0S;IjyyXJG-)!hCLrdGC*L*can)AkuzcnB|!u zn**V?7yRw^2U{HpFxeGka?sb9uP$&kFuvMLg8YIRfH5=(0GGh=M4*#63p^r=85p=e zfH0%e8j~47LDdr1h?3y^w370~qErUo#N?v<+|-oJLS?-v|XG0|S%x zvNh*{8g_fSIEGZrNlrMxCZW0~S=edG%*2{`4&I4*aVtMm)M?l|&2tV3j&D7`J%C}2 zoyXM6Cr({Ea>UKXsGC(o;pMrd`L7;uvDj_$edWNYFX{T*$ADwQHy?JcBOQ{v9eA|+ z%raPlPI~pp1vI)Gu2K-qN|y`cVa)rt)PZqlR_hcMgZ&<>UHLT*h=?wqGjn!ySlF_; z;fL8SX+_Li^=!(tw`-y=X)zi4Xe>W?{*cm+wP7sJB*S`pc0H?+En8#9&Jb^{Q>Lu* RkP+w&22WQ%mvv4FO#rNU2+IHf literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/silk/exclamation.png b/NP_TrackBack/branches/DOM-branch/trackback/silk/exclamation.png new file mode 100644 index 0000000000000000000000000000000000000000..39d45928ae125037c9e09600278b43be5f463ca9 GIT binary patch literal 890 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vk7#J9v1AIbU z|NsC0@7?SF?_U3X^YYiL=ii?{{`TzAx2F$(-Msww`new$PkcLf?Bl6}?~m{QdwA=w z{hNO5+xY6>&fj}izC5_&*PazWcP{&}ZQ+ltOMh%x@O?87E%~rz#n%msKd)c*WzE9Z z>lb}mIsfAdAe#MU*`$w4XMSEb@yFt>AB#F4FQ4^eVaLNI)88$a`eAo#-ztBrEeQEKQ*Mj zY0P=ql=Y<{>2qD;=bD6L_a7_ zcv=+sGC%%xUevvU$mcn+uW};q7R25thrnrVOF z2rzaUOM?7@8G!LIpx}s|RuRxKoCO|{#S9EwA3&JVX^qJYprC4rYeY$Kep*R+Vo@rC zZ(?#$er{??W}<>yW>IQ+eo=O@f^UR^k%56pd)b=vKn)i>T^vIy<|HQ^V4Ly7C+6;2 z))|R4e%$$~oSat!?DaJ6ANBA!d(t!Zh|xspBk5ZV#XfyXO5orVEA2>TZ%}S5soW{9lgHSCZ9cZs(70g6PJg&hpKwIk-?Lvq8d}O7+E8NY*IFDI&+4LOGIha zO$WY*nxCf@pE*|++>;~FVlj35jthR#xA!dylXxZ>*86GKFR$9NHFoR_1%+Bd?E6f2 Q0sY3{>FVdQ&MBb@09cy?jsO4v literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/silk/help.png b/NP_TrackBack/branches/DOM-branch/trackback/silk/help.png new file mode 100644 index 0000000000000000000000000000000000000000..477a0152c98cf873f426f54c3cc126becec79571 GIT binary patch literal 1016 zcmd5(`%hX27`^IT8A-P$-I8V97WQaYlWDuEzbx5eQ9D_tHpMMjeT z>uj*jwoxo?!P44Evk_;gu$H^>roNyE2yziBaCu&-B6tB6=jea2FFEHVCppP?a#+VJ zzS@m_2MYkeZbDhfiL~x{2~1X+59Yo>OiNY^o=}CsU>4n#E&#}I9sj1PbZ2KLvH35$ zu^mrtp~-DDnL?9W(fDR$eRCz2M53wiS|YTzg+$`PmAEgw?tYQ-hu7g{6b{GXaMBY- zVI;bQB-}{M8HzhX8%rV78H_uENk;&M{4u*P3i;9;vwBg;8=Z&OEuJ;2Ct`tD&F)o` zYsKga&plt6exB4jR&@?!#vW4JlXDCpY;NMz3rRR?NZw82mDWNBYbUKJ!TR@ME2KLjOXlb4hfb ziCORX3^F$5{X=0FDB%&MS0IB%pFnq?KwNNX7+m6k?h$a|p47?(owq;-S8V2rO>8m5 zeh6Kkuns)54~`pHW40dQ!WE&JDO~7!VCfOeG9MU!9i8qPHFgM07k)Q(+&6UJ)wc8J zTKR_aylMKdp2pMBZfnopnxx&FJjEbn%Jr)wt_mSXke>< z98}d0DC@5&>#oTuS7m3e%If{R^0*s*vLy{ z;DrU8w7H*AdXhnGu4A;5=oFxwM5Z@4QO-1waK{?xl=fyiwFOsx5_jbA;eyL;LPI)W zB9t7h`iV=fQM~$gHbbA=N2#vq%qz~x*^i6tWk$}wt8K;SAMxb+)c22e9@s@NhhHJN zUHC)dgRk?uMWP=na`x@&XdEo1m(=RRNHWubui%uf%eQ z3NEcGoUo_l;>x_*{Y8Dd@-HmQYT8xPu(Rs;((=w7*{$2MTDPSY@62l2n%=NEv2ky7)4~r;4Lde9_}J8tV^e~TO%6OZIjCf{ z|FMYyM<)30nHYMw*L!zw=%H?p{H3-TOWij1#H20tm@r{N?qc(a{k;b}+_M*(@9%U@ zTI{yF({)d$W5yzj_=V2%OkRcXNaN?mC-|4bIWC zHFs860Y-?(2qPrp&mAZRQl$l%Pytu&5xnIn+ zPkefIm~}V5c?V~7Y2=g?8?OpCyK1YxL`$7!UX5mMttKwrM%Ib3mKu%B7G=gNwH$KQ z%vBERZ<_bM0;YteB|(0{48XV_^nmMc_Z6UnISV`@iy0WWK7cTz(;AZ*Kta_K*NBqf z{Irtt#G+IN-^Api{M^)(%tQsZ%%art{G#k)1>Xn-BLf4I_OdnSff}B8x;TbZ%t=mQ zV0Pm(b7NCE5OMRONVm$N8!}l*FQoa!6W8!xyL|a_fqzSvK^W_+Un1hwS?s0_t`eu2 zw(Obg;(FTo%x852=ASF;X03bqXwRNQv0MH2ex4~Iv&ZDlrXxFc?$~jN>$mbU|1^O! zUsnh}VEwdn(%YzX-H8ba0-O31pK^7dTTw9a>wFc?ZE9U}ZT-Bw!mc?O)@X5iD6~&D z_P=%G(5Y)~Ycm*``#Un1bEPkyvuDzzrCCpMSlP1Om7k0K`?jw$*z1b$vnx6&2B*)> wFY+^I#|X4-nh&D%YL--C(aS+CjByi+n#K>sp$y85}Sb4q9e0Nhbh2LJ#7 literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/silk/link.png b/NP_TrackBack/branches/DOM-branch/trackback/silk/link.png new file mode 100644 index 0000000000000000000000000000000000000000..93d4f0e694bfcfc6eb6d2c44b99dd204b3c3a64c GIT binary patch literal 504 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vkfZRm^J|V9E z|NsB<=g+TSzkdAq@%{Vvj~_q2c=6)?{rh+C-o1VM_N`mDZrr$W`SRuS=g*%zckalM zBZm$hI(YElfddEj?%lh4_wG%bHf`9jVcoiQYuBz_xpL*adGlt^o;`i~^eI!OOqw)l z;>3v)CQRtS?-v|XG0|S%xvNh*{ z8mc^9978JRtUc$>)MOyy8aPWz#lzH##VNz-h3fD7v+ipqzk4(HV(^q;BPYMlw_Ahd zr2elBEOV9neP`m~6>JZ#hi&wGSsvA${+2mK_1g9a5BHhNPM360dE<2|^=4{nHwQy6 yr{czpN8+AtEDL6RzVKBpZ+D{E)#5(+-;8s;xxzmETKxj(3I*vp(KYsoD@$>JOAAi4p|NiOgpN}6uK7RY_;j5o7Uc9*d z{Kvf~-|s&8e&fmaM~@!ezkmPg-LH4=-o1VM_NCijZr!?d);zCU^P+pwo-ysGDXY01z{PKE- zYky35Xm#h?|M`sU3NjWKZfDQh!uoHb%DUjE37Ts5efHTsFTH23@7cbCz)4zS_d{7DeNim&r6ptdwyGGBM0-{mCqH_IRuuJzMWatxX0nV z%SW!;v2!ju$u01cZOi0}Fb(#3?!vg_anYT3&JlUrj(0cLgl?BURret~d~N!=8}1kR k!`c0MOqWgj^87M;>U}Ah0}K-{1KrQy>FVdQ&MBb@0NnwnMgRZ+ literal 0 HcmV?d00001 diff --git a/NP_TrackBack/branches/DOM-branch/trackback/silk/plugin_edit.png b/NP_TrackBack/branches/DOM-branch/trackback/silk/plugin_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..80c9a62344daf4c863e09f3a5313db96a75f9bce GIT binary patch literal 985 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vk7#J8Y2Ka=y z{{R2~+n=w0zaRhq`RU(phyH#$^8eF=Umu@+fB*FB+s8j2Z~F7#$d5;{-ycPPe;D=s ze)6}wIbZKbzq_&V>z%l-cjCWYUiabBmQUBJ-d|et@k;fZt92hPSH8Vc^A1Q}sQ7tu z;?Lt#o}Vs%dn$L?&DqOu&RKF}=HeSO7u}e?==zLBH)brnK5OCi=?kw#`t|;K zSEtUsI{Ep5?m1T`&%89@`M&ZQ7yGAQ>YaA6ciM&isTX>tobQ@^zI*EV?n&pnCZ6xu za6GN=Y}>`{6Phnn_MBz2DMHF0OyiP_PYX1H~%^FA{zGIdMb zm8njXm&IP2>U?yDXX5&(x)qMGtHUCf2kqjMZgI;}C80Tfg%ag8Vm&QB{TPb^Ah@J&oE%Fj(r$xKvm%PdMQ&o9a@ zR`88bFfuSOX)jxI9;o5Cr;B4q#hm1X16*Hhn72&$*>g{8R-=Yi&6Tq{4`kHU|1S{8 zZC-I@k5)&+?oFH8+V<^RxiU1i$9<^)bMyRJv%(`x1a8dkF!a7+Y{1g~OX}#cwDjfP zg_2!G%NtBmrP5PH(@$*R(l~m(pn=8fEI0S()R`_7N4wRSc3M6ayq22V<#VWJQm^nb zCe~BAIYN_SB7RgZnSJx%HM1L`<~yxkahc-@Nhm>a{nQ4?o(s^Y+%Q*EX#@w{+#{ zr4uf-%s(}&|6soH_Tz%y}nf_MUHCbYy<-xrXlZ^>dHU=sZ`~b*{esY)$9c z+V(TmZD(p)Pggdbu4p|`)qJv|^<-7s$;!r4Wlg8b8&8(iohYe1kXyDlr)+O_>E4{& zEy=lClXEvG=WI&K+LVyBAt7^peDa3KjCFD8YhzN@L?#W zF^fZD76(Ty3W{717(U-WaF(ZgpMyiIrG2xdZL_&ulZ9=gxlMzab-k%oorz_wu~n_f zitqnvk>CUB6-JqD6c8JI)_SS*N}rEos53S5HoJ8TMQ}7~tmSeE4R+Xqrv;?5WGPb=w;s vauO?dzs{gy$ILuCTtSdJDx>H?esD?sNC~;rZN?7wGSOz~rzA zK@bOgDC8i$o9)rqP_MSf-wD>6VXB8uh_SKpv&n#$1Yuww=ojJ%J$7}_ZR>P8>}+9Y zTMumii|x&=olR_QZ0hID^^L7J*m#XM%UEB=+9FmL*VosvI*-+bm6a7NzF1mX!oma= zUSReKW*_5~7Bi!Bb94A-1k)N!4q53ZvAm-hB{QBNW2uAnX*wP}^Ad`K@tl2+NBU#`qW zO$us~QT+p|lOalKXlN)=uy8MdugHQZ4x(7zUzswQ48nK_;vmp#3dq&-b-CSp;H~=hr zus#Kglvd>$C-OqNEkkscA#{xqQEW_z$?D$)OVHV80Dn!yJzSXj?op45fyIq zJC0$cpIqeI29+H1=AQ87yiYE&C9};bznYT^?avgLeU@wHl5660qG2IrhJ`B5GKoee9J@P%-1hJWO{}&gBdZ*w8)fbf*MIr zVI)OI#Yb9s#ivB4F;Ws!t*D_^PA5+~-}q57q(9j5A-jkCR7R%}23Jo7Yl-)$UmDp4 zt~qJ7TKR_G2$5=W*}?DmF>4Nq(>9{uXBy1&cOpWknHotqwJXz~2}k7y8n z`@;uaTI1Z#@#ts0)3c(I^EI42@v9PlI%Oy!>H>{ViXDE`yD#{({~TTYcq)=c3o|?X zJ6m1mnkcsHlIHYTKXYsOc#V5};_cajck6up272clZp+Kf9bRf5#!Tc4*xQ-c&KRxE ti2J`7file = ($prefix ? $prefix . '/' : '') . $file; + $this->prefix = $prefix; + } + + function set($name, $value) { + $this->vars[$name] = is_object($value) ? $value->fetch() : $value; + } + + function template($file = null) { + $language = ereg_replace( '[\\|/]', '', getLanguageName()); + $this->file = (file_exists(($this->prefix ? $this->prefix . '/' : '') . $language.'.'.$file))? ($this->prefix ? $this->prefix . '/' : '') . $language.'.'.$file: ($this->prefix ? $this->prefix . '/' : '') . $file; + } + + function fetch($file = null) { + if(!$file) $file = $this->file; + else ($prefix ? $prefix . '/' : '') . $file; + + if ($file != null) + { + if (is_array($this->vars)) extract($this->vars); + + ob_start(); + include($file); + $contents = ob_get_contents(); + ob_end_clean(); + + return $contents; + } + } +} diff --git a/NP_TrackBack/branches/DOM-branch/trackback/templates/all.html b/NP_TrackBack/branches/DOM-branch/trackback/templates/all.html new file mode 100644 index 0000000..56c75b1 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/templates/all.html @@ -0,0 +1,106 @@ + +

+ All trackbacks + $amount): ?> + (Page of ) + +

+ + + $amount): ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateStoryTitle, Blog and ExcerptActions
+ + + + + Visit + + ()
+ +
+ Block + + Delete +
+ + $amount): ?> + + + + + + + + \ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/templates/all_ajax.html b/NP_TrackBack/branches/DOM-branch/trackback/templates/all_ajax.html new file mode 100644 index 0000000..cb19843 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/templates/all_ajax.html @@ -0,0 +1,128 @@ + +

+ All trackbacks +

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
 idDateStoryTitle, Blog and Excerpt 
+With selected: +Delete +Block +
+ + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/templates/blocked.html b/NP_TrackBack/branches/DOM-branch/trackback/templates/blocked.html new file mode 100644 index 0000000..15b98de --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/templates/blocked.html @@ -0,0 +1,119 @@ + +

+ Blocked trackbacks + $amount): ?> + (Page of ) + +

+ + + + + $amount): ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateStoryTitle, Blog and ExcerptActions
+ + + + + ">Visit + + () + ' : + '';?> + ';?> +
+ +
+ Unblock + + Delete +
+ + $amount): ?> + + + + + + + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/templates/blocked_ajax.html b/NP_TrackBack/branches/DOM-branch/trackback/templates/blocked_ajax.html new file mode 100644 index 0000000..394a603 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/templates/blocked_ajax.html @@ -0,0 +1,133 @@ + +

+ Blocked Trackbacks +

+ + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
 idDateStoryTitle, Blog and Excerpt 
+With selected: +Unblock +Delete +
+ + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/templates/form.html b/NP_TrackBack/branches/DOM-branch/trackback/templates/form.html new file mode 100644 index 0000000..ba61b48 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/templates/form.html @@ -0,0 +1,56 @@ + + + + Add TrackBack + + + + +

TrackBack Ping

+ +

+ Your trackback has been received properly. +

+ + +

+ +

+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Article URL
Article Title
Excerpt from article
Your Blog Name
Add TrackBack
+
+ +
+ + + \ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/templates/index.html b/NP_TrackBack/branches/DOM-branch/trackback/templates/index.html new file mode 100644 index 0000000..15a2ce4 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/templates/index.html @@ -0,0 +1,34 @@ + +

Overview of all items

+ + + + + + + + + + + + + + + + + + + + + + + + +
Blog: TotalAction
+ + + + + Trackbacks +
+ \ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/templates/list.html b/NP_TrackBack/branches/DOM-branch/trackback/templates/list.html new file mode 100644 index 0000000..0fcf3c3 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/templates/list.html @@ -0,0 +1,107 @@ + +

+ All trackbacks for "" + $amount): ?> + (Page of ) + +

+ + + $amount): ?> + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateTitle, Blog and ExcerptActions
+ + + Visit + + ()
+ +
+ Block + + Delete +
+ + $amount): ?> + + + + + + + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/templates/menu.html b/NP_TrackBack/branches/DOM-branch/trackback/templates/menu.html new file mode 100644 index 0000000..92fa7e1 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/templates/menu.html @@ -0,0 +1,33 @@ + + + + + +

Trackback

+ + \ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/templates/ping.html b/NP_TrackBack/branches/DOM-branch/trackback/templates/ping.html new file mode 100644 index 0000000..91216ce --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/templates/ping.html @@ -0,0 +1,50 @@ + +

Manually ping another weblog

+ +
+ + + + addTicketHidden(); ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Manually Ping
Your URL + +
Your Title + +
Your Excerpt + +
Your Blog Name + +
External Ping URL + +
Send Ping
+ +
\ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/templates/response_all.xml b/NP_TrackBack/branches/DOM-branch/trackback/templates/response_all.xml new file mode 100644 index 0000000..7a160ad --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/templates/response_all.xml @@ -0,0 +1,35 @@ +';?> + + + + + + + + + 0 + + + + + + + + + + + + + + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/templates/response_blocked.xml b/NP_TrackBack/branches/DOM-branch/trackback/templates/response_blocked.xml new file mode 100644 index 0000000..d085390 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/templates/response_blocked.xml @@ -0,0 +1,41 @@ +';?> + + + + + + + + + 0 + + + + + + + + + + + + + + + + diff --git a/NP_TrackBack/branches/DOM-branch/trackback/templates/response_doblock.xml b/NP_TrackBack/branches/DOM-branch/trackback/templates/response_doblock.xml new file mode 100644 index 0000000..a53f37c --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/templates/response_doblock.xml @@ -0,0 +1,8 @@ +';?> + + + + + + + \ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/templates/response_dodelete.xml b/NP_TrackBack/branches/DOM-branch/trackback/templates/response_dodelete.xml new file mode 100644 index 0000000..a53f37c --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/templates/response_dodelete.xml @@ -0,0 +1,8 @@ +';?> + + + + + + + \ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/templates/response_dounblock.xml b/NP_TrackBack/branches/DOM-branch/trackback/templates/response_dounblock.xml new file mode 100644 index 0000000..a53f37c --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/templates/response_dounblock.xml @@ -0,0 +1,8 @@ +';?> + + + + + + + \ No newline at end of file diff --git a/NP_TrackBack/branches/DOM-branch/trackback/templates/updatetable.html b/NP_TrackBack/branches/DOM-branch/trackback/templates/updatetable.html new file mode 100644 index 0000000..113e9e6 --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/templates/updatetable.html @@ -0,0 +1,9 @@ + +
Table update:
+
+ + + addTicketHidden(); ?> +
+
+ diff --git a/NP_TrackBack/branches/DOM-branch/trackback/templates/updatetablefinished.html b/NP_TrackBack/branches/DOM-branch/trackback/templates/updatetablefinished.html new file mode 100644 index 0000000..d94969e --- /dev/null +++ b/NP_TrackBack/branches/DOM-branch/trackback/templates/updatetablefinished.html @@ -0,0 +1,5 @@ + +
+Table update done ! +
+ diff --git a/NP_TrackBack/trunk/NP_TrackBack.php b/NP_TrackBack/trunk/NP_TrackBack.php new file mode 100644 index 0000000..83ccb06 --- /dev/null +++ b/NP_TrackBack/trunk/NP_TrackBack.php @@ -0,0 +1,2586 @@ +isError = false; + $this->inTarget = false; + } + + function parse($data){ + $rx = '/(<'.'?xml.*encoding=[\'"])(.*?)([\'"].*?'.'>)/m'; + if (preg_match($rx, $data, $m)) { + $encoding = strtoupper($m[2]); + } else { + $encoding = mb_detect_encoding($data, NP_TRACKBACK_ENCODING_DETECT_ORDER); + } + + if($encoding == "UTF-8" || $encoding == "ISO-8859-1") { + // noting + } else { + $data = @mb_convert_encoding($data, "UTF-8", $encoding); + $data = str_replace ( $m[0], $m[1].'UTF-8'.$m[3], $data); + $encoding = 'UTF-8'; + } + + $this->parser = xml_parser_create($encoding); + xml_set_object($this->parser, $this); + xml_set_element_handler($this->parser, "_open", "_close"); + xml_set_character_data_handler($this->parser, "_cdata"); + xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, 'UTF-8'). + + $this->words = array(); + xml_parse($this->parser, $data); + $errcode = xml_get_error_code($this->parser); + if ( $errcode != XML_ERROR_NONE ) { + $this->isError = true; + $this->message = 'XML Parse Error: ' . xml_error_string($errcode) . ' in '. xml_get_current_line_number($this->parser); + } + return $this->message; + } + + function free(){ + xml_parser_free($this->parser); + } + + function _open($parser, $name, $attribute){ + switch( $name ){ + case 'MESSAGE': + $this->inTarget = 'MESSAGE'; + break; + case 'ERROR': + $this->inTarget = 'ERROR'; + break; + } + } + + function _close($parser, $name){ + if( $name == $this->inTarget ) $this->inTarget = null; + } + + function _cdata($parser, $data){ + switch( $this->inTarget ){ + case 'MESSAGE': + $this->message = trim($data); + break; + case 'ERROR': + $this->isError = ($data ? true : false); + break; + } + } + } + + class NP_TrackBack extends NucleusPlugin { + var $useCurl = 1; // use curl? 2:precheck+read by curl, 1: read by curl 0: fread + +//modify start+++++++++ + function _createItemLink($itemid, $b){ + global $CONF, $manager; + + $itemLink = createItemLink($itemid,''); + if( strpos($itemLink, 'http') === 0 ){ + return $itemLink; + } + + $blogurl = $b->getURL(); + if (!$blogurl) { + $b =& $manager->getBlog($CONF['DefaultBlog']); + $blogurl = $b->getURL(); + if (!$blogurl) { + $blogurl = $CONF['IndexURL']; + } + } + + if(substr($blogurl, -1) == '/') $blogurl = substr($blogurl, 0, -1); + $usePathInfo = ($CONF['URLMode'] == 'pathinfo'); + $itemUrlOrg = $CONF['ItemURL']; + if( ! ($usePathInfo || substr($blogurl, -4) == '.php') ) $blogurl .= '/index.php'; + $CONF['ItemURL'] = $blogurl; + + $itemLink = createItemLink($itemid,''); + $CONF['ItemURL'] = $itemUrlOrg; + + return $itemLink; + } +//modify end+++++++++ + + /************************************************************************************** + * SKIN VARS, TEMPLATE VARS AND ACTIONS + */ + + /* + * TrackBack data can be inserted using skinvars (or templatevars) + */ + function doSkinVar($skinType, $what = '', $tb_id = '', $amount = 'limit-1') { + + global $itemid, $manager, $CONF; + +//modify start+++++++++ + if(preg_match('/limit/i', $tb_id)){ + $amount = $tb_id; + $tb_id = ''; + } + $amount = intval(str_replace('limit', '', $amount)); +//modify end+++++++++ + + if ($tb_id == '') $tb_id = intval($itemid); + +//mod by cles + $isAcceptPing = $this->isAcceptTrackBack($tb_id); + + //if( $skinType == 'template' && (! $isAcceptPing ) ){ + // return; + //} +//mod by cles end + switch ($what) { + + // Insert Auto-discovery RDF code + case 'tbcode': + case 'code': +//mod by cles +// if($skinType == 'item') + + $spamcheck = array ( + 'type' => 'tbcode', + 'id' => -1, + 'title' => '', + 'excerpt' => '', + 'blogname' => '', + 'url' => '', + 'return' => true, + 'live' => true, + + /* Backwards compatibility with SpamCheck API 1*/ + 'data' => '', + 'ipblock' => true, + ); + global $manager; + //$manager->notify('SpamCheck', array ('spamcheck' => & $spamcheck)); + $spam = false; + if (isset($spamcheck['result']) && $spamcheck['result'] == true){ + $spam = true; + } + + if( ($skinType == 'item') && (!$spam) && $isAcceptPing ) +//mod by cles end + $this->insertCode($tb_id); + break; + + // Insert TrackBack URL + case 'tburl': + case 'url': +//mod by cles +// echo $this->getTrackBackUrl($tb_id); + if($isAcceptPing) + echo $this->getTrackBackUrl($tb_id); + else + echo 'Sorry, no trackback pings are accepted.'; +//mod by cles end + break; + + // Insert manual ping URL + case 'form': + case 'manualpingformlink': + echo $this->getManualPingUrl($tb_id); + break; + + case 'sendpinglink': + echo $manager->addTicketToUrl($CONF['PluginURL'] . 'trackback/index.php?action=ping&id=' . intval($tb_id)); + break; + + // Insert TrackBack count + case 'count': + $count = $this->getTrackBackCount($tb_id); + switch ($count) { + case 0: echo TEMPLATE::fill($this->getOption('tplTbNone'), array('number' => $count)); break; + case 1: echo TEMPLATE::fill($this->getOption('tplTbOne'), array('number' => $count)); break; + default: echo TEMPLATE::fill($this->getOption('tplTbMore'), array('number' => $count)); break; + } + break; + + // Shows the TrackBack list + case 'list': + case '': +//modify start+++++++++ +// $this->showList($tb_id); + $this->showList($tb_id, $amount); +//modify end+++++++++ + break; +//mod by cles + // show requred URL + case 'required': + echo $this->getRequiredURL($tb_id); + break; + + // shows the Local list + case 'locallist': + $this->showLocalList($tb_id); + break; +//mod by cles end + + default: + return; + } + } + + /* + * When used in templates, the tb_id will be determined by the itemid there + */ + function doTemplateVar(&$item, $what = '') { + $this->doSkinVar('template', $what, $item->itemid); + } + + function doTemplateCommentsVar(&$item, &$comment, $what = ''){ + $this->doSkinVar('templatecomments', $what, $item->itemid); + } + + /* + * A trackback ping is to be received on the URL + * http://yourdomain.com/item/1234.trackback + * Extra variables to be passed along are url, title, excerpt, blog_name + */ + function event_InitSkinParse(&$data) { + global $CONF, $itemid; + $format = requestVar('format'); + + if ($CONF['URLMode'] == 'pathinfo') { + if (preg_match('/(\/|\.)(trackback)(\/|$)/', serverVar('PATH_INFO'), $matches)) { + $format = $matches[2]; + } + } + + if ($format == 'trackback' && $data['type'] == 'item') + { + $errorMsg = $this->handlePing(intval($itemid)); + + if ($errorMsg != '') + $this->xmlResponse($errorMsg); + else + $this->xmlResponse(); + + exit; + } + } + + /* + * A trackback ping is to be received on the URL + * http://yourdomain.com/action.php?action=plugin&name=TrackBack&tb_id=1234 + * Extra variables to be passed along are url, title, excerpt, blog_name + */ + function doAction($type) + { + global $CONF,$manager; + $aActionsNotToCheck = array( + '', + 'ping', + 'form', + 'redirect', + 'left', + ); + if (!in_array($type, $aActionsNotToCheck)) { + if (!$manager->checkTicket()) return _ERROR_BADTICKET; + } + + switch ($type) { + + // When no action type is given, assume it's a ping + case '': + $errorMsg = $this->handlePing(); + $this->xmlResponse($errorMsg); + break; + + // Manual ping + case 'ping': + $errorMsg = $this->handlePing(); + if ($errorMsg != '') + $this->showManualPingError(intRequestVar('tb_id'), $errorMsg); + else + $this->showManualPingSuccess(intRequestVar('tb_id')); + break; + + // Show manual ping form + case 'form': +//mod by cles +// $this->showManualPingForm(intRequestVar('tb_id')); + $tb_id = intRequestVar('tb_id'); + $isAcceptPing = $this->isAcceptTrackBack($tb_id); + + if( $isAcceptPing ) + $this->showManualPingForm($tb_id); + else + echo 'Sorry, no trackback pings are accepted.'; +//mod by cles end + break; + + // Detect trackback + case 'detect': + list($url, $title) = + $this->getURIfromLink(html_entity_decode(requestVar('tb_link'))); + + $url = addslashes($url); + $url = $this->_utf8_to_javascript($url); + + $title = addslashes($title); + $title = $this->_utf8_to_javascript($title); + + echo "tbDone('" . requestVar('tb_link') . "', '" . $url . "', '" . $title . "');"; + + break; +//mod by cles + // redirect + case 'redirect': + return $this->redirect(intRequestVar('tb_id'), requestVar('urlHash')); + break; +//mod by cles end + case 'left': + echo $this->showLeftList(intRequestVar('tb_id'), intRequestVar('amount')); + break; + + // delete a trackback(local) + case 'deletelc': + $err = $this->deleteLocal(intRequestVar('tb_id'), intRequestVar('from_id')); + if( $err ) + return $err; + header('Location: ' . serverVar('HTTP_REFERER')); + break; + } + + exit; + } + + function doIf($key = '', $value = '') + { + global $itemid; + //echo "key: $key, value: $value"; + + switch( strtolower($key) ){ + case '': + case 'accept': + if( $value == '' ) $value = 'yes'; + $value = ( $value == 'no' || (! $value) ) ? false : true; + + $ret = false; + if( $itemid ) + $ret = $this->isAcceptTrackBack($itemid); + else + $ret = $this->isAcceptTrackBack(); + return ( $value == false ) ? (! $ret) : $ret; + + case 'required': + if( $value == '' ) $value = 'yes'; + $value = ( $value == 'no' || (! $value) ) ? false : true; + + $ret = false; + if( $itemid ) + $ret = $this->isEnableLinkCheck($itemid); + + return ( $value == false ) ? (! $ret) : $ret; + + default: + return false; + } + } + + /************************************************************************************** + * OUTPUT + */ + + /* + * Show a list of left trackbacks for this ID + */ + function showLeftList($tb_id, $offset = 0, $amount = 99999999) { + global $manager, $blog, $CONF; + + $out = array(); + $query = ' + SELECT + url, + md5(url) as urlHash, + blog_name, + excerpt, + title, + UNIX_TIMESTAMP(timestamp) AS timestamp + FROM + '.sql_table('plugin_tb').' + WHERE + tb_id = '.intval($tb_id).' AND + block = 0 + ORDER BY + timestamp DESC + '; + if($offset) + $query .= ' LIMIT '.intval($offset).', ' .intval($amount); + $res = sql_query($query); + while ($row = mysql_fetch_array($res)) + { + + $row['blog_name'] = htmlspecialchars($row['blog_name'], ENT_QUOTES); + $row['title'] = htmlspecialchars($row['title'], ENT_QUOTES); + $row['excerpt'] = htmlspecialchars($row['excerpt'], ENT_QUOTES); + if (_CHARSET != 'UTF-8') { +//modify start+++++++++ + $row['blog_name'] = $this->_restore_to_utf8($row['blog_name']); + $row['title'] = $this->_restore_to_utf8($row['title']); + $row['excerpt'] = $this->_restore_to_utf8($row['excerpt']); +//modify end+++++++++ + $row['blog_name'] = $this->_utf8_to_entities($row['blog_name']); + $row['title'] = $this->_utf8_to_entities($row['title']); + $row['excerpt'] = $this->_utf8_to_entities($row['excerpt']); + } + $iVars = array( + 'action' => $this->getTrackBackUrl($tb_id), + 'form' => $this->getManualPingUrl($tb_id), + 'name' => $row['blog_name'], + 'title' => $row['title'], + 'excerpt' => $this->_cut_string($row['excerpt'], 400), + 'url' => htmlspecialchars($row['url'], ENT_QUOTES), + 'date' => htmlspecialchars(strftime($this->getOption('dateFormat'), $row['timestamp']), ENT_QUOTES) + ); + +//mod by cles + if( $this->getOption('HideUrl') == 'yes' ) + $iVars['url'] = $CONF['ActionURL'] . '?action=plugin&name=TrackBack&type=redirect&tb_id=' . $tb_id . '&urlHash=' . $row['urlHash']; + else + $iVars['url'] = $row['url']; +//mod by cles end + + $out[] = TEMPLATE::fill($this->getOption('tplItem'), $iVars); + } + mysql_free_result($res); + + return @join("\n",$out); + } + + /* + * Show a list of all trackbacks for this ID + */ + function showList($tb_id, $amount = 0) { + $tb_id = intval($tb_id); + global $manager, $blog, $CONF, $member; +//mod by cles + $enableHideurl = true; + // for TB LinkLookup + if( + strpos(serverVar('HTTP_USER_AGENT'),'Hatena Diary Track') === false + || strpos(serverVar('HTTP_USER_AGENT'),'NP_TrackBack') === false + || strpos(serverVar('HTTP_USER_AGENT'),'TBPingLinkLookup') === false + || strpos(serverVar('HTTP_USER_AGENT'),'MT::Plugin::BanNoReferTb') === false + || strpos(serverVar('HTTP_USER_AGENT'),'livedoorBlog') === false + ){ + $enableHideurl = false; + $amount = '-1'; + } +//mod by cles end + +/* + $res = sql_query(' + SELECT + url, + md5(url) as urlHash, + blog_name, + excerpt, + title, + UNIX_TIMESTAMP(timestamp) AS timestamp + FROM + '.sql_table('plugin_tb').' + WHERE + tb_id = '.$tb_id .' AND + block = 0 + ORDER BY + timestamp ASC + '); +*/ + $query = ' + SELECT + url, + md5(url) as urlHash, + blog_name, + excerpt, + title, + UNIX_TIMESTAMP(timestamp) AS timestamp + FROM + '.sql_table('plugin_tb').' + WHERE + tb_id = '.intval($tb_id) .' AND + block = 0 + ORDER BY + timestamp DESC + '; + if( $amount == '-1' ) + $query .= ' LIMIT 9999999'; + elseif( $amount ) + $query .= ' LIMIT '.intval($amount); + + if( $amount != 0) + $res = sql_query($query); + + $gVars = array( + 'action' => $this->getTrackBackUrl(intval($tb_id)), + 'form' => $this->getManualPingUrl(intval($tb_id)), + 'required' => $this->getRequiredURL(intval($tb_id)), + ); + + if ( $member->isLoggedIn() ){ + $adminurl = htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'] . 'trackback/index.php?action=list&id=' . intval($tb_id)), ENT_QUOTES); + $pingformurl = htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'] . 'trackback/index.php?action=ping&id=' . intval($tb_id)), ENT_QUOTES); + $gVars['admin'] = '[admin]'; + $gVars['pingform'] = '[pingform]'; + } + + echo TEMPLATE::fill($this->getOption('tplHeader'), $gVars); + + + while ($amount != 0 && $row = mysql_fetch_array($res)) + { + + $row['blog_name'] = htmlspecialchars($row['blog_name'], ENT_QUOTES); + $row['title'] = htmlspecialchars($row['title'], ENT_QUOTES); + $row['excerpt'] = htmlspecialchars($row['excerpt'], ENT_QUOTES); + +/* +*/ + if (_CHARSET != 'UTF-8') { +//modify start+++++++++ +/* + $row['blog_name'] = $this->_utf8_to_entities($row['blog_name']); + $row['title'] = $this->_utf8_to_entities($row['title']); + $row['excerpt'] = $this->_utf8_to_entities($row['excerpt']); +*/ + $row['blog_name'] = $this->_restore_to_utf8($row['blog_name']); + $row['title'] = $this->_restore_to_utf8($row['title']); + $row['excerpt'] = $this->_restore_to_utf8($row['excerpt']); + + $row['blog_name'] = mb_convert_encoding($row['blog_name'], _CHARSET, 'UTF-8'); + $row['title'] = mb_convert_encoding($row['title'], _CHARSET, 'UTF-8'); + $row['excerpt'] = mb_convert_encoding($row['excerpt'], _CHARSET, 'UTF-8'); +//modify end+++++++++ + } + +//modify start+++++++++ +/* + $iVars = array( + 'action' => $this->getTrackBackUrl($tb_id), + 'form' => $this->getManualPingUrl($tb_id), + 'name' => $row['blog_name'], + 'title' => $row['title'], + 'excerpt' => $row['excerpt'], + 'url' => htmlspecialchars($row['url'], ENT_QUOTES), + 'date' => htmlspecialchars(strftime($this->getOption('dateFormat'), $row['timestamp'] + ($blog->getTimeOffset() * 3600)), ENT_QUOTES) + ); +*/ + $iVars = array( + 'action' => $this->getTrackBackUrl($tb_id), + 'form' => $this->getManualPingUrl($tb_id), + 'name' => htmlspecialchars($row['blog_name'], ENT_QUOTES), + 'title' => htmlspecialchars($row['title'], ENT_QUOTES), + 'excerpt' => htmlspecialchars($this->_cut_string($row['excerpt'], 400), ENT_QUOTES), + 'url' => htmlspecialchars($row['url'], ENT_QUOTES), + 'date' => htmlspecialchars(strftime($this->getOption('dateFormat'), $row['timestamp']), ENT_QUOTES) + ); + +//mod by cles + if( $enableHideurl && $this->getOption('HideUrl') == 'yes' ) + $iVars['url'] = $CONF['ActionURL'] . '?action=plugin&name=TrackBack&type=redirect&tb_id=' . intval($tb_id) . '&urlHash=' . $row['urlHash']; + else + $iVars['url'] = $row['url']; +//mod by cles end + +//modify end+++++++++ + echo TEMPLATE::fill($this->getOption('tplItem'), $iVars); + + } + +//modify start+++++++++ + $q = ' + SELECT + count(*) + FROM + '.sql_table('plugin_tb').' + WHERE + tb_id = '.intval($tb_id) .' AND + block = 0 + ORDER BY + timestamp DESC + '; + $result = sql_query($q); + $total = mysql_result($result,0,0); + + if($amount != -1 && $total > $amount){ + $leftcount = $total - $amount; + + echo ''; + +?> + + + + +
+ +getOption('tplEmpty'), $gVars); + } + mysql_free_result($res); + + echo TEMPLATE::fill($this->getOption('tplFooter'), $gVars); + + } + + /* + * Returns the TrackBack count for a TrackBack item + */ + function getTrackBackCount($tb_id) { + return quickQuery('SELECT COUNT(*) as result FROM ' . sql_table('plugin_tb') . ' WHERE tb_id='.intval($tb_id).' AND block = 0'); + } + + /** + * Returns the manual ping URL + */ + function getManualPingUrl($itemid) { + global $CONF; + return $CONF['ActionURL'] . '?action=plugin&name=TrackBack&type=form&tb_id='.$itemid; + } + + /** + * Show the manual ping form + */ + function showManualPingError($itemid, $status = '') { + global $CONF; + + $form = true; $error = true; $success = false; + sendContentType('text/html', 'admin-trackback', _CHARSET); +//modify start+++++++++ +// include ($this->getDirectory() . '/templates/form.html'); + require_once($this->getDirectory() . '/template.php'); + $mTemplate = new Trackback_Template(null, $this->getDirectory()); + $mTemplate->set ('CONF', $CONF); + $mTemplate->set ('itemid', $itemid); + $mTemplate->set ('form', $form); + $mTemplate->set ('error', $error); + $mTemplate->set ('success', $success); + $mTemplate->set ('status', $status); + $mTemplate->template('templates/form.html'); + echo $mTemplate->fetch(); +//modify end+++++++++ + } + + function showManualPingSuccess($itemid, $status = '') { + global $CONF; + + $form = false; $error = false; $success = true; + sendContentType('text/html', 'admin-trackback', _CHARSET); +//modify start+++++++++ + //include ($this->getDirectory() . '/templates/form.html'); + require_once($this->getDirectory() . '/template.php'); + $mTemplate = new Trackback_Template(null, $this->getDirectory()); + $mTemplate->set ('CONF', $CONF); + $mTemplate->set ('itemid', $itemid); + $mTemplate->set ('form', $form); + $mTemplate->set ('error', $error); + $mTemplate->set ('success', $success); + $mTemplate->set ('status', $status); + $mTemplate->template('templates/form.html'); + echo $mTemplate->fetch(); +//modify end+++++++++ + } + + function showManualPingForm($itemid, $text = '') { + global $CONF; + + $form = true; $error = false; $success = false; + + // Check if we are allowed to accept pings + if ( !$this->isAcceptTrackBack($itemid) ) { + $text = 'Sorry, no trackback pings are accepted'; + $form = false; $error = true; + } + + sendContentType('text/html', 'admin-trackback', _CHARSET); +//modify start+++++++++ + //include ($this->getDirectory() . '/templates/form.html'); + require_once($this->getDirectory() . '/template.php'); + $mTemplate = new Trackback_Template(null, $this->getDirectory()); + $mTemplate->set ('CONF', $CONF); + $mTemplate->set ('itemid', $itemid); + $mTemplate->set ('form', $form); + $mTemplate->set ('error', $error); + $mTemplate->set ('success', $success); + $mTemplate->set ('status', $status); + $mTemplate->template('templates/form.html'); + echo $mTemplate->fetch(); +//modify end+++++++++ + } + + /** + * Returns the trackback URL + */ + function getTrackBackUrl($itemid) { + global $CONF, $manager; + return $CONF['ActionURL'] . '?action=plugin&name=TrackBack&tb_id='.$itemid; + } + + /* + * Insert RDF code for item + */ + function insertCode($itemid) { + $itemid = intval($itemid); + global $manager, $CONF; + + $item = & $manager->getItem($itemid, 0, 0); + $blog = & $manager->getBlog(getBlogIDFromItemID($item['itemid'])); + +/* + $CONF['ItemURL'] = preg_replace('/\/$/', '', $blog->getURL()); + $uri = createItemLink($item['itemid'],''); +*/ + $uri = $this->_createItemLink($item['itemid'],$blog); + + $title = strip_tags($item['title']); + $desc = strip_tags($item['body']); + $desc = $this->_cut_string($desc, 200); + $desc = htmlspecialchars($desc, ENT_QUOTES); + + ?> + + getItem($tb_id, 0, 0); + + if($item) + { + $blog =& $manager->getBlog(getBlogIDFromItemID($item['itemid'])); + + $blog_name = $blog->getName(); + $title = $item['title']; + $excerpt = $item['body']; + +//modify start+++++++++ +/* + if (_CHARSET != 'UTF-8') + { + $title = $this->_convert_to_utf8($title, $encoding); + $excerpt = $this->_convert_to_utf8($excerpt, $encoding); + $blog_name = $this->_convert_to_utf8($blog_name, $encoding); + } + + $title = $this->_decode_entities(strip_tags($title)); + $excerpt = $this->_decode_entities(strip_tags($excerpt)); + $blog_name = $this->_decode_entities(strip_tags($blog_name)); +*/ + + $title = $this->_restore_to_utf8($title); + $excerpt = $this->_restore_to_utf8($excerpt); + $blog_name = $this->_restore_to_utf8($blog_name); +//modify end+++++++++ + + $excerpt = $this->_cut_string($excerpt, 200); + + +//modify start+++++++++ +/* + $CONF['ItemURL'] = preg_replace('/\/$/', '', $blog->getURL()); + $url = createItemLink($item['itemid'],''); +*/ + $url = $this->_createItemLink($item['itemid'],$blog); +//modify end+++++++++ + + // Use UTF-8 charset for output + header('Content-Type: text/xml'); + echo "<","?xml version='1.0' encoding='UTF-8'?",">\n"; + + echo "\n"; + echo "\t0\n"; + echo "\t\n"; + echo "\t\t\n"; + echo "\t\t\t".htmlspecialchars($title, ENT_QUOTES)."\n"; + echo "\t\t\t".htmlspecialchars($url, ENT_QUOTES)."\n"; + echo "\t\t\t".htmlspecialchars($excerpt, ENT_QUOTES)."\n"; + + $query = 'SELECT url, blog_name, excerpt, title, UNIX_TIMESTAMP(timestamp) as timestamp FROM '.sql_table('plugin_tb').' WHERE tb_id='.intval($tb_id).' AND block = 0 ORDER BY timestamp DESC'; + $res = sql_query($query); + while ($o = mysql_fetch_object($res)) + { + // No need to do conversion, because it is already UTF-8 + $data = array ( + 'url' => htmlspecialchars($o->url, ENT_QUOTES), + 'blogname' => htmlspecialchars($this->_restore_to_utf8($o->blog_name), ENT_QUOTES), + 'timestamp' => strftime('%Y-%m-%d',$o->timestamp), + 'title' => htmlspecialchars($this->_restore_to_utf8($o->title), ENT_QUOTES), + 'excerpt' => htmlspecialchars($this->_restore_to_utf8($o->excerpt), ENT_QUOTES), + 'tburl' => $this->getTrackBackUrl($tb_id) + ); + + echo "\n"; + echo "\t\t\t\n"; + echo "\t\t\t\t".$data['title']."\n"; + echo "\t\t\t\t".$data['url']."\n"; + echo "\t\t\t\t".$data['excerpt']."\n"; + echo "\t\t\t\n"; + } + echo "\t\t\n"; + echo "\t\n"; + echo ""; + exit; + } + else + { + $this->xmlResponse(_ERROR_NOSUCHITEM); + } + + } + + + + /************************************************************************************** + * SENDING AND RECEIVING TRACKBACK PINGS + */ + + /* + * Send a Trackback ping to another website + */ + function sendPing($itemid, $title, $url, $excerpt, $blog_name, $ping_url) + { + $sendEncoding = 'UTF-8'; + + // 1. Check some basic things + if (!$this->canSendPing()) { + return 'You\'re not allowed to send pings'; + } + + if ($this->getOption('SendPings') == 'no') { + return 'Sending trackback pings is disabled'; + } + + if ($ping_url == '') { + return 'No ping URL'; + } + + // 2. Check if protocol is correct http URL + $parsed_url = parse_url($ping_url); + + if ($parsed_url['scheme'] != 'http' || $parsed_url['host'] == '') + return 'Bad ping URL'; + + $port = ($parsed_url['port']) ? $parsed_url['port'] : 80; + + // 3. Create contents + if($sendEncoding != _CHARSET){ + $title = mb_convert_encoding($title, $sendEncoding, _CHARSET); + $excerpt = mb_convert_encoding($excerpt, $sendEncoding, _CHARSET); + $blog_name = mb_convert_encoding($blog_name, $sendEncoding, _CHARSET); + } + + + $content = 'title=' . urlencode( $title ); + $content .= '&url=' . urlencode( $url ); + $content .= '&excerpt=' . urlencode( $excerpt ); + $content .= '&blog_name=' . urlencode( $blog_name ); + + // 4. Prepare HTTP request + $request = 'POST ' . $parsed_url['path']; + + if ($parsed_url['query'] != '') + $request .= '?' . $parsed_url['query']; + + $request .= " HTTP/1.1\r\n"; + $request .= "Accept: */*\r\n"; + $request .= "User-Agent: " . $this->userAgent . "\r\n"; + $request .= ( $port == 80 )? + "Host: " . $parsed_url['host'] . "\r\n": + "Host: " . $parsed_url['host'] . ":" . $port . "\r\n"; + $request .= "Cache-Control: no-cache\r\n"; + $request .= "Connection: Close\r\n"; + $request .= "Content-Length: " . strlen( $content ) . "\r\n"; + $request .= "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n"; + $request .= "\r\n"; + $request .= $content; + + $socket = fsockopen( $parsed_url['host'], $port, $errno, $errstr ); + if ( ! $socket ) + return 'Could not send ping: '.$errstr.' ('.$errno.')'; + + // 5. Execute HTTP request + fputs($socket, $request); + + // 6. Receive response + $result = ''; + while (!feof($socket)) { + $result .= fgets($socket, 4096); + } + + fclose($socket); + +//modify start+++++++++ + list($header, $body) = split("\r\n\r\n", $result, 2); + preg_match("/HTTP\/1\.[0-1] ([0-9]+) ([^\r\n]*)\r?\n/", $header, $httpresp); + $respCd = $httpresp[1]; + $respMsg = $httpresp[2]; + + if( $respCd != 200 ){ + return 'An error occurred: HTTP Error: [' . $respCd . '] ' . $respMsg; + } + + if( defined('NP_TRACKBACK_USE_XML_PARSER') && function_exists('xml_parser_create') ){ + $p = new NP_TrackBack_XMLParser(); + + # remove invalid string + $body = strstr($body, '<'); + $body = substr($body, 0, strrpos($body,'>') === false ? 0 : strrpos($body,'>') + 1 ); + + $p->parse($body); + $p->free(); + if( $p->isError ){ + $errorMessage = mb_convert_encoding($p->message, _CHARSET, 'UTF-8'); + return 'An error occurred: ' . htmlspecialchars($errorMessage, ENT_QUOTES); + } + } else { + if ( strpos($DATA[1],'0') === false ){ + preg_match("/(.*?)<\/message>/",$DATA[1],$error_message); + if( $error_message[1] ){ + $errorMessage = mb_convert_encoding($error_message[1], _CHARSET); + return 'An error occurred: '.htmlspecialchars($errorMessage, ENT_QUOTES); + } else { + return 'An error occurred: fatal error.'; + } + } + } + + return ''; + } +//modify end+++++++++ + + /* + * Handle a Trackback ping sent to this website + */ + function handlePing($tb_id = 0) { + global $manager; + + // Defaults + $spam = false; + $link = false; +//modify start+++++++++ +// $block = true; + $block = false; +//modify end+++++++++ + if ($tb_id == 0) + $tb_id = intRequestVar('tb_id'); + + $rss = requestVar('__mode') == 'rss'; +//mod by cles + $enableLinkCheck = $this->isEnableLinkCheck($tb_id); + $block = ( $enableLinkCheck ) ? true : false ; +//mod by cles end + + if (!$tb_id) { + return 'TrackBack ID is missing (tb_id)'; + } + + if ((!$manager->existsItem($tb_id,0,0)) && ($this->getOption('CheckIDs') == 'yes')) { + return _ERROR_NOSUCHITEM; + } + + // 0. Check if we need to output the list as rss + if ($rss) { + $this->rssResponse($tb_id); + return; + } +//mod by cles + // check: accept pings. + $blogId = getBlogIDFromItemID($tb_id); + $isAcceptPing = $this->isAcceptTrackBack($tb_id); + + if (! $isAcceptPing) + return 'Sorry, no trackback pings are accepted.'; +//mod by cles end + + // 1. Get attributes +//modify start+++++++++ + $b =& $manager->getBlog($blogId); +//modify end+++++++++ + $url = requestVar('url'); + $title = requestVar('title'); + $excerpt = requestVar('excerpt'); + $blog_name = requestVar('blog_name'); + + if( $url && preg_match('/https?:\/\/([^\/]+)/', $url, $matches) ){ + if( gethostbynamel($matches[1]) === FALSE ) + return 'URL is invalid (url)'; + } else { + return 'URL is missing or invalid (url)'; + } + + // 2. Conversion of encoding... +//modify start+++++++++ +/* if (preg_match ("/;\s*charset=([^\n]+)/is", $_SERVER["CONTENT_TYPE"], $regs)) + $encoding = strtoupper(trim($regs[1])); + else + $encoding = $this->_detect_encoding($excerpt); +*/ + $encoding = $this->_detect_encoding($excerpt); +//modify end+++++++++ + +//modify start+++++++++ + if (_CHARSET != 'UTF-8'){ + $title = $this->_strip_controlchar(strip_tags(mb_convert_encoding($title, _CHARSET, $encoding))); + $excerpt = $this->_strip_controlchar(strip_tags(mb_convert_encoding($excerpt, _CHARSET, $encoding))); + $blog_name = $this->_strip_controlchar(strip_tags(mb_convert_encoding($blog_name, _CHARSET, $encoding))); + }else{ + $title = $this->_strip_controlchar($this->_convert_to_utf8($title, $encoding)); + $excerpt = $this->_strip_controlchar($this->_convert_to_utf8($excerpt, $encoding)); + $blog_name = $this->_strip_controlchar($this->_convert_to_utf8($blog_name, $encoding)); + + $title = $this->_decode_entities(strip_tags($title)); + $excerpt = $this->_decode_entities(strip_tags($excerpt)); + $blog_name = $this->_decode_entities(strip_tags($blog_name)); + } +//modify end+++++++++ + + // 4. Save data in the DB + $res = @sql_query(' + SELECT + tb_id, block, spam + FROM + '.sql_table('plugin_tb').' + WHERE + url = \''.mysql_real_escape_string($url).'\' AND + tb_id = \''.intval($tb_id).'\' + '); + + if (mysql_num_rows($res) != 0) + { + // Existing TB, update it +/* + $res = @sql_query(' + UPDATE + '.sql_table('plugin_tb').' + SET + title = "'.mysql_real_escape_string($title).'", + excerpt = "'.mysql_real_escape_string($excerpt).'", + blog_name = "'.mysql_real_escape_string($blog_name).'", + timestamp = '.mysqldate(time()).' + WHERE + url = "'.mysql_real_escape_string($url).'" AND + tb_id = "'.$tb_id.'" + '); +*/ +//modify start+++++++++ + $rows = mysql_fetch_assoc($res); + $spam = ( $rows['block'] || $rows['spam'] ) ? true : false; + $res = @sql_query(' + UPDATE + '.sql_table('plugin_tb').' + SET + title = \''.mysql_real_escape_string($title).'\', + excerpt = \''.mysql_real_escape_string($excerpt).'\', + blog_name = \''.mysql_real_escape_string($blog_name).'\', + timestamp = '.mysqldate($b->getCorrectTime()).' + WHERE + url = \''.mysql_real_escape_string($url).'\' AND + tb_id = \''.mysql_real_escape_string(intval($tb_id)).'\' + '); +//modify end+++++++++ + + if (!$res) { + return 'Could not update trackback data: '.mysql_error(); + } + } + else + { +//mod by cles + // spam block + $res = @sql_query('SELECT id FROM '.sql_table('plugin_tb').' WHERE block = 1 and url = \''.mysql_real_escape_string($url).'\'' ); + if (mysql_num_rows($res) != 0) { + // NP_Trackback has blocked tb ! + ACTIONLOG :: add(INFO, "Trackback: Duplicated Blocked Trackback [ignore] (itemid:$tb_id from: $url)"); + return 'Sorry, trackback ping is not accepted.'; + } +//mod by cles end + + // 4. SPAM check (for SpamCheck API 2 /w compat. API 1) + $spamcheck = array ( + 'type' => 'trackback', + 'id' => $tb_id, + 'title' => $title, + 'excerpt' => $excerpt, + 'blogname' => $blog_name, + 'url' => $url, + 'return' => true, + 'live' => true, + + /* Backwards compatibility with SpamCheck API 1*/ + 'data' => $url . "\n" . $title . "\n" . $excerpt . "\n" . $blog_name . "\n" . serverVar('HTTP_USER_AGENT'), + 'ipblock' => true, + ); + + $manager->notify('SpamCheck', array ('spamcheck' => & $spamcheck)); + + if (isset($spamcheck['result']) && $spamcheck['result'] == true) + { + $spam = true; + } + + // 5. Content check (TO DO) + if($spam == false || $enableLinkCheck == 'ignore' ) //modify + { +//mod by cles +// $contents = $this->retrieveUrl ($url); +// +// if (preg_match("/(".preg_quote($_SERVER["REQUEST_URI"], '/').")|(".preg_quote($_SERVER["SERVER_NAME"], '/').")/i", $contents)) { +// $link = true; +// } + if( $enableLinkCheck ){ + $contents = $this->retrieveUrl($url); + + $linkArray = $this->getPermaLinksFromText($contents); + + if( defined('NP_TRACKBACK_LINKCHECK_STRICT') ) + $itemLink = $this->_createItemLink($tb_id, $b); + else + $itemLink = $b->getURL(); + + $itemLinkPat = '{^' . preg_quote($itemLink) .'}i'; + $itemLinkPat = str_replace('&','&(amp;)?', $itemLinkPat); + + foreach($linkArray as $l) { + if(preg_match($itemLinkPat, $l)){ + ACTIONLOG :: add(INFO, "Trackback: LinkCheck OK. (link: $l pat: $itemLinkPat )"); + $link = true; + break; + } + } + if( ! $link ){ + $cnt = @count($linkArray); + if( $enableLinkCheck == 'ignore' ){ + ACTIONLOG :: add(INFO, "Trackback: LinkCheck NG. [ignore] (itemid:$tb_id from: $url cnt: $cnt pat: $itemLinkPat)"); + return 'Sorry, trackback ping is not accepted.'; + } else { + ACTIONLOG :: add(INFO, "Trackback: LinkCheck NG. [block] (itemid:$tb_id from: $url cnt: $cnt pat: $itemLinkPat"); + } + } + } +//mod by cles end + } + + // 6. Determine if Trackback is safe... +//modify start+++++++++ +// $block = $spam == true || $link == false; +// $block = $spam == true ; +//modify end+++++++++ +//mod by cles + if ( $enableLinkCheck ) + $block = ($spam == true || $link == false); + else + $block = $spam == true ; +//mod by cles end + // New TB, insert it +/* + $query = ' + INSERT INTO + '.sql_table('plugin_tb').' + SET + tb_id = "'.$tb_id.'", + block = "'.($block ? '1' : '0').'", + spam = "'.($spam ? '1' : '0').'", + link = "'.($link ? '1' : '0').'", + url = "'.mysql_real_escape_string($url).'", + title = "'.mysql_real_escape_string($title).'", + excerpt = "'.mysql_real_escape_string($excerpt).'", + blog_name = "'.mysql_real_escape_string($blog_name).'", + timestamp = '.mysqldate(time()).' + '; +*/ +//modify start+++++++++ + $query = ' + INSERT INTO + '.sql_table('plugin_tb').' + SET + tb_id = \''.mysql_real_escape_string(intval($tb_id)).'\', + block = \''.($block ? '1' : '0').'\', + spam = \''.($spam ? '1' : '0').'\', + link = \''.($link ? '1' : '0').'\', + url = \''.mysql_real_escape_string($url).'\', + title = \''.mysql_real_escape_string($title).'\', + excerpt = \''.mysql_real_escape_string($excerpt).'\', + blog_name = \''.mysql_real_escape_string($blog_name).'\', + timestamp = '.mysqldate($b->getCorrectTime()).' + '; +//modify end+++++++++ + + $res = @sql_query($query); + + if (!$res) { + return 'Could not save trackback data, possibly because of a double entry: ' . mysql_error() . $query; + } + } + + // 7. Send notification e-mail if needed + $notifyAddrs = $this->getOption('NotifyEmail'); + $notifyAddrs = ( $notifyAddrs ? $notifyAddrs . ';' : '') + . $this->getBlogOption($blogId ,'NotifyEmailBlog'); + + if ($notifyAddrs && $spam == false) + { + + $vars = array ( + 'tb_id' => $tb_id, + 'url' => $url, + 'title' => $title, + 'excerpt' => $excerpt, + 'blogname' => $blog_name + ); + +//modify start+++++++++ +/* + $vars = array ( + 'tb_id' => $tb_id, + 'url' => $url, + 'title' => mb_convert_encoding($title, 'ISO-2022-JP', _CHARSET), + 'excerpt' => mb_convert_encoding($excerpt, 'ISO-2022-JP', _CHARSET), + 'blogname' => mb_convert_encoding($blog_name, 'ISO-2022-JP', _CHARSET) + ); +*/ +//maybe not needed because japanese version has "mb_send_mail" in function notify +//modify end+++++++++ + + $mailto_title = TEMPLATE::fill($this->notificationMailTitle, $vars); + $mailto_msg = TEMPLATE::fill($this->notificationMail, $vars); + + global $CONF, $DIR_LIBS; + + // make sure notification class is loaded + if (!class_exists('notification')) + include($DIR_LIBS . 'NOTIFICATION.php'); + + $notify = new NOTIFICATION($notifyAddrs); + $notify->notify($mailto_title, $mailto_msg , $CONF['AdminEmail']); + +//mod by cles+++++++++++ + if ($manager->pluginInstalled('NP_Cache')){ + $p =& $manager->getPlugin('NP_Cache'); + $p->setCurrentBlog($tb_id); + $p->cleanItem($tb_id); + $p->cleanArray(array('index')); + } +//mod by cles end +++++++++++ + } + + if( $block ) + return 'Sorry, trackback ping is not accepted.'; + return ''; + } + + function xmlResponse($errorMessage = '') + { + header('Content-type: application/xml; charset=utf-8'); + echo "<"."?xml version='1.0' encoding='UTF-8'?".">\n"; + echo "\n"; + + if ($errorMessage){ + if (_CHARSET != 'UTF-8') + $errorMessage = mb_convert_encoding($errorMessage, 'UTF-8'); + echo "1\n"; + echo "".htmlspecialchars($errorMessage, ENT_QUOTES)."\n"; + } else { + echo "0\n"; + } + + echo ""; + exit; + } + + /* + * Check if member may send ping (check if logged in) + */ + function canSendPing() { + global $member; + return $member->isLoggedIn() || $this->xmlrpc; + } + + +//mod by cles + function redirect($tb_id, $urlHash){ + global $CONF; + $query = 'SELECT url FROM '.sql_table('plugin_tb').' WHERE tb_id='.intval($tb_id).' and md5(url)="'.$urlHash.'"'; + $res = sql_query($query); + + $url = $CONF['SiteURL']; + + if ($o = mysql_fetch_object($res)) { + $url = htmlspecialchars($o->url, ENT_QUOTES); + } + + $url = stripslashes($url); + $url = str_replace('&','&',$url); + $url = str_replace('<','<',$url); + $url = str_replace('>','>',$url); + $url = str_replace('"','"',$url); + + header('Location: '.$url); + } + + function getRequiredURL($itemid){ + global $manager; + $blog = & $manager->getBlog(getBlogIDFromItemID($itemid)); + if( $this->isEnableLinkCheck($itemid) ) + return $this->_createItemLink($itemid, $blog); + return null; + } + + function isEnableLinkCheck($itemid){ + $blogid = getBlogIDFromItemID($itemid); + + switch( $this->getItemOption($itemid, 'isAcceptW/OLink') ){ + case 'default': + $def = $this->getBlogOption($blogid, 'isAcceptW/OLinkDef'); + if($def == 'yes') + return false; + else + return $def; // block or ignore + case 'yes': + return false; + case 'no': + return true; + default : + ACTIONLOG :: add(INFO, "Trackback: Unknown Option (itemid:$itemid, value:$val)"); + return false; + } + } + + function isAcceptTrackBack($itemid = null){ + $ret = false; + if( $this->getOption('AcceptPing') == 'yes' ){ + $bid = null; + if($itemid){ + $bid = getBlogIDFromItemID(intval($itemid)); + } else { + global $blog; + $bid = $blog->getID(); + } + + if( $this->getBlogOption($bid, "AllowTrackBack") == 'yes' ){ + if( $itemid ){ + $ret = ( $this->getItemOption(intval($itemid), 'ItemAcceptPing') == 'yes' ) ? true : false ; + } else { + $ret = true; + } + } else { + $ret = false; + } + } + return $ret; + } + +//mod by cles end + + /************************************************************************************** + * EVENTS + */ + + function event_SendTrackback($data) { + global $manager; + + // Enable sending trackbacks for the XML-RPC API, otherwise we would + // get an error because the current user is not exactly logged in. + $this->xmlrpc = true; + + $itemid = $data['tb_id']; + $item = &$manager->getItem($itemid, 0, 0); + if (!$item) return; // don't ping for draft & future + if ($item['draft']) return; // don't ping on draft items + + // gather some more information, needed to send the ping (blog name, etc) + $blog =& $manager->getBlog(getBlogIDFromItemID($itemid)); + $blog_name = $blog->getName(); + + $title = $data['title'] != '' ? $data['title'] : $item['title']; + $title = strip_tags($title); + + $excerpt = $data['body'] != '' ? $data['body'] : $item['body']; + $excerpt = strip_tags($excerpt); + $excerpt = $this->_cut_string($excerpt, 200); + + $CONF['ItemURL'] = preg_replace('/\/$/', '', $blog->getURL()); + //$url = createItemLink($itemid); + $url = $this->_createItemLink($itemid, $blog); + + while (list(,$url) = each($data['urls'])) { + $res = $this->sendPing($itemid, $title, $url, $excerpt, $blog_name, $url); + if ($res) ACTIONLOG::add(WARNING, 'TrackBack Error:' . $res . ' (' . $url . ')'); + } + } + + function event_RetrieveTrackback($data) { + + $res = sql_query(' + SELECT + url, + title, + UNIX_TIMESTAMP(timestamp) AS timestamp + FROM + '.sql_table('plugin_tb').' + WHERE + tb_id = '.intval($data['tb_id']).' AND + block = 0 + ORDER BY + timestamp ASC + '); + + while ($row = mysql_fetch_array($res)) { + + $trackback = array( + 'title' => $row['title'], + 'url' => $row['url'], + 'ip' => '' + ); + + $data['trackbacks'][] = $trackback; + } + } +/* + function event_BookmarkletExtraHead($data) { + global $NP_TB_URL; + list ($NP_TB_URL,) = $this->getURIfromLink(requestVar('loglink')); + } +*/ + function event_PrepareItemForEdit($data) { +// if (!$this->getOption('AutoXMLHttp')) + if ($this->getOption('AutoXMLHttp') == 'no') + { + // The space between body and more is to make sure we didn't join 2 words accidently.... + $this->larray = $this->autoDiscovery($data['item']['body'].' '.$data['item']['more']); + } + } + + /* + * After an item has been added to the database, send out a ping if requested + * (trackback_ping_url variable in request) + */ + function event_PostAddItem($data) { + $this->pingTrackback($data); + } + + function event_PreUpdateItem($data) { + $this->pingTrackback($data); + } + + /** + * Add trackback options to add item form/bookmarklet + */ + function event_AddItemFormExtras($data) { + +// global $NP_TB_URL; + + ?> +

TrackBack

+

+ + + +
+ + + +
+ + getOption('AutoXMLHttp')) + if ($this->getOption('AutoXMLHttp') == 'yes') + { + ?> +

+ +
+
+
+ +
+ + jsautodiscovery(); + } + ?> +

+ + +

TrackBack

+

+
+ + + + getOption('AutoXMLHttp')) + if ($this->getOption('AutoXMLHttp') == 'yes') + { + ?> + + +

+ +
+
+
+ +
+ + jsautodiscovery(); + } + else + { + if (count($this->larray) > 0) + { + ?> + Auto Discovered Ping URL's:
+ larray).'" />'; + + $i = 0; + + while (list($url, $title) = each ($this->larray)) + { +//modify start+++++++++ + if (_CHARSET != 'UTF-8') { + $title = $this->_utf8_to_entities($title); + $title = mb_convert_encoding($title, _CHARSET, 'UTF-8'); + } +//modify end+++++++++ + + echo '
'; + + $i++; + } + } + } + ?> +

+ + + getItem($itemid, 0, 0); + if (!$item) return; // don't ping for draft & future + if ($item['draft']) return; // don't ping on draft items + + // gather some more information, needed to send the ping (blog name, etc) + $blog =& $manager->getBlog(getBlogIDFromItemID($itemid)); + $blog_name = $blog->getName(); + + $title = $data['title'] != '' ? $data['title'] : $item['title']; + $title = strip_tags($title); + + $excerpt = $data['body'] != '' ? $data['body'] : $item['body']; + $excerpt = strip_tags($excerpt); + $excerpt = $this->_cut_string($excerpt, 200); + +/* + $CONF['ItemURL'] = preg_replace('/\/$/', '', $blog->getURL()); + $url = createItemLink($itemid); +*/ + $url = $this->_createItemLink($item['itemid'],$blog); + + // send the ping(s) (add errors to actionlog) + for ($i=0; $isendPing($itemid, $title, $url, $excerpt, $blog_name, $ping_urls[$i]); + else + $res = $this->handleLocalPing($itemid, $title, $excerpt, $blog_name, $ping_urls[$i]); + if ($res) ACTIONLOG::add(WARNING, 'TrackBack Error:' . $res . ' (' . $ping_urls[$i] . ')'); + } + } + + + + + /************************************************************************************** + * AUTO-DISCOVERY + */ + + /* + * Auto-Discovery of TrackBack Ping URLs based on HTML story + */ + function autoDiscovery($text) + { + $links = $this->getPermaLinksFromText($text); + $result = array(); + + for ($i = 0; $i < count($links); $i++) + { + list ($url, $title) = $this->getURIfromLink($links[$i]); + + if ($url != '') + $result[$url] = $title; + } + + return $result; + } + + /* + * Auto-Discovery of TrackBack Ping URLs based on single link + */ + function getURIfromLink($link) + { + + // Check to see if the cache contains this link + $res = sql_query('SELECT url, title FROM '.sql_table('plugin_tb_lookup').' WHERE link=\''.mysql_real_escape_string($link).'\''); + + if ($row = mysql_fetch_array($res)) + { + if ($row['title'] != '') + { +//modify start+++++++++ + if (_CHARSET != 'UTF-8'){ + $row['title'] = mb_convert_encoding($row['title'], 'UTF-8', _CHARSET); + $row['title'] = $this->_decode_entities($row['title']); + } +//modify end+++++++++ + return array ( + $row['url'], $row['title'] + ); + } + else + { + return array ( + $row['url'], $row['url'] + ); + } + } + + // Retrieve RDF + if (($rdf = $this->getRDFFromLink($link)) !== false) + { + // Get PING attribute + if (($uri = $this->getAttributeFromRDF($rdf, 'trackback:ping')) !== false) + { + // Get TITLE attribute + if (($title = $this->getAttributeFromRDF($rdf, 'dc:title')) !== false) + { + // Get CREATOR attribute + if (($author = $this->getAttributeFromRDF($rdf, 'dc:creator')) !== false) + { + $title = $author. ": " . $title; + } + + $uri = $this->_decode_entities($uri); +//modify start+++++++++ + if (_CHARSET != 'UTF-8') + $convertedTitle = mb_convert_encoding($title, _CHARSET, 'UTF-8'); + else + $convertedTitle = $title; +/* + // Store in cache + $res = sql_query("INSERT INTO ".sql_table('plugin_tb_lookup')." (link, url, title) VALUES ('".mysql_real_escape_string($link)."','".mysql_real_escape_string($uri)."','".mysql_real_escape_string($title)."')"); +*/ + // Store in cache + $res = sql_query("INSERT INTO ".sql_table('plugin_tb_lookup')." (link, url, title) VALUES ('".mysql_real_escape_string($link)."','".mysql_real_escape_string($uri)."','".mysql_real_escape_string($convertedTitle)."')"); +//modify end+++++++++ + $title = $this->_decode_entities($title); + + return array ( + $uri, $title + ); + } + else + { + $uri = html_entity_decode($uri, ENT_COMPAT); + + // Store in cache + $res = sql_query("INSERT INTO ".sql_table('plugin_tb_lookup')." (link, url, title) VALUES ('".mysql_real_escape_string($link)."','".mysql_real_escape_string($uri)."','')"); + + return array ( + $uri, $uri + ); + } + } + } + + // Store in cache + $res = sql_query("INSERT INTO ".sql_table('plugin_tb_lookup')." (link, url, title) VALUES ('".mysql_real_escape_string($link)."','','')"); + + return array ('', ''); + } + + /* + * Detect links used in HTML code + */ + function getPermaLinksFromText($text) + { + $links = array(); + + if (preg_match_all('/]+)>/i', $text, $array, PREG_SET_ORDER)) + { + $count = count($array); + for ($i = 0; $i < $count; $i++) + { + if( preg_match('/https?:\/\/[-_.!~*\'()a-z0-9;\/?:@&=+$,%]+/i', $array[$i][1], $matches) ) + $links[$matches[0]] = 1; + } + } + + return array_keys($links); + } + + /* + * Retrieve RDF code from external link + */ + function getRDFFromLink($link) + { + if ($content = $this->getContents($link)) + { + preg_match_all('/()/sm', $content, $rdfs, PREG_SET_ORDER); + + if (count($rdfs) > 1) + { + for ($i = 0; $i < count($rdfs); $i++) + { + if (preg_match('|dc:identifier="'.preg_quote($link).'"|ms',$rdfs[$i][1])) + { + return $rdfs[$i][1]; + } + } + } + else + { + // No need to check the identifier + return $rdfs[0][1]; + } + } + + return false; + } + + /** + * Retrieve the contents of an external (X)HTML document + */ + function getContents($link) { + + // Use cURL extention if available + if (function_exists("curl_init") && $this->useCurl == 2) + { + // Make HEAD request + $ch = curl_init(); + @curl_setopt($ch, CURLOPT_URL, $link); + @curl_setopt($ch, CURLOPT_HEADER, true); + @curl_setopt($ch, CURLOPT_NOBODY, true); + @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + @curl_setopt($ch, CURLOPT_MAXREDIRS, 5); + @curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + @curl_setopt($ch, CURLOPT_TIMEOUT, 20); + @curl_setopt($ch, CURLOPT_USERAGENT, $this->userAgent); + + $headers = curl_exec($ch); + curl_close($ch); + + // Check if the link points to a (X)HTML document + if (preg_match('/Content-Type: (text\/html|application\/xhtml+xml)/i', $headers)) + { + return $this->retrieveUrl ($link); + } + + return false; + } + else + { + return $this->retrieveUrl ($link); + } + } + + /* + * Get a single attribute from RDF + */ + function getAttributeFromRDF($rdf, $attribute) + { + if (preg_match('/'.$attribute.'="([^"]+)"/', $rdf, $matches)) + { + return $matches[1]; + } + + return false; + } + + + + + + + /**************************************************************************************/ + /* Internal helper functions for dealing with external file retrieval */ + + function retrieveUrl ($url) { +//mod by cles + $ua = ini_set('user_agent', $this->userAgent); +//mod by cles end + if (function_exists('curl_init') && $this->useCurl > 0) + { + // Set options + $ch = curl_init(); + @curl_setopt($ch, CURLOPT_URL, $url); + @curl_setopt($ch, CURLOPT_HEADER, 1); + @curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + @curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); + @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); + @curl_setopt($ch, CURLOPT_MAXREDIRS, 5); + @curl_setopt($ch, CURLOPT_TIMEOUT, 20); + @curl_setopt($ch, CURLOPT_USERAGENT, $this->userAgent); + + // Retrieve response + $raw = curl_exec($ch); + $info = curl_getinfo($ch); + + // Split into headers and contents + $headers = substr($raw, 0, $info['header_size']); + $contents = substr($raw, $info['header_size']); + + curl_close($ch); + } + elseif ($fp = @fopen ($url, "rb")) + { +//mod by cles +// $contents = fread($fp, 8192); + $contents = ''; + while (!feof($fp)) { + $contents .= fread($fp, 8192); + } +//mod by cles end + $headers = ''; + + fclose($fp); + } +//mod by cles + ini_set('user_agent', $ua); +//mod by cles end + + // Next normalize the encoding to UTF8... + $contents = $this->_convert_to_utf8_auto($contents, $headers); + + return $contents; + } + + + /**************************************************************************************/ + /* Internal helper functions for dealing with encodings and entities */ + + var $entities_default = array ( + '"' => '"', + '&' => '&', + ''' => ''', + '<' => '<', + '>' => '>', + ); + +//modify start+++++++++ + function _restore_to_utf8($contents) + { + if (_CHARSET != 'UTF-8') + { + $contents = mb_convert_encoding($contents, 'UTF-8', _CHARSET); + } + $contents = $this->_decode_entities(strip_tags($contents)); + return $contents; + } +//modify end+++++++++ + function _detect_encoding($string) + { +//modify start+++++++++ + if (function_exists('mb_convert_encoding')) { + $encoding = (preg_match ("/;\s*charset=([^\n]+)/is", serverVar("CONTENT_TYPE"), $regs))? + strtoupper(trim($regs[1])): + ''; + + if ( ($encoding !="") && ((mb_http_input("P") == "") || ( strtolower( ini_get("mbstring.http_input") ) == "pass")) ) { + return $encoding; + } else { + $encoding = mb_detect_encoding($string, NP_TRACKBACK_ENCODING_DETECT_ORDER); + } + return ( $encoding ) ? $encoding : _CHARSET; + } +//modify end+++++++++ + if (!ereg("[\x80-\xFF]", $string) && !ereg("\x1B", $string)) + return 'US-ASCII'; + + if (!ereg("[\x80-\xFF]", $string) && ereg("\x1B", $string)) + return 'ISO-2022-JP'; + + if (preg_match("/^([\x01-\x7F]|[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF][\x80-\xBF])+$/", $string) == 1) + return 'UTF-8'; + + if (preg_match("/^([\x01-\x7F]|\x8E[\xA0-\xDF]|\x8F[xA1-\xFE][\xA1-\xFE]|[\xA1-\xFE][\xA1-\xFE])+$/", $string) == 1) + return 'EUC-JP'; + + if (preg_match("/^([\x01-\x7F]|[\xA0-\xDF]|[\x81-\xFC][\x40-\xFC])+$/", $string) == 1) + return 'Shift_JIS'; + + return 'ISO-8859-1'; + } + + function _convert_to_utf8($contents, $encoding) + { + $done = false; + +//modify start+++++++++ +// if (!$done && function_exists('iconv')) +// { +// +// $result = @iconv($encoding, 'UTF-8//IGNORE', $contents); +// +// if ($result) +// { +// $contents = $result; +// $done = true; +// } +// } + + if(!$done && function_exists('mb_convert_encoding')) + { + + if( function_exists('mb_substitute_character') ){ + @mb_substitute_character('none'); + } + $result = @mb_convert_encoding($contents, 'UTF-8', $encoding ); + + if ($result) + { + $contents = $result; + $done = true; + } + } + + if (!$done && function_exists('iconv')) + { + + $result = @iconv($encoding, 'UTF-8//IGNORE', $contents); + + if ($result) + { + $contents = $result; + $done = true; + } + } +//modify end+++++++++ + return $contents; + } + + function _convert_to_utf8_auto($contents, $headers = '') + { + /* IN: string in unknown encoding, headers received during transfer + * OUT: string in UTF-8 encoding + */ + + $str = substr($contents, 0, 4096); + $len = strlen($str); + $pos = 0; + $out = ''; + + while ($pos < $len) + { + $ord = ord($str[$pos]); + + if ($ord > 32 && $ord < 128) + $out .= $str[$pos]; + + $pos++; + } + + // Detection of encoding, check headers + if (preg_match ("/;\s*charset=([^\n]+)/is", $headers, $regs)) + $encoding = strtoupper(trim($regs[1])); + + // Then check meta inside document + if (preg_match ("/;\s*charset=([^\"']+)/is", $out, $regs)) + $encoding = strtoupper(trim($regs[1])); + + // Then check xml declaration + if (preg_match("/<\?xml.+encoding\s*=\s*[\"|']([^\"']+)[\"|']\s*\?>/i", $out, $regs)) + $encoding = strtoupper(trim($regs[1])); + + // Converts + return $this->_convert_to_utf8($contents, $encoding); + } + + function _decode_entities($string) + { + /* IN: string in UTF-8 containing entities + * OUT: string in UTF-8 without entities + */ + + /// Convert all hexadecimal entities to decimal entities + $string = preg_replace('/&#[Xx]([0-9A-Fa-f]+);/e', "'&#'.hexdec('\\1').';'", $string); + + global $_entities; + // Deal with invalid cp1251 numeric entities + $string = strtr($string, $_entities['cp1251']); + + // Convert all named entities to numeric entities + $string = strtr($string, $this->entities_default); + $string = strtr($string, $_entities['named']); + + // Convert all numeric entities to UTF-8 + $string = preg_replace('/&#([0-9]+);/e', "'&#x'.dechex('\\1').';'", $string); + $string = preg_replace('/&#[Xx]([0-9A-Fa-f]+);/e', "NP_TrackBack::_hex_to_utf8('\\1')", $string); + + return $string; + } + + function _hex_to_utf8($s){ + return entity::_hex_to_utf8($s); + } + + function _utf8_to_entities($string) + { + /* IN: string in UTF-8 encoding + * OUT: string consisting of only characters ranging from 0x00 to 0x7f, + * using numeric entities to represent the other characters + */ + + $len = strlen ($string); + $pos = 0; + $out = ''; + + while ($pos < $len) + { + $ascii = ord (substr ($string, $pos, 1)); + + if ($ascii >= 0xF0) + { + $byte[1] = ord(substr ($string, $pos, 1)) - 0xF0; + $byte[2] = ord(substr ($string, $pos + 1, 1)) - 0x80; + $byte[3] = ord(substr ($string, $pos + 2, 1)) - 0x80; + $byte[4] = ord(substr ($string, $pos + 3, 1)) - 0x80; + + $char_code = ($byte[1] << 18) + ($byte[2] << 12) + ($byte[3] << 6) + $byte[4]; + $pos += 4; + } + elseif (($ascii >= 0xE0) && ($ascii < 0xF0)) + { + $byte[1] = ord(substr ($string, $pos, 1)) - 0xE0; + $byte[2] = ord(substr ($string, $pos + 1, 1)) - 0x80; + $byte[3] = ord(substr ($string, $pos + 2, 1)) - 0x80; + + $char_code = ($byte[1] << 12) + ($byte[2] << 6) + $byte[3]; + $pos += 3; + } + elseif (($ascii >= 0xC0) && ($ascii < 0xE0)) + { + $byte[1] = ord(substr ($string, $pos, 1)) - 0xC0; + $byte[2] = ord(substr ($string, $pos + 1, 1)) - 0x80; + + $char_code = ($byte[1] << 6) + $byte[2]; + $pos += 2; + } + else + { + $char_code = ord(substr ($string, $pos, 1)); + $pos += 1; + } + + if ($char_code < 0x80) + $out .= chr($char_code); + else + $out .= '&#'. str_pad($char_code, 5, '0', STR_PAD_LEFT) . ';'; + } + + return $out; + } + + function _utf8_to_javascript($string) + { + /* IN: string in UTF-8 encoding + * OUT: string consisting of only characters ranging from 0x00 to 0x7f, + * using javascript escapes to represent the other characters + */ + + $len = strlen ($string); + $pos = 0; + $out = ''; + + while ($pos < $len) + { + $ascii = ord (substr ($string, $pos, 1)); + + if ($ascii >= 0xF0) + { + $byte[1] = ord(substr ($string, $pos, 1)) - 0xF0; + $byte[2] = ord(substr ($string, $pos + 1, 1)) - 0x80; + $byte[3] = ord(substr ($string, $pos + 2, 1)) - 0x80; + $byte[4] = ord(substr ($string, $pos + 3, 1)) - 0x80; + + $char_code = ($byte[1] << 18) + ($byte[2] << 12) + ($byte[3] << 6) + $byte[4]; + $pos += 4; + } + elseif (($ascii >= 0xE0) && ($ascii < 0xF0)) + { + $byte[1] = ord(substr ($string, $pos, 1)) - 0xE0; + $byte[2] = ord(substr ($string, $pos + 1, 1)) - 0x80; + $byte[3] = ord(substr ($string, $pos + 2, 1)) - 0x80; + + $char_code = ($byte[1] << 12) + ($byte[2] << 6) + $byte[3]; + $pos += 3; + } + elseif (($ascii >= 0xC0) && ($ascii < 0xE0)) + { + $byte[1] = ord(substr ($string, $pos, 1)) - 0xC0; + $byte[2] = ord(substr ($string, $pos + 1, 1)) - 0x80; + + $char_code = ($byte[1] << 6) + $byte[2]; + $pos += 2; + } + else + { + $char_code = ord(substr ($string, $pos, 1)); + $pos += 1; + } + + if ($char_code < 0x80) + $out .= chr($char_code); + else + $out .= '\\u'. str_pad(dechex($char_code), 4, '0', STR_PAD_LEFT); + } + + return $out; + } +/* + function _cut_string($string, $dl = 0) { + + $defaultLength = $dl > 0 ? $dl : $this->getOption('defaultLength'); + + if ($defaultLength < 1) + return $string; + + $border = 6; + $count = 0; + $lastvalue = 0; + + for ($i = 0; $i < strlen($string); $i++) + { + $value = ord($string[$i]); + + if ($value > 127) + { + if ($value >= 192 && $value <= 223) + $i++; + elseif ($value >= 224 && $value <= 239) + $i = $i + 2; + elseif ($value >= 240 && $value <= 247) + $i = $i + 3; + + if ($lastvalue <= 223 && $value >= 223 && + $count >= $defaultLength - $border) + { + return substr($string, 0, $i) . '...'; + } + + // Chinese and Japanese characters are + // wider than Latin characters + if ($value >= 224) + $count++; + + } + elseif ($string[$i] == '/' || $string[$i] == '?' || + $string[$i] == '-' || $string[$i] == ':' || + $string[$i] == ',' || $string[$i] == ';') + { + if ($count >= $defaultLength - $border) + return substr($string, 0, $i) . '...'; + } + elseif ($string[$i] == ' ') + { + if ($count >= $defaultLength - $border) + return substr($string, 0, $i) . '...'; + } + + if ($count == $defaultLength) + return substr($string, 0, $i + 1) . '...'; + + $lastvalue = $value; + $count++; + } + + return $string; + } +*/ + +function _cut_string($string, $dl = 0) { + $maxLength = $dl > 0 ? $dl : $this->getOption('defaultLength'); + + if ($maxLength < 1) + return $string; + if (strlen($string) > $maxLength) + $string = mb_strimwidth($string, 0, $maxLength, '...', _CHARSET); + + return $string; +} + +function _strip_controlchar($string){ + $string = preg_replace("/[\x01-\x08\x0b\x0c\x0e-\x1f\x7f]+/","",$string); + $string = str_replace("\0","",$string); + return $string; +} + +//modify start+++++++++ + function checkTableVersion(){ + $res = sql_query("SHOW FIELDS from ".sql_table('plugin_tb') ); + $fieldnames = array(); + while ($co = mysql_fetch_assoc($res)) { + if($co['Field'] == 'block') return true; + } + return false; + } +//modify end+++++++++ + +/*---------------------------------------------------------------------------------- */ +/* LOCAL */ +/*---------------------------------------------------------------------------------- */ + /** + * Handle an incoming TrackBack ping and save the data in the database + */ + function handleLocalPing($itemid, $title, $excerpt, $blog_name, $ping_url){ + global $manager; + $ping_url = trim($ping_url); + + if( preg_match("/^.+tb_id=([0-9]+)$/",$ping_url,$idnum) ){ + $tb_id = intval($idnum[1]); + } elseif ( preg_match("/([0-9]+)\.trackback/",$ping_url,$idnum) ){ + $tb_id = intval($idnum[1]); + } elseif ( preg_match("/itemid=([0-9]+)/",$ping_url,$idnum) ){ + $tb_id = intval($idnum[1]); + } + + if ((!$manager->existsItem($tb_id,0,0)) && ($this->getOption('CheckIDs') == 'yes')) + return _ERROR_NOSUCHITEM . "[ $tb_id ]"; + + // save data in the DB + $query = 'INSERT INTO ' . sql_table('plugin_tb_lc') . " (tb_id, from_id) VALUES ('".intval($tb_id)."','".intval($itemid)."')"; + $res = @sql_query($query); + if (!$res) + return 'Could not save trackback data, possibly because of a double entry: ' . mysql_error(); + } + + /** + * Show the list of TrackBack pings for a certain Trackback ID + */ + function showLocalList($tb_id) { + global $CONF, $manager; + + // create SQL query + $query = 'SELECT t.from_id as from_id , i.ititle as ititle, i.ibody as ibody, i.itime as itime, i.iblog as iblog FROM '.sql_table('plugin_tb_lc').' as t, '.sql_table('item').' as i WHERE t.tb_id='.intval($tb_id) .' and i.inumber=t.from_id ORDER BY i.itime DESC'; + $res = sql_query($query); + + $vars = array( + 'tburl' => $this->getTrackBackUrl($tb_id) + ); + + // when no TrackBack pings are found + if (!$res || mysql_num_rows($res) == 0) { + echo TEMPLATE::fill($this->getOption('tplLocalEmpty'), $vars); + return; + } + + // when TrackBack pings are found + echo TEMPLATE::fill($this->getOption('tplLocalHeader'), $vars); + + while ($o = mysql_fetch_object($res)) { + $canDelete = $this->canDelete($tb_id); + $data = array( + 'url' => createItemLink($o->from_id), + 'blogname' => htmlspecialchars(getBlogNameFromID($o->iblog)), + 'timestamp' => strftime('%Y-%m-%d',strtotime($o->itime)), + 'title' => htmlspecialchars($o->ititle), + 'excerpt' => htmlspecialchars(shorten(strip_tags($o->ibody),200,'...')), + 'delete' => $canDelete?'[delete]':'', + 'tburl' => $this->getTrackBackUrl($tb_id), + 'commentcount'=> quickQuery('SELECT COUNT(*) as result FROM '.sql_table('comment').' WHERE citem=' . intval($o->from_id)) + ); + echo TEMPLATE::fill($this->getOption('tplLocalItem'), $data); + } + echo TEMPLATE::fill($this->getOption('tplLocalFooter'), $vars); + } + + /** + * Delete a TrackBack item, redirect to referer + */ + function deleteLocal($tb_id, $from_id) { + if (!$this->canDelete($tb_id)) + return 'You\'re not allowed to delete this trackback item'; + $query = 'DELETE FROM ' . sql_table('plugin_tb_lc') . " WHERE tb_id='" . intval($tb_id) . "' and from_id='" . intval($from_id) ."'"; + sql_query($query); + return ''; + } + + function canDelete($tb_id) { + global $member, $manager; + + if ( ! $member->isLoggedIn() ) return 0; + + $checkIDs = $this->getOption('CheckIDs'); + $itemExists =& $manager->existsItem($tb_id,0,0); + + // if CheckIDs option is set, check if member canEdit($tb_id) + // if CheckIDs option is not set, and item exists, check if member canEdit($tb_id) + // if CheckIDs option is not set, and item does not exists, check if member isAdmin() + + if (($checkIDs == 'yes') || ($itemExists)) + return $member->canAlterItem($tb_id); + else + return $member->isAdmin(); + } + + /**************************************************************************************/ + /* Plugin API calls, for installation, configuration and setup */ + + function getName() { return 'TrackBack'; } + function getAuthor() { return 'rakaz + nakahara21 + hsur'; } + function getURL() { return 'http://blog.cles.jp/np_cles/category/31/subcatid/3'; } + function getVersion() { return '2.0.3 jp13'; } + function getDescription() { return '[$Revision: 1.311 $]
' . _TB_DESCRIPTION; } + +//modify start+++++++++ +/* + function getTableList() { return array(sql_table("plugin_tb"), sql_table("plugin_tb_lookup")); } + function getEventList() { return array('QuickMenu','PostAddItem','AddItemFormExtras','EditItemFormExtras','PreUpdateItem','PrepareItemForEdit', 'BookmarkletExtraHead'); } +*/ + function getTableList() { return array(sql_table("plugin_tb"), sql_table("plugin_tb_lookup"), sql_table('plugin_tb_lc')); } + + function getEventList() { return array('QuickMenu','PostAddItem','AddItemFormExtras','EditItemFormExtras','PreUpdateItem','PrepareItemForEdit', 'BookmarkletExtraHead', 'RetrieveTrackback', 'SendTrackback', 'InitSkinParse'); } +//modify end+++++++++ + function getMinNucleusVersion() { return 330; } + + function supportsFeature($feature) { + switch($feature) { + case 'SqlTablePrefix': + return 1; +//modify start+++++++++ +// case 'HelpPage': +// return 1; +//modify end+++++++++ + default: + return 0; + } + } + + + function hasAdminArea() { return 1; } + + function event_QuickMenu(&$data) { + global $member, $nucleus, $blogid; + + // only show to admins + if (!$member->isLoggedIn()) return; + + array_push( + $data['options'], + array( + 'title' => 'Trackback', + 'url' => $this->getAdminURL(), + 'tooltip' => 'Manage your trackbacks' + ) + ); + } + + function install() { + $this->createOption('AcceptPing', _TB_AcceptPing,'yesno','yes'); + $this->createOption('SendPings', _TB_SendPings,'yesno','yes'); + $this->createOption('AutoXMLHttp', _TB_AutoXMLHttp, 'yesno', 'yes'); + $this->createOption('CheckIDs', _TB_CheckIDs,'yesno','yes'); + + $this->createOption('tplHeader', _TB_tplHeader, 'textarea', _TB_tplHeader_VAL); + $this->createOption('tplEmpty', _TB_tplEmpty, 'textarea', _TB_tplEmpty_VAL); + $this->createOption('tplItem', _TB_tplItem, 'textarea', _TB_tplItem_VAL); + $this->createOption('tplFooter', _TB_tplFooter, 'textarea', _TB_tplFooter_VAL); +//mod by cles + $this->createOption('tplLocalHeader', _TB_tplLocalHeader, 'textarea', _TB_tplLocalHeader_VAL); + $this->createOption('tplLocalEmpty', _TB_tplLocalEmpty, 'textarea', _TB_tplLocalEmpty_VAL); + $this->createOption('tplLocalItem', _TB_tplLocalItem, 'textarea', _TB_tplLocalItem_VAL); + $this->createOption('tplLocalFooter', _TB_tplLocalFooter, 'textarea', _TB_tplLocalFooter_VAL); +//mod by cles end + + $this->createOption('tplTbNone', _TB_tplTbNone, 'text', "No Trackbacks"); + $this->createOption('tplTbOne', _TB_tplTbOne, 'text', "1 Trackback"); + $this->createOption('tplTbMore', _TB_tplTbMore, 'text', "<%number%> Trackbacks"); + $this->createOption('dateFormat', _TB_dateFormat, 'text', _TB_dateFormat_VAL); + + $this->createOption('NotifyEmail', _TB_NotifyEmail,'text',''); + $this->createOption('DropTable', _TB_DropTable,'yesno','no'); +//mod by cles + $this->createOption('HideUrl',_TB_HideUrl,'yesno','yes'); + $this->createOption('ajaxEnabled',_TB_ajaxEnabled,'yesno','no'); + + $this->createItemOption('ItemAcceptPing',_TB_ItemAcceptPing,'yesno','yes'); + $this->createItemOption('isAcceptW/OLink',_TB_isAcceptWOLink,'select','default', _TB_isAcceptWOLink_VAL); + + $this->createBlogOption('NotifyEmailBlog', _TB_NotifyEmailBlog,'text',''); + $this->createBlogOption('isAcceptW/OLinkDef',_TB_isAcceptWOLinkDef,'select','block', _TB_isAcceptWOLinkDef_VAL); + $this->createBlogOption('AllowTrackBack',_TB_AllowTrackBack,'yesno','yes'); +//mod by cles end + + /* Create tables */ + sql_query(" + CREATE TABLE IF NOT EXISTS + ".sql_table('plugin_tb')." + ( + `id` INT(11) NOT NULL AUTO_INCREMENT, + `tb_id` INT(11) NOT NULL, + `url` TEXT NOT NULL, + `block` TINYINT(4) NOT NULL, + `spam` TINYINT(4) NOT NULL, + `link` TINYINT(4) NOT NULL, + `title` TEXT, + `excerpt` TEXT, + `blog_name` TEXT, + `timestamp` DATETIME, + + PRIMARY KEY (`id`) + ) + "); + + sql_query(" + CREATE TABLE IF NOT EXISTS + ".sql_table('plugin_tb_lookup')." + ( + `link` TEXT NOT NULL, + `url` TEXT NOT NULL, + `title` TEXT, + + PRIMARY KEY (`link` (100)) + ) + "); +//modify start+++++++++ + @sql_query('ALTER TABLE `' . sql_table('plugin_tb') . '` ADD INDEX `tb_id_block_timestamp_idx` ( `tb_id`, `block`, `timestamp` DESC )'); + @sql_query('CREATE TABLE IF NOT EXISTS ' . sql_table('plugin_tb_lc'). ' (tb_id int(11) not null, from_id int(11) not null, PRIMARY KEY (tb_id,from_id))'); +//modify end+++++++++ + } + + function uninstall() { + if ($this->getOption('DropTable') == 'yes') { + sql_query ('DROP TABLE '.sql_table('plugin_tb')); + sql_query ('DROP TABLE '.sql_table('plugin_tb_lookup')); + sql_query ("DROP table ".sql_table('plugin_tb_lc')); + } + } + + function init() { + // include language file for this plugin + $language = ereg_replace( '[\\|/]', '', getLanguageName()); + if (file_exists($this->getDirectory().'language/'.$language.'.php')) + include_once($this->getDirectory().'language/'.$language.'.php'); + else + include_once($this->getDirectory().'language/'.'english.php'); + $this->notificationMail = _TB_NORTIFICATION_MAIL_BODY; + $this->notificationMailTitle = _TB_NORTIFICATION_MAIL_TITLE; + + $this->userAgent = 'NucleusCMS NP_TrackBack plugin ( '.$this->getVersion().' )'; + } + } diff --git a/NP_TrackBack/trunk/trackback/CHANGELOG.txt b/NP_TrackBack/trunk/trackback/CHANGELOG.txt new file mode 100644 index 0000000..299c1d4 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/CHANGELOG.txt @@ -0,0 +1,123 @@ + + + 0.9.0 Initial version of Referer by Xiffy + 0.9.1 Added the possibility to call pop, 10 to show the most populair pages + Minor bugfixes for htmlspecialchars + Added substr to trim the line. Internet Explorer makes long lines instead of braking them + 0.9.2 Added timeoffset functionality to refWhen ... + 0.9.3 Added three display options (needs reinstallation!) + Bugfixes and another calling option; lastall + Added "-" on each refer* + + ------------------------------------------------------------ + + 1.0 Initial release + 1.1 Version that takes advantage of the new features in Nucleus v2.0 + (v1.55 users still need to addapt their templates) + 1.2 - Fix: Typo (cechkids) + - Fix: $CONF['ActionURL'] instead of $CONF['SiteURL'] . 'action.php' + - Fix: also works with php option 'short_open_tags' set to Off + - Added: manualpingform + - Requires Nucleus v2.0... + - Support for tableprefix (Nucleus versions > 2.0) + + 1.3 Release by caw + - Removed: Table backwards compatibility code + - Added: Support for adding TrackBack when editing item + - Change: Table name changed from [nucleus_]plugin_tb to [nucleus_]plug_trackback + + 1.4 Release by TeRanEX + (didn't wrote anything myself, only merged some modifications) + - Added: Table backwards compatibility code (was removed in 1.3 but I don't + see any reason why) + - Change: Table name changed from [nucleus_]plug_trackback to [nucleus_]plugin_tb + again (what was the reason for the change in 1.3? + - Added all fixes/mods/additions of thread http://forum.nucleuscms.org/viewtopic.php?t=3247 + - Send a ping on edit item + - sendPing with POST instead of GET + - "Retrieving TrackBack Pings" Implementation + - "Auto-Discovery of TrackBack Ping URLs" Implementation + - automatically-detecting trackbackURL of permalink linked by item + - Change: the RDF output so that it looks the same as in the MT TrackBack Spec + (see http://forum.nucleuscms.org/viewtopic.php?t=1974) + + 1.5 Release by admun and TeRanEX + - Added: Trackback updates, sending the newest data + - Added: Autodiscovery to the bookmarklet + - Added: Autodiscovery to the pingform + - Fixed: Autodiscovery now looks also in the 'more'-part of an item + - Changed/fixed: autodiscovery when editing an item, now you can check a checkbox for + every trackback that was discovered and you want to ping + - Added: License info + - Changed: The description of the plugin + + ------------------------------------------------------------ + + 2.0a Release by Niels Leenheer (rakaz) + - Added: Caching of auto-detected trackback URLs in a database table + - Added: If the cURL extension is present a HEAD request is send first, to make + sure we are dealing with a (X)HTML page and not some large binary file format. + - Added: The auto-detection of trackback URLs now happen in real time - as you type - + thanks to client-side Javascript and the XmlHttpRequest object which requests + the required data from the plugin. + + 2.0b - Added spinning auto-detection indicator + - Added support for multiple character encoding methods. The plugin + works internally fully in UTF-8 (Unicode) and can convert other + character encodings. The output of the plugin is in UTF-8 or in US-ASCII + with unicode characters encoded using numeric entities. + - Added spam protection using the Blacklist plugin (thanks to Xiffy for + helping me out by adding a generic spam check API to his plugin). + - Added a check to see if the page which send the trackback actually + contains a link to our server. If not, then it is probably a spamming + attempt and block by default. + - The output of this plugin is now fully configurable. You can specify + you're own (X)HTML code. + - Added a admin interface which can be used to manage trackbacks and + manually send trackbacks to other sites. It is possible to delete + trackbacks, but also to block and unblock trackbacks. All trackbacks + which are marked as spam are not deleted automatically, but they end + up in a list called 'Blocked trackbacks'. You can manually verify this + list and unblock any trackback which is marked as spam by mistake. + - Fixed a number of bugs, including missing hostnames and double // in + URLs. Fixed a bug introduced in 2.0a which prevented the title and + excerpt from showing up when sending trackbacks from a newly created + story. Also filtering of tags is more stringent. + + - REMOVED: Manual ping forms. The form which is need to ping other + weblogs is now integrated into the admin interface. The form needed + for other weblog authors to manually add trackbacks to your website + will return in the next release. + - REMOVED: The ability to show a list of trackbacks in a popup window. + This will probably return in the next release. + - REMOVED: The ability to delete trackbacks directly from the list + shown to administrators. This is now handled by the admin interface. + + 2.0 final + - Made the help page Nucleus 3.2 compatible + - Added a manual ping form, which allows weblog authors to add a trackback + to your stories even when their software doesn't support trackbacks. + - Removed en from the RSS output, because we can't + be sure about the language of the contents of the RSS stream. + + 2.0.1 - Security fix: Plugin admin interface was exposed to all logged in users, + not only to users with admin rights. + + 2.0.2 - Added autodetection of the encoding of trackbacks, which is needed when + a trackback is send in a foreign encoding by a sender which does not + support version 1.2 of the trackback specifications. Supported encodings: + US-ASCII, ISO-2022-JP, UTF-8, EUC-JP, Shift_JIS. If the encoding is not + specified according to version 1.2 of the specs AND it is not one of the + encodings specified above, the plugin will assume it is encoding using + ISO-8859-1. + - Added two new events SendTrackback and RetrieveTrackback which can be + used by other plugins or the XML-RPC APIs to allow external blog editors + to send trackbacks. (This functionality does require a modification to + the XML-RPC APIs). + - Added support for more clean Trackback URLs, for example: + http://www.rakaz.nl/nucleus/item/84.trackback or + http://www.rakaz.nl/nucleus/item.php?id=84&format=trackback + + 2.0.3 - Added support for a more advanced version of the SpamCheck API + + \ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/autodetect.php b/NP_TrackBack/trunk/trackback/autodetect.php new file mode 100644 index 0000000..a3f107d --- /dev/null +++ b/NP_TrackBack/trunk/trackback/autodetect.php @@ -0,0 +1,259 @@ +addTicketToUrl($CONF['ActionURL'] . '?action=plugin&name=TrackBack&type=detect') +?> + var xmlhttp = false; + var inProgress = false; + + var TrackbackAction = ""; + var TrackbackSource = new Array; + var TrackbackName = new Array; + var TrackbackURL = new Array; + + var LookupTable = new Array; + var Lookup = ''; + var countTotal = 0; + + var regexp = /href\s*=\s*([\"\'])(http:[^\"\'>]+)([\"\'])/ig; + + + function tbParseLinks () + { + oinputbody = document.getElementById('inputbody'); + oinputmore = document.getElementById('inputmore'); + full = oinputbody.value + ' ' + oinputmore.value; + + while (vArray = regexp.exec(full)) + { + unused = true; + + if (Lookup == vArray[2]) + unused = false; + + for (var i = 0; i < LookupTable.length; i++) + if (LookupTable[i] == vArray[2]) + unused = false; + + for (var i = 0; i < TrackbackSource.length; i++) + if (TrackbackSource[i] == vArray[2]) + unused = false; + + if (unused == true) + LookupTable.push(vArray[2]); + } + } + + function tbAutoDetect() + { + if (LookupTable.length > 0) + { + tbBusy(true); + + if (!inProgress) + { + // We have something to do and the connection is free + Lookup = LookupTable.shift(); + inProgress = true; + + // The reason we use GET instead of POST is because + // Opera does not properly support setting headers yet, + // which is a requirement for using POST. + xmlhttp.open("GET", TrackbackAction + "&tb_link=" + escape(Lookup), true); + xmlhttp.onreadystatechange = tbStateChange; + xmlhttp.send(''); + } + else + { + // Still busy... simply wait until next turn + } + } + else + { + // Nothing to do, check back later... + if (Lookup == '') + { + tbBusy(false); + } + } + } + + function tbStateChange () + { + if (inProgress == true && xmlhttp.readyState == 4 && xmlhttp.status == 200) + { + eval (xmlhttp.responseText); + inProgress = false; + Lookup = ''; + } + } + + function tbBusy(toggle) + { + + if (toggle) + { + document.forms[0].discoverit.style.color = "#888888"; + document.forms[0].discoverit.style.fontWeight="bold"; + document.forms[0].discoverit.value = " Loading ...."; + } + else + { + document.forms[0].discoverit.style.color = "#888888"; + document.forms[0].discoverit.style.fontWeight="bold"; + document.forms[0].discoverit.value = " D o n e ! "; + } + + o = document.getElementById('tb_busy'); + + if (o) + { + if (toggle) + o.style.display = ''; + else + o.style.display = 'none' + } + } + + function tbDone(source, url, name) + { + TrackbackSource.push(source); + TrackbackURL.push(url); + TrackbackName.push(name); + +// var parent = document.getElementById('tb_auto'); + var amount = document.getElementById('tb_url_amount'); + var subtitle = document.getElementById('tb_auto_title'); + var listtable = document.getElementById('tb_ping_list'); + + if (url != '') + { +// count = parseInt(amount.value); + count = countTotal; + + mycurrent_row=document.createElement("TR"); + + checkbox = document.createElement("input"); + checkbox.type = 'checkbox'; + checkbox.name = "tb_url_" + count; + checkbox.id = "tb_url_" + count; + checkbox.value = url; + checkbox.defaultChecked = true; + + label = document.createElement("label"); + label.htmlFor = "tb_url_" + count; + label.title = source; + + text = document.createTextNode(name); + label.appendChild(text); + + +// br = document.createElement("br"); + +// subtitle.innerHTML = "Auto Discovered Ping URL's:"; +// parent.appendChild(checkbox); +// parent.appendChild(label); + + mycurrent_cell=document.createElement("TD"); + mycurrent_cell.appendChild(checkbox); + mycurrent_row.appendChild(mycurrent_cell); + mycurrent_cell=document.createElement("TD"); + mycurrent_cell.appendChild(label); + mycurrent_row.appendChild(mycurrent_cell); + + mycurrent_row.appendChild(mycurrent_cell); + + + if(url.indexOf("",0) != -1) + { + //local? + checkboxL = document.createElement("input"); + checkboxL.type = 'checkbox'; + checkboxL.name = "tb_url_" + count + "_local"; + checkboxL.id = "tb_url_" + count + "_local"; + checkboxL.defaultChecked = true; + + labelL = document.createElement("label"); + labelL.htmlFor = "tb_url_" + count + "_local"; + labelL.title = "local?"; + + text = document.createTextNode("local?"); + labelL.appendChild(text); +// parent.appendChild(checkboxL); +// parent.appendChild(labelL); + mycurrent_cell=document.createElement("TD"); + mycurrent_cell.appendChild(checkboxL); + mycurrent_cell.appendChild(labelL); + mycurrent_row.appendChild(mycurrent_cell); + + } + else + { + mycurrent_cell=document.createElement("TD"); + mycurrent_row.appendChild(mycurrent_cell); + } +// parent.appendChild(br); + listtable.appendChild(mycurrent_row); + +// amount.value = count + 1; + countTotal++; + amount.value = countTotal; + } + else + { + subtitle.innerHTML = "No Trackbak URLs."; + } + } + + function tbSetup() + { + try + { + xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); + } + catch (e) + { + try + { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } + catch (e) + { + xmlhttp = false; + } + } + + if (!xmlhttp && typeof XMLHttpRequest!='undefined') + { + xmlhttp = new XMLHttpRequest(); + } + + setInterval ('tbParseLinks();', 500); + setInterval ('tbAutoDetect();', 500); + + if (window.onloadtrackback) + window.onloadtrackback(); + } + + function AddStart() + { + var strString = ""; + strString = document.forms[0].trackback_ping_url.value; + strArray = strString.split("\n"); + for (var i = 0; i < strArray.length; i++) + { + strTemp = trim(strArray[i]); + if (strTemp != "" && strTemp.match(/^http/)) + { + tbDone(strTemp,strTemp,strTemp); + } + } + document.forms[0].trackback_ping_url.value = ''; + } + + function trim(string) + { + return string.replace(/(^\s*)|(\s*$)/g,''); + } diff --git a/NP_TrackBack/trunk/trackback/detectlist.php b/NP_TrackBack/trunk/trackback/detectlist.php new file mode 100644 index 0000000..c3affe6 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/detectlist.php @@ -0,0 +1,70 @@ + + var TrackbackAction = ""; + var tb_id = ""; + var tb_amount = ""; + var xmlhttp = false; + + function resttbStart() + { + document.getElementById("tbhidenavi").style.display = "block"; + document.getElementById("tbshownavi").style.display = "none"; + try + { + xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); + } + catch (e) + { + try + { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } + catch (e) + { + xmlhttp = false; + } + } + + if (!xmlhttp && typeof XMLHttpRequest!='undefined') + { + xmlhttp = new XMLHttpRequest(); + } + + if (xmlhttp) + { + loadXMLDoc(); + } + + } + + function loadXMLDoc() + { + + var url = TrackbackAction + '?action=plugin&name=TrackBack&type=left&tb_id=' + tb_id + '&amount=' + tb_amount; + + xmlhttp.onreadystatechange=xmlhttpChange + xmlhttp.open("GET",url,true) + xmlhttp.send('') + } + + function xmlhttpChange() + { + if (xmlhttp.readyState == 4 && xmlhttp.status == 200) + { + var result = document.getElementById("resttb"); + result.innerHTML = xmlhttp.responseText; + } + } + + function hideresttb() + { + var result = document.getElementById("resttb"); + result.innerHTML = ""; + + document.getElementById("tbhidenavi").style.display = "none"; + document.getElementById("tbshownavi").style.display = "block"; + + } diff --git a/NP_TrackBack/trunk/trackback/grid.php b/NP_TrackBack/trunk/trackback/grid.php new file mode 100644 index 0000000..5b3ed15 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/grid.php @@ -0,0 +1,238 @@ +isLoggedIn() ) + { + $oPluginAdmin->start(); + echo '

' . _ERROR_DISALLOWED . '

'; + $oPluginAdmin->end(); + exit; + } + + // Actions + $action = requestVar('action'); + $aActionsNotToCheck = array( + '', + ); + if (!in_array($action, $aActionsNotToCheck)) { + if (!$manager->checkTicket()) doError(_ERROR_BADTICKET); + } + +//modify start+++++++++ + $plug =& $oPluginAdmin->plugin; + $tableVersion = $plug->checkTableVersion(); + + // include language file for this plugin + $language = ereg_replace( '[\\|/]', '', getLanguageName()); + if (file_exists($plug->getDirectory().'language/'.$language.'.php')) + include_once($plug->getDirectory().'language/'.$language.'.php'); + else + include_once($plug->getDirectory().'language/'.'english.php'); +//modify end+++++++++ + + $oTemplate = new Trackback_Template(); + $oTemplate->set ('CONF', $CONF); + $oTemplate->set ('plugindirurl', $oPluginAdmin->plugin->getAdminURL()); + $oTemplate->set ('ticket', $manager->_generateTicket()); + + $whereClause = ''; + if( ! $member->isAdmin() ){ + // where clause + $res = sql_query('SELECT tblog FROM '.sql_table('team').' WHERE tadmin = 1 AND tmember = '.$member->getID() ); + $adminBlog = array(); + while ($row = mysql_fetch_array($res)){ + $adminBlog[] = $row[0]; + } + if($adminBlog) + $whereClause = ' i.iblog in (' . implode(', ', $adminBlog) . ') '; + + if( $whereClause ) + $whereClause = ' AND ( i.iauthor = '.$member->getID().' OR ' . $whereClause . ' )'; + else + $whereClause = ' AND i.iauthor = '.$member->getID(); + } + + $requiredItemEditRights = array( + 'dodelete', + 'doblock', + 'dounblock', + ); + $safeids = array(); + if (in_array($action, $requiredItemEditRights)) { + $ids = explode(',', requestVar('ids')); + $safeids = array(); + foreach( $ids as $id ){ + $id = trim($id); + if( is_numeric($id) ) + $safeids[] = $id; + } + if( ! $member->isAdmin() ){ + $query = 'SELECT t.id FROM ' . sql_table('plugin_tb') . ' t, ' . sql_table('item') . ' i WHERE t.tb_id = i.inumber AND t.id in ( '. implode(',', $safeids) . ' ) '. $whereClause ; + $res = sql_query($query); + $safeids = array(); + while ($row = mysql_fetch_array($res)){ + $safeids[] = $row[0]; + } + } + } + + // Pages + switch($action) { + + case 'ajax': + $type = requestVar('type') == 'all' ? 'all' : 'blocked' ; + $filter['all'] = ' t.block = 0 '; + $filter['blocked'] = ' t.block = 1 '; + + $start = intRequestVar('offset') ? intRequestVar('offset') : 0; + $amount = intRequestVar('page_size') ? intRequestVar('page_size') : 25; + + $colname = array(); + $colname['date'] = 'timestamp'; + $colname['item'] = 'story_id'; + $colname['title'] = 'title'; + + $sort_col = requestVar('sort_col'); + $sort_col = $colname[$sort_col]; + if( !$sort_col ) $sort_col = $colname['date']; + + $sort_dir = ( requestVar('sort_dir') == 'ASC' ) ? 'ASC' : 'DESC'; + + $rres = sql_query (" + SELECT + count(*) as count + FROM + ".sql_table('plugin_tb')." AS t, + ".sql_table('item')." AS i + WHERE + t.tb_id = i.inumber AND + ".$filter[$type].$whereClause); + $rrow = mysql_fetch_array($rres); + $count = $rrow['count']; + + $rres = sql_query (" + SELECT + i.ititle AS story, + i.inumber AS story_id, + t.id AS id, + t.title AS title, + t.blog_name AS blog_name, + t.excerpt AS excerpt, + t.url AS url, + t.spam AS spam, + UNIX_TIMESTAMP(t.timestamp) AS timestamp + FROM + ".sql_table('plugin_tb')." AS t, + ".sql_table('item')." AS i + WHERE + t.tb_id = i.inumber AND + ".$filter[$type].$whereClause." + ORDER BY + ".$sort_col." ".$sort_dir." + LIMIT + ".$start.",".$amount." + "); + + $items = array(); + + while ($rrow = mysql_fetch_array($rres)) + { + $rrow['title'] = $oPluginAdmin->plugin->_cut_string($rrow['title'], 50); + $rrow['title'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['title']); + $rrow['title'] = htmlspecialchars($rrow['title']); + $rrow['title'] = preg_replace("/-+/","-",$rrow['title']); + + $rrow['blog_name'] = $oPluginAdmin->plugin->_cut_string($rrow['blog_name'], 50); + $rrow['blog_name'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['blog_name']); + $rrow['blog_name'] = htmlspecialchars($rrow['blog_name']); + $rrow['blog_name'] = preg_replace("/-+/","-",$rrow['blog_name']); + + $rrow['excerpt'] = $oPluginAdmin->plugin->_cut_string($rrow['excerpt'], 100); + $rrow['excerpt'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['excerpt']); + $rrow['excerpt'] = htmlspecialchars($rrow['excerpt']); + $rrow['excerpt'] = preg_replace("/-+/","-",$rrow['excerpt']); + + $rrow['url'] = htmlspecialchars($rrow['url'], ENT_QUOTES); + + $blog = & $manager->getBlog(getBlogIDFromItemID($rrow['story_id'])); + $rrow['story_url'] = $oPluginAdmin->plugin->_createItemLink($rrow['story_id'], $blog); + $rrow['story'] = htmlspecialchars(strip_tags($rrow['story']), ENT_QUOTES); + + $items[] = $rrow; + } + + $oTemplate->set ('amount', $amount); + $oTemplate->set ('count', $count); + $oTemplate->set ('start', $start); + $oTemplate->set ('items', $items); + $oTemplate->template('templates/response_'.$type.'.xml'); + break; + + case 'dodelete': + if( count($safeids) > 0 ){ + $safeids = implode(',',$safeids); + + $res = sql_query( + ' DELETE FROM ' + . sql_table('plugin_tb') + . ' WHERE id in (' . $safeids. ')' + ); + $oTemplate->set ('message', $safeids . ' deleted.'); + } else { + $oTemplate->set ('message', 'no rows deleted.'); + } + + $oTemplate->template('templates/response_dodelete.xml'); + break; + + case 'doblock': + if( count($safeids) > 0 ){ + $safeids = implode(',',$safeids); + + $res = sql_query( + ' UPDATE ' + . sql_table('plugin_tb') + .' SET block = 1 ' + . ' WHERE id in (' . $safeids. ')' + ); + $oTemplate->set ('message', $safeids . ' blocked.'); + } else { + $oTemplate->set ('message', 'no rows blocked.'); + } + + $oTemplate->template('templates/response_doblock.xml'); + break; + + case 'dounblock': + if( count($safeids) > 0 ){ + $safeids = implode(',',$safeids); + + $res = sql_query( + ' UPDATE ' + . sql_table('plugin_tb') + .' SET block = 0 ' + . ' WHERE id in (' . $safeids. ')' + ); + $oTemplate->set ('message', $safeids . ' unblocked.'); + } else { + $oTemplate->set ('message', 'no rows unblocked.'); + } + + $oTemplate->template('templates/response_dounblock.xml'); + break; + } + + // Create the admin area page + echo $oTemplate->fetch(); + diff --git a/NP_TrackBack/trunk/trackback/help.html b/NP_TrackBack/trunk/trackback/help.html new file mode 100644 index 0000000..41a60ae --- /dev/null +++ b/NP_TrackBack/trunk/trackback/help.html @@ -0,0 +1,111 @@ +

Help

+ + +

Skin variables

+ +

+ <%TrackBack(list)%> +

+

+ Show a list of trackbacks for the current page. Optionally it is also possible to + add an additional parameter, the story id number, which makes it possible to + show a list of trackbacks from a different page. The output of this variable is + fully configurable in the plugin options. +

+ +

+ <%TrackBack(code)%> +

+

+ Inserts a small piece of invisible RDF code in the page, which is used by other + weblogs to auto-detect the trackback URL. If you do not include this variable in + your skin for item pages, other weblogs will not be able to auto-detect that your + weblog is able to accept trackbacks. +

+ +

+ <%TrackBack(form)%> +

+

+ Insert the URL to a manual ping form. Using this form authors of other weblogs + can add trackbacks to your stories, even when their software does not support + trackbacks, such as Blogger. A link to this form is included in the footer of + the trackback list by default. If you want to place this link somewhere else + on your page, simply remove the <%form%> variable from the + Footer field in the plugin settings and add the skinvar somewhere on + your webpage. +

+ +

+ <%TrackBack(url)%> +

+

+ Insert the Trackback Ping URL. A this URL is also included in the footer of + the trackback list by default. If you want to place this link somewhere else + on your page, simply remove the <%action%> variable from the + Footer field in the plugin settings and add the skinvar somewhere on + your webpage. +

+ +

Template variables

+ +

+ All the skin variables documented above are also available as template variables. +

+ +

+ <%TrackBack(count)%> +

+

+ If you want to include an indication of how many trackbacks are present for each + page you can use this variable. By default this variable will show: "No Trackbacks", + "1 Trackback", "2 Trackbacks", etc. This is however also fully configurable in + the plugin options. +

+ + +

Changing the output

+ +

+ It is possible to fully change the output of this plugin. You can manually change + the XHTML code in the plugin options, but you can also use CSS to style the default + output to your liking. Below you will find an example of what a little snippet of + CSS can do. +

+ +
div.tb {
+	border: 1px solid #000; background: #FFF;
+}
+div.tb div.head {
+	padding: 4px;
+	background: #000; color: #FFF;
+	font-weight: bold; text-transform: lowercase; letter-spacing: 0.6em;
+}
+div.tb div.empty {
+	padding: 4px;
+	font-size: 95%;
+}
+div.tb div.item {
+	padding: 4px;
+}
+div.tb div.item div.name {
+	margin-bottom: 8px;
+	font-size: 120%; font-weight: bold;
+}
+div.tb div.item div.body {
+	font-size: 95%;
+}
+div.tb div.item div.body a {
+	font-weight: bold;
+}
+div.tb div.item div.date {
+	margin-bottom: 8px;
+	color: #888;
+	font-size: 85%; text-align: right;
+}
+div.tb div.info {
+	padding: 4px;
+	color: #FFF; background: #888;
+	font-size: 85%; font-style: italic;
+}
+ diff --git a/NP_TrackBack/trunk/trackback/index.php b/NP_TrackBack/trunk/trackback/index.php new file mode 100644 index 0000000..ef09755 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/index.php @@ -0,0 +1,496 @@ +isLoggedIn() ) + { + $oPluginAdmin->start(); + echo '

' . _ERROR_DISALLOWED . '

'; + $oPluginAdmin->end(); + exit; + } + + // Actions + $action = requestVar('action'); + $aActionsNotToCheck = array( + '', + 'ping', + ); + if (!in_array($action, $aActionsNotToCheck)) { + if (!$manager->checkTicket()) doError(_ERROR_BADTICKET); + } + + $oPluginAdmin->start(); + +//modify start+++++++++ + $plug =& $oPluginAdmin->plugin; + $tableVersion = $plug->checkTableVersion(); + + // include language file for this plugin + $language = ereg_replace( '[\\|/]', '', getLanguageName()); + if (file_exists($plug->getDirectory().'language/'.$language.'.php')) + include_once($plug->getDirectory().'language/'.$language.'.php'); + else + include_once($plug->getDirectory().'language/'.'english.php'); +//modify end+++++++++ + + $mTemplate = new Trackback_Template(); + $mTemplate->set ('CONF', $CONF); + $mTemplate->set ('plugid', $plug->getID()); + $mTemplate->set ('plugindirurl', $oPluginAdmin->plugin->getAdminURL()); + $mTemplate->template('templates/menu.html'); + echo $mTemplate->fetch(); + + $oTemplate = new Trackback_Template(); + $oTemplate->set ('CONF', $CONF); + $oTemplate->set ('plugindirurl', $oPluginAdmin->plugin->getAdminURL()); + $oTemplate->set ('ticket', $manager->_generateTicket()); + $ajaxEnabled = ($oPluginAdmin->plugin->getOption('ajaxEnabled') == 'yes') ? true : false; + $oTemplate->set ('ajaxEnabled', $ajaxEnabled); + + $whereClause = ''; + if( ! $member->isAdmin() ){ + // where clause + $res = sql_query('SELECT tblog FROM '.sql_table('team').' WHERE tadmin = 1 AND tmember = '.$member->getID() ); + $adminBlog = array(); + while ($row = mysql_fetch_array($res)){ + $adminBlog[] = $row[0]; + } + if($adminBlog) + $whereClause = ' i.iblog in (' . implode(', ', $adminBlog) . ') '; + + if( $whereClause ) + $whereClause = ' AND ( i.iauthor = '.$member->getID().' OR ' . $whereClause . ' )'; + else + $whereClause = ' AND i.iauthor = '.$member->getID(); + } + //echo "

Debug: $whereClause

"; + + $requiredAdminRights = array( + 'tableUpgrade', + 'blocked_clear', + 'blocked_spamclear', + ); + if (in_array($action, $requiredAdminRights)) { + if( ! $member->isAdmin() ){ + echo '

' . _ERROR_DISALLOWED . '

'; + echo '

Reason: ' . __LINE__ . '

'; + $oPluginAdmin->end(); + exit; + } + } + + $requiredItemEditRights = array( + 'block', + 'unblock', + 'delete', + ); + if (in_array($action, $requiredItemEditRights)) { + if( ! $member->isAdmin() ){ + $tb = intRequestVar('tb'); + $query = 'SELECT i.inumber FROM ' . sql_table('plugin_tb') . ' t, ' . sql_table('item') . ' i WHERE t.tb_id = i.inumber AND t.id = '. $tb . $whereClause ; + $res = sql_query($query); + if( ! @mysql_num_rows($res) ){ + echo '

' . _ERROR_DISALLOWED . '

'; + echo '

Reason: ' . __LINE__ . '

'; + $oPluginAdmin->end(); + exit; + } + } + } + + switch($action) { + +//modify start+++++++++ + case 'tableUpgrade': + sql_query(" + CREATE TABLE IF NOT EXISTS + ".sql_table('plugin_tb_lookup')." + ( + `link` TEXT NOT NULL, + `url` TEXT NOT NULL, + `title` TEXT, + + PRIMARY KEY (`link` (100)) + ) + "); + echo $q = "ALTER TABLE ".sql_table('plugin_tb')." + ADD `block` TINYINT( 4 ) NOT NULL AFTER `url` , + ADD `spam` TINYINT( 4 ) NOT NULL AFTER `block` , + ADD `link` TINYINT( 4 ) NOT NULL AFTER `spam` , + CHANGE `url` `url` TEXT NOT NULL, + CHANGE `title` `title` TEXT NOT NULL, + CHANGE `excerpt` `excerpt` TEXT NOT NULL, + CHANGE `blog_name` `blog_name` TEXT NOT NULL, + DROP PRIMARY KEY, + ADD `id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST ;"; + $res = @sql_query($q); + if (!$res){ + echo 'Could not alter table: ' . mysql_error(); + }else{ + $tableVersion = 1; + $oTemplate->template('templates/updatetablefinished.html'); + } + @sql_query('ALTER TABLE `' . sql_table('plugin_tb') . '` ADD INDEX `tb_id_block_timestamp_idx` ( `tb_id`, `block`, `timestamp` DESC )'); + break; +//modify end+++++++++ + + case 'block': + $tb = intRequestVar('tb'); + + $res = sql_query (" + UPDATE + ".sql_table('plugin_tb')." + SET + block = 1 + WHERE + id = '".$tb."' + "); + + $action = requestVar('next'); + break; + + case 'blocked_clear': + $res = sql_query ("DELETE FROM ".sql_table('plugin_tb')." WHERE block = 1"); + $action = requestVar('next'); + break; + + case 'blocked_spamclear': + $res = sql_query ("DELETE FROM ".sql_table('plugin_tb')." WHERE block = 1 and spam = 1"); + $action = requestVar('next'); + break; + + case 'unblock': + $tb = intRequestVar('tb'); + + $res = sql_query (" + UPDATE + ".sql_table('plugin_tb')." + SET + block = 0 + WHERE + id = '".$tb."' + "); + + $action = requestVar('next'); + break; + + case 'delete': + $tb = intRequestVar('tb'); + + $res = sql_query (" + DELETE FROM + ".sql_table('plugin_tb')." + WHERE + id = '".$tb."' + "); + + $action = requestVar('next'); + break; + + case 'sendping': + $title = requestVar('title'); + $url = requestVar('url'); + $excerpt = requestVar('excerpt'); + $blog_name = requestVar('blog_name'); + $ping_url = requestVar('ping_url'); + + // No charset conversion needs to be done here, because + // the charset used to receive the info is used to send + // it... + + if ($ping_url) { + $error = $oPluginAdmin->plugin->sendPing(0, $title, $url, $excerpt, $blog_name, $ping_url); + + if ($error) { + echo 'TrackBack Error:' . $error . ''; + } + } + + $action = requestVar('next'); + break; + + case 'ping': + $id = intRequestVar('id'); + + $usePathInfo = ($CONF['URLMode'] == 'pathinfo'); + if ($usePathInfo) + @ include($strRel . 'fancyurls.config.php'); + + global $manager; + $itemData = $manager->getItem($id, 0, 0); + + if(is_array($itemData)){ + $blog =& $manager->getBlog($itemData['blogid']); + $CONF['ItemURL'] = ($usePathInfo)? preg_replace('/\/$/', '', $blog->getURL()): $blog->getURL(); + $itemData['url'] = createItemLink($id); + $itemData['excerpt'] = shorten(strip_tags($itemData['body'].$itemData['more']), 250, '...'); + $itemData['blogname'] = $blog->getName(); + }else{ + $itemData = array(); + $itemData['url'] = $CONF['IndexURL']; + $itemData['blogname'] = $CONF['SiteName']; + } + $oTemplate->set('item', $itemData); + + $oTemplate->template('templates/ping.html'); + break; + } + + // Pages + switch($action) { + + case 'help': + $oTemplate->template('help.html'); + break; + + case 'ping': + $oTemplate->template('templates/ping.html'); + break; + + case 'blocked': + case 'all': + $rres = sql_query (" + SELECT + COUNT(*) AS count + FROM + ".sql_table('plugin_tb')." AS t, + ".sql_table('item')." AS i + WHERE + t.tb_id = i.inumber AND + t.block = " . (( $action == 'all') ? 0 : 1) . $whereClause ); + + if ($row = mysql_fetch_array($rres)) + $count = $row['count']; + else + $count = 0; + $oTemplate->set('count', $count); + + if($ajaxEnabled){ + if( $action == 'all') + $oTemplate->template('templates/all_ajax.html'); + else + $oTemplate->template('templates/blocked_ajax.html'); + } else { + $start = intRequestVar('start') ? intRequestVar('start') : 0; + $amount = intRequestVar('amount') ? intRequestVar('amount') : 25; + + $rres = sql_query (" + SELECT + i.ititle AS story, + i.inumber AS story_id, + t.id AS id, + t.title AS title, + t.blog_name AS blog_name, + t.excerpt AS excerpt, + t.url AS url, + UNIX_TIMESTAMP(t.timestamp) AS timestamp, + t.spam AS spam, + t.link AS link + FROM + ".sql_table('plugin_tb')." AS t, + ".sql_table('item')." AS i + WHERE + t.tb_id = i.inumber AND + t.block = " . (( $action == 'all') ? 0 : 1) . $whereClause ." + ORDER BY + timestamp DESC + LIMIT + ".$start.",".$amount); + + $items = array(); + + while ($rrow = mysql_fetch_array($rres)){ + $rrow['title'] = $oPluginAdmin->plugin->_cut_string($rrow['title'], 50); + $rrow['title'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['title']); + $rrow['title'] = htmlspecialchars($rrow['title']); + + $rrow['blog_name'] = $oPluginAdmin->plugin->_cut_string($rrow['blog_name'], 50); + $rrow['blog_name'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['blog_name']); + $rrow['blog_name'] = htmlspecialchars($rrow['blog_name']); + + $rrow['excerpt'] = $oPluginAdmin->plugin->_cut_string($rrow['excerpt'], 800); + $rrow['excerpt'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['excerpt']); + $rrow['excerpt'] = htmlspecialchars($rrow['excerpt']); + + $rrow['url'] = htmlspecialchars($rrow['url'], ENT_QUOTES); + $rrow['timestamp'] = htmlspecialchars($rrow['timestamp'], ENT_QUOTES); + + $blog = & $manager->getBlog(getBlogIDFromItemID($item['itemid'])); + $rrow['story_url'] = $oPluginAdmin->plugin->_createItemLink($rrow['story_id'], $blog); + $rrow['story'] = htmlspecialchars(strip_tags($rrow['story']), ENT_QUOTES); + + $items[] = $rrow; + } + + $oTemplate->set('amount', $amount); + $oTemplate->set('start', $start); + $oTemplate->set('items', $items); + + if( $action == 'all') + $oTemplate->template('templates/all.html'); + else + $oTemplate->template('templates/blocked.html'); + } + break; + + case 'list': + $id = requestVar('id'); + $start = intRequestVar('start') ? intRequestVar('start') : 0; + $amount = intRequestVar('amount') ? intRequestVar('amount') : 25; + + $ires = sql_query (" + SELECT + i.ititle, + i.inumber + FROM + ".sql_table('item')." i + WHERE + i.inumber = '".$id."' + ". $whereClause ); + + if ($irow = mysql_fetch_array($ires)) + { + $story['id'] = $id; + $story['title'] = $irow['ititle']; + + $rres = sql_query (" + SELECT + COUNT(*) AS count + FROM + ".sql_table('plugin_tb')." AS t + WHERE + t.tb_id = '".$id."' AND + t.block = 0 + "); + + if ($row = mysql_fetch_array($rres)) + $count = $row['count']; + else + $count = 0; + + $rres = sql_query (" + SELECT + t.id AS id, + t.title AS title, + t.blog_name AS blog_name, + t.excerpt AS excerpt, + t.url AS url, + UNIX_TIMESTAMP(t.timestamp) AS timestamp + FROM + ".sql_table('plugin_tb')." AS t + WHERE + t.tb_id = '".$id."' AND + t.block = 0 + ORDER BY + timestamp DESC + LIMIT + ".$start.",".$amount." + "); + + $items = array(); + + while ($rrow = mysql_fetch_array($rres)) + { + $rrow['title'] = $oPluginAdmin->plugin->_cut_string($rrow['title'], 50); + $rrow['title'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['title']); + $rrow['title'] = htmlspecialchars($rrow['title']); +// $rrow['title'] = _CHARSET == 'UTF-8' ? $rrow['title'] : $oPluginAdmin->plugin->_utf8_to_entities($rrow['title']); + + $rrow['blog_name'] = $oPluginAdmin->plugin->_cut_string($rrow['blog_name'], 50); + $rrow['blog_name'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['blog_name']); + $rrow['blog_name'] = htmlspecialchars($rrow['blog_name']); +// $rrow['blog_name'] = _CHARSET == 'UTF-8' ? $rrow['blog_name'] : $oPluginAdmin->plugin->_utf8_to_entities($rrow['blog_name']); + + $rrow['excerpt'] = $oPluginAdmin->plugin->_cut_string($rrow['excerpt'], 800); + $rrow['excerpt'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['excerpt']); + $rrow['excerpt'] = htmlspecialchars($rrow['excerpt']); +// $rrow['excerpt'] = _CHARSET == 'UTF-8' ? $rrow['excerpt'] : $oPluginAdmin->plugin->_utf8_to_entities($rrow['excerpt']); + + $rrow['url'] = htmlspecialchars($rrow['url'], ENT_QUOTES); + $rrow['story'] = htmlspecialchars(strip_tags($rrow['story']), ENT_QUOTES); + $items[] = $rrow; + } + + $oTemplate->set ('amount', $amount); + $oTemplate->set ('count', $count); + $oTemplate->set ('start', $start); + $oTemplate->set ('items', $items); + $oTemplate->set ('story', $story); + $oTemplate->template('templates/list.html'); + } + + break; + + + case 'index': + $bres = sql_query (" + SELECT + bnumber AS bnumber, + bname AS bname, + burl AS burl + FROM + ".sql_table('blog')." + ORDER BY + bname + "); + + $blogs = array(); + + while ($brow = mysql_fetch_array($bres)) + { + if( !$member->isTeamMember($brow['bnumber']) ) continue; + $ires = sql_query (" + SELECT + i.inumber AS inumber, + i.ititle AS ititle, + COUNT(*) AS total + FROM + ".sql_table('item')." AS i, + ".sql_table('plugin_tb')." AS t + WHERE + i.iblog = ".$brow['bnumber']." AND + t.tb_id = i.inumber AND + t.block = 0 ".$whereClause." + GROUP BY + i.inumber + ORDER BY + i.inumber DESC + "); + + $items = array(); + + while ($irow = mysql_fetch_array($ires)) + { + $items[] = $irow; + } + + $brow['items'] = $items; + $blogs[] = $brow; + } + + $oTemplate->set ('blogs', $blogs); + $oTemplate->template('templates/index.html'); + break; + + default: + //modify start+++++++++ + if(!$tableVersion){ + $oTemplate->template('templates/updatetable.html'); + } + //modify end+++++++++ + break; + } + + // Create the admin area page + echo $oTemplate->fetch(); + + echo '
Powered by Silk icon
'; + $oPluginAdmin->end(); + diff --git a/NP_TrackBack/trunk/trackback/japanese-euc.help.html b/NP_TrackBack/trunk/trackback/japanese-euc.help.html new file mode 100644 index 0000000..aa0b185 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-euc.help.html @@ -0,0 +1,116 @@ +

¥Ø¥ë¥×

+ + +

¥¹¥­¥ó¤Ø¤Îµ­½ÒÎã

+

+Nucleus CMS Japan Wiki¤ÎNP_TrackBack¤Î¥Ú¡¼¥¸¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£ +

+ +

ɽ¼¨¤Î¥«¥¹¥¿¥Þ¥¤¥º

+

+ ¥È¥é¥Ã¥¯¥Ð¥Ã¥¯´ØÏ¢¤Îɽ¼¨ÊýË¡¤Ï¥Æ¥ó¥×¥ì¡¼¥È¤òÊÔ½¸¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤Ç¤­¤Þ¤¹¤¬¡¢¿§¤ä;Çò¤Ê¤É¤Î¥Ç¥¶¥¤¥ó¤ÏCSS¦¤Ç»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥Æ¥ó¥×¥ì¡¼¥ÈÆâ¤ËÆþÎϤ·¤¿¥¯¥é¥¹Ì¾¤Î¥×¥í¥Ñ¥Æ¥£¤Ïcss¤Ç»ØÄꤷ¤Æ¤¯¤À¤µ¤¤¡£¥Ç¥Õ¥©¥ë¥È¤Î¥Æ¥ó¥×¥ì¡¼¥È¤ò¾þ¤ëCSS¥×¥í¥Ñ¥Æ¥£¤ÎÎã¤ò¤¢¤²¤Æ¤ª¤­¤Þ¤¹¡£ +

+ +
div.tb {
+	border: 1px solid #000; background: #FFF;
+}
+div.tb div.head {
+	padding: 4px;
+	background: #000; color: #FFF;
+	font-weight: bold; text-transform: lowercase; letter-spacing: 0.6em;
+}
+div.tb div.empty {
+	padding: 4px;
+	font-size: 95%;
+}
+div.tb div.item {
+	padding: 4px;
+}
+div.tb div.item div.name {
+	margin-bottom: 8px;
+	font-size: 120%; font-weight: bold;
+}
+div.tb div.item div.body {
+	font-size: 95%;
+}
+div.tb div.item div.body a {
+	font-weight: bold;
+}
+div.tb div.item div.date {
+	margin-bottom: 8px;
+	color: #888;
+	font-size: 85%; text-align: right;
+}
+div.tb div.info {
+	padding: 4px;
+	color: #FFF; background: #888;
+	font-size: 85%; font-style: italic;
+}
+ +

ÆüËܸìÈǹ¹¿·ÍúÎò

+ +
    +
  • Version 2.0.3jp13 : (2008/12/14)
  • +
  • ¡¡[Fixed] Ping¥Õ¥©¡¼¥à¤Ø¤Î¥ê¥ó¥¯¤ò³«¤³¤¦¤È¤¹¤ë¤ÈInvalid or expired ticket.¤Ë¤Ê¤ëÌäÂê¤ò½¤Àµ
  • +
  • ¡¡[Fixed] TrackBackÁ÷¿®»þ¤Î¥¨¥é¡¼¥Ï¥ó¥É¥ê¥ó¥°¤ò²þÎɤ·¤¿
  • +
  • ¡¡[Fixed] TrackBack¤Îʸ»ú¥³¡¼¥É¤Î¸¡½Ð¤¬Àµ¤·¤¯¹Ô¤ï¤ì¤Ê¤¤¾ì¹ç¤¬¤¢¤ëÌäÂê¤ò½¤Àµ
  • + +
  • Version 2.0.3jp12 : (2008/01/12)
  • +
  • ¡¡[Fixed] ¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤Îʸ»ú¥³¡¼¥É¤¬Å¬ÀڤǤʤ«¤Ã¤¿ÌäÂê¤ò½¤Àµ
  • +
  • ¡¡[Fixed] ¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤ÎÁ÷¿®Ê¸»ú¥³¡¼¥É¤òUTF-8¸ÇÄê¤Ë¤·¤¿
  • +
  • ¡¡[Fixed] ¥È¥é¥Ã¥¯¥Ð¥Ã¥¯²Ä/ÉԲĤÎȽÄ꤬¤ª¤«¤·¤«¤Ã¤¿ÌäÂê¤ò½¤Àµ
  • + +
  • Version 2.0.3jp11 : (2007/09/30)
  • +
  • ¡¡[Added] SuperAdmin°Ê³°¤Ç¤âTrackBack¤¬´ÉÍý¤Ç¤­¤ë¤è¤¦¤Ë¤·¤¿
  • + +
  • Version 2.0.3jp10 : (2007/06/30)
  • +
  • ¡¡[Fixed] mysql_query()¤òsql_query()¤ËÊѹ¹
  • +
  • ¡¡[Changed] ¼ÂÂλ²¾È¥Æ¡¼¥Ö¥ë¤Ë¤Ä¤¤¤ÆNucleusɸ½à¤â¤Î¤ò»È¤¦¤è¤¦¤Ë¤·¤¿
  • +
  • ¡¡[Changed] ¥¤¥ó¥¹¥È¡¼¥ë¤Ç¤­¤ë¥Ð¡¼¥¸¥ç¥ó¤ò3.3°Ê¹ß¤·¤¿
  • +
  • ¡¡[Changed] Rico¤ò2.0¤Ë¥¢¥Ã¥×¥Ç¡¼¥È¤·¤¿¤Î¤Ëȼ¤¤¡¢´ÉÍý²èÌ̤ε¡Ç½¤òÁý¶¯
  • +
  • ¡¡[Added] ¥³¥á¥ó¥ÈÉôʬ¤Ç¤â¥Æ¥ó¥×¥ì¡¼¥ÈÊÑ¿ô¤¬»È¤¨¤ë¤è¤¦¤Ë¤·¤¿
  • +
  • ¡¡[Fixed] ¥È¥é¥Ã¥¯¥Ð¥Ã¥¯Á÷¿®Éôʬ¤ÎÉÔ¶ñ¹ç¤ò½¤Àµ(FC2Âкö)
  • +
  • ¡¡[Changed] UserAgent¤ò¥ª¥ê¥¸¥Ê¥ëÈǤˤ¢¤ï¤»¤ÆÊѹ¹
  • +
  • ¡¡[Changed] TrackBack¤Î¥ì¥¹¥Ý¥ó¥¹¤Î²òÀϤËXML¥Ñ¡¼¥µ¡¼¤ò»È¤¦¤è¤¦¤Ë¤·¤¿
  • +
  • ¡¡[Fixed] ¸ÀµÚ¥ê¥ó¥¯¥Á¥§¥Ã¥¯¤ÎÉÔ¶ñ¹ç¤ò½¤Àµ
  • +
  • ¡¡[Added] ÊÝα¤Ë¤·¤Æ¤¤¤ëURL¤ÈƱ¤¸URL¤Î¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤ò̵»ë¤¹¤ë¤è¤¦¤Ë¤·¤¿
  • + +
  • ¡¡[Fixed] ¸ÀµÚ¥ê¥ó¥¯¥Á¥§¥Ã¥¯¤ÎÍѤÎURLÀ¸À®¥ë¡¼¥Á¥ó¤ÎÉÔ¶ñ¹ç¤ò½¤Àµ
  • + +
  • ¡¡[Added] spam¥È¥é¥Ã¥¯¥Ð¥Ã¥¯°ì³ç¾Ãµî»þ¤Ë³Îǧ¤¬½Ð¤ë¤è¤¦¤Ë¤·¤¿
  • + +
  • Version 2.0.3jp9 : (2007/05/04)
  • +
  • ¡¡[Added] doIf()¤òÄɲÃ(Nucleus 3.3¸þ¤±)
  • +
  • ¡¡[Added] URL¤¬Ìµ¸ú¤Ê¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤ò̵»ë¤¹¤ë¤è¤¦¤Ë¤·¤¿
  • + +
  • Version 2.0.3jp8 : (2007/03/18)
  • +
  • ¡¡[Fixed] ´ÉÍý²èÌ̤ÇStory¤Î¥ê¥ó¥¯¤ÎÉÔ¶ñ¹ç¤ò½¤Àµ
  • +
  • ¡¡[Changed] URLÃê½Ð¥ë¡¼¥Á¥ó¤ò²þÎÉ
  • +
  • ¡¡[Changed] ´ÉÍý²èÌ̤ؤΥê¥ó¥¯¤ò½¤Àµ
  • +
  • ¡¡[Changed] ´ÉÍý²èÌ̤Υڡ¼¥¸¥ó¥°¤òAjaxÂбþ¤Ë¤·¤¿
  • +
  • ¡¡[Changed] ¥È¥é¥Ã¥¯¥Ð¥Ã¥¯ÄÌÃÎ¥¢¥É¥ì¥¹¤ò¥Ö¥í¥°¤´¤È¤ËÀßÄê¤Ç¤­¤ë¤è¤¦¤Ë¤·¤¿
  • +
  • ¡¡[Fixed] php¤Îshort open¥¿¥°¤ò½¤Àµ
  • +
  • ¡¡[Fixed] ´ÉÍý²èÌ̤Υȥé¥Ã¥¯¥Ð¥Ã¥¯°ìÍ÷¤ÇÆüÉÕ¤¬Àµ¾ï¤Ëɽ¼¨¤µ¤ì¤Ê¤¤ÌäÂê¤ò½¤Àµ
  • + +
  • Version 2.0.3jp7 : (2006/11/26)
  • +
  • ¡¡[Changed] SpamChek¤Ë¤Ä¤¤¤ÆÈùÄ´À°
  • +
  • ¡¡[Added] Ticket½èÍý¤òÄɲÃ(CSRFÂкö)
  • +
  • ¡¡[Fixed] URL¤Ë&¤¬Æþ¤Ã¤Æ¤¤¤ë¤È¤­¤ÎÆ°ºî¤òÊѹ¹
  • +
  • ¡¡[Added] ´ÉÍý²èÌ̤˥¢¥¤¥³¥ó¤òÄɲÃ
  • + +
  • Version 2.0.3jp6 : (2006/09/30)
  • +
  • ¡¡[Fixed] ¥»¥­¥å¥ê¥Æ¥£¤Î¸þ¾å
  • + +
  • Version 2.0.3jp5 : (2006/09/16)
  • +
  • ¡¡[Fixed] getPermaLinksFromText()Æâ¤ÎURLÃê½Ð¥ë¡¼¥Á¥ó¤ÎÉÔ¶ñ¹ç¤ò½¤Àµ
  • +
  • ¡¡[Fixed] Auto-Discovery»þ¤ËSQL¥¨¥é¡¼¤¬½Ð¤ëÉÔ¶ñ¹ç¤ò½¤Àµ
  • +
  • ¡¡[Fixed] ´ÉÍý²èÌ̤ǥѡ¼¥¹¥¨¥é¡¼¤¬½Ð¤ë¾ì¹ç¤¬¤¢¤ëÉÔ¶ñ¹ç¤ò½¤Àµ
  • +
  • ¡¡[Changed] SQL¤Î¥¯¥©¡¼¥È¤ò"¤«¤é'¤ËÊѹ¹
  • +
  • ¡¡[Fixed] mb_emulator´Ä¶­¤Ë¤Æ¥¨¥é¡¼¤¬½Ð¤ëÌäÂê¤ò½¤Àµ
  • +
  • ¡¡[Fixed] curl¤¬Í­¸ú¤Ê´Ä¶­¤Ç¥¨¥é¡¼¤¬½Ð¤ëÌäÂê¤ò½¤Àµ
  • + +
  • Version 2.0.3jp4 : (2006/07/15)
  • +
  • ¡¡[Added] AutoDiscoveryURL½ÐÎÏ»þ¤ËSpamCheck¤ò¹Ô¤¦¤è¤¦¤Ë¤·¤¿
  • +
  • ¡¡[Added] ¥á¥Ã¥»¡¼¥¸¡¢¥Ç¥Õ¥©¥ë¥ÈÃͤòÆüËܸ첽
  • +
  • ¡¡[Added] Âç¼êASP¤Î¸ÀµÚ¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¥Á¥§¥Ã¥¯¤ÎºÝ¤ËURL¤Î¥ê¥À¥¤¥ì¥¯¥È¤ò²ò½ü¤¹¤ë¤è¤¦¤Ë¤·¤¿
  • +
\ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/japanese-euc.templates/all.html b/NP_TrackBack/trunk/trackback/japanese-euc.templates/all.html new file mode 100644 index 0000000..67ea054 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-euc.templates/all.html @@ -0,0 +1,106 @@ + +

+ All trackbacks + $amount): ?> + (Page of ) + +

+ + + $amount): ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateStoryTitle, Blog and ExcerptActions
+ + + + + Visit + + ()
+ +
+ Block + + Delete +
+ + $amount): ?> + + + + + + + + \ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/japanese-euc.templates/all_ajax.html b/NP_TrackBack/trunk/trackback/japanese-euc.templates/all_ajax.html new file mode 100644 index 0000000..f75b50c --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-euc.templates/all_ajax.html @@ -0,0 +1,130 @@ + +

+ All trackbacks +

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
 idDateStoryTitle, Blog and Excerpt 
+ +¾åµ­¤ÇÁªÂò¤·¤¿¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤ò°ì³ç¤·¤Æ½èÍý¤·¤Þ¤¹ +Delete +Block +
+ + + + diff --git a/NP_TrackBack/trunk/trackback/japanese-euc.templates/blocked.html b/NP_TrackBack/trunk/trackback/japanese-euc.templates/blocked.html new file mode 100644 index 0000000..e510f86 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-euc.templates/blocked.html @@ -0,0 +1,119 @@ + +

+ ¥Ö¥í¥Ã¥¯¤µ¤ì¤¿¥È¥é¥Ã¥¯¥Ð¥Ã¥¯ + $amount): ?> + (Page of ) + +

+ + + + + $amount): ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateStoryTitle, Blog and ExcerptActions
+ + + + + Visit + + () + ' : + '';?> + ';?> +
+ +
+ Unblock + + Delete +
+ + $amount): ?> + + + + + + + + + diff --git a/NP_TrackBack/trunk/trackback/japanese-euc.templates/blocked_ajax.html b/NP_TrackBack/trunk/trackback/japanese-euc.templates/blocked_ajax.html new file mode 100644 index 0000000..7f5aa82 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-euc.templates/blocked_ajax.html @@ -0,0 +1,134 @@ + +

+ ¥Ö¥í¥Ã¥¯¤µ¤ì¤¿¥È¥é¥Ã¥¯¥Ð¥Ã¥¯ +

+ + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
 idDateStoryTitle, Blog and Excerpt 
+¾åµ­¤ÇÁªÂò¤·¤¿¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤ò°ì³ç¤·¤Æ½èÍý¤·¤Þ¤¹ +Unblock +Delete +
+ + + + diff --git a/NP_TrackBack/trunk/trackback/japanese-euc.templates/form.html b/NP_TrackBack/trunk/trackback/japanese-euc.templates/form.html new file mode 100644 index 0000000..24ce702 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-euc.templates/form.html @@ -0,0 +1,56 @@ + + + + TrackBack¤Î¼êÆ°Á÷¿® + + + + +

TrackBack¤Î¼êÆ°Á÷¿®

+ +

+ ¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤ÎÁ÷¿®¤¬´°Î»¤·¤Þ¤·¤¿ +

+ + +

+ +

+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
¤¢¤Ê¤¿¤Îµ­»ö¤Îurl
µ­»ö¤Î¥¿¥¤¥È¥ë
µ­»ö¤ÎÍ×Ìóʸ
¤¢¤Ê¤¿¤Îblog¤Î̾Á°
¥È¥é¥Ã¥¯¥Ð¥Ã¥¯Á÷¿®
+
+ +
+ + + \ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/japanese-euc.templates/index.html b/NP_TrackBack/trunk/trackback/japanese-euc.templates/index.html new file mode 100644 index 0000000..a2a00ed --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-euc.templates/index.html @@ -0,0 +1,34 @@ + +

Overview of all items

+ + + + + + + + + + + + + + + + + + + + + + + + +
Blog: TotalAction
+ + + + + Trackbacks +
+ \ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/japanese-euc.templates/list.html b/NP_TrackBack/trunk/trackback/japanese-euc.templates/list.html new file mode 100644 index 0000000..05eeeb8 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-euc.templates/list.html @@ -0,0 +1,107 @@ + +

+ All trackbacks for "" + $amount): ?> + (Page of ) + +

+ + + $amount): ?> + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateTitle, Blog and ExcerptActions
+ + + Visit + + ()
+ +
+ Block + + Delete +
+ + $amount): ?> + + + + + + + + + diff --git a/NP_TrackBack/trunk/trackback/japanese-euc.templates/menu.html b/NP_TrackBack/trunk/trackback/japanese-euc.templates/menu.html new file mode 100644 index 0000000..e98b6af --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-euc.templates/menu.html @@ -0,0 +1,32 @@ + +

Trackback

+ + + + + diff --git a/NP_TrackBack/trunk/trackback/japanese-euc.templates/ping.html b/NP_TrackBack/trunk/trackback/japanese-euc.templates/ping.html new file mode 100644 index 0000000..0d993ec --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-euc.templates/ping.html @@ -0,0 +1,50 @@ + +

¼êÆ°ping¥Õ¥©¡¼¥à

+ +
+ + + + addTicketHidden(); ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
¼êÆ°ping
¤¢¤Ê¤¿¤Îurl + +
µ­»ö¤Î¥¿¥¤¥È¥ë + +
µ­»ö¤ÎÍ×Ìóʸ + +
Blog̾ + +
pingÀèurl + +
Á÷¿®
+ +
\ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/japanese-euc.templates/response_all.xml b/NP_TrackBack/trunk/trackback/japanese-euc.templates/response_all.xml new file mode 100644 index 0000000..4ae2445 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-euc.templates/response_all.xml @@ -0,0 +1,35 @@ +';?> + + + + + + + + + 0 + + + + + + "> + ]]> + + + "> + Visit + + + + () + ]]> + + + + + + + diff --git a/NP_TrackBack/trunk/trackback/japanese-euc.templates/response_blocked.xml b/NP_TrackBack/trunk/trackback/japanese-euc.templates/response_blocked.xml new file mode 100644 index 0000000..29faac9 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-euc.templates/response_blocked.xml @@ -0,0 +1,41 @@ +';?> + + + + + + + + + 0 + + + + + + "> + ]]> + + + "> + Visit + + + ' : + '';?> + ';?> + + () + ]]> + + + + + + + diff --git a/NP_TrackBack/trunk/trackback/japanese-euc.templates/response_doblock.xml b/NP_TrackBack/trunk/trackback/japanese-euc.templates/response_doblock.xml new file mode 100644 index 0000000..fdceb49 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-euc.templates/response_doblock.xml @@ -0,0 +1,8 @@ +';?> + + + + + + + \ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/japanese-euc.templates/response_dodelete.xml b/NP_TrackBack/trunk/trackback/japanese-euc.templates/response_dodelete.xml new file mode 100644 index 0000000..fdceb49 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-euc.templates/response_dodelete.xml @@ -0,0 +1,8 @@ +';?> + + + + + + + \ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/japanese-euc.templates/response_dounblock.xml b/NP_TrackBack/trunk/trackback/japanese-euc.templates/response_dounblock.xml new file mode 100644 index 0000000..fdceb49 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-euc.templates/response_dounblock.xml @@ -0,0 +1,8 @@ +';?> + + + + + + + \ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/japanese-euc.templates/updatetable.html b/NP_TrackBack/trunk/trackback/japanese-euc.templates/updatetable.html new file mode 100644 index 0000000..7435a03 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-euc.templates/updatetable.html @@ -0,0 +1,13 @@ + +
¥¢¥Ã¥×¥Ç¡¼¥È¤¬É¬ÍפǤ¹:
+¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç±¿ÍѤ¹¤ë¤¿¤á¤Ë¤ÏDBÆâ¤Î¥Æ¡¼¥Ö¥ë¤Î¥¢¥Ã¥×¥Ç¡¼¥È¤¬É¬ÍפǤ¹¡£
+º£¤Þ¤Ç¤Î¥Ç¡¼¥¿¤¬ºï½ü¤µ¤ì¤ë¤³¤È¤Ï¤¢¤ê¤Þ¤»¤ó¡£ +²¼¤Î¥¢¥Ã¥×¥Ç¡¼¥È¥Ü¥¿¥ó¤ò²¡¤·¤Æ¤¯¤À¤µ¤¤¡£ + +
+ + + addTicketHidden(); ?> +
+
+ diff --git a/NP_TrackBack/trunk/trackback/japanese-euc.templates/updatetablefinished.html b/NP_TrackBack/trunk/trackback/japanese-euc.templates/updatetablefinished.html new file mode 100644 index 0000000..a16df97 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-euc.templates/updatetablefinished.html @@ -0,0 +1,5 @@ + +
+¥Æ¡¼¥Ö¥ë¤Î¥¢¥Ã¥×¥Ç¡¼¥È¤Ï´°Î»¤·¤Þ¤·¤¿¡£ +
+ diff --git a/NP_TrackBack/trunk/trackback/japanese-utf8.help.html b/NP_TrackBack/trunk/trackback/japanese-utf8.help.html new file mode 100644 index 0000000..752f956 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-utf8.help.html @@ -0,0 +1,116 @@ +

ヘルプ

+ + +

スキンへの記述例

+

+Nucleus CMS Japan WikiのNP_TrackBackのページを参照してください。 +

+ +

表示のカスタマイズ

+

+ トラックバック関連の表示方法はテンプレートを編集することによってカスタマイズできますが、色や余白などのデザインはCSS側で指定する必要があります。テンプレート内に入力したクラス名のプロパティはcssで指定してください。デフォルトのテンプレートを飾るCSSプロパティの例をあげておきます。 +

+ +
div.tb {
+	border: 1px solid #000; background: #FFF;
+}
+div.tb div.head {
+	padding: 4px;
+	background: #000; color: #FFF;
+	font-weight: bold; text-transform: lowercase; letter-spacing: 0.6em;
+}
+div.tb div.empty {
+	padding: 4px;
+	font-size: 95%;
+}
+div.tb div.item {
+	padding: 4px;
+}
+div.tb div.item div.name {
+	margin-bottom: 8px;
+	font-size: 120%; font-weight: bold;
+}
+div.tb div.item div.body {
+	font-size: 95%;
+}
+div.tb div.item div.body a {
+	font-weight: bold;
+}
+div.tb div.item div.date {
+	margin-bottom: 8px;
+	color: #888;
+	font-size: 85%; text-align: right;
+}
+div.tb div.info {
+	padding: 4px;
+	color: #FFF; background: #888;
+	font-size: 85%; font-style: italic;
+}
+ +

日本語版更新履歴

+ +
    +
  • Version 2.0.3jp13 : (2008/12/14)
  • +
  •  [Fixed] Pingフォームへのリンクを開こうとするとInvalid or expired ticket.になる問題を修正
  • +
  •  [Fixed] TrackBack送信時のエラーハンドリングを改良した
  • +
  •  [Fixed] TrackBackの文字コードの検出が正しく行われない場合がある問題を修正
  • + +
  • Version 2.0.3jp12 : (2008/01/12)
  • +
  •  [Fixed] エラーメッセージの文字コードが適切でなかった問題を修正
  • +
  •  [Fixed] トラックバックの送信文字コードをUTF-8固定にした
  • +
  •  [Fixed] トラックバック可/不可の判定がおかしかった問題を修正
  • + +
  • Version 2.0.3jp11 : (2007/09/30)
  • +
  •  [Added] SuperAdmin以外でもTrackBackが管理できるようにした
  • + +
  • Version 2.0.3jp10 : (2007/06/30)
  • +
  •  [Fixed] mysql_query()をsql_query()に変更
  • +
  •  [Changed] 実体参照テーブルについてNucleus標準ものを使うようにした
  • +
  •  [Changed] インストールできるバージョンを3.3以降した
  • +
  •  [Changed] Ricoを2.0にアップデートしたのに伴い、管理画面の機能を増強
  • +
  •  [Added] コメント部分でもテンプレート変数が使えるようにした
  • +
  •  [Fixed] トラックバック送信部分の不具合を修正(FC2対策)
  • +
  •  [Changed] UserAgentをオリジナル版にあわせて変更
  • +
  •  [Changed] TrackBackのレスポンスの解析にXMLパーサーを使うようにした
  • +
  •  [Fixed] 言及リンクチェックの不具合を修正
  • +
  •  [Added] 保留にしているURLと同じURLのトラックバックを無視するようにした
  • + +
  •  [Fixed] 言及リンクチェックの用のURL生成ルーチンの不具合を修正
  • + +
  •  [Added] spamトラックバック一括消去時に確認が出るようにした
  • + +
  • Version 2.0.3jp9 : (2007/05/04)
  • +
  •  [Added] doIf()を追加(Nucleus 3.3向け)
  • +
  •  [Added] URLが無効なトラックバックを無視するようにした
  • + +
  • Version 2.0.3jp8 : (2007/03/18)
  • +
  •  [Fixed] 管理画面でStoryのリンクの不具合を修正
  • +
  •  [Changed] URL抽出ルーチンを改良
  • +
  •  [Changed] 管理画面へのリンクを修正
  • +
  •  [Changed] 管理画面のページングをAjax対応にした
  • +
  •  [Changed] トラックバック通知アドレスをブログごとに設定できるようにした
  • +
  •  [Fixed] phpのshort openタグを修正
  • +
  •  [Fixed] 管理画面のトラックバック一覧で日付が正常に表示されない問題を修正
  • + +
  • Version 2.0.3jp7 : (2006/11/26)
  • +
  •  [Changed] SpamChekについて微調整
  • +
  •  [Added] Ticket処理を追加(CSRF対策)
  • +
  •  [Fixed] URLに&が入っているときの動作を変更
  • +
  •  [Added] 管理画面にアイコンを追加
  • + +
  • Version 2.0.3jp6 : (2006/09/30)
  • +
  •  [Fixed] セキュリティの向上
  • + +
  • Version 2.0.3jp5 : (2006/09/16)
  • +
  •  [Fixed] getPermaLinksFromText()内のURL抽出ルーチンの不具合を修正
  • +
  •  [Fixed] Auto-Discovery時にSQLエラーが出る不具合を修正
  • +
  •  [Fixed] 管理画面でパースエラーが出る場合がある不具合を修正
  • +
  •  [Changed] SQLのクォートを"から'に変更
  • +
  •  [Fixed] mb_emulator環境にてエラーが出る問題を修正
  • +
  •  [Fixed] curlが有効な環境でエラーが出る問題を修正
  • + +
  • Version 2.0.3jp4 : (2006/07/15)
  • +
  •  [Added] AutoDiscoveryURL出力時にSpamCheckを行うようにした
  • +
  •  [Added] メッセージ、デフォルト値を日本語化
  • +
  •  [Added] 大手ASPの言及トラックバックチェックの際にURLのリダイレクトを解除するようにした
  • +
\ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/japanese-utf8.templates/all.html b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/all.html new file mode 100644 index 0000000..56c75b1 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/all.html @@ -0,0 +1,106 @@ + +

+ All trackbacks + $amount): ?> + (Page of ) + +

+ + + $amount): ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateStoryTitle, Blog and ExcerptActions
+ + + + + Visit + + ()
+ +
+ Block + + Delete +
+ + $amount): ?> + + + + + + + + \ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/japanese-utf8.templates/all_ajax.html b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/all_ajax.html new file mode 100644 index 0000000..38788e4 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/all_ajax.html @@ -0,0 +1,130 @@ + +

+ All trackbacks +

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
 idDateStoryTitle, Blog and Excerpt 
+ +上記で選択したトラックバックを一括して処理します +Delete +Block +
+ + + + diff --git a/NP_TrackBack/trunk/trackback/japanese-utf8.templates/blocked.html b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/blocked.html new file mode 100644 index 0000000..b6d553b --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/blocked.html @@ -0,0 +1,119 @@ + +

+ ブロックされたトラックバック + $amount): ?> + (Page of ) + +

+ + + + + $amount): ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateStoryTitle, Blog and ExcerptActions
+ + + + + Visit + + () + ' : + '';?> + ';?> +
+ +
+ Unblock + + Delete +
+ + $amount): ?> + + + + + + + + + diff --git a/NP_TrackBack/trunk/trackback/japanese-utf8.templates/blocked_ajax.html b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/blocked_ajax.html new file mode 100644 index 0000000..7474160 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/blocked_ajax.html @@ -0,0 +1,134 @@ + +

+ ブロックされたトラックバック +

+ + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
 idDateStoryTitle, Blog and Excerpt 
+上記で選択したトラックバックを一括して処理します +Unblock +Delete +
+ + + + diff --git a/NP_TrackBack/trunk/trackback/japanese-utf8.templates/form.html b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/form.html new file mode 100644 index 0000000..add813a --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/form.html @@ -0,0 +1,56 @@ + + + + TrackBackの手動送信 + + + + +

TrackBackの手動送信

+ +

+ トラックバックの送信が完了しました +

+ + +

+ +

+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
あなたの記事のurl
記事のタイトル
記事の要約文
あなたのblogの名前
トラックバック送信
+
+ +
+ + + \ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/japanese-utf8.templates/index.html b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/index.html new file mode 100644 index 0000000..15a2ce4 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/index.html @@ -0,0 +1,34 @@ + +

Overview of all items

+ + + + + + + + + + + + + + + + + + + + + + + + +
Blog: TotalAction
+ + + + + Trackbacks +
+ \ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/japanese-utf8.templates/list.html b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/list.html new file mode 100644 index 0000000..0fcf3c3 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/list.html @@ -0,0 +1,107 @@ + +

+ All trackbacks for "" + $amount): ?> + (Page of ) + +

+ + + $amount): ?> + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateTitle, Blog and ExcerptActions
+ + + Visit + + ()
+ +
+ Block + + Delete +
+ + $amount): ?> + + + + + + + + + diff --git a/NP_TrackBack/trunk/trackback/japanese-utf8.templates/menu.html b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/menu.html new file mode 100644 index 0000000..ac37024 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/menu.html @@ -0,0 +1,32 @@ + +

Trackback

+ + + + + diff --git a/NP_TrackBack/trunk/trackback/japanese-utf8.templates/ping.html b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/ping.html new file mode 100644 index 0000000..84a882c --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/ping.html @@ -0,0 +1,50 @@ + +

手動pingフォーム

+ +
+ + + + addTicketHidden(); ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
手動ping
あなたのurl + +
記事のタイトル + +
記事の要約文 + +
Blog名 + +
ping先url + +
送信
+ +
\ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/japanese-utf8.templates/response_all.xml b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/response_all.xml new file mode 100644 index 0000000..4ae2445 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/response_all.xml @@ -0,0 +1,35 @@ +';?> + + + + + + + + + 0 + + + + + + "> + ]]> + + + "> + Visit + + + + () + ]]> + + + + + + + diff --git a/NP_TrackBack/trunk/trackback/japanese-utf8.templates/response_blocked.xml b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/response_blocked.xml new file mode 100644 index 0000000..29faac9 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/response_blocked.xml @@ -0,0 +1,41 @@ +';?> + + + + + + + + + 0 + + + + + + "> + ]]> + + + "> + Visit + + + ' : + '';?> + ';?> + + () + ]]> + + + + + + + diff --git a/NP_TrackBack/trunk/trackback/japanese-utf8.templates/response_doblock.xml b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/response_doblock.xml new file mode 100644 index 0000000..a53f37c --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/response_doblock.xml @@ -0,0 +1,8 @@ +';?> + + + + + + + \ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/japanese-utf8.templates/response_dodelete.xml b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/response_dodelete.xml new file mode 100644 index 0000000..a53f37c --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/response_dodelete.xml @@ -0,0 +1,8 @@ +';?> + + + + + + + \ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/japanese-utf8.templates/response_dounblock.xml b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/response_dounblock.xml new file mode 100644 index 0000000..a53f37c --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/response_dounblock.xml @@ -0,0 +1,8 @@ +';?> + + + + + + + \ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/japanese-utf8.templates/updatetable.html b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/updatetable.html new file mode 100644 index 0000000..a426a8a --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/updatetable.html @@ -0,0 +1,13 @@ + +
アップデートが必要です:
+このバージョンで運用するためにはDB内のテーブルのアップデートが必要です。
+今までのデータが削除されることはありません。 +下のアップデートボタンを押してください。 + +
+ + + addTicketHidden(); ?> +
+
+ diff --git a/NP_TrackBack/trunk/trackback/japanese-utf8.templates/updatetablefinished.html b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/updatetablefinished.html new file mode 100644 index 0000000..6b1ea94 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/japanese-utf8.templates/updatetablefinished.html @@ -0,0 +1,5 @@ + +
+テーブルのアップデートは完了しました。 +
+ diff --git a/NP_TrackBack/trunk/trackback/js/prototype.js b/NP_TrackBack/trunk/trackback/js/prototype.js new file mode 100644 index 0000000..5d2100f --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/prototype.js @@ -0,0 +1,3271 @@ +/* Prototype JavaScript framework, version 1.5.1 + * (c) 2005-2007 Sam Stephenson + * + * Prototype is freely distributable under the terms of an MIT-style license. + * For details, see the Prototype web site: http://www.prototypejs.org/ + * +/*--------------------------------------------------------------------------*/ + +var Prototype = { + Version: '1.5.1', + + Browser: { + IE: !!(window.attachEvent && !window.opera), + Opera: !!window.opera, + WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1, + Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1 + }, + + BrowserFeatures: { + XPath: !!document.evaluate, + ElementExtensions: !!window.HTMLElement, + SpecificElementExtensions: + (document.createElement('div').__proto__ !== + document.createElement('form').__proto__) + }, + + ScriptFragment: ']*>([\u0001-\uFFFF]*?)', + JSONFilter: /^\/\*-secure-\s*(.*)\s*\*\/\s*$/, + + emptyFunction: function() { }, + K: function(x) { return x } +} + +var Class = { + create: function() { + return function() { + this.initialize.apply(this, arguments); + } + } +} + +var Abstract = new Object(); + +Object.extend = function(destination, source) { + for (var property in source) { + destination[property] = source[property]; + } + return destination; +} + +Object.extend(Object, { + inspect: function(object) { + try { + if (object === undefined) return 'undefined'; + if (object === null) return 'null'; + return object.inspect ? object.inspect() : object.toString(); + } catch (e) { + if (e instanceof RangeError) return '...'; + throw e; + } + }, + + toJSON: function(object) { + var type = typeof object; + switch(type) { + case 'undefined': + case 'function': + case 'unknown': return; + case 'boolean': return object.toString(); + } + if (object === null) return 'null'; + if (object.toJSON) return object.toJSON(); + if (object.ownerDocument === document) return; + var results = []; + for (var property in object) { + var value = Object.toJSON(object[property]); + if (value !== undefined) + results.push(property.toJSON() + ': ' + value); + } + return '{' + results.join(', ') + '}'; + }, + + keys: function(object) { + var keys = []; + for (var property in object) + keys.push(property); + return keys; + }, + + values: function(object) { + var values = []; + for (var property in object) + values.push(object[property]); + return values; + }, + + clone: function(object) { + return Object.extend({}, object); + } +}); + +Function.prototype.bind = function() { + var __method = this, args = $A(arguments), object = args.shift(); + return function() { + return __method.apply(object, args.concat($A(arguments))); + } +} + +Function.prototype.bindAsEventListener = function(object) { + var __method = this, args = $A(arguments), object = args.shift(); + return function(event) { + return __method.apply(object, [event || window.event].concat(args)); + } +} + +Object.extend(Number.prototype, { + toColorPart: function() { + return this.toPaddedString(2, 16); + }, + + succ: function() { + return this + 1; + }, + + times: function(iterator) { + $R(0, this, true).each(iterator); + return this; + }, + + toPaddedString: function(length, radix) { + var string = this.toString(radix || 10); + return '0'.times(length - string.length) + string; + }, + + toJSON: function() { + return isFinite(this) ? this.toString() : 'null'; + } +}); + +Date.prototype.toJSON = function() { + return '"' + this.getFullYear() + '-' + + (this.getMonth() + 1).toPaddedString(2) + '-' + + this.getDate().toPaddedString(2) + 'T' + + this.getHours().toPaddedString(2) + ':' + + this.getMinutes().toPaddedString(2) + ':' + + this.getSeconds().toPaddedString(2) + '"'; +}; + +var Try = { + these: function() { + var returnValue; + + for (var i = 0, length = arguments.length; i < length; i++) { + var lambda = arguments[i]; + try { + returnValue = lambda(); + break; + } catch (e) {} + } + + return returnValue; + } +} + +/*--------------------------------------------------------------------------*/ + +var PeriodicalExecuter = Class.create(); +PeriodicalExecuter.prototype = { + initialize: function(callback, frequency) { + this.callback = callback; + this.frequency = frequency; + this.currentlyExecuting = false; + + this.registerCallback(); + }, + + registerCallback: function() { + this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); + }, + + stop: function() { + if (!this.timer) return; + clearInterval(this.timer); + this.timer = null; + }, + + onTimerEvent: function() { + if (!this.currentlyExecuting) { + try { + this.currentlyExecuting = true; + this.callback(this); + } finally { + this.currentlyExecuting = false; + } + } + } +} +Object.extend(String, { + interpret: function(value) { + return value == null ? '' : String(value); + }, + specialChar: { + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '\\': '\\\\' + } +}); + +Object.extend(String.prototype, { + gsub: function(pattern, replacement) { + var result = '', source = this, match; + replacement = arguments.callee.prepareReplacement(replacement); + + while (source.length > 0) { + if (match = source.match(pattern)) { + result += source.slice(0, match.index); + result += String.interpret(replacement(match)); + source = source.slice(match.index + match[0].length); + } else { + result += source, source = ''; + } + } + return result; + }, + + sub: function(pattern, replacement, count) { + replacement = this.gsub.prepareReplacement(replacement); + count = count === undefined ? 1 : count; + + return this.gsub(pattern, function(match) { + if (--count < 0) return match[0]; + return replacement(match); + }); + }, + + scan: function(pattern, iterator) { + this.gsub(pattern, iterator); + return this; + }, + + truncate: function(length, truncation) { + length = length || 30; + truncation = truncation === undefined ? '...' : truncation; + return this.length > length ? + this.slice(0, length - truncation.length) + truncation : this; + }, + + strip: function() { + return this.replace(/^\s+/, '').replace(/\s+$/, ''); + }, + + stripTags: function() { + return this.replace(/<\/?[^>]+>/gi, ''); + }, + + stripScripts: function() { + return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); + }, + + extractScripts: function() { + var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); + var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); + return (this.match(matchAll) || []).map(function(scriptTag) { + return (scriptTag.match(matchOne) || ['', ''])[1]; + }); + }, + + evalScripts: function() { + return this.extractScripts().map(function(script) { return eval(script) }); + }, + + escapeHTML: function() { + var self = arguments.callee; + self.text.data = this; + return self.div.innerHTML; + }, + + unescapeHTML: function() { + var div = document.createElement('div'); + div.innerHTML = this.stripTags(); + return div.childNodes[0] ? (div.childNodes.length > 1 ? + $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) : + div.childNodes[0].nodeValue) : ''; + }, + + toQueryParams: function(separator) { + var match = this.strip().match(/([^?#]*)(#.*)?$/); + if (!match) return {}; + + return match[1].split(separator || '&').inject({}, function(hash, pair) { + if ((pair = pair.split('='))[0]) { + var key = decodeURIComponent(pair.shift()); + var value = pair.length > 1 ? pair.join('=') : pair[0]; + if (value != undefined) value = decodeURIComponent(value); + + if (key in hash) { + if (hash[key].constructor != Array) hash[key] = [hash[key]]; + hash[key].push(value); + } + else hash[key] = value; + } + return hash; + }); + }, + + toArray: function() { + return this.split(''); + }, + + succ: function() { + return this.slice(0, this.length - 1) + + String.fromCharCode(this.charCodeAt(this.length - 1) + 1); + }, + + times: function(count) { + var result = ''; + for (var i = 0; i < count; i++) result += this; + return result; + }, + + camelize: function() { + var parts = this.split('-'), len = parts.length; + if (len == 1) return parts[0]; + + var camelized = this.charAt(0) == '-' + ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1) + : parts[0]; + + for (var i = 1; i < len; i++) + camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1); + + return camelized; + }, + + capitalize: function() { + return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); + }, + + underscore: function() { + return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase(); + }, + + dasherize: function() { + return this.gsub(/_/,'-'); + }, + + inspect: function(useDoubleQuotes) { + var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) { + var character = String.specialChar[match[0]]; + return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16); + }); + if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; + return "'" + escapedString.replace(/'/g, '\\\'') + "'"; + }, + + toJSON: function() { + return this.inspect(true); + }, + + unfilterJSON: function(filter) { + return this.sub(filter || Prototype.JSONFilter, '#{1}'); + }, + + evalJSON: function(sanitize) { + var json = this.unfilterJSON(); + try { + if (!sanitize || (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(json))) + return eval('(' + json + ')'); + } catch (e) { } + throw new SyntaxError('Badly formed JSON string: ' + this.inspect()); + }, + + include: function(pattern) { + return this.indexOf(pattern) > -1; + }, + + startsWith: function(pattern) { + return this.indexOf(pattern) === 0; + }, + + endsWith: function(pattern) { + var d = this.length - pattern.length; + return d >= 0 && this.lastIndexOf(pattern) === d; + }, + + empty: function() { + return this == ''; + }, + + blank: function() { + return /^\s*$/.test(this); + } +}); + +if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, { + escapeHTML: function() { + return this.replace(/&/g,'&').replace(//g,'>'); + }, + unescapeHTML: function() { + return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); + } +}); + +String.prototype.gsub.prepareReplacement = function(replacement) { + if (typeof replacement == 'function') return replacement; + var template = new Template(replacement); + return function(match) { return template.evaluate(match) }; +} + +String.prototype.parseQuery = String.prototype.toQueryParams; + +Object.extend(String.prototype.escapeHTML, { + div: document.createElement('div'), + text: document.createTextNode('') +}); + +with (String.prototype.escapeHTML) div.appendChild(text); + +var Template = Class.create(); +Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; +Template.prototype = { + initialize: function(template, pattern) { + this.template = template.toString(); + this.pattern = pattern || Template.Pattern; + }, + + evaluate: function(object) { + return this.template.gsub(this.pattern, function(match) { + var before = match[1]; + if (before == '\\') return match[2]; + return before + String.interpret(object[match[3]]); + }); + } +} + +var $break = {}, $continue = new Error('"throw $continue" is deprecated, use "return" instead'); + +var Enumerable = { + each: function(iterator) { + var index = 0; + try { + this._each(function(value) { + iterator(value, index++); + }); + } catch (e) { + if (e != $break) throw e; + } + return this; + }, + + eachSlice: function(number, iterator) { + var index = -number, slices = [], array = this.toArray(); + while ((index += number) < array.length) + slices.push(array.slice(index, index+number)); + return slices.map(iterator); + }, + + all: function(iterator) { + var result = true; + this.each(function(value, index) { + result = result && !!(iterator || Prototype.K)(value, index); + if (!result) throw $break; + }); + return result; + }, + + any: function(iterator) { + var result = false; + this.each(function(value, index) { + if (result = !!(iterator || Prototype.K)(value, index)) + throw $break; + }); + return result; + }, + + collect: function(iterator) { + var results = []; + this.each(function(value, index) { + results.push((iterator || Prototype.K)(value, index)); + }); + return results; + }, + + detect: function(iterator) { + var result; + this.each(function(value, index) { + if (iterator(value, index)) { + result = value; + throw $break; + } + }); + return result; + }, + + findAll: function(iterator) { + var results = []; + this.each(function(value, index) { + if (iterator(value, index)) + results.push(value); + }); + return results; + }, + + grep: function(pattern, iterator) { + var results = []; + this.each(function(value, index) { + var stringValue = value.toString(); + if (stringValue.match(pattern)) + results.push((iterator || Prototype.K)(value, index)); + }) + return results; + }, + + include: function(object) { + var found = false; + this.each(function(value) { + if (value == object) { + found = true; + throw $break; + } + }); + return found; + }, + + inGroupsOf: function(number, fillWith) { + fillWith = fillWith === undefined ? null : fillWith; + return this.eachSlice(number, function(slice) { + while(slice.length < number) slice.push(fillWith); + return slice; + }); + }, + + inject: function(memo, iterator) { + this.each(function(value, index) { + memo = iterator(memo, value, index); + }); + return memo; + }, + + invoke: function(method) { + var args = $A(arguments).slice(1); + return this.map(function(value) { + return value[method].apply(value, args); + }); + }, + + max: function(iterator) { + var result; + this.each(function(value, index) { + value = (iterator || Prototype.K)(value, index); + if (result == undefined || value >= result) + result = value; + }); + return result; + }, + + min: function(iterator) { + var result; + this.each(function(value, index) { + value = (iterator || Prototype.K)(value, index); + if (result == undefined || value < result) + result = value; + }); + return result; + }, + + partition: function(iterator) { + var trues = [], falses = []; + this.each(function(value, index) { + ((iterator || Prototype.K)(value, index) ? + trues : falses).push(value); + }); + return [trues, falses]; + }, + + pluck: function(property) { + var results = []; + this.each(function(value, index) { + results.push(value[property]); + }); + return results; + }, + + reject: function(iterator) { + var results = []; + this.each(function(value, index) { + if (!iterator(value, index)) + results.push(value); + }); + return results; + }, + + sortBy: function(iterator) { + return this.map(function(value, index) { + return {value: value, criteria: iterator(value, index)}; + }).sort(function(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }).pluck('value'); + }, + + toArray: function() { + return this.map(); + }, + + zip: function() { + var iterator = Prototype.K, args = $A(arguments); + if (typeof args.last() == 'function') + iterator = args.pop(); + + var collections = [this].concat(args).map($A); + return this.map(function(value, index) { + return iterator(collections.pluck(index)); + }); + }, + + size: function() { + return this.toArray().length; + }, + + inspect: function() { + return '#'; + } +} + +Object.extend(Enumerable, { + map: Enumerable.collect, + find: Enumerable.detect, + select: Enumerable.findAll, + member: Enumerable.include, + entries: Enumerable.toArray +}); +var $A = Array.from = function(iterable) { + if (!iterable) return []; + if (iterable.toArray) { + return iterable.toArray(); + } else { + var results = []; + for (var i = 0, length = iterable.length; i < length; i++) + results.push(iterable[i]); + return results; + } +} + +if (Prototype.Browser.WebKit) { + $A = Array.from = function(iterable) { + if (!iterable) return []; + if (!(typeof iterable == 'function' && iterable == '[object NodeList]') && + iterable.toArray) { + return iterable.toArray(); + } else { + var results = []; + for (var i = 0, length = iterable.length; i < length; i++) + results.push(iterable[i]); + return results; + } + } +} + +Object.extend(Array.prototype, Enumerable); + +if (!Array.prototype._reverse) + Array.prototype._reverse = Array.prototype.reverse; + +Object.extend(Array.prototype, { + _each: function(iterator) { + for (var i = 0, length = this.length; i < length; i++) + iterator(this[i]); + }, + + clear: function() { + this.length = 0; + return this; + }, + + first: function() { + return this[0]; + }, + + last: function() { + return this[this.length - 1]; + }, + + compact: function() { + return this.select(function(value) { + return value != null; + }); + }, + + flatten: function() { + return this.inject([], function(array, value) { + return array.concat(value && value.constructor == Array ? + value.flatten() : [value]); + }); + }, + + without: function() { + var values = $A(arguments); + return this.select(function(value) { + return !values.include(value); + }); + }, + + indexOf: function(object) { + for (var i = 0, length = this.length; i < length; i++) + if (this[i] == object) return i; + return -1; + }, + + reverse: function(inline) { + return (inline !== false ? this : this.toArray())._reverse(); + }, + + reduce: function() { + return this.length > 1 ? this : this[0]; + }, + + uniq: function(sorted) { + return this.inject([], function(array, value, index) { + if (0 == index || (sorted ? array.last() != value : !array.include(value))) + array.push(value); + return array; + }); + }, + + clone: function() { + return [].concat(this); + }, + + size: function() { + return this.length; + }, + + inspect: function() { + return '[' + this.map(Object.inspect).join(', ') + ']'; + }, + + toJSON: function() { + var results = []; + this.each(function(object) { + var value = Object.toJSON(object); + if (value !== undefined) results.push(value); + }); + return '[' + results.join(', ') + ']'; + } +}); + +Array.prototype.toArray = Array.prototype.clone; + +function $w(string) { + string = string.strip(); + return string ? string.split(/\s+/) : []; +} + +if (Prototype.Browser.Opera){ + Array.prototype.concat = function() { + var array = []; + for (var i = 0, length = this.length; i < length; i++) array.push(this[i]); + for (var i = 0, length = arguments.length; i < length; i++) { + if (arguments[i].constructor == Array) { + for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++) + array.push(arguments[i][j]); + } else { + array.push(arguments[i]); + } + } + return array; + } +} +var Hash = function(object) { + if (object instanceof Hash) this.merge(object); + else Object.extend(this, object || {}); +}; + +Object.extend(Hash, { + toQueryString: function(obj) { + var parts = []; + parts.add = arguments.callee.addPair; + + this.prototype._each.call(obj, function(pair) { + if (!pair.key) return; + var value = pair.value; + + if (value && typeof value == 'object') { + if (value.constructor == Array) value.each(function(value) { + parts.add(pair.key, value); + }); + return; + } + parts.add(pair.key, value); + }); + + return parts.join('&'); + }, + + toJSON: function(object) { + var results = []; + this.prototype._each.call(object, function(pair) { + var value = Object.toJSON(pair.value); + if (value !== undefined) results.push(pair.key.toJSON() + ': ' + value); + }); + return '{' + results.join(', ') + '}'; + } +}); + +Hash.toQueryString.addPair = function(key, value, prefix) { + key = encodeURIComponent(key); + if (value === undefined) this.push(key); + else this.push(key + '=' + (value == null ? '' : encodeURIComponent(value))); +} + +Object.extend(Hash.prototype, Enumerable); +Object.extend(Hash.prototype, { + _each: function(iterator) { + for (var key in this) { + var value = this[key]; + if (value && value == Hash.prototype[key]) continue; + + var pair = [key, value]; + pair.key = key; + pair.value = value; + iterator(pair); + } + }, + + keys: function() { + return this.pluck('key'); + }, + + values: function() { + return this.pluck('value'); + }, + + merge: function(hash) { + return $H(hash).inject(this, function(mergedHash, pair) { + mergedHash[pair.key] = pair.value; + return mergedHash; + }); + }, + + remove: function() { + var result; + for(var i = 0, length = arguments.length; i < length; i++) { + var value = this[arguments[i]]; + if (value !== undefined){ + if (result === undefined) result = value; + else { + if (result.constructor != Array) result = [result]; + result.push(value) + } + } + delete this[arguments[i]]; + } + return result; + }, + + toQueryString: function() { + return Hash.toQueryString(this); + }, + + inspect: function() { + return '#'; + }, + + toJSON: function() { + return Hash.toJSON(this); + } +}); + +function $H(object) { + if (object instanceof Hash) return object; + return new Hash(object); +}; + +// Safari iterates over shadowed properties +if (function() { + var i = 0, Test = function(value) { this.key = value }; + Test.prototype.key = 'foo'; + for (var property in new Test('bar')) i++; + return i > 1; +}()) Hash.prototype._each = function(iterator) { + var cache = []; + for (var key in this) { + var value = this[key]; + if ((value && value == Hash.prototype[key]) || cache.include(key)) continue; + cache.push(key); + var pair = [key, value]; + pair.key = key; + pair.value = value; + iterator(pair); + } +}; +ObjectRange = Class.create(); +Object.extend(ObjectRange.prototype, Enumerable); +Object.extend(ObjectRange.prototype, { + initialize: function(start, end, exclusive) { + this.start = start; + this.end = end; + this.exclusive = exclusive; + }, + + _each: function(iterator) { + var value = this.start; + while (this.include(value)) { + iterator(value); + value = value.succ(); + } + }, + + include: function(value) { + if (value < this.start) + return false; + if (this.exclusive) + return value < this.end; + return value <= this.end; + } +}); + +var $R = function(start, end, exclusive) { + return new ObjectRange(start, end, exclusive); +} + +var Ajax = { + getTransport: function() { + return Try.these( + function() {return new XMLHttpRequest()}, + function() {return new ActiveXObject('Msxml2.XMLHTTP')}, + function() {return new ActiveXObject('Microsoft.XMLHTTP')} + ) || false; + }, + + activeRequestCount: 0 +} + +Ajax.Responders = { + responders: [], + + _each: function(iterator) { + this.responders._each(iterator); + }, + + register: function(responder) { + if (!this.include(responder)) + this.responders.push(responder); + }, + + unregister: function(responder) { + this.responders = this.responders.without(responder); + }, + + dispatch: function(callback, request, transport, json) { + this.each(function(responder) { + if (typeof responder[callback] == 'function') { + try { + responder[callback].apply(responder, [request, transport, json]); + } catch (e) {} + } + }); + } +}; + +Object.extend(Ajax.Responders, Enumerable); + +Ajax.Responders.register({ + onCreate: function() { + Ajax.activeRequestCount++; + }, + onComplete: function() { + Ajax.activeRequestCount--; + } +}); + +Ajax.Base = function() {}; +Ajax.Base.prototype = { + setOptions: function(options) { + this.options = { + method: 'post', + asynchronous: true, + contentType: 'application/x-www-form-urlencoded', + encoding: 'UTF-8', + parameters: '' + } + Object.extend(this.options, options || {}); + + this.options.method = this.options.method.toLowerCase(); + if (typeof this.options.parameters == 'string') + this.options.parameters = this.options.parameters.toQueryParams(); + } +} + +Ajax.Request = Class.create(); +Ajax.Request.Events = + ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; + +Ajax.Request.prototype = Object.extend(new Ajax.Base(), { + _complete: false, + + initialize: function(url, options) { + this.transport = Ajax.getTransport(); + this.setOptions(options); + this.request(url); + }, + + request: function(url) { + this.url = url; + this.method = this.options.method; + var params = Object.clone(this.options.parameters); + + if (!['get', 'post'].include(this.method)) { + // simulate other verbs over post + params['_method'] = this.method; + this.method = 'post'; + } + + this.parameters = params; + + if (params = Hash.toQueryString(params)) { + // when GET, append parameters to URL + if (this.method == 'get') + this.url += (this.url.include('?') ? '&' : '?') + params; + else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) + params += '&_='; + } + + try { + if (this.options.onCreate) this.options.onCreate(this.transport); + Ajax.Responders.dispatch('onCreate', this, this.transport); + + this.transport.open(this.method.toUpperCase(), this.url, + this.options.asynchronous); + + if (this.options.asynchronous) + setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10); + + this.transport.onreadystatechange = this.onStateChange.bind(this); + this.setRequestHeaders(); + + this.body = this.method == 'post' ? (this.options.postBody || params) : null; + this.transport.send(this.body); + + /* Force Firefox to handle ready state 4 for synchronous requests */ + if (!this.options.asynchronous && this.transport.overrideMimeType) + this.onStateChange(); + + } + catch (e) { + this.dispatchException(e); + } + }, + + onStateChange: function() { + var readyState = this.transport.readyState; + if (readyState > 1 && !((readyState == 4) && this._complete)) + this.respondToReadyState(this.transport.readyState); + }, + + setRequestHeaders: function() { + var headers = { + 'X-Requested-With': 'XMLHttpRequest', + 'X-Prototype-Version': Prototype.Version, + 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' + }; + + if (this.method == 'post') { + headers['Content-type'] = this.options.contentType + + (this.options.encoding ? '; charset=' + this.options.encoding : ''); + + /* Force "Connection: close" for older Mozilla browsers to work + * around a bug where XMLHttpRequest sends an incorrect + * Content-length header. See Mozilla Bugzilla #246651. + */ + if (this.transport.overrideMimeType && + (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005) + headers['Connection'] = 'close'; + } + + // user-defined headers + if (typeof this.options.requestHeaders == 'object') { + var extras = this.options.requestHeaders; + + if (typeof extras.push == 'function') + for (var i = 0, length = extras.length; i < length; i += 2) + headers[extras[i]] = extras[i+1]; + else + $H(extras).each(function(pair) { headers[pair.key] = pair.value }); + } + + for (var name in headers) + this.transport.setRequestHeader(name, headers[name]); + }, + + success: function() { + return !this.transport.status + || (this.transport.status >= 200 && this.transport.status < 300); + }, + + respondToReadyState: function(readyState) { + var state = Ajax.Request.Events[readyState]; + var transport = this.transport, json = this.evalJSON(); + + if (state == 'Complete') { + try { + this._complete = true; + (this.options['on' + this.transport.status] + || this.options['on' + (this.success() ? 'Success' : 'Failure')] + || Prototype.emptyFunction)(transport, json); + } catch (e) { + this.dispatchException(e); + } + + var contentType = this.getHeader('Content-type'); + if (contentType && contentType.strip(). + match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i)) + this.evalResponse(); + } + + try { + (this.options['on' + state] || Prototype.emptyFunction)(transport, json); + Ajax.Responders.dispatch('on' + state, this, transport, json); + } catch (e) { + this.dispatchException(e); + } + + if (state == 'Complete') { + // avoid memory leak in MSIE: clean up + this.transport.onreadystatechange = Prototype.emptyFunction; + } + }, + + getHeader: function(name) { + try { + return this.transport.getResponseHeader(name); + } catch (e) { return null } + }, + + evalJSON: function() { + try { + var json = this.getHeader('X-JSON'); + return json ? json.evalJSON() : null; + } catch (e) { return null } + }, + + evalResponse: function() { + try { + return eval((this.transport.responseText || '').unfilterJSON()); + } catch (e) { + this.dispatchException(e); + } + }, + + dispatchException: function(exception) { + (this.options.onException || Prototype.emptyFunction)(this, exception); + Ajax.Responders.dispatch('onException', this, exception); + } +}); + +Ajax.Updater = Class.create(); + +Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { + initialize: function(container, url, options) { + this.container = { + success: (container.success || container), + failure: (container.failure || (container.success ? null : container)) + } + + this.transport = Ajax.getTransport(); + this.setOptions(options); + + var onComplete = this.options.onComplete || Prototype.emptyFunction; + this.options.onComplete = (function(transport, param) { + this.updateContent(); + onComplete(transport, param); + }).bind(this); + + this.request(url); + }, + + updateContent: function() { + var receiver = this.container[this.success() ? 'success' : 'failure']; + var response = this.transport.responseText; + + if (!this.options.evalScripts) response = response.stripScripts(); + + if (receiver = $(receiver)) { + if (this.options.insertion) + new this.options.insertion(receiver, response); + else + receiver.update(response); + } + + if (this.success()) { + if (this.onComplete) + setTimeout(this.onComplete.bind(this), 10); + } + } +}); + +Ajax.PeriodicalUpdater = Class.create(); +Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), { + initialize: function(container, url, options) { + this.setOptions(options); + this.onComplete = this.options.onComplete; + + this.frequency = (this.options.frequency || 2); + this.decay = (this.options.decay || 1); + + this.updater = {}; + this.container = container; + this.url = url; + + this.start(); + }, + + start: function() { + this.options.onComplete = this.updateComplete.bind(this); + this.onTimerEvent(); + }, + + stop: function() { + this.updater.options.onComplete = undefined; + clearTimeout(this.timer); + (this.onComplete || Prototype.emptyFunction).apply(this, arguments); + }, + + updateComplete: function(request) { + if (this.options.decay) { + this.decay = (request.responseText == this.lastText ? + this.decay * this.options.decay : 1); + + this.lastText = request.responseText; + } + this.timer = setTimeout(this.onTimerEvent.bind(this), + this.decay * this.frequency * 1000); + }, + + onTimerEvent: function() { + this.updater = new Ajax.Updater(this.container, this.url, this.options); + } +}); +function $(element) { + if (arguments.length > 1) { + for (var i = 0, elements = [], length = arguments.length; i < length; i++) + elements.push($(arguments[i])); + return elements; + } + if (typeof element == 'string') + element = document.getElementById(element); + return Element.extend(element); +} + +if (Prototype.BrowserFeatures.XPath) { + document._getElementsByXPath = function(expression, parentElement) { + var results = []; + var query = document.evaluate(expression, $(parentElement) || document, + null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); + for (var i = 0, length = query.snapshotLength; i < length; i++) + results.push(query.snapshotItem(i)); + return results; + }; + + document.getElementsByClassName = function(className, parentElement) { + var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]"; + return document._getElementsByXPath(q, parentElement); + } + +} else document.getElementsByClassName = function(className, parentElement) { + var children = ($(parentElement) || document.body).getElementsByTagName('*'); + var elements = [], child; + for (var i = 0, length = children.length; i < length; i++) { + child = children[i]; + if (Element.hasClassName(child, className)) + elements.push(Element.extend(child)); + } + return elements; +}; + +/*--------------------------------------------------------------------------*/ + +if (!window.Element) var Element = {}; + +Element.extend = function(element) { + var F = Prototype.BrowserFeatures; + if (!element || !element.tagName || element.nodeType == 3 || + element._extended || F.SpecificElementExtensions || element == window) + return element; + + var methods = {}, tagName = element.tagName, cache = Element.extend.cache, + T = Element.Methods.ByTag; + + // extend methods for all tags (Safari doesn't need this) + if (!F.ElementExtensions) { + Object.extend(methods, Element.Methods), + Object.extend(methods, Element.Methods.Simulated); + } + + // extend methods for specific tags + if (T[tagName]) Object.extend(methods, T[tagName]); + + for (var property in methods) { + var value = methods[property]; + if (typeof value == 'function' && !(property in element)) + element[property] = cache.findOrStore(value); + } + + element._extended = Prototype.emptyFunction; + return element; +}; + +Element.extend.cache = { + findOrStore: function(value) { + return this[value] = this[value] || function() { + return value.apply(null, [this].concat($A(arguments))); + } + } +}; + +Element.Methods = { + visible: function(element) { + return $(element).style.display != 'none'; + }, + + toggle: function(element) { + element = $(element); + Element[Element.visible(element) ? 'hide' : 'show'](element); + return element; + }, + + hide: function(element) { + $(element).style.display = 'none'; + return element; + }, + + show: function(element) { + $(element).style.display = ''; + return element; + }, + + remove: function(element) { + element = $(element); + element.parentNode.removeChild(element); + return element; + }, + + update: function(element, html) { + html = typeof html == 'undefined' ? '' : html.toString(); + $(element).innerHTML = html.stripScripts(); + setTimeout(function() {html.evalScripts()}, 10); + return element; + }, + + replace: function(element, html) { + element = $(element); + html = typeof html == 'undefined' ? '' : html.toString(); + if (element.outerHTML) { + element.outerHTML = html.stripScripts(); + } else { + var range = element.ownerDocument.createRange(); + range.selectNodeContents(element); + element.parentNode.replaceChild( + range.createContextualFragment(html.stripScripts()), element); + } + setTimeout(function() {html.evalScripts()}, 10); + return element; + }, + + inspect: function(element) { + element = $(element); + var result = '<' + element.tagName.toLowerCase(); + $H({'id': 'id', 'className': 'class'}).each(function(pair) { + var property = pair.first(), attribute = pair.last(); + var value = (element[property] || '').toString(); + if (value) result += ' ' + attribute + '=' + value.inspect(true); + }); + return result + '>'; + }, + + recursivelyCollect: function(element, property) { + element = $(element); + var elements = []; + while (element = element[property]) + if (element.nodeType == 1) + elements.push(Element.extend(element)); + return elements; + }, + + ancestors: function(element) { + return $(element).recursivelyCollect('parentNode'); + }, + + descendants: function(element) { + return $A($(element).getElementsByTagName('*')).each(Element.extend); + }, + + firstDescendant: function(element) { + element = $(element).firstChild; + while (element && element.nodeType != 1) element = element.nextSibling; + return $(element); + }, + + immediateDescendants: function(element) { + if (!(element = $(element).firstChild)) return []; + while (element && element.nodeType != 1) element = element.nextSibling; + if (element) return [element].concat($(element).nextSiblings()); + return []; + }, + + previousSiblings: function(element) { + return $(element).recursivelyCollect('previousSibling'); + }, + + nextSiblings: function(element) { + return $(element).recursivelyCollect('nextSibling'); + }, + + siblings: function(element) { + element = $(element); + return element.previousSiblings().reverse().concat(element.nextSiblings()); + }, + + match: function(element, selector) { + if (typeof selector == 'string') + selector = new Selector(selector); + return selector.match($(element)); + }, + + up: function(element, expression, index) { + element = $(element); + if (arguments.length == 1) return $(element.parentNode); + var ancestors = element.ancestors(); + return expression ? Selector.findElement(ancestors, expression, index) : + ancestors[index || 0]; + }, + + down: function(element, expression, index) { + element = $(element); + if (arguments.length == 1) return element.firstDescendant(); + var descendants = element.descendants(); + return expression ? Selector.findElement(descendants, expression, index) : + descendants[index || 0]; + }, + + previous: function(element, expression, index) { + element = $(element); + if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element)); + var previousSiblings = element.previousSiblings(); + return expression ? Selector.findElement(previousSiblings, expression, index) : + previousSiblings[index || 0]; + }, + + next: function(element, expression, index) { + element = $(element); + if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element)); + var nextSiblings = element.nextSiblings(); + return expression ? Selector.findElement(nextSiblings, expression, index) : + nextSiblings[index || 0]; + }, + + getElementsBySelector: function() { + var args = $A(arguments), element = $(args.shift()); + return Selector.findChildElements(element, args); + }, + + getElementsByClassName: function(element, className) { + return document.getElementsByClassName(className, element); + }, + + readAttribute: function(element, name) { + element = $(element); + if (Prototype.Browser.IE) { + if (!element.attributes) return null; + var t = Element._attributeTranslations; + if (t.values[name]) return t.values[name](element, name); + if (t.names[name]) name = t.names[name]; + var attribute = element.attributes[name]; + return attribute ? attribute.nodeValue : null; + } + return element.getAttribute(name); + }, + + getHeight: function(element) { + return $(element).getDimensions().height; + }, + + getWidth: function(element) { + return $(element).getDimensions().width; + }, + + classNames: function(element) { + return new Element.ClassNames(element); + }, + + hasClassName: function(element, className) { + if (!(element = $(element))) return; + var elementClassName = element.className; + if (elementClassName.length == 0) return false; + if (elementClassName == className || + elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) + return true; + return false; + }, + + addClassName: function(element, className) { + if (!(element = $(element))) return; + Element.classNames(element).add(className); + return element; + }, + + removeClassName: function(element, className) { + if (!(element = $(element))) return; + Element.classNames(element).remove(className); + return element; + }, + + toggleClassName: function(element, className) { + if (!(element = $(element))) return; + Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className); + return element; + }, + + observe: function() { + Event.observe.apply(Event, arguments); + return $A(arguments).first(); + }, + + stopObserving: function() { + Event.stopObserving.apply(Event, arguments); + return $A(arguments).first(); + }, + + // removes whitespace-only text node children + cleanWhitespace: function(element) { + element = $(element); + var node = element.firstChild; + while (node) { + var nextNode = node.nextSibling; + if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) + element.removeChild(node); + node = nextNode; + } + return element; + }, + + empty: function(element) { + return $(element).innerHTML.blank(); + }, + + descendantOf: function(element, ancestor) { + element = $(element), ancestor = $(ancestor); + while (element = element.parentNode) + if (element == ancestor) return true; + return false; + }, + + scrollTo: function(element) { + element = $(element); + var pos = Position.cumulativeOffset(element); + window.scrollTo(pos[0], pos[1]); + return element; + }, + + getStyle: function(element, style) { + element = $(element); + style = style == 'float' ? 'cssFloat' : style.camelize(); + var value = element.style[style]; + if (!value) { + var css = document.defaultView.getComputedStyle(element, null); + value = css ? css[style] : null; + } + if (style == 'opacity') return value ? parseFloat(value) : 1.0; + return value == 'auto' ? null : value; + }, + + getOpacity: function(element) { + return $(element).getStyle('opacity'); + }, + + setStyle: function(element, styles, camelized) { + element = $(element); + var elementStyle = element.style; + + for (var property in styles) + if (property == 'opacity') element.setOpacity(styles[property]) + else + elementStyle[(property == 'float' || property == 'cssFloat') ? + (elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') : + (camelized ? property : property.camelize())] = styles[property]; + + return element; + }, + + setOpacity: function(element, value) { + element = $(element); + element.style.opacity = (value == 1 || value === '') ? '' : + (value < 0.00001) ? 0 : value; + return element; + }, + + getDimensions: function(element) { + element = $(element); + var display = $(element).getStyle('display'); + if (display != 'none' && display != null) // Safari bug + return {width: element.offsetWidth, height: element.offsetHeight}; + + // All *Width and *Height properties give 0 on elements with display none, + // so enable the element temporarily + var els = element.style; + var originalVisibility = els.visibility; + var originalPosition = els.position; + var originalDisplay = els.display; + els.visibility = 'hidden'; + els.position = 'absolute'; + els.display = 'block'; + var originalWidth = element.clientWidth; + var originalHeight = element.clientHeight; + els.display = originalDisplay; + els.position = originalPosition; + els.visibility = originalVisibility; + return {width: originalWidth, height: originalHeight}; + }, + + makePositioned: function(element) { + element = $(element); + var pos = Element.getStyle(element, 'position'); + if (pos == 'static' || !pos) { + element._madePositioned = true; + element.style.position = 'relative'; + // Opera returns the offset relative to the positioning context, when an + // element is position relative but top and left have not been defined + if (window.opera) { + element.style.top = 0; + element.style.left = 0; + } + } + return element; + }, + + undoPositioned: function(element) { + element = $(element); + if (element._madePositioned) { + element._madePositioned = undefined; + element.style.position = + element.style.top = + element.style.left = + element.style.bottom = + element.style.right = ''; + } + return element; + }, + + makeClipping: function(element) { + element = $(element); + if (element._overflow) return element; + element._overflow = element.style.overflow || 'auto'; + if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') + element.style.overflow = 'hidden'; + return element; + }, + + undoClipping: function(element) { + element = $(element); + if (!element._overflow) return element; + element.style.overflow = element._overflow == 'auto' ? '' : element._overflow; + element._overflow = null; + return element; + } +}; + +Object.extend(Element.Methods, { + childOf: Element.Methods.descendantOf, + childElements: Element.Methods.immediateDescendants +}); + +if (Prototype.Browser.Opera) { + Element.Methods._getStyle = Element.Methods.getStyle; + Element.Methods.getStyle = function(element, style) { + switch(style) { + case 'left': + case 'top': + case 'right': + case 'bottom': + if (Element._getStyle(element, 'position') == 'static') return null; + default: return Element._getStyle(element, style); + } + }; +} +else if (Prototype.Browser.IE) { + Element.Methods.getStyle = function(element, style) { + element = $(element); + style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize(); + var value = element.style[style]; + if (!value && element.currentStyle) value = element.currentStyle[style]; + + if (style == 'opacity') { + if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/)) + if (value[1]) return parseFloat(value[1]) / 100; + return 1.0; + } + + if (value == 'auto') { + if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none')) + return element['offset'+style.capitalize()] + 'px'; + return null; + } + return value; + }; + + Element.Methods.setOpacity = function(element, value) { + element = $(element); + var filter = element.getStyle('filter'), style = element.style; + if (value == 1 || value === '') { + style.filter = filter.replace(/alpha\([^\)]*\)/gi,''); + return element; + } else if (value < 0.00001) value = 0; + style.filter = filter.replace(/alpha\([^\)]*\)/gi, '') + + 'alpha(opacity=' + (value * 100) + ')'; + return element; + }; + + // IE is missing .innerHTML support for TABLE-related elements + Element.Methods.update = function(element, html) { + element = $(element); + html = typeof html == 'undefined' ? '' : html.toString(); + var tagName = element.tagName.toUpperCase(); + if (['THEAD','TBODY','TR','TD'].include(tagName)) { + var div = document.createElement('div'); + switch (tagName) { + case 'THEAD': + case 'TBODY': + div.innerHTML = '' + html.stripScripts() + '
'; + depth = 2; + break; + case 'TR': + div.innerHTML = '' + html.stripScripts() + '
'; + depth = 3; + break; + case 'TD': + div.innerHTML = '
' + html.stripScripts() + '
'; + depth = 4; + } + $A(element.childNodes).each(function(node) { element.removeChild(node) }); + depth.times(function() { div = div.firstChild }); + $A(div.childNodes).each(function(node) { element.appendChild(node) }); + } else { + element.innerHTML = html.stripScripts(); + } + setTimeout(function() { html.evalScripts() }, 10); + return element; + } +} +else if (Prototype.Browser.Gecko) { + Element.Methods.setOpacity = function(element, value) { + element = $(element); + element.style.opacity = (value == 1) ? 0.999999 : + (value === '') ? '' : (value < 0.00001) ? 0 : value; + return element; + }; +} + +Element._attributeTranslations = { + names: { + colspan: "colSpan", + rowspan: "rowSpan", + valign: "vAlign", + datetime: "dateTime", + accesskey: "accessKey", + tabindex: "tabIndex", + enctype: "encType", + maxlength: "maxLength", + readonly: "readOnly", + longdesc: "longDesc" + }, + values: { + _getAttr: function(element, attribute) { + return element.getAttribute(attribute, 2); + }, + _flag: function(element, attribute) { + return $(element).hasAttribute(attribute) ? attribute : null; + }, + style: function(element) { + return element.style.cssText.toLowerCase(); + }, + title: function(element) { + var node = element.getAttributeNode('title'); + return node.specified ? node.nodeValue : null; + } + } +}; + +(function() { + Object.extend(this, { + href: this._getAttr, + src: this._getAttr, + type: this._getAttr, + disabled: this._flag, + checked: this._flag, + readonly: this._flag, + multiple: this._flag + }); +}).call(Element._attributeTranslations.values); + +Element.Methods.Simulated = { + hasAttribute: function(element, attribute) { + var t = Element._attributeTranslations, node; + attribute = t.names[attribute] || attribute; + node = $(element).getAttributeNode(attribute); + return node && node.specified; + } +}; + +Element.Methods.ByTag = {}; + +Object.extend(Element, Element.Methods); + +if (!Prototype.BrowserFeatures.ElementExtensions && + document.createElement('div').__proto__) { + window.HTMLElement = {}; + window.HTMLElement.prototype = document.createElement('div').__proto__; + Prototype.BrowserFeatures.ElementExtensions = true; +} + +Element.hasAttribute = function(element, attribute) { + if (element.hasAttribute) return element.hasAttribute(attribute); + return Element.Methods.Simulated.hasAttribute(element, attribute); +}; + +Element.addMethods = function(methods) { + var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag; + + if (!methods) { + Object.extend(Form, Form.Methods); + Object.extend(Form.Element, Form.Element.Methods); + Object.extend(Element.Methods.ByTag, { + "FORM": Object.clone(Form.Methods), + "INPUT": Object.clone(Form.Element.Methods), + "SELECT": Object.clone(Form.Element.Methods), + "TEXTAREA": Object.clone(Form.Element.Methods) + }); + } + + if (arguments.length == 2) { + var tagName = methods; + methods = arguments[1]; + } + + if (!tagName) Object.extend(Element.Methods, methods || {}); + else { + if (tagName.constructor == Array) tagName.each(extend); + else extend(tagName); + } + + function extend(tagName) { + tagName = tagName.toUpperCase(); + if (!Element.Methods.ByTag[tagName]) + Element.Methods.ByTag[tagName] = {}; + Object.extend(Element.Methods.ByTag[tagName], methods); + } + + function copy(methods, destination, onlyIfAbsent) { + onlyIfAbsent = onlyIfAbsent || false; + var cache = Element.extend.cache; + for (var property in methods) { + var value = methods[property]; + if (!onlyIfAbsent || !(property in destination)) + destination[property] = cache.findOrStore(value); + } + } + + function findDOMClass(tagName) { + var klass; + var trans = { + "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph", + "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList", + "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading", + "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote", + "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION": + "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD": + "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR": + "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET": + "FrameSet", "IFRAME": "IFrame" + }; + if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element'; + if (window[klass]) return window[klass]; + klass = 'HTML' + tagName + 'Element'; + if (window[klass]) return window[klass]; + klass = 'HTML' + tagName.capitalize() + 'Element'; + if (window[klass]) return window[klass]; + + window[klass] = {}; + window[klass].prototype = document.createElement(tagName).__proto__; + return window[klass]; + } + + if (F.ElementExtensions) { + copy(Element.Methods, HTMLElement.prototype); + copy(Element.Methods.Simulated, HTMLElement.prototype, true); + } + + if (F.SpecificElementExtensions) { + for (var tag in Element.Methods.ByTag) { + var klass = findDOMClass(tag); + if (typeof klass == "undefined") continue; + copy(T[tag], klass.prototype); + } + } + + Object.extend(Element, Element.Methods); + delete Element.ByTag; +}; + +var Toggle = { display: Element.toggle }; + +/*--------------------------------------------------------------------------*/ + +Abstract.Insertion = function(adjacency) { + this.adjacency = adjacency; +} + +Abstract.Insertion.prototype = { + initialize: function(element, content) { + this.element = $(element); + this.content = content.stripScripts(); + + if (this.adjacency && this.element.insertAdjacentHTML) { + try { + this.element.insertAdjacentHTML(this.adjacency, this.content); + } catch (e) { + var tagName = this.element.tagName.toUpperCase(); + if (['TBODY', 'TR'].include(tagName)) { + this.insertContent(this.contentFromAnonymousTable()); + } else { + throw e; + } + } + } else { + this.range = this.element.ownerDocument.createRange(); + if (this.initializeRange) this.initializeRange(); + this.insertContent([this.range.createContextualFragment(this.content)]); + } + + setTimeout(function() {content.evalScripts()}, 10); + }, + + contentFromAnonymousTable: function() { + var div = document.createElement('div'); + div.innerHTML = '' + this.content + '
'; + return $A(div.childNodes[0].childNodes[0].childNodes); + } +} + +var Insertion = new Object(); + +Insertion.Before = Class.create(); +Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), { + initializeRange: function() { + this.range.setStartBefore(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.parentNode.insertBefore(fragment, this.element); + }).bind(this)); + } +}); + +Insertion.Top = Class.create(); +Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), { + initializeRange: function() { + this.range.selectNodeContents(this.element); + this.range.collapse(true); + }, + + insertContent: function(fragments) { + fragments.reverse(false).each((function(fragment) { + this.element.insertBefore(fragment, this.element.firstChild); + }).bind(this)); + } +}); + +Insertion.Bottom = Class.create(); +Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), { + initializeRange: function() { + this.range.selectNodeContents(this.element); + this.range.collapse(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.appendChild(fragment); + }).bind(this)); + } +}); + +Insertion.After = Class.create(); +Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), { + initializeRange: function() { + this.range.setStartAfter(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.parentNode.insertBefore(fragment, + this.element.nextSibling); + }).bind(this)); + } +}); + +/*--------------------------------------------------------------------------*/ + +Element.ClassNames = Class.create(); +Element.ClassNames.prototype = { + initialize: function(element) { + this.element = $(element); + }, + + _each: function(iterator) { + this.element.className.split(/\s+/).select(function(name) { + return name.length > 0; + })._each(iterator); + }, + + set: function(className) { + this.element.className = className; + }, + + add: function(classNameToAdd) { + if (this.include(classNameToAdd)) return; + this.set($A(this).concat(classNameToAdd).join(' ')); + }, + + remove: function(classNameToRemove) { + if (!this.include(classNameToRemove)) return; + this.set($A(this).without(classNameToRemove).join(' ')); + }, + + toString: function() { + return $A(this).join(' '); + } +}; + +Object.extend(Element.ClassNames.prototype, Enumerable); +/* Portions of the Selector class are derived from Jack Slocum’s DomQuery, + * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style + * license. Please see http://www.yui-ext.com/ for more information. */ + +var Selector = Class.create(); + +Selector.prototype = { + initialize: function(expression) { + this.expression = expression.strip(); + this.compileMatcher(); + }, + + compileMatcher: function() { + // Selectors with namespaced attributes can't use the XPath version + if (Prototype.BrowserFeatures.XPath && !(/\[[\w-]*?:/).test(this.expression)) + return this.compileXPathMatcher(); + + var e = this.expression, ps = Selector.patterns, h = Selector.handlers, + c = Selector.criteria, le, p, m; + + if (Selector._cache[e]) { + this.matcher = Selector._cache[e]; return; + } + this.matcher = ["this.matcher = function(root) {", + "var r = root, h = Selector.handlers, c = false, n;"]; + + while (e && le != e && (/\S/).test(e)) { + le = e; + for (var i in ps) { + p = ps[i]; + if (m = e.match(p)) { + this.matcher.push(typeof c[i] == 'function' ? c[i](m) : + new Template(c[i]).evaluate(m)); + e = e.replace(m[0], ''); + break; + } + } + } + + this.matcher.push("return h.unique(n);\n}"); + eval(this.matcher.join('\n')); + Selector._cache[this.expression] = this.matcher; + }, + + compileXPathMatcher: function() { + var e = this.expression, ps = Selector.patterns, + x = Selector.xpath, le, m; + + if (Selector._cache[e]) { + this.xpath = Selector._cache[e]; return; + } + + this.matcher = ['.//*']; + while (e && le != e && (/\S/).test(e)) { + le = e; + for (var i in ps) { + if (m = e.match(ps[i])) { + this.matcher.push(typeof x[i] == 'function' ? x[i](m) : + new Template(x[i]).evaluate(m)); + e = e.replace(m[0], ''); + break; + } + } + } + + this.xpath = this.matcher.join(''); + Selector._cache[this.expression] = this.xpath; + }, + + findElements: function(root) { + root = root || document; + if (this.xpath) return document._getElementsByXPath(this.xpath, root); + return this.matcher(root); + }, + + match: function(element) { + return this.findElements(document).include(element); + }, + + toString: function() { + return this.expression; + }, + + inspect: function() { + return "#"; + } +}; + +Object.extend(Selector, { + _cache: {}, + + xpath: { + descendant: "//*", + child: "/*", + adjacent: "/following-sibling::*[1]", + laterSibling: '/following-sibling::*', + tagName: function(m) { + if (m[1] == '*') return ''; + return "[local-name()='" + m[1].toLowerCase() + + "' or local-name()='" + m[1].toUpperCase() + "']"; + }, + className: "[contains(concat(' ', @class, ' '), ' #{1} ')]", + id: "[@id='#{1}']", + attrPresence: "[@#{1}]", + attr: function(m) { + m[3] = m[5] || m[6]; + return new Template(Selector.xpath.operators[m[2]]).evaluate(m); + }, + pseudo: function(m) { + var h = Selector.xpath.pseudos[m[1]]; + if (!h) return ''; + if (typeof h === 'function') return h(m); + return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m); + }, + operators: { + '=': "[@#{1}='#{3}']", + '!=': "[@#{1}!='#{3}']", + '^=': "[starts-with(@#{1}, '#{3}')]", + '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']", + '*=': "[contains(@#{1}, '#{3}')]", + '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]", + '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]" + }, + pseudos: { + 'first-child': '[not(preceding-sibling::*)]', + 'last-child': '[not(following-sibling::*)]', + 'only-child': '[not(preceding-sibling::* or following-sibling::*)]', + 'empty': "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]", + 'checked': "[@checked]", + 'disabled': "[@disabled]", + 'enabled': "[not(@disabled)]", + 'not': function(m) { + var e = m[6], p = Selector.patterns, + x = Selector.xpath, le, m, v; + + var exclusion = []; + while (e && le != e && (/\S/).test(e)) { + le = e; + for (var i in p) { + if (m = e.match(p[i])) { + v = typeof x[i] == 'function' ? x[i](m) : new Template(x[i]).evaluate(m); + exclusion.push("(" + v.substring(1, v.length - 1) + ")"); + e = e.replace(m[0], ''); + break; + } + } + } + return "[not(" + exclusion.join(" and ") + ")]"; + }, + 'nth-child': function(m) { + return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m); + }, + 'nth-last-child': function(m) { + return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m); + }, + 'nth-of-type': function(m) { + return Selector.xpath.pseudos.nth("position() ", m); + }, + 'nth-last-of-type': function(m) { + return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m); + }, + 'first-of-type': function(m) { + m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m); + }, + 'last-of-type': function(m) { + m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m); + }, + 'only-of-type': function(m) { + var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m); + }, + nth: function(fragment, m) { + var mm, formula = m[6], predicate; + if (formula == 'even') formula = '2n+0'; + if (formula == 'odd') formula = '2n+1'; + if (mm = formula.match(/^(\d+)$/)) // digit only + return '[' + fragment + "= " + mm[1] + ']'; + if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b + if (mm[1] == "-") mm[1] = -1; + var a = mm[1] ? Number(mm[1]) : 1; + var b = mm[2] ? Number(mm[2]) : 0; + predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " + + "((#{fragment} - #{b}) div #{a} >= 0)]"; + return new Template(predicate).evaluate({ + fragment: fragment, a: a, b: b }); + } + } + } + }, + + criteria: { + tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;', + className: 'n = h.className(n, r, "#{1}", c); c = false;', + id: 'n = h.id(n, r, "#{1}", c); c = false;', + attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;', + attr: function(m) { + m[3] = (m[5] || m[6]); + return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m); + }, + pseudo: function(m) { + if (m[6]) m[6] = m[6].replace(/"/g, '\\"'); + return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m); + }, + descendant: 'c = "descendant";', + child: 'c = "child";', + adjacent: 'c = "adjacent";', + laterSibling: 'c = "laterSibling";' + }, + + patterns: { + // combinators must be listed first + // (and descendant needs to be last combinator) + laterSibling: /^\s*~\s*/, + child: /^\s*>\s*/, + adjacent: /^\s*\+\s*/, + descendant: /^\s/, + + // selectors follow + tagName: /^\s*(\*|[\w\-]+)(\b|$)?/, + id: /^#([\w\-\*]+)(\b|$)/, + className: /^\.([\w\-\*]+)(\b|$)/, + pseudo: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|\s|(?=:))/, + attrPresence: /^\[([\w]+)\]/, + attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\]]*?)\4|([^'"][^\]]*?)))?\]/ + }, + + handlers: { + // UTILITY FUNCTIONS + // joins two collections + concat: function(a, b) { + for (var i = 0, node; node = b[i]; i++) + a.push(node); + return a; + }, + + // marks an array of nodes for counting + mark: function(nodes) { + for (var i = 0, node; node = nodes[i]; i++) + node._counted = true; + return nodes; + }, + + unmark: function(nodes) { + for (var i = 0, node; node = nodes[i]; i++) + node._counted = undefined; + return nodes; + }, + + // mark each child node with its position (for nth calls) + // "ofType" flag indicates whether we're indexing for nth-of-type + // rather than nth-child + index: function(parentNode, reverse, ofType) { + parentNode._counted = true; + if (reverse) { + for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) { + node = nodes[i]; + if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++; + } + } else { + for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++) + if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++; + } + }, + + // filters out duplicates and extends all nodes + unique: function(nodes) { + if (nodes.length == 0) return nodes; + var results = [], n; + for (var i = 0, l = nodes.length; i < l; i++) + if (!(n = nodes[i])._counted) { + n._counted = true; + results.push(Element.extend(n)); + } + return Selector.handlers.unmark(results); + }, + + // COMBINATOR FUNCTIONS + descendant: function(nodes) { + var h = Selector.handlers; + for (var i = 0, results = [], node; node = nodes[i]; i++) + h.concat(results, node.getElementsByTagName('*')); + return results; + }, + + child: function(nodes) { + var h = Selector.handlers; + for (var i = 0, results = [], node; node = nodes[i]; i++) { + for (var j = 0, children = [], child; child = node.childNodes[j]; j++) + if (child.nodeType == 1 && child.tagName != '!') results.push(child); + } + return results; + }, + + adjacent: function(nodes) { + for (var i = 0, results = [], node; node = nodes[i]; i++) { + var next = this.nextElementSibling(node); + if (next) results.push(next); + } + return results; + }, + + laterSibling: function(nodes) { + var h = Selector.handlers; + for (var i = 0, results = [], node; node = nodes[i]; i++) + h.concat(results, Element.nextSiblings(node)); + return results; + }, + + nextElementSibling: function(node) { + while (node = node.nextSibling) + if (node.nodeType == 1) return node; + return null; + }, + + previousElementSibling: function(node) { + while (node = node.previousSibling) + if (node.nodeType == 1) return node; + return null; + }, + + // TOKEN FUNCTIONS + tagName: function(nodes, root, tagName, combinator) { + tagName = tagName.toUpperCase(); + var results = [], h = Selector.handlers; + if (nodes) { + if (combinator) { + // fastlane for ordinary descendant combinators + if (combinator == "descendant") { + for (var i = 0, node; node = nodes[i]; i++) + h.concat(results, node.getElementsByTagName(tagName)); + return results; + } else nodes = this[combinator](nodes); + if (tagName == "*") return nodes; + } + for (var i = 0, node; node = nodes[i]; i++) + if (node.tagName.toUpperCase() == tagName) results.push(node); + return results; + } else return root.getElementsByTagName(tagName); + }, + + id: function(nodes, root, id, combinator) { + var targetNode = $(id), h = Selector.handlers; + if (!nodes && root == document) return targetNode ? [targetNode] : []; + if (nodes) { + if (combinator) { + if (combinator == 'child') { + for (var i = 0, node; node = nodes[i]; i++) + if (targetNode.parentNode == node) return [targetNode]; + } else if (combinator == 'descendant') { + for (var i = 0, node; node = nodes[i]; i++) + if (Element.descendantOf(targetNode, node)) return [targetNode]; + } else if (combinator == 'adjacent') { + for (var i = 0, node; node = nodes[i]; i++) + if (Selector.handlers.previousElementSibling(targetNode) == node) + return [targetNode]; + } else nodes = h[combinator](nodes); + } + for (var i = 0, node; node = nodes[i]; i++) + if (node == targetNode) return [targetNode]; + return []; + } + return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : []; + }, + + className: function(nodes, root, className, combinator) { + if (nodes && combinator) nodes = this[combinator](nodes); + return Selector.handlers.byClassName(nodes, root, className); + }, + + byClassName: function(nodes, root, className) { + if (!nodes) nodes = Selector.handlers.descendant([root]); + var needle = ' ' + className + ' '; + for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) { + nodeClassName = node.className; + if (nodeClassName.length == 0) continue; + if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle)) + results.push(node); + } + return results; + }, + + attrPresence: function(nodes, root, attr) { + var results = []; + for (var i = 0, node; node = nodes[i]; i++) + if (Element.hasAttribute(node, attr)) results.push(node); + return results; + }, + + attr: function(nodes, root, attr, value, operator) { + if (!nodes) nodes = root.getElementsByTagName("*"); + var handler = Selector.operators[operator], results = []; + for (var i = 0, node; node = nodes[i]; i++) { + var nodeValue = Element.readAttribute(node, attr); + if (nodeValue === null) continue; + if (handler(nodeValue, value)) results.push(node); + } + return results; + }, + + pseudo: function(nodes, name, value, root, combinator) { + if (nodes && combinator) nodes = this[combinator](nodes); + if (!nodes) nodes = root.getElementsByTagName("*"); + return Selector.pseudos[name](nodes, value, root); + } + }, + + pseudos: { + 'first-child': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) { + if (Selector.handlers.previousElementSibling(node)) continue; + results.push(node); + } + return results; + }, + 'last-child': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) { + if (Selector.handlers.nextElementSibling(node)) continue; + results.push(node); + } + return results; + }, + 'only-child': function(nodes, value, root) { + var h = Selector.handlers; + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (!h.previousElementSibling(node) && !h.nextElementSibling(node)) + results.push(node); + return results; + }, + 'nth-child': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, formula, root); + }, + 'nth-last-child': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, formula, root, true); + }, + 'nth-of-type': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, formula, root, false, true); + }, + 'nth-last-of-type': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, formula, root, true, true); + }, + 'first-of-type': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, "1", root, false, true); + }, + 'last-of-type': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, "1", root, true, true); + }, + 'only-of-type': function(nodes, formula, root) { + var p = Selector.pseudos; + return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root); + }, + + // handles the an+b logic + getIndices: function(a, b, total) { + if (a == 0) return b > 0 ? [b] : []; + return $R(1, total).inject([], function(memo, i) { + if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i); + return memo; + }); + }, + + // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type + nth: function(nodes, formula, root, reverse, ofType) { + if (nodes.length == 0) return []; + if (formula == 'even') formula = '2n+0'; + if (formula == 'odd') formula = '2n+1'; + var h = Selector.handlers, results = [], indexed = [], m; + h.mark(nodes); + for (var i = 0, node; node = nodes[i]; i++) { + if (!node.parentNode._counted) { + h.index(node.parentNode, reverse, ofType); + indexed.push(node.parentNode); + } + } + if (formula.match(/^\d+$/)) { // just a number + formula = Number(formula); + for (var i = 0, node; node = nodes[i]; i++) + if (node.nodeIndex == formula) results.push(node); + } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b + if (m[1] == "-") m[1] = -1; + var a = m[1] ? Number(m[1]) : 1; + var b = m[2] ? Number(m[2]) : 0; + var indices = Selector.pseudos.getIndices(a, b, nodes.length); + for (var i = 0, node, l = indices.length; node = nodes[i]; i++) { + for (var j = 0; j < l; j++) + if (node.nodeIndex == indices[j]) results.push(node); + } + } + h.unmark(nodes); + h.unmark(indexed); + return results; + }, + + 'empty': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) { + // IE treats comments as element nodes + if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue; + results.push(node); + } + return results; + }, + + 'not': function(nodes, selector, root) { + var h = Selector.handlers, selectorType, m; + var exclusions = new Selector(selector).findElements(root); + h.mark(exclusions); + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (!node._counted) results.push(node); + h.unmark(exclusions); + return results; + }, + + 'enabled': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (!node.disabled) results.push(node); + return results; + }, + + 'disabled': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (node.disabled) results.push(node); + return results; + }, + + 'checked': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (node.checked) results.push(node); + return results; + } + }, + + operators: { + '=': function(nv, v) { return nv == v; }, + '!=': function(nv, v) { return nv != v; }, + '^=': function(nv, v) { return nv.startsWith(v); }, + '$=': function(nv, v) { return nv.endsWith(v); }, + '*=': function(nv, v) { return nv.include(v); }, + '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); }, + '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); } + }, + + matchElements: function(elements, expression) { + var matches = new Selector(expression).findElements(), h = Selector.handlers; + h.mark(matches); + for (var i = 0, results = [], element; element = elements[i]; i++) + if (element._counted) results.push(element); + h.unmark(matches); + return results; + }, + + findElement: function(elements, expression, index) { + if (typeof expression == 'number') { + index = expression; expression = false; + } + return Selector.matchElements(elements, expression || '*')[index || 0]; + }, + + findChildElements: function(element, expressions) { + var exprs = expressions.join(','), expressions = []; + exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) { + expressions.push(m[1].strip()); + }); + var results = [], h = Selector.handlers; + for (var i = 0, l = expressions.length, selector; i < l; i++) { + selector = new Selector(expressions[i].strip()); + h.concat(results, selector.findElements(element)); + } + return (l > 1) ? h.unique(results) : results; + } +}); + +function $$() { + return Selector.findChildElements(document, $A(arguments)); +} +var Form = { + reset: function(form) { + $(form).reset(); + return form; + }, + + serializeElements: function(elements, getHash) { + var data = elements.inject({}, function(result, element) { + if (!element.disabled && element.name) { + var key = element.name, value = $(element).getValue(); + if (value != null) { + if (key in result) { + if (result[key].constructor != Array) result[key] = [result[key]]; + result[key].push(value); + } + else result[key] = value; + } + } + return result; + }); + + return getHash ? data : Hash.toQueryString(data); + } +}; + +Form.Methods = { + serialize: function(form, getHash) { + return Form.serializeElements(Form.getElements(form), getHash); + }, + + getElements: function(form) { + return $A($(form).getElementsByTagName('*')).inject([], + function(elements, child) { + if (Form.Element.Serializers[child.tagName.toLowerCase()]) + elements.push(Element.extend(child)); + return elements; + } + ); + }, + + getInputs: function(form, typeName, name) { + form = $(form); + var inputs = form.getElementsByTagName('input'); + + if (!typeName && !name) return $A(inputs).map(Element.extend); + + for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) { + var input = inputs[i]; + if ((typeName && input.type != typeName) || (name && input.name != name)) + continue; + matchingInputs.push(Element.extend(input)); + } + + return matchingInputs; + }, + + disable: function(form) { + form = $(form); + Form.getElements(form).invoke('disable'); + return form; + }, + + enable: function(form) { + form = $(form); + Form.getElements(form).invoke('enable'); + return form; + }, + + findFirstElement: function(form) { + return $(form).getElements().find(function(element) { + return element.type != 'hidden' && !element.disabled && + ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); + }); + }, + + focusFirstElement: function(form) { + form = $(form); + form.findFirstElement().activate(); + return form; + }, + + request: function(form, options) { + form = $(form), options = Object.clone(options || {}); + + var params = options.parameters; + options.parameters = form.serialize(true); + + if (params) { + if (typeof params == 'string') params = params.toQueryParams(); + Object.extend(options.parameters, params); + } + + if (form.hasAttribute('method') && !options.method) + options.method = form.method; + + return new Ajax.Request(form.readAttribute('action'), options); + } +} + +/*--------------------------------------------------------------------------*/ + +Form.Element = { + focus: function(element) { + $(element).focus(); + return element; + }, + + select: function(element) { + $(element).select(); + return element; + } +} + +Form.Element.Methods = { + serialize: function(element) { + element = $(element); + if (!element.disabled && element.name) { + var value = element.getValue(); + if (value != undefined) { + var pair = {}; + pair[element.name] = value; + return Hash.toQueryString(pair); + } + } + return ''; + }, + + getValue: function(element) { + element = $(element); + var method = element.tagName.toLowerCase(); + return Form.Element.Serializers[method](element); + }, + + clear: function(element) { + $(element).value = ''; + return element; + }, + + present: function(element) { + return $(element).value != ''; + }, + + activate: function(element) { + element = $(element); + try { + element.focus(); + if (element.select && (element.tagName.toLowerCase() != 'input' || + !['button', 'reset', 'submit'].include(element.type))) + element.select(); + } catch (e) {} + return element; + }, + + disable: function(element) { + element = $(element); + element.blur(); + element.disabled = true; + return element; + }, + + enable: function(element) { + element = $(element); + element.disabled = false; + return element; + } +} + +/*--------------------------------------------------------------------------*/ + +var Field = Form.Element; +var $F = Form.Element.Methods.getValue; + +/*--------------------------------------------------------------------------*/ + +Form.Element.Serializers = { + input: function(element) { + switch (element.type.toLowerCase()) { + case 'checkbox': + case 'radio': + return Form.Element.Serializers.inputSelector(element); + default: + return Form.Element.Serializers.textarea(element); + } + }, + + inputSelector: function(element) { + return element.checked ? element.value : null; + }, + + textarea: function(element) { + return element.value; + }, + + select: function(element) { + return this[element.type == 'select-one' ? + 'selectOne' : 'selectMany'](element); + }, + + selectOne: function(element) { + var index = element.selectedIndex; + return index >= 0 ? this.optionValue(element.options[index]) : null; + }, + + selectMany: function(element) { + var values, length = element.length; + if (!length) return null; + + for (var i = 0, values = []; i < length; i++) { + var opt = element.options[i]; + if (opt.selected) values.push(this.optionValue(opt)); + } + return values; + }, + + optionValue: function(opt) { + // extend element because hasAttribute may not be native + return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text; + } +} + +/*--------------------------------------------------------------------------*/ + +Abstract.TimedObserver = function() {} +Abstract.TimedObserver.prototype = { + initialize: function(element, frequency, callback) { + this.frequency = frequency; + this.element = $(element); + this.callback = callback; + + this.lastValue = this.getValue(); + this.registerCallback(); + }, + + registerCallback: function() { + setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); + }, + + onTimerEvent: function() { + var value = this.getValue(); + var changed = ('string' == typeof this.lastValue && 'string' == typeof value + ? this.lastValue != value : String(this.lastValue) != String(value)); + if (changed) { + this.callback(this.element, value); + this.lastValue = value; + } + } +} + +Form.Element.Observer = Class.create(); +Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.Observer = Class.create(); +Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { + getValue: function() { + return Form.serialize(this.element); + } +}); + +/*--------------------------------------------------------------------------*/ + +Abstract.EventObserver = function() {} +Abstract.EventObserver.prototype = { + initialize: function(element, callback) { + this.element = $(element); + this.callback = callback; + + this.lastValue = this.getValue(); + if (this.element.tagName.toLowerCase() == 'form') + this.registerFormCallbacks(); + else + this.registerCallback(this.element); + }, + + onElementEvent: function() { + var value = this.getValue(); + if (this.lastValue != value) { + this.callback(this.element, value); + this.lastValue = value; + } + }, + + registerFormCallbacks: function() { + Form.getElements(this.element).each(this.registerCallback.bind(this)); + }, + + registerCallback: function(element) { + if (element.type) { + switch (element.type.toLowerCase()) { + case 'checkbox': + case 'radio': + Event.observe(element, 'click', this.onElementEvent.bind(this)); + break; + default: + Event.observe(element, 'change', this.onElementEvent.bind(this)); + break; + } + } + } +} + +Form.Element.EventObserver = Class.create(); +Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.EventObserver = Class.create(); +Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { + getValue: function() { + return Form.serialize(this.element); + } +}); +if (!window.Event) { + var Event = new Object(); +} + +Object.extend(Event, { + KEY_BACKSPACE: 8, + KEY_TAB: 9, + KEY_RETURN: 13, + KEY_ESC: 27, + KEY_LEFT: 37, + KEY_UP: 38, + KEY_RIGHT: 39, + KEY_DOWN: 40, + KEY_DELETE: 46, + KEY_HOME: 36, + KEY_END: 35, + KEY_PAGEUP: 33, + KEY_PAGEDOWN: 34, + + element: function(event) { + return $(event.target || event.srcElement); + }, + + isLeftClick: function(event) { + return (((event.which) && (event.which == 1)) || + ((event.button) && (event.button == 1))); + }, + + pointerX: function(event) { + return event.pageX || (event.clientX + + (document.documentElement.scrollLeft || document.body.scrollLeft)); + }, + + pointerY: function(event) { + return event.pageY || (event.clientY + + (document.documentElement.scrollTop || document.body.scrollTop)); + }, + + stop: function(event) { + if (event.preventDefault) { + event.preventDefault(); + event.stopPropagation(); + } else { + event.returnValue = false; + event.cancelBubble = true; + } + }, + + // find the first node with the given tagName, starting from the + // node the event was triggered on; traverses the DOM upwards + findElement: function(event, tagName) { + var element = Event.element(event); + while (element.parentNode && (!element.tagName || + (element.tagName.toUpperCase() != tagName.toUpperCase()))) + element = element.parentNode; + return element; + }, + + observers: false, + + _observeAndCache: function(element, name, observer, useCapture) { + if (!this.observers) this.observers = []; + if (element.addEventListener) { + this.observers.push([element, name, observer, useCapture]); + element.addEventListener(name, observer, useCapture); + } else if (element.attachEvent) { + this.observers.push([element, name, observer, useCapture]); + element.attachEvent('on' + name, observer); + } + }, + + unloadCache: function() { + if (!Event.observers) return; + for (var i = 0, length = Event.observers.length; i < length; i++) { + Event.stopObserving.apply(this, Event.observers[i]); + Event.observers[i][0] = null; + } + Event.observers = false; + }, + + observe: function(element, name, observer, useCapture) { + element = $(element); + useCapture = useCapture || false; + + if (name == 'keypress' && + (Prototype.Browser.WebKit || element.attachEvent)) + name = 'keydown'; + + Event._observeAndCache(element, name, observer, useCapture); + }, + + stopObserving: function(element, name, observer, useCapture) { + element = $(element); + useCapture = useCapture || false; + + if (name == 'keypress' && + (Prototype.Browser.WebKit || element.attachEvent)) + name = 'keydown'; + + if (element.removeEventListener) { + element.removeEventListener(name, observer, useCapture); + } else if (element.detachEvent) { + try { + element.detachEvent('on' + name, observer); + } catch (e) {} + } + } +}); + +/* prevent memory leaks in IE */ +if (Prototype.Browser.IE) + Event.observe(window, 'unload', Event.unloadCache, false); +var Position = { + // set to true if needed, warning: firefox performance problems + // NOT neeeded for page scrolling, only if draggable contained in + // scrollable elements + includeScrollOffsets: false, + + // must be called before calling withinIncludingScrolloffset, every time the + // page is scrolled + prepare: function() { + this.deltaX = window.pageXOffset + || document.documentElement.scrollLeft + || document.body.scrollLeft + || 0; + this.deltaY = window.pageYOffset + || document.documentElement.scrollTop + || document.body.scrollTop + || 0; + }, + + realOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.scrollTop || 0; + valueL += element.scrollLeft || 0; + element = element.parentNode; + } while (element); + return [valueL, valueT]; + }, + + cumulativeOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + } while (element); + return [valueL, valueT]; + }, + + positionedOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + if (element) { + if(element.tagName=='BODY') break; + var p = Element.getStyle(element, 'position'); + if (p == 'relative' || p == 'absolute') break; + } + } while (element); + return [valueL, valueT]; + }, + + offsetParent: function(element) { + if (element.offsetParent) return element.offsetParent; + if (element == document.body) return element; + + while ((element = element.parentNode) && element != document.body) + if (Element.getStyle(element, 'position') != 'static') + return element; + + return document.body; + }, + + // caches x/y coordinate pair to use with overlap + within: function(element, x, y) { + if (this.includeScrollOffsets) + return this.withinIncludingScrolloffsets(element, x, y); + this.xcomp = x; + this.ycomp = y; + this.offset = this.cumulativeOffset(element); + + return (y >= this.offset[1] && + y < this.offset[1] + element.offsetHeight && + x >= this.offset[0] && + x < this.offset[0] + element.offsetWidth); + }, + + withinIncludingScrolloffsets: function(element, x, y) { + var offsetcache = this.realOffset(element); + + this.xcomp = x + offsetcache[0] - this.deltaX; + this.ycomp = y + offsetcache[1] - this.deltaY; + this.offset = this.cumulativeOffset(element); + + return (this.ycomp >= this.offset[1] && + this.ycomp < this.offset[1] + element.offsetHeight && + this.xcomp >= this.offset[0] && + this.xcomp < this.offset[0] + element.offsetWidth); + }, + + // within must be called directly before + overlap: function(mode, element) { + if (!mode) return 0; + if (mode == 'vertical') + return ((this.offset[1] + element.offsetHeight) - this.ycomp) / + element.offsetHeight; + if (mode == 'horizontal') + return ((this.offset[0] + element.offsetWidth) - this.xcomp) / + element.offsetWidth; + }, + + page: function(forElement) { + var valueT = 0, valueL = 0; + + var element = forElement; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + + // Safari fix + if (element.offsetParent == document.body) + if (Element.getStyle(element,'position')=='absolute') break; + + } while (element = element.offsetParent); + + element = forElement; + do { + if (!window.opera || element.tagName=='BODY') { + valueT -= element.scrollTop || 0; + valueL -= element.scrollLeft || 0; + } + } while (element = element.parentNode); + + return [valueL, valueT]; + }, + + clone: function(source, target) { + var options = Object.extend({ + setLeft: true, + setTop: true, + setWidth: true, + setHeight: true, + offsetTop: 0, + offsetLeft: 0 + }, arguments[2] || {}) + + // find page position of source + source = $(source); + var p = Position.page(source); + + // find coordinate system to use + target = $(target); + var delta = [0, 0]; + var parent = null; + // delta [0,0] will do fine with position: fixed elements, + // position:absolute needs offsetParent deltas + if (Element.getStyle(target,'position') == 'absolute') { + parent = Position.offsetParent(target); + delta = Position.page(parent); + } + + // correct by body offsets (fixes Safari) + if (parent == document.body) { + delta[0] -= document.body.offsetLeft; + delta[1] -= document.body.offsetTop; + } + + // set position + if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; + if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; + if(options.setWidth) target.style.width = source.offsetWidth + 'px'; + if(options.setHeight) target.style.height = source.offsetHeight + 'px'; + }, + + absolutize: function(element) { + element = $(element); + if (element.style.position == 'absolute') return; + Position.prepare(); + + var offsets = Position.positionedOffset(element); + var top = offsets[1]; + var left = offsets[0]; + var width = element.clientWidth; + var height = element.clientHeight; + + element._originalLeft = left - parseFloat(element.style.left || 0); + element._originalTop = top - parseFloat(element.style.top || 0); + element._originalWidth = element.style.width; + element._originalHeight = element.style.height; + + element.style.position = 'absolute'; + element.style.top = top + 'px'; + element.style.left = left + 'px'; + element.style.width = width + 'px'; + element.style.height = height + 'px'; + }, + + relativize: function(element) { + element = $(element); + if (element.style.position == 'relative') return; + Position.prepare(); + + element.style.position = 'relative'; + var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); + var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); + + element.style.top = top + 'px'; + element.style.left = left + 'px'; + element.style.height = element._originalHeight; + element.style.width = element._originalWidth; + } +} + +// Safari returns margins on body which is incorrect if the child is absolutely +// positioned. For performance reasons, redefine Position.cumulativeOffset for +// KHTML/WebKit only. +if (Prototype.Browser.WebKit) { + Position.cumulativeOffset = function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + if (element.offsetParent == document.body) + if (Element.getStyle(element, 'position') == 'absolute') break; + + element = element.offsetParent; + } while (element); + + return [valueL, valueT]; + } +} + +Element.addMethods(); \ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/js/rico/css/coffee-with-milk.css b/NP_TrackBack/trunk/trackback/js/rico/css/coffee-with-milk.css new file mode 100644 index 0000000..86a1998 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/css/coffee-with-milk.css @@ -0,0 +1,73 @@ +/* +Based on "Coffee with milk" table design by Roger Johansson, 456 Berea Street +www.456bereastreet.com +================================================*/ + +.ricoLG_table { + border-top:1px solid #523A0B !important; + border-right:none; + font:normal 76%/150% "Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif; + color:#000; +} +tr.ricoLG_hdg .ricoLG_cell, tr.ricoLG_hdg th, tr.ricoLG_hdg td { /* td/th required for IE */ + background:#EBE5D9 !important; + line-height:normal; + text-align:left; +} + +tr.ricoLG_hdg th, tr.ricoLG_hdg td { + border-bottom:1px solid #523A0B; + background:#EBE5D9; + } + +tr.ricoLG_hdg th, tr.ricoLG_hdg td { + border-left: 1px solid #E0D8CD !important; +} + +.ricoLG_bottom th, .ricoLG_bottom td { + border-left: 1px solid #FFF; +} + +tr.ricoLG_hdg div.ricoLG_cell { + background:#EBE5D9; + font-weight:bold; + padding:0.5em 0 0.5em 0.5em; +} +div.ricoLG_outerDiv table a { + color:#523A0B; + text-decoration:none; + border-bottom:1px dotted; + } +div.ricoLG_outerDiv tbody a:visited { + color:#444; + font-weight:normal; + } +div.ricoLG_outerDiv table a:hover { + border-bottom-style:solid; + } + +.ricoLG_bottom div.ricoLG_oddRow { + background-color:#F7F4EE; + border-top: 1px solid #EBE5D9; + border-bottom: 1px solid #EBE5D9; +} +.ricoLG_bottom div.ricoLG_evenRow { + border-top: 1px solid #FFF; + border-bottom: 1px solid #FFF; +} +.ricoLG_selection { + background-color:#ffffee !important; + border-color:#523A0B !important; +} +.ricoLG_table { + border-style:none; +} + +caption { + font-family:Georgia,Times,serif; + font-weight:normal; + font-size:1.4em; + text-align:left; + margin:0; + padding:0.5em 0.25em; + } \ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/js/rico/css/grayedout.css b/NP_TrackBack/trunk/trackback/js/rico/css/grayedout.css new file mode 100644 index 0000000..d5a0dd4 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/css/grayedout.css @@ -0,0 +1,68 @@ +/* ------------------------------------------------------- +Based on Grayed Out table design +Author: Terence Ordona +URL: http://www.imaputz.com/ + ------------------------------------------------------- */ +div.ricoLG_outerDiv *, div.ricoLG_cell { + font-size: 11px; + font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; +} + +.ricoLG_table { + border-top: 1px solid #CCC; + border-right: 1px solid #CCC; +} + +tr.ricoLG_hdg th, tr.ricoLG_hdg td { + background-color: #FFF !important; + background: url(../images/grayedout.gif) #FFF repeat-x scroll center left; + border-bottom: 1px solid #CCC; +} + +.ricoLG_table th, .ricoLG_table td { + border-left: 1px solid #CCC; +} + +.ricoLG_bottom th, .ricoLG_bottom td { + border-bottom: 1px solid #CCC; +} + +.ricoLG_bottom div.ricoLG_cell { + border-bottom: none; + padding: 5px; +} + +tr.ricoLG_hdg .ricoLG_cell { + font-weight: normal; +} + +div.ricoLG_outerDiv a:visited, div.ricoLG_outerDiv a:link { + color: #009; + text-decoration: none; +} + +div.ricoLG_outerDiv a:hover { + color: #009; + text-decoration: underline; +} + +.ricoLG_oddRow { + background-color: #EEE; +} + +div.ricoLG_selection { + background-color: #999; + color: #FFF; +} + +div.ricoLG_highlightDiv { + border-color: #999; +} + +caption { + text-align: left; + font-size: 100%; + padding: .75em; + color: #000; +} + diff --git a/NP_TrackBack/trunk/trackback/js/rico/css/greenHdg.css b/NP_TrackBack/trunk/trackback/js/rico/css/greenHdg.css new file mode 100644 index 0000000..f46dfb1 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/css/greenHdg.css @@ -0,0 +1,8 @@ +/* display grid headings with a green background */ + +tr.ricoLG_hdg .ricoLG_cell, tr.ricoLG_hdg th, tr.ricoLG_hdg td { /* td/th required for IE */ + background-color : #cedebd !important; + color : #000000; + font-weight : bold; +} +div.ricoLG_selection { background-color: #cedebd; } diff --git a/NP_TrackBack/trunk/trackback/js/rico/css/iegradient.css b/NP_TrackBack/trunk/trackback/js/rico/css/iegradient.css new file mode 100644 index 0000000..6d4b80e --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/css/iegradient.css @@ -0,0 +1,3 @@ +tr.ricoLG_hdg .ricoLG_cell, tr.ricoLG_hdg th, tr.ricoLG_hdg td { /* td/th required for IE */ + Filter: progid:DXImageTransform.Microsoft.Gradient(gradientType=0,startColorStr=white,endColorStr=Gainsboro); +} diff --git a/NP_TrackBack/trunk/trackback/js/rico/css/ricoCalendar.css b/NP_TrackBack/trunk/trackback/js/rico/css/ricoCalendar.css new file mode 100644 index 0000000..18c3ad4 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/css/ricoCalendar.css @@ -0,0 +1,112 @@ +/* ricoCalendar */ + +div.ricoCalContainer, div.ricoTreeContainer { + position:absolute; + z-index:9999; + font-size:8pt; + left:0px; + top:0px; +} + +table.ricoCalTab { + border:1px solid #666666; +} + +table.ricoCalTab thead a { + border:1px solid #D4D0C8; + text-decoration: none; + color:black; +} + +table.ricoCalTab thead img { + border:none; + padding-left: 0.3em; + padding-right: 0.3em; +} + +table.ricoCalTab thead a:hover { + border:1px solid #666666; + cursor:pointer; +} + +table.ricoCalTab thead td { + background-color: #D4D0C8; + font-weight: bold; + text-align:center; + padding: 2px; +} + +table.ricoCalTab tfoot td { + color:#FFF; + text-align:center; + background-color: #666666; + padding: 2px; +} + +table.ricoCalTab tfoot span { + text-decoration: underline; + cursor:pointer; +} + +table.ricoCalTab tbody { + background-color: white; +} + +tr.ricoCalDayNames td { + font-weight: bold; + padding: 0px 2px 0px 2px; + text-align:right; +} + +td.ricoCal0, td.ricoCal1, td.ricoCal2, td.ricoCal3, td.ricoCal4, td.ricoCal5, td.ricoCal6, td.ricoCalToday, td.ricoCalEmpty { + text-decoration:none; + text-align:right; + width:3em; +} + +/* Monday-Friday */ +td.ricoCal1, td.ricoCal2, td.ricoCal3, td.ricoCal4, td.ricoCal5 { + cursor:pointer; + color:black; +} + +/* Sunday, Saturday */ +td.ricoCal0, td.ricoCal6 { + cursor:pointer; + color:#999; +} + +td.ricoCalToday { + cursor:pointer; + color:red; + font-weight:bold; +} + +td.ricoCalWeekNum { + background-color: #D4D0C8; + color:black; + text-align:center; +} + +.ricoCalMenu { + position:absolute; + background-color: #FEE; + border-bottom:1px solid #666666; + border-right:1px solid #666666; +} + +.ricoCalMenu td { + border-top:1px solid #666666; + border-left:1px solid #666666; +} + +.ricoCalMenu a { + display:block; + text-decoration:none; + color:black; + cursor:pointer; +} + +.ricoCalMenu a:hover { + background-color: #FCC; +} diff --git a/NP_TrackBack/trunk/trackback/js/rico/css/ricoGrid.css b/NP_TrackBack/trunk/trackback/js/rico/css/ricoGrid.css new file mode 100644 index 0000000..6760ce6 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/css/ricoGrid.css @@ -0,0 +1,125 @@ +div.ricoLG_outerDiv { + position:relative; + /*border:thin solid blue; /* for debugging */ +} + +div.ricoLG_innerDiv, div.ricoLG_frozenTabsDiv { + overflow:hidden; + margin:0px; + padding:0px; + position:absolute; + top:0px; +} + +div.ricoLG_scrollDiv { + overflow:scroll; + position:relative; +} + +div.ricoLG_scrollTabsDiv { + position:absolute; + top:0px; +} + +div.ricoLG_resizeDiv { + position:absolute; + top:0px; + width:1px; + z-index:2; + background-color:blue; +} + +div.ricoLG_highlightDiv { + position:absolute; + border: 2px solid black; +} + +.ricoLG_table { + margin: 0px; + padding: 0px; + border-right: 1px solid silver; + border-top: 1px solid silver; +} + +.ricoLG_table th, .ricoLG_table td { + border-left: 1px solid silver; +} + +table.ricoLG_bottom { + border-top-style: none; +} + +.ricoLG_evenRow { } +.ricoLG_oddRow { background-color: #EEE; } +.ricoLG_selection { background-color: #cedebd; } + +div.ricoLG_col { + overflow:hidden; + width:100px; +} + +.ricoLG_top div.ricoLG_col { + position:relative; +} + +.ricoLG_top div.ricoLG_Resize { + position:absolute; + width:5px; + height:100%; + top:0px; + cursor:e-resize; +} + +.ricoLG_HdrIcon { + padding-left:2px; + padding-right:2px; +} + +.ricoLG_bottom div.ricoLG_cell, .ricoLG_top th, .ricoLG_top td { + border-bottom: 1px solid silver; +} + +div.ricoLG_cell { + overflow:hidden; + height:1.2em; + padding-left: 3px; + margin: 0px; + font-size: 10pt; + padding-top:3px; + padding-bottom:3px; +} + +div.ricoLG_messageDiv { + position:absolute; + z-index:200; + border:1px solid green; + background-color:white; + font-weight:bold; + font-size:larger; + color:navy; + text-align:center; + padding:4px; +} + +p.ricoBookmark { + margin-bottom: 3px; + font-size: 10pt; +} + +div.alignleft { + text-align: left; +} + +div.aligncenter { + text-align: center; +} + +div.alignright { + text-align: right; +} + +span.ricoSessionTimer { + background-color:black; + color:white; +} + diff --git a/NP_TrackBack/trunk/trackback/js/rico/css/ricoLiveGridForms.css b/NP_TrackBack/trunk/trackback/js/rico/css/ricoLiveGridForms.css new file mode 100644 index 0000000..e43e729 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/css/ricoLiveGridForms.css @@ -0,0 +1,81 @@ +/* ricoLiveGridForms */ + +span.ricoSaveMsg { + background-color:yellow; +} + +span.ricoSessionTimer { + background-color:black; + color:white; +} + +div.ricoLG_editDiv, div.ricoLG_editResponseDiv { + color:#000; background:#E8ECF3; + overflow:auto; + padding:8px; + border: 1px solid navy; + position:absolute; + font-size: 10pt; + z-index:300; + top:0px; + left:0px; +} + +form .ricoEditLabel, form .ricoEditLabelWithHelp { + font-weight: bold; + text-align: left; + padding-right: 1em; +} + +form .ricoEditLabelWithHelp { + color: navy; +} + +form { + margin:0px; +} + +.tabHeader { + height: 1.8em; + color : #AAA; + background: #D8E0F2; + font-weight : bold; + float: left; + display: inline; + margin-left: 2px; + margin-right: 2px; + text-align: center; + white-space:nowrap; + overflow:hidden; +} + +.tabHover { + color : #666; + cursor: pointer; +} + +.tabSelected { + color : #444; + background: #CFD4E6; + cursor: auto; +} + +.tabContentContainer { + clear:both; +} + +div.ricoLG_editDiv .tabContent, div.ricoLG_editDiv .noTabContent { + color:#000; background:#CFD4E6; + overflow: hidden; + padding: 4px; + white-space:nowrap; +} + +div.ricoLG_editDiv .noTabContent { + float:left; /* required by IE7 */ +} + +span.ricoLookup { + display:none; +} + diff --git a/NP_TrackBack/trunk/trackback/js/rico/css/ricoMenu.css b/NP_TrackBack/trunk/trackback/js/rico/css/ricoMenu.css new file mode 100644 index 0000000..b694c79 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/css/ricoMenu.css @@ -0,0 +1,95 @@ +/* ricoMenu */ + +div.ricoMenu, div.ricoMenuSafari { +position: absolute; +z-index: 100; +border:1px solid #666; +padding:2px; +cursor:default; +visibility: hidden; +} + +div.ricoMenu, div.ricoMenu div.ricoMenuHeading, div.ricoMenu a { +background-color:menu; +color: menutext; +text-decoration: none; +font-family:tahoma,arial,helvetica,sans-serif; +font-size: 8pt; +display:block; +} + +div.ricoMenuSafari, div.ricoMenuSafari div.ricoMenuHeading, div.ricoMenuSafari a { +background-color:#EDEDED; +text-decoration: none; +font-family:tahoma,arial,helvetica,sans-serif; +font-size: 8pt; +display:block; +} + +div.ricoMenu div.ricoMenuHeading{ +padding: 1px 0px; +font-weight:bold; +} + +div.ricoMenuSafari div.ricoMenuHeading{ +padding: 1px 0px; +color: black; +display: block; +font-weight:bold; +} + +div.ricoMenu .enabled { +position: relative; +} + +div.ricoMenuSafari .enabled { +color: black; +} + +div.ricoMenu .enabled, div.ricoMenu .enabled-hover, div.ricoMenuSafari .enabled, div.ricoMenuSafari .enabled-hover, div.ricoMenu .disabled, div.ricoMenuSafari .disabled { +padding-left: 1em; +padding-top:0.1em; +padding-bottom:0.1em; +z-index: 101; +} + +div.ricoMenu .disabled, div.ricoMenuSafari .disabled { +color: #999; +} + +div.ricoMenu hr{ +height:1px; +margin:1px; +border:0; +color: menu; +background-color: menu; +} + +div.ricoMenu .enabled-hover, div.ricoMenu .ricoSubMenuOpen { + background-color: Highlight; + color: HighlightText; +} + +div.ricoMenuSafari .enabled-hover, div.ricoMenuSafari .ricoSubMenuOpen { + background-color: #1657B8; + color: white; +} + +div.ricoMenu .ricoSubMenu, div.ricoMenu .ricoSubMenuOpen, div.ricoMenuSafari .ricoSubMenu, div.ricoMenuSafari .ricoSubMenuOpen { +padding: 1px 0px; +display: block; +font-weight:bold; +z-index: 101; +position: relative; +} + +div.ricoMenu div.ricoMenuBreak, div.ricoMenuSafari div.ricoMenuBreak { +height:1px; +margin:3px 0 3px 0; +padding:0; +background-color: #AAA; +width:100%; +line-height:5px; +overflow:hidden; +} + diff --git a/NP_TrackBack/trunk/trackback/js/rico/css/ricoTree.css b/NP_TrackBack/trunk/trackback/js/rico/css/ricoTree.css new file mode 100644 index 0000000..33a457c --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/css/ricoTree.css @@ -0,0 +1,42 @@ +/* ricoTree */ + +div.ricoTreeContainer { + background-color:#cedebd; + padding:4px; + border:1px solid black; + top:0px; + left:0px; + position:absolute; + z-index:9999; +} + +div.ricoTree { + border:thin inset; + overflow:auto; + background-color:#FFF; +} + +div.ricoTree p, div.ricoTree a { + margin:0px; + padding-left:0.3em; + white-space:nowrap; +} + +div.ricoTree a { + cursor:pointer; + text-decoration:none; +} + +div.ricoTree a:hover { + background-color:#EEE; +} + +div.ricoTree img { + margin:0px; + padding:0px; + display:block; +} + +div.ricoTree * { + font-size:8pt; +} diff --git a/NP_TrackBack/trunk/trackback/js/rico/css/tanChisel.css b/NP_TrackBack/trunk/trackback/js/rico/css/tanChisel.css new file mode 100644 index 0000000..706437e --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/css/tanChisel.css @@ -0,0 +1,36 @@ +tr.ricoLG_hdg .ricoLG_cell, tr.ricoLG_hdg th, tr.ricoLG_hdg td { /* td/th required for IE */ + background-color:#e0e0c0 !important; + vertical-align:middle; +} + +tr.ricoLG_hdg div.ricoLG_cell { + border-top: 1px solid #F0F0E8; +} + +.ricoLG_bottom div.ricoLG_cell, .ricoLG_top th, .ricoLG_top td { + border-bottom: 1px solid #D8d0c0;; +} + +.ricoLG_table th, .ricoLG_table td { + border-left: 1px solid #F0F0E8; + border-right: 1px solid #D8d0c0; +} + +div.ricoMenu, div.ricoMenu div.ricoMenuHeading, div.ricoMenu .ricoSubMenu, div.ricoMenuSafari, div.ricoMenuSafari div.ricoMenuHeading, div.ricoMenuSafari .ricoSubMenu { + background-color:#f0f0e0; +} + +div.ricoMenu, div.ricoMenu div.ricoMenuHeading, div.ricoMenu .ricoSubMenu, div.ricoMenu .ricoSubMenuOpen, div.ricoMenuSafari, div.ricoMenuSafari div.ricoMenuHeading, div.ricoMenuSafari .ricoSubMenu, div.ricoMenuSafari .ricoSubMenuOpen { + border-top: 1px solid #F0F0E8; + border-left: 1px solid #F0F0E8; + border-bottom: 1px solid #D8d0c0;; + border-right: 1px solid #D8d0c0; +} + +.ricoLG_table { + border-style:none; +} + +div.ricoLG_selection { + background-color:#e0e0c0; +} diff --git a/NP_TrackBack/trunk/trackback/js/rico/css/warmfall.css b/NP_TrackBack/trunk/trackback/js/rico/css/warmfall.css new file mode 100644 index 0000000..1af5155 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/css/warmfall.css @@ -0,0 +1,63 @@ +/* ------------------------------------------------------- +Based on warm fall table design +Author: Mya Leigh +Theme: A Warm, Fall Table - Easy to Read +URL: http://www.myaleigh.com + ------------------------------------------------------- */ +.ricoLG_table { + border-top: 1px solid #84785e; + border-right: 1px solid #84785e; +} + +tr.ricoLG_hdg .ricoLG_cell, tr.ricoLG_hdg th, tr.ricoLG_hdg td { /* td/th required for IE */ + background-color: #a24116 !important; + color: #ffffff !important; +} + +.ricoLG_table th, .ricoLG_table td { + border-left: 1px solid #84785e; +} + +.ricoLG_bottom div.ricoLG_cell, .ricoLG_top th, .ricoLG_top td { + border-bottom: 1px solid #84785e; +} + +tr.ricoLG_hdg .ricoLG_cell { + background-color: #a24116; + border: 0; + color: #ffffff; + padding: .75em; + font: "Verdana", Arial, Helvetica, sans-serif; + font-weight: bold; +} + +div.ricoLG_outerDiv a:visited, div.ricoLG_outerDiv a:link, div.ricoLG_outerDiv a:active { + color: #101011; + text-decoration: none; +} + +div.ricoLG_outerDiv a:hover { + text-decoration: underline; +} + +div.ricoLG_outerDiv tbody a:visited { + color:#444; +} + +.ricoLG_oddRow { + background-color: #fffce1; + color: #101011; +} + +.ricoLG_selection { + background-color: #a24116; + color: #ffffff; +} + +caption { + text-align: left; + font-size: 100%; + padding: .75em; + color: #000; +} + diff --git a/NP_TrackBack/trunk/trackback/js/rico/export-owc.html b/NP_TrackBack/trunk/trackback/js/rico/export-owc.html new file mode 100644 index 0000000..8819eca --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/export-owc.html @@ -0,0 +1,34 @@ + + +Export + + + + + + diff --git a/NP_TrackBack/trunk/trackback/js/rico/export-plain.html b/NP_TrackBack/trunk/trackback/js/rico/export-plain.html new file mode 100644 index 0000000..b158c58 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/export-plain.html @@ -0,0 +1,28 @@ + + +Export + + + + + diff --git a/NP_TrackBack/trunk/trackback/js/rico/images/aline.gif b/NP_TrackBack/trunk/trackback/js/rico/images/aline.gif new file mode 100644 index 0000000000000000000000000000000000000000..7f5cb4346e9fa6b5522328ba104c475b02fb3c68 GIT binary patch literal 47 wcmZ?wbhEHb)M8{}XkY+=|NsB%fM}420~23M|H{*E`4`XGa;tmuyt<8 literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/js/rico/images/calarrow.png b/NP_TrackBack/trunk/trackback/js/rico/images/calarrow.png new file mode 100644 index 0000000000000000000000000000000000000000..acdcfed97b5a1f46d3423708909df78743d87dde GIT binary patch literal 917 zcmeAS@N?(olHy`uVBq!ia0vp^sz5Bn!3-o{+do%fU|?nl@Ck7}aNxlI|Nk2r8i3;e z&!jOh%mgwFS$q7nq1_p*n3~40?7=n&AF*U4`2w>C; z)o?R*4B5DdVS`r6;svWDBmx9nR~h{AD3xBQ=z79!g_4t*5xC%}qXZH5? zHa9mH6&0O#bc~6K`Om;$Y;3HquCA!4$iTqxkC6#T;s=U9Sy)9FL>P2H%0PB9ur?$p z^rcAhIIUXurhvowjE``$gNd*>r;UFn%UQuQl2xso36jhz49!oUT(I^jV`fSW2w<${ zcv|GcR>S(RF!^SLcXLMJ>^FAHZ@$_X%TuuXenJs1e{FGEL3wIQI=hfb{{$1E0#+UY g!5K4W3h;!)aBwYLw3v&7gPWb3XZ4!3>l7KR0p2rH+5i9m literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/js/rico/images/close.gif b/NP_TrackBack/trunk/trackback/js/rico/images/close.gif new file mode 100644 index 0000000000000000000000000000000000000000..65c5f16ff6c1eb9e5b9ec77e5f03de1fc041c443 GIT binary patch literal 111 zcmZ?wbhEHb6kyo|Nk>EFf=qYI5;@CxVQk>K%n@O1x)LJNRV0vW)q2B zcSIFVX&zr}5hc+&V_uo3VgQr$)44A=>Vki5Dq^2+8htJD>9<7(5ZZ}vfiVO*5cq@8>HBXNhWk9<>-=+m;M~a*SNBqywkaMy z{Ct=^cHWmTzL#E=w-Sj&GMP-JQf+N*>2x}i$#isdbaizN4-XFx4(4*XY&L6mybTSl z(?k7bzt>kcH`m|3nPwtKBt!~uCT4O>!lX5Ro# zjV%a;a43bezzs8e+o+(M0*Q-h({89c|L zVxzDP2dIG}c#RVQ6-)pR7?2j0C=eB~5EjgU7<*N*kR7~%8`o-LAxdPAq!BH$L~IBN zsUQaUhF6$_8;C|3WI|ow51=tBVB#L&Iqq?QVWB063=YAHy&=BPOmq)zK@*TVVn(jW z63s(eNC=Uj2JX>IScIpzK9(7`7IMH3LLdSXrFf1@>`)AV{}X1cUebY)k&*H7@j{_c zEEX%3%KZF%wOZZS*r?TN^?JS0XhczDJ6kg|v)=po!!fcjVa5vM2o5R!FPu$2A#2I> z&&@37qs0EB{)?yP-GBGdjp-}7{LU`-sQ=xI(xe?PoTjg}rO7C2w3i-G(^Tj6^0RFF z?8mz_cI(gWHQ(2ixU_PtW$fDLiQb<2$1JAo3yOpP{7t4!>*L-zir*n0& ub&by4k5;;S`ino_7e_x#rRsZ1`GvmT(Qk)}Kl4kzdHddlg}G%Y>goz1`(bFP6gXzIsU#~{__0L`7DypQ#`uvHxfE>( z6}5%*F_Z*-wG0G7(9Xa{C=nFummm8#D{Llh;)>Giz1j7%3v;>ezVpt#@7y=xo|Ekz zu_{zy9grnCem6e<pymOQkPq_~F4A)1~8RRzz_r#pi-TyYdg z_z;&!5*!1J1CLcNePXG?NrQTIzrB!`{ped0buXbwQ0T%%N!|hRAZV6GopPJ_t;v>+ zes5#8*u(&)gL@zkkkZ*-$3}BD`aH}`qrB1u>hZVXfB@>k{g2-qp;i}E4`0v%)lT^? z6ZuwIE_cDO$;`knig4ZT-Bq+T6Q>?XrYhw%DyqNek_R!4)gPZ|c^3_fTM Z_C9ZnC46tIVyDTGi?`-S4(mFO{sT|s+J685 literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/js/rico/images/drop.gif b/NP_TrackBack/trunk/trackback/js/rico/images/drop.gif new file mode 100644 index 0000000000000000000000000000000000000000..afce892c6cbaf6d6ab2de4d71c9005ae6b0584dd GIT binary patch literal 102 zcmZ?wbhEHbSOWl&yb%Hb literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/js/rico/images/filtercol.gif b/NP_TrackBack/trunk/trackback/js/rico/images/filtercol.gif new file mode 100644 index 0000000000000000000000000000000000000000..2e9382829419239c42ce2d23c94ea9e0452d42a8 GIT binary patch literal 293 zcmZ?wbhEHbdun>KCQw{PFEW5>2_+xG3-x2~?P)vH%OeE9J2;lthC-Ip$1x^m^p+_`httXVU8 z^5jpSKHa%CMpunI5vI^uU1~w;$2?ZW9|N2g(TvBdO5ou|7 ztl0U-!M-U`@dJxS&#BNK&N*E3oSlu$__$;kmihkSRgX1P?1Sy=M{(ue&dBu`J7oiwE zLm_^&>L7&p2P$Z7(*rKjfHaF4szI?4!GPfLxz`KfexB#+yeVG3IC<{+Vam{N3L}ZX zBu)u-NwR^lx3S(j7#bQ%rBWj!Bk6QHlgVVW*<3D{&*w{}((LT)^z?M0Q1Dxc&&}=9 zihc7RyPNy_yRTl}XCfg|A_F)RGYOM28I#9577`&9G9iyoSxJ;s$&@@+vXL06kr_GG zPU>VH5CJKK3Or$t1k5bV%52OY`LGvZ6*ggy^tcvfRW@ahYVcZ&)!2+ZR*JJao3lru z5Duk~7Wu&m5}*PGb$A zuP_HU5REd(gu2KdK?5paLJ#m9_c*}t*b+nrhhW9t5npU3x`(!)2}m6=BUfaJ<{>R4 zgh)^W_vj@o!c(XZGDB-22mBxeA|O$U=eWcU#Q^v}Va95W#>(aL($Z43TCLS;J3Bkg zX0zRHcRHPJx7+LW`u+Z3Fz`PI_4>0UNy3NY8tOWwWXJlXv$lHm=dTyd<6D)<`6Fi^o&GwrT3kJ~-1@jydU&O>*!jfAXzCw)DYwi3 literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/js/rico/images/folderopen.gif b/NP_TrackBack/trunk/trackback/js/rico/images/folderopen.gif new file mode 100644 index 0000000000000000000000000000000000000000..c16e11b1b35e55a49e4969ad1c29e94dc554908b GIT binary patch literal 909 zcmX9-U4)cj6h0So@hw{#X{_DZ*cCPGRp+8cWOrjL8J0|U8B5M}>SBvYpDu=`r0g0U zT{PN$FJg^|h^5-K%~2G)T{OhXvZ5WLAv!(p+sk-=&+~V_Iev2L@S&Lj%F%BMBaOc_ zPAPV2x`gp{>GAvROeT{gNq>KTHk-}ma`}9Ibab>(D3r_PQmHgKIaw?gy_)*;^cv0C z5C6Hgyt%pd{Ml_L5+WrsfHN_ZFe#HUdAwsG5mF%&^7xdML`juQ$zvrOiIEzakz?(o zPUZm-kV2@y6ZS~J%)+e9#_W*~dl6P)6ZS}tYf)BZQ}(C^ufInRs*yHR@sxL%|t52T{Q&Y{LO+ zpa@<=BA|i^-~j{D;t~aFsvg6F84zP{rXI6{H*n+HTs=mK?2$C0MV5#SAt4pS0N?Nm zb8rLED1%I>i~JEZpaLfJ0MBuc0}PKXL1b_UR_q<|#b%;=XbYNv)DbgsMV4qD(n3Or z1T}DvUcw?gh58^fv=(x}4?-XU5~X;KOYBe#fd3O_tRB%wrBa!lovqbsjYgy0Zns*k z_4V~mr?auKv9-0;?RI;;p8wfyHXo*G8a^B+j}vCBFvf65;lD7RTp;hupIB^8T6wgZ9VyTfBbB2UJuTEXe5^htE<1hAH8>K&)zFZy71}g>7g^PU%e=Nu1~zF?-<%e GNB#k)k+;wQ literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/js/rico/images/grayedout.gif b/NP_TrackBack/trunk/trackback/js/rico/images/grayedout.gif new file mode 100644 index 0000000000000000000000000000000000000000..ead27afc6c6883ca9b1ea0b88b2af8df279bcac5 GIT binary patch literal 2983 zcmdUq`#%%Ab`TD$GulM8g!{_n-oOiUhu)GZxH2^#S0FH2W?f?MJ z0}KEHgm+K*d_IrIJfFgciic2Aj>^U~dQ!wqRnj*Vors zLbC)V2;szHt*)-F3B0g%A>Y0UL)bJb z?GIEzQ-u;h6TH4AIDd*GT!$l&a9u7}_`ClT#Q0zU6!zrbr%B1rp1(**O-s*snVFTH zlbe_S3jVsF5K&ZIQd(ACQCU@8gRHH4Q{V6w)rfAwV4GW7+uA!i-@X6vv8%hMw-1N! zA0QA1hlWQ!jgrR3Ka(dWDO1xkvtQ=szkd6^u=s;YTl)FyH=VJ(!dzWjXR$Xpn_Jsl z9v>hoq2lni_#;eQR__M>ZAo{Mw5C&m1FE$5g(5I`8jsTKkprjz0J@pq9nPw|BjSr? z{9swyc3tm7Ybx6;7+&9%^o>UDHmhkV}m|{CN?;b=g`kY;dB+u3~ikL{(4-E9bS`@>n6v zhd2H>pK-lcohI|H-LwA6``EH;X_B#Fb6r|1pG~%8Lnny)&Najnf#C~8^|P6~Pi&ct zp;FCPxh}0I$uroqA@mMP?a#T+>ymc|vzss0*jVaE|J*hkFVm#;B}liQ{gw5l8zwdk z^5e+O;_fR9BepkR(k9zOjrgbIHbI^Rp8IccIb0@3K`n8fdtMD99`&OLw8yO47qV9s zuPSaO<)C(vwS%f2V{Yj?@38L_6%ji#uQLzT>Pq^ObhI)?4Z;ahRDEhV;D7+@+|B>? zRAUKW1~XYwm`_*WDSnSB-xcJ`hjL!wG*ay3sT%3d^!&2Si!wE;xgNW#za-CtmdkS- zBrG%cUrhjXNgV0J-pvzFkXD8-L*CwfJ?XEDDA4@->1?5XON~x8sQ%EcctD$@&f{5> zLSPZd3{YMCpl|U5JpN1@6prf64JyrnCI?liKRr}}$P05?s=QzCOGU1LlvI&rw#b^Q zS~v|^RzkN7h>mKk392>Ql&C4mTAb7`fxJWB$$NgYS~sTI9{#Jovl3oY_2#QYC>9f} zq!H72NwOY^4TsZfek{PNp3K~Brsk5O;I-vlxyKrs(nKB~N38|5BirD)?ZGIKDrKX# zHi|@72T;DC7M(pLG0X1~lia#n1i>Dn;?!Z&hB%d^d*S$)gcMY#PIJNi^6}XvCQ;2} z>K75)c7uu2#1-fdqIm`pc{|=CiUiV?2v(-Yvky;qG@!yF)2P`+U?QtXp)Z6VRMQWsgsRM9k^#Uq)rZP#y{8} z8Z#Ic-PSl8${u8XO%XlK{+{T$ul4&G2BnUYBevB2c{(yIXex!k!Qg-mtta5R_fy*l z^$im3Jpqi(O#&p296FEC|7p4WzR@jq95WTyzHsyr8A%DGAQ%*F$^9TA;fqxG9CY6l zSK^cYUm!mHC;<^LHy_fr?a(OeZjD`9olPM3|j*5 zg9E##SI+jH)vxl$tbV2Lhn|9|QC+C0 zrHgN)E_C0LFjcft$}|c#|E0tZ$9Jo4E+^USEtO7k=+RI@C0U;;mC3{R9JPA*Z1r*J z!Rzv!8QKq@dl5C{F!)}>xRn>ad&?AY4t>V(m6Sl2G9_~L-|{UhsSi@hRDL+%tSBpK zF~l-eHXe6ob0rK8?>KM?&djcMsnA2iQoZ@+sK9GExkS7~!=k2{DZ18wH~nJ;f+44@xme%(fm7)IZ*0Y~uH|uEIz3Z*tSsoZ9Y# zA^O^sv6pU54JKT#t75@qw4NF2F$U?^3inEcj=z!}4=GkrHtwNBqGWSuKGBX7xL|od zP{qCD1jnIU`+!9wPiimehmgn4e10qHU+b+i;PU=?&YKUB`qw`yk!OdlH0E^bmRJt@rcNgGhlGgrbOMXqD$1Jx4kNEG$a{4x5(D^GqNjWo?aeyw zJ&}e=32^zQG_}!ZF@#FHtr=GRp@QVwbCt@xsDi#p>j9^PlF&nnl|8xIHDX2eN6PX^3IYNWX)`sZ3=d$tD)d4Gqk9ZktOpjKz4{QXeZ^o2_x{NBVmN zwVEu<-E!P?GcZM5O#eY0D0$)6B`e!|c}5zyLL3dsDmrhcGvcv__4(v1l`(Q|$uu!8 zBKQsq<)Lh$t6ZwPZexLxbF z|Bj2K{rtn#<~l!@S~s0}HzR6D=gfT4Bg3E?QCLmhaMk_26xaK-zNVQq{o!X9E{g=> z&bw#L#1ysum odNc-lEFY@Z0yUU`8g4*OD8h^_U?yHLvly5~{!W;jqBy|%KZmgqnE(I) literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/js/rico/images/left.gif b/NP_TrackBack/trunk/trackback/js/rico/images/left.gif new file mode 100644 index 0000000000000000000000000000000000000000..f65207578a00bc16df73d4f3f7d35177f4698836 GIT binary patch literal 105 zcmZ?wbhEHb)h!xmq)CeDZt2J4FIY*5X=Ao literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/js/rico/images/link.gif b/NP_TrackBack/trunk/trackback/js/rico/images/link.gif new file mode 100644 index 0000000000000000000000000000000000000000..a679f4d33f80ec11cbac551069bf5583196a7fde GIT binary patch literal 954 zcmX9-OGuPa6h1l=jUeSDOs`Q)H;OKbgQz4?gQ){eSmC0T26llxa~76`sETc44^B^S#bL9qIPwrZc-JLBA**f&T@5 z3a|@;X^fB44`oD%H}`VuOKobnatm@Bj-pQsU!1GS;z^AkP4ZvWF@C0N~&a7 z8;OxxhzLkWsK668Pr%HMS(ugCJRkPXu{c)8=IL?mghg0|&8xv{r!2~dd=^8ZoB^L!mQx4n>7V zVH*xm14Zx}CITv$03I+P%`Z_PDq=n?m;o{Ns$xDncmp@C)x><1$R0@}T4agX5E4>B z4Db!FFb6jfjWWoDI?wMxLsY3J9@>H?Aa%ryT#+T3 zhqRCoB0&w@qnEGhJGOjT9ePJ2m`d`T0AAl2b^BTLe)spP&d81}W#>xfT>D6CP2$JPr{i;X8}IKqmTo-zdZ_tmd&8&rqqazI z&D!nS^7^*O-{kV%4;RlLA1+i*^@Bb zb@1`$#mvl1tJRvFoo%<kR((C_yb7Z>wYlS@lSvK7Dc{OH@+ z+0m!nO%*W_7YV>sRK-+WB~-HBsfn4mNtk4PsxIc@F5!~3QbR1nLn0(ur+7+aK?Kr- z3Z7_I0#!9tR}IyyeC*BCO~W)RJ=f;yuHl+h4X-WKLnAb6rKNgmq-GV0aFimg^1}%U zsK8Li+hT(QhMPsT1SK1H3%9HeQQ%<_menn4JS`GK#TlN9sA3e`IG_eacrA%Qg$eM$ zKw4c=;NhM%EX+X6KEktRhc~#nj`XZil08WiEm;y9A(09(;2W=)!wsS-Lni7fe+4b5 zz?2^FoO=!!SzAJ6IE0mb5?^g5-J>lufz*kaT*;E=kroLN2{pKU~UftbX>uxClbwfI}4( z9E6%rP$`PoGdGKwG8BqnI~h*VX{ z>B+|rFI2=tTqFQjQ592hl~BogrzU3NCSj8Gsk)epyM#;DN)53P4~dXuo#H8x1rbOS zDtMw<2~^coT{Tp*^07BlHx1LQ^jw>(yM}94HN3V^4~@{Qm6qzMk(yN~!cmH}$`2s1X3qvawSWeM_MFAB-G%ZUSbhXrM}24twj#} z5P}FKr99`79mN3rpO{&_la1+gy1TnOo6Yw2_KuH_=kxhuu~;sbtJUi4?Cj#=V!dAH zpY#3ww@uTO4<{w-#LS9ugF`9*g*)vH$xDN+gZ+n29D{C4pA=vnvLgI8Oh-h6p} MRUiMo(v{o)0K7tw&;S4c literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/js/rico/images/nodelast.gif b/NP_TrackBack/trunk/trackback/js/rico/images/nodelast.gif new file mode 100644 index 0000000000000000000000000000000000000000..3fe0a7e16c9279b26b6d57be0fcf67a148c87aad GIT binary patch literal 838 zcmXAoJ!_Lu6vxldAwq|SLLAJXb&5I&XVBsz5nmzDrJE26a=t&f4Ep{4>gsAfZE|hxKwii1JURG! ze0=cn!z&dr5f=%-RaC`PTqRVp-l>V1xJj5~eX1_z;x6HmwNgVY#6uz^S*LhPWI+Vd zgbJQ$RsvNuRaXtwtbFXv)J?-QD?Qid>aO9MRSmB#)I%dQYo(=nYNTcrig1)7t@6VO z38=tO$J=6q1BRPLwFD&_cMG?y4pHD?5th|0YCJ6xL&X`Mi>P80+c=;GMR+ZVK!pkL zz(87EQsCj9H7v|P%s#@iW`{SpxsLR#QIb7L6D?U18zGSjG2k1on8OXCDMKdeDt`qn zsKAsS@SJ-N7+G6FWH^MCeG*@7Cf%bgG=bEKnOw<|=8+Z&5eYT8ria9OKXt> zKZGCxNh!~{WJfUo|0iZv@8r^OINaRa9F0cf@pylKe=?aI9v)7o)1#xK*=%-pb~c~S z^Y7{Q_D<6@<-NlLd$4?_Mv2`+ELw=gFfd>v!*LFH2YcNEvPYwRLLQwe2zE z*YU@n7fVY^P1AHbot2f9ZnxX(^;TC``~Cjb*4D(yM}94HN3V^4~@{Qm6qzMk(yN~!cmH}$`2s1X3qvawSWeM_MFAB-G%ZUSbhXrM}24twj#} z5P}FKr99`79mN3rpO{&Fkej2?XlG|>u0QB@8oBomNt2RO literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/js/rico/images/nodem.gif b/NP_TrackBack/trunk/trackback/js/rico/images/nodem.gif new file mode 100644 index 0000000000000000000000000000000000000000..fcc2d37333116b6a7fdafb7eb099b0fbf16f5f63 GIT binary patch literal 97 zcmZ?wbhEHb6krfzn8?h~(9rPz|9=Js1|X^UlZBCiftf)E$YlV@GcXy=>0inAdcV{h y&KuRqH*8MaDwJnxxm_{k(5@=y&r{V-%~+?@{-rzd%6SH^X6Fa%Bnm|s7_0$apd^X_ literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/js/rico/images/nodemlast.gif b/NP_TrackBack/trunk/trackback/js/rico/images/nodemlast.gif new file mode 100644 index 0000000000000000000000000000000000000000..11ae43a5ae00b76b81e0bf2aa8d2b33efbbb5e53 GIT binary patch literal 125 zcmZ?wbhEHb6krfz*v!Dt(9rPz|9=MJ08pjkPZmZ721W)QkPeU;3@lm(Cp=eAeekN* p_`j$^Uvhd>T*aykg+2Kb&IWtk{95(e)U)Zpf&vd6DN{iPYXB-WAG`nn literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/js/rico/images/nodep.gif b/NP_TrackBack/trunk/trackback/js/rico/images/nodep.gif new file mode 100644 index 0000000000000000000000000000000000000000..5b680136ee9db9cd706b2ef642e89d6edda3989a GIT binary patch literal 133 zcmZ?wbhEHb6krfz*v!Dt(9rPz|9=MD;J|?ca7my_#h)yU3=G^1Iv_!i84N5&1t&dM zPkr#J*7(1uLSJ%v)IB91&8h2VXrB2z>Fyhr+skJywiWMW(K^=S5qIfERMD)-91PX~ DC2=QD literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/js/rico/images/nodeplast.gif b/NP_TrackBack/trunk/trackback/js/rico/images/nodeplast.gif new file mode 100644 index 0000000000000000000000000000000000000000..b87f003154502f8e9f569fefb12d57a5a1ebb515 GIT binary patch literal 130 zcmZ?wbhEHb6krfz*v!Dt(9rPz|9=MJ08pjkPZmZ721W)QkPeU;3@rKvCp=eAeekN* v_`j$^Uvhd>oPv+$)O9m7&lFF%`-bKA@>z>*#XDKFr20=RDO%adz+epk!mc6H literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/js/rico/images/resize.gif b/NP_TrackBack/trunk/trackback/js/rico/images/resize.gif new file mode 100644 index 0000000000000000000000000000000000000000..8efd1b5fae11687458f943a1999ce6ed3903078f GIT binary patch literal 51 ycmZ?wbhEHbWM*JyC}3bv{K>+|z`(?y!vF*zu|^<0bLLDC7bwm$MO2-Y!5RR+BL>s} literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/js/rico/images/ricologo.gif b/NP_TrackBack/trunk/trackback/js/rico/images/ricologo.gif new file mode 100644 index 0000000000000000000000000000000000000000..9b142039bef7c315749505367e55bc8c037d0531 GIT binary patch literal 1105 zcmV-X1g`r>Nk%w1VSfNp0K^smwY;s`-PVwrgno%{b%AB|_VkC6d84bCc`B%zQnhFig2v6qNA&snWB!{-qz98%&oMe|NsANd0YSg{{R30000000000000000 z000000000000000A^8LW000&MEC2ui0Dk~d000I5pe2r$^fXnfu59bRa4gSsoi>j| z?qh`7z@TtQbTuNp(WJ<1I-jXY@&T<{udv5%iS2r;Qc>hfE*FuOpLxxWHA?NcoMoEZ z41ejE#QJpJjV#)pJ8&{ZrB4V`%x&cW>i_`%0OrN`SBAe@Ftk2J zP}D`@3I@r(7~obFShIUu5HN^0bLtfiqD^M_RhHe(PQq~x84|!J*)fh1h}>GpVo^D-WE_pXsxT0%svOifPQkkK=M)%xZgI3Ug#|>Yrz&8>0Cd#gQw8wuSAJDi z^lSW1h2F-{=D4g<08B7NrbOQn^-{QJ4{d9}w!L zG9EM=x^P)5$$_SzQXT=Z+$ur5s0wZYmS`d?EpljM3M>*KV=6KBrPq$+37A|^Jr40B z1wl3g#aR^)z)FNVR=9#vGAYSQiY;)n%82_Y*usA2X=tSiP{tr+4F*vt&I}B$XXcwM zgvcZjLuqG&QUN_FCJWe!SRb7$xChq|WcEozpy9a*U<(iq3gA$R1`%f}`7QIIpG3Mq zW`9L?+SMw01~J^9fkoz^qcnuGYN%(bz-V_v7(}I~Q(BQ`1xtQLl~}jVaOx@F!J(MTt)G$Va1Z3PZacacNXSm@9+)l9r$!5COSfrbTKbX`OkBTyms5L)mM_SrR% X&4UkY&u~N%JD6}a+c@aJLkIvni-+cW literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/js/rico/images/right.gif b/NP_TrackBack/trunk/trackback/js/rico/images/right.gif new file mode 100644 index 0000000000000000000000000000000000000000..5517f2bc0c57eaa8fc5b1f58d027ae0e79b7f139 GIT binary patch literal 105 zcmZ?wbhEHbw@-~%V!j>5nyDn1^}}A5n2EM literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/js/rico/images/shadow.png b/NP_TrackBack/trunk/trackback/js/rico/images/shadow.png new file mode 100644 index 0000000000000000000000000000000000000000..7862c9bb23fd861dab3ffdc1511d73421d65a0a7 GIT binary patch literal 3576 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYV2a>i1B%QlYbpRzEX7WqAsj$Z!;#Vf4nJaD4z_MyE9#iRWF{)OWfrBD=NDxcEBHq2o~We)bc&Csi(^Q|oVRy(`#la2 zakw}+@ZbK&;)1NAO^t&5{u3pP92Y6x5}dhJ<#gYrIc2Z!W#>;zm1JOO2)>bH7H(W@ zZES8_ym$Zob7$_JvH559IER7ZK)qW7&=Hc1ObiSuEF26B69g3)7#v0gM+0OuF^pz} z(UM`bR2;1lMr*^-+HkZs9IXw9ZEZN`(x=Fa)&1wU<@J9BoOAJ8}^8TJ#O z-z<7uS0?z$!2R~dZN|lS&vP;`#B?0q9=G?Lp2fU0arxI;C!`d*MM2hE^W87{Y9*iU zcuk;kR&%k!Igoqrm+lbF?w#=b?^e70XY07H-L+I>VPMcZRoJp7|JbkRvlVX7th6~@ k0rbpL%YR(IKGyzY(w^C>%l*A*8&Efcr>mdKI;Vst0C%$>vj6}9 literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/js/rico/images/shadow_ll.png b/NP_TrackBack/trunk/trackback/js/rico/images/shadow_ll.png new file mode 100644 index 0000000000000000000000000000000000000000..cc0665b430c3838bdef71bba52a0acb17c24956b GIT binary patch literal 274 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqEX7WqAsj$Z!;#Vf4nJ zaD4z_MyE9#iRWF{)OWfrBD=NDxcEBHq2o~We)RGa4M;uumf$M@Vpu0swyEf4c| zXNR)%KXU!`kAKC|TX}nzOgJ#1@#oAX54xn~DiRL~m-mS3mKMfoChu@@CJ`sjqq=m1AXa{V&i)22WQ% Jmvv4FO#lyMU1k6P literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/js/rico/images/shadow_ur.png b/NP_TrackBack/trunk/trackback/js/rico/images/shadow_ur.png new file mode 100644 index 0000000000000000000000000000000000000000..cad0f2c75c4ca7478645b0186522e80903f158fc GIT binary patch literal 275 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqEX7WqAsj$Z!;#Vf4nJ zaD4z_MyE9#iRWF{)OWfrBD=NDxcEBHq2o~We)RGaSU;uumf$M>8!7n37T%ft2Z zR$bh&yNb^}`1@XEN07v_yGv9X<(Wb~Lk~(aR~wXHC~$V?eJ0Y=ChBc8HRaNWBb@Cj zeV)ge^Y=V*c(u9w&SU1BACH75MjsWOp3u3XetuW-h309yrpSxk68g5~w*6F~l?dhCYGe8D3oWGWGIAWq$;?3`UWs4{$yd~ eVqj#@VE_V<76vBn9_Hl-y6*7I$v?!zU=0ASUlv;c literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/js/rico/images/sort_desc.gif b/NP_TrackBack/trunk/trackback/js/rico/images/sort_desc.gif new file mode 100644 index 0000000000000000000000000000000000000000..b3a681c95431b75e111e29ae7ad6c51607ee7fd7 GIT binary patch literal 76 zcmZ?wbhEHbdhCYGe8D3oWGWGIAWq$;?3`UWs4{$yd~ cVqj#@VE_V<76vA+mik7?E?&u;1Th9{0F68pQUCw| literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/js/rico/prototype.js b/NP_TrackBack/trunk/trackback/js/rico/prototype.js new file mode 100644 index 0000000..5906575 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/prototype.js @@ -0,0 +1,3269 @@ +/* Prototype JavaScript framework, version 1.5.1_rc3 + * (c) 2005-2007 Sam Stephenson + * + * Prototype is freely distributable under the terms of an MIT-style license. + * For details, see the Prototype web site: http://www.prototypejs.org/ + * +/*--------------------------------------------------------------------------*/ + +var Prototype = { + Version: '1.5.1_rc3', + + Browser: { + IE: !!(window.attachEvent && !window.opera), + Opera: !!window.opera, + WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1, + Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1 + }, + + BrowserFeatures: { + XPath: !!document.evaluate, + ElementExtensions: !!window.HTMLElement, + SpecificElementExtensions: + (document.createElement('div').__proto__ !== + document.createElement('form').__proto__) + }, + + ScriptFragment: ']*>([\u0001-\uFFFF]*?)', + JSONFilter: /^\/\*-secure-\s*(.*)\s*\*\/\s*$/, + + emptyFunction: function() { }, + K: function(x) { return x } +} + +var Class = { + create: function() { + return function() { + this.initialize.apply(this, arguments); + } + } +} + +var Abstract = new Object(); + +Object.extend = function(destination, source) { + for (var property in source) { + destination[property] = source[property]; + } + return destination; +} + +Object.extend(Object, { + inspect: function(object) { + try { + if (object === undefined) return 'undefined'; + if (object === null) return 'null'; + return object.inspect ? object.inspect() : object.toString(); + } catch (e) { + if (e instanceof RangeError) return '...'; + throw e; + } + }, + + toJSON: function(object) { + var type = typeof object; + switch(type) { + case 'undefined': + case 'function': + case 'unknown': return; + case 'boolean': return object.toString(); + } + if (object === null) return 'null'; + if (object.toJSON) return object.toJSON(); + if (object.ownerDocument === document) return; + var results = []; + for (var property in object) { + var value = Object.toJSON(object[property]); + if (value !== undefined) + results.push(property.toJSON() + ': ' + value); + } + return '{' + results.join(', ') + '}'; + }, + + keys: function(object) { + var keys = []; + for (var property in object) + keys.push(property); + return keys; + }, + + values: function(object) { + var values = []; + for (var property in object) + values.push(object[property]); + return values; + }, + + clone: function(object) { + return Object.extend({}, object); + } +}); + +Function.prototype.bind = function() { + var __method = this, args = $A(arguments), object = args.shift(); + return function() { + return __method.apply(object, args.concat($A(arguments))); + } +} + +Function.prototype.bindAsEventListener = function(object) { + var __method = this, args = $A(arguments), object = args.shift(); + return function(event) { + return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments))); + } +} + +Object.extend(Number.prototype, { + toColorPart: function() { + return this.toPaddedString(2, 16); + }, + + succ: function() { + return this + 1; + }, + + times: function(iterator) { + $R(0, this, true).each(iterator); + return this; + }, + + toPaddedString: function(length, radix) { + var string = this.toString(radix || 10); + return '0'.times(length - string.length) + string; + }, + + toJSON: function() { + return isFinite(this) ? this.toString() : 'null'; + } +}); + +Date.prototype.toJSON = function() { + return '"' + this.getFullYear() + '-' + + (this.getMonth() + 1).toPaddedString(2) + '-' + + this.getDate().toPaddedString(2) + 'T' + + this.getHours().toPaddedString(2) + ':' + + this.getMinutes().toPaddedString(2) + ':' + + this.getSeconds().toPaddedString(2) + '"'; +}; + +var Try = { + these: function() { + var returnValue; + + for (var i = 0, length = arguments.length; i < length; i++) { + var lambda = arguments[i]; + try { + returnValue = lambda(); + break; + } catch (e) {} + } + + return returnValue; + } +} + +/*--------------------------------------------------------------------------*/ + +var PeriodicalExecuter = Class.create(); +PeriodicalExecuter.prototype = { + initialize: function(callback, frequency) { + this.callback = callback; + this.frequency = frequency; + this.currentlyExecuting = false; + + this.registerCallback(); + }, + + registerCallback: function() { + this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); + }, + + stop: function() { + if (!this.timer) return; + clearInterval(this.timer); + this.timer = null; + }, + + onTimerEvent: function() { + if (!this.currentlyExecuting) { + try { + this.currentlyExecuting = true; + this.callback(this); + } finally { + this.currentlyExecuting = false; + } + } + } +} +Object.extend(String, { + interpret: function(value) { + return value == null ? '' : String(value); + }, + specialChar: { + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '\\': '\\\\' + } +}); + +Object.extend(String.prototype, { + gsub: function(pattern, replacement) { + var result = '', source = this, match; + replacement = arguments.callee.prepareReplacement(replacement); + + while (source.length > 0) { + if (match = source.match(pattern)) { + result += source.slice(0, match.index); + result += String.interpret(replacement(match)); + source = source.slice(match.index + match[0].length); + } else { + result += source, source = ''; + } + } + return result; + }, + + sub: function(pattern, replacement, count) { + replacement = this.gsub.prepareReplacement(replacement); + count = count === undefined ? 1 : count; + + return this.gsub(pattern, function(match) { + if (--count < 0) return match[0]; + return replacement(match); + }); + }, + + scan: function(pattern, iterator) { + this.gsub(pattern, iterator); + return this; + }, + + truncate: function(length, truncation) { + length = length || 30; + truncation = truncation === undefined ? '...' : truncation; + return this.length > length ? + this.slice(0, length - truncation.length) + truncation : this; + }, + + strip: function() { + return this.replace(/^\s+/, '').replace(/\s+$/, ''); + }, + + stripTags: function() { + return this.replace(/<\/?[^>]+>/gi, ''); + }, + + stripScripts: function() { + return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); + }, + + extractScripts: function() { + var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); + var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); + return (this.match(matchAll) || []).map(function(scriptTag) { + return (scriptTag.match(matchOne) || ['', ''])[1]; + }); + }, + + evalScripts: function() { + return this.extractScripts().map(function(script) { return eval(script) }); + }, + + escapeHTML: function() { + var self = arguments.callee; + self.text.data = this; + return self.div.innerHTML; + }, + + unescapeHTML: function() { + var div = document.createElement('div'); + div.innerHTML = this.stripTags(); + return div.childNodes[0] ? (div.childNodes.length > 1 ? + $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) : + div.childNodes[0].nodeValue) : ''; + }, + + toQueryParams: function(separator) { + var match = this.strip().match(/([^?#]*)(#.*)?$/); + if (!match) return {}; + + return match[1].split(separator || '&').inject({}, function(hash, pair) { + if ((pair = pair.split('='))[0]) { + var key = decodeURIComponent(pair.shift()); + var value = pair.length > 1 ? pair.join('=') : pair[0]; + if (value != undefined) value = decodeURIComponent(value); + + if (key in hash) { + if (hash[key].constructor != Array) hash[key] = [hash[key]]; + hash[key].push(value); + } + else hash[key] = value; + } + return hash; + }); + }, + + toArray: function() { + return this.split(''); + }, + + succ: function() { + return this.slice(0, this.length - 1) + + String.fromCharCode(this.charCodeAt(this.length - 1) + 1); + }, + + times: function(count) { + var result = ''; + for (var i = 0; i < count; i++) result += this; + return result; + }, + + camelize: function() { + var parts = this.split('-'), len = parts.length; + if (len == 1) return parts[0]; + + var camelized = this.charAt(0) == '-' + ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1) + : parts[0]; + + for (var i = 1; i < len; i++) + camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1); + + return camelized; + }, + + capitalize: function() { + return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); + }, + + underscore: function() { + return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase(); + }, + + dasherize: function() { + return this.gsub(/_/,'-'); + }, + + inspect: function(useDoubleQuotes) { + var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) { + var character = String.specialChar[match[0]]; + return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16); + }); + if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; + return "'" + escapedString.replace(/'/g, '\\\'') + "'"; + }, + + toJSON: function() { + return this.inspect(true); + }, + + unfilterJSON: function(filter) { + return this.sub(filter || Prototype.JSONFilter, '#{1}'); + }, + + evalJSON: function(sanitize) { + var json = this.unfilterJSON(); + try { + if (!sanitize || (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(json))) + return eval('(' + json + ')'); + } catch (e) { } + throw new SyntaxError('Badly formed JSON string: ' + this.inspect()); + }, + + include: function(pattern) { + return this.indexOf(pattern) > -1; + }, + + startsWith: function(pattern) { + return this.indexOf(pattern) === 0; + }, + + endsWith: function(pattern) { + var d = this.length - pattern.length; + return d >= 0 && this.lastIndexOf(pattern) === d; + }, + + empty: function() { + return this == ''; + }, + + blank: function() { + return /^\s*$/.test(this); + } +}); + +if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, { + escapeHTML: function() { + return this.replace(/&/g,'&').replace(//g,'>'); + }, + unescapeHTML: function() { + return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); + } +}); + +String.prototype.gsub.prepareReplacement = function(replacement) { + if (typeof replacement == 'function') return replacement; + var template = new Template(replacement); + return function(match) { return template.evaluate(match) }; +} + +String.prototype.parseQuery = String.prototype.toQueryParams; + +Object.extend(String.prototype.escapeHTML, { + div: document.createElement('div'), + text: document.createTextNode('') +}); + +with (String.prototype.escapeHTML) div.appendChild(text); + +var Template = Class.create(); +Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; +Template.prototype = { + initialize: function(template, pattern) { + this.template = template.toString(); + this.pattern = pattern || Template.Pattern; + }, + + evaluate: function(object) { + return this.template.gsub(this.pattern, function(match) { + var before = match[1]; + if (before == '\\') return match[2]; + return before + String.interpret(object[match[3]]); + }); + } +} + +var $break = new Object(); +var $continue = new Object(); + +var Enumerable = { + each: function(iterator) { + var index = 0; + try { + this._each(function(value) { + iterator(value, index++); + }); + } catch (e) { + if (e != $break) throw e; + } + return this; + }, + + eachSlice: function(number, iterator) { + var index = -number, slices = [], array = this.toArray(); + while ((index += number) < array.length) + slices.push(array.slice(index, index+number)); + return slices.map(iterator); + }, + + all: function(iterator) { + var result = true; + this.each(function(value, index) { + result = result && !!(iterator || Prototype.K)(value, index); + if (!result) throw $break; + }); + return result; + }, + + any: function(iterator) { + var result = false; + this.each(function(value, index) { + if (result = !!(iterator || Prototype.K)(value, index)) + throw $break; + }); + return result; + }, + + collect: function(iterator) { + var results = []; + this.each(function(value, index) { + results.push((iterator || Prototype.K)(value, index)); + }); + return results; + }, + + detect: function(iterator) { + var result; + this.each(function(value, index) { + if (iterator(value, index)) { + result = value; + throw $break; + } + }); + return result; + }, + + findAll: function(iterator) { + var results = []; + this.each(function(value, index) { + if (iterator(value, index)) + results.push(value); + }); + return results; + }, + + grep: function(pattern, iterator) { + var results = []; + this.each(function(value, index) { + var stringValue = value.toString(); + if (stringValue.match(pattern)) + results.push((iterator || Prototype.K)(value, index)); + }) + return results; + }, + + include: function(object) { + var found = false; + this.each(function(value) { + if (value == object) { + found = true; + throw $break; + } + }); + return found; + }, + + inGroupsOf: function(number, fillWith) { + fillWith = fillWith === undefined ? null : fillWith; + return this.eachSlice(number, function(slice) { + while(slice.length < number) slice.push(fillWith); + return slice; + }); + }, + + inject: function(memo, iterator) { + this.each(function(value, index) { + memo = iterator(memo, value, index); + }); + return memo; + }, + + invoke: function(method) { + var args = $A(arguments).slice(1); + return this.map(function(value) { + return value[method].apply(value, args); + }); + }, + + max: function(iterator) { + var result; + this.each(function(value, index) { + value = (iterator || Prototype.K)(value, index); + if (result == undefined || value >= result) + result = value; + }); + return result; + }, + + min: function(iterator) { + var result; + this.each(function(value, index) { + value = (iterator || Prototype.K)(value, index); + if (result == undefined || value < result) + result = value; + }); + return result; + }, + + partition: function(iterator) { + var trues = [], falses = []; + this.each(function(value, index) { + ((iterator || Prototype.K)(value, index) ? + trues : falses).push(value); + }); + return [trues, falses]; + }, + + pluck: function(property) { + var results = []; + this.each(function(value, index) { + results.push(value[property]); + }); + return results; + }, + + reject: function(iterator) { + var results = []; + this.each(function(value, index) { + if (!iterator(value, index)) + results.push(value); + }); + return results; + }, + + sortBy: function(iterator) { + return this.map(function(value, index) { + return {value: value, criteria: iterator(value, index)}; + }).sort(function(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }).pluck('value'); + }, + + toArray: function() { + return this.map(); + }, + + zip: function() { + var iterator = Prototype.K, args = $A(arguments); + if (typeof args.last() == 'function') + iterator = args.pop(); + + var collections = [this].concat(args).map($A); + return this.map(function(value, index) { + return iterator(collections.pluck(index)); + }); + }, + + size: function() { + return this.toArray().length; + }, + + inspect: function() { + return '#'; + } +} + +Object.extend(Enumerable, { + map: Enumerable.collect, + find: Enumerable.detect, + select: Enumerable.findAll, + member: Enumerable.include, + entries: Enumerable.toArray +}); +var $A = Array.from = function(iterable) { + if (!iterable) return []; + if (iterable.toArray) { + return iterable.toArray(); + } else { + var results = []; + for (var i = 0, length = iterable.length; i < length; i++) + results.push(iterable[i]); + return results; + } +} + +if (Prototype.Browser.WebKit) { + $A = Array.from = function(iterable) { + if (!iterable) return []; + if (!(typeof iterable == 'function' && iterable == '[object NodeList]') && + iterable.toArray) { + return iterable.toArray(); + } else { + var results = []; + for (var i = 0, length = iterable.length; i < length; i++) + results.push(iterable[i]); + return results; + } + } +} + +Object.extend(Array.prototype, Enumerable); + +if (!Array.prototype._reverse) + Array.prototype._reverse = Array.prototype.reverse; + +Object.extend(Array.prototype, { + _each: function(iterator) { + for (var i = 0, length = this.length; i < length; i++) + iterator(this[i]); + }, + + clear: function() { + this.length = 0; + return this; + }, + + first: function() { + return this[0]; + }, + + last: function() { + return this[this.length - 1]; + }, + + compact: function() { + return this.select(function(value) { + return value != null; + }); + }, + + flatten: function() { + return this.inject([], function(array, value) { + return array.concat(value && value.constructor == Array ? + value.flatten() : [value]); + }); + }, + + without: function() { + var values = $A(arguments); + return this.select(function(value) { + return !values.include(value); + }); + }, + + indexOf: function(object) { + for (var i = 0, length = this.length; i < length; i++) + if (this[i] == object) return i; + return -1; + }, + + reverse: function(inline) { + return (inline !== false ? this : this.toArray())._reverse(); + }, + + reduce: function() { + return this.length > 1 ? this : this[0]; + }, + + uniq: function(sorted) { + return this.inject([], function(array, value, index) { + if (0 == index || (sorted ? array.last() != value : !array.include(value))) + array.push(value); + return array; + }); + }, + + clone: function() { + return [].concat(this); + }, + + size: function() { + return this.length; + }, + + inspect: function() { + return '[' + this.map(Object.inspect).join(', ') + ']'; + }, + + toJSON: function() { + var results = []; + this.each(function(object) { + var value = Object.toJSON(object); + if (value !== undefined) results.push(value); + }); + return '[' + results.join(', ') + ']'; + } +}); + +Array.prototype.toArray = Array.prototype.clone; + +function $w(string) { + string = string.strip(); + return string ? string.split(/\s+/) : []; +} + +if (Prototype.Browser.Opera){ + Array.prototype.concat = function() { + var array = []; + for (var i = 0, length = this.length; i < length; i++) array.push(this[i]); + for (var i = 0, length = arguments.length; i < length; i++) { + if (arguments[i].constructor == Array) { + for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++) + array.push(arguments[i][j]); + } else { + array.push(arguments[i]); + } + } + return array; + } +} +var Hash = function(object) { + if (object instanceof Hash) this.merge(object); + else Object.extend(this, object || {}); +}; + +Object.extend(Hash, { + toQueryString: function(obj) { + var parts = []; + parts.add = arguments.callee.addPair; + + this.prototype._each.call(obj, function(pair) { + if (!pair.key) return; + var value = pair.value; + + if (value && typeof value == 'object') { + if (value.constructor == Array) value.each(function(value) { + parts.add(pair.key, value); + }); + return; + } + parts.add(pair.key, value); + }); + + return parts.join('&'); + }, + + toJSON: function(object) { + var results = []; + this.prototype._each.call(object, function(pair) { + var value = Object.toJSON(pair.value); + if (value !== undefined) results.push(pair.key.toJSON() + ': ' + value); + }); + return '{' + results.join(', ') + '}'; + } +}); + +Hash.toQueryString.addPair = function(key, value, prefix) { + key = encodeURIComponent(key); + if (value === undefined) this.push(key); + else this.push(key + '=' + (value == null ? '' : encodeURIComponent(value))); +} + +Object.extend(Hash.prototype, Enumerable); +Object.extend(Hash.prototype, { + _each: function(iterator) { + for (var key in this) { + var value = this[key]; + if (value && value == Hash.prototype[key]) continue; + + var pair = [key, value]; + pair.key = key; + pair.value = value; + iterator(pair); + } + }, + + keys: function() { + return this.pluck('key'); + }, + + values: function() { + return this.pluck('value'); + }, + + merge: function(hash) { + return $H(hash).inject(this, function(mergedHash, pair) { + mergedHash[pair.key] = pair.value; + return mergedHash; + }); + }, + + remove: function() { + var result; + for(var i = 0, length = arguments.length; i < length; i++) { + var value = this[arguments[i]]; + if (value !== undefined){ + if (result === undefined) result = value; + else { + if (result.constructor != Array) result = [result]; + result.push(value) + } + } + delete this[arguments[i]]; + } + return result; + }, + + toQueryString: function() { + return Hash.toQueryString(this); + }, + + inspect: function() { + return '#'; + }, + + toJSON: function() { + return Hash.toJSON(this); + } +}); + +function $H(object) { + if (object instanceof Hash) return object; + return new Hash(object); +}; + +// Safari iterates over shadowed properties +if (function() { + var i = 0, Test = function(value) { this.key = value }; + Test.prototype.key = 'foo'; + for (var property in new Test('bar')) i++; + return i > 1; +}()) Hash.prototype._each = function(iterator) { + var cache = []; + for (var key in this) { + var value = this[key]; + if ((value && value == Hash.prototype[key]) || cache.include(key)) continue; + cache.push(key); + var pair = [key, value]; + pair.key = key; + pair.value = value; + iterator(pair); + } +}; +ObjectRange = Class.create(); +Object.extend(ObjectRange.prototype, Enumerable); +Object.extend(ObjectRange.prototype, { + initialize: function(start, end, exclusive) { + this.start = start; + this.end = end; + this.exclusive = exclusive; + }, + + _each: function(iterator) { + var value = this.start; + while (this.include(value)) { + iterator(value); + value = value.succ(); + } + }, + + include: function(value) { + if (value < this.start) + return false; + if (this.exclusive) + return value < this.end; + return value <= this.end; + } +}); + +var $R = function(start, end, exclusive) { + return new ObjectRange(start, end, exclusive); +} + +var Ajax = { + getTransport: function() { + return Try.these( + function() {return new XMLHttpRequest()}, + function() {return new ActiveXObject('Msxml2.XMLHTTP')}, + function() {return new ActiveXObject('Microsoft.XMLHTTP')} + ) || false; + }, + + activeRequestCount: 0 +} + +Ajax.Responders = { + responders: [], + + _each: function(iterator) { + this.responders._each(iterator); + }, + + register: function(responder) { + if (!this.include(responder)) + this.responders.push(responder); + }, + + unregister: function(responder) { + this.responders = this.responders.without(responder); + }, + + dispatch: function(callback, request, transport, json) { + this.each(function(responder) { + if (typeof responder[callback] == 'function') { + try { + responder[callback].apply(responder, [request, transport, json]); + } catch (e) {} + } + }); + } +}; + +Object.extend(Ajax.Responders, Enumerable); + +Ajax.Responders.register({ + onCreate: function() { + Ajax.activeRequestCount++; + }, + onComplete: function() { + Ajax.activeRequestCount--; + } +}); + +Ajax.Base = function() {}; +Ajax.Base.prototype = { + setOptions: function(options) { + this.options = { + method: 'post', + asynchronous: true, + contentType: 'application/x-www-form-urlencoded', + encoding: 'UTF-8', + parameters: '' + } + Object.extend(this.options, options || {}); + + this.options.method = this.options.method.toLowerCase(); + if (typeof this.options.parameters == 'string') + this.options.parameters = this.options.parameters.toQueryParams(); + } +} + +Ajax.Request = Class.create(); +Ajax.Request.Events = + ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; + +Ajax.Request.prototype = Object.extend(new Ajax.Base(), { + _complete: false, + + initialize: function(url, options) { + this.transport = Ajax.getTransport(); + this.setOptions(options); + this.request(url); + }, + + request: function(url) { + this.url = url; + this.method = this.options.method; + var params = Object.clone(this.options.parameters); + + if (!['get', 'post'].include(this.method)) { + // simulate other verbs over post + params['_method'] = this.method; + this.method = 'post'; + } + + this.parameters = params; + + if (params = Hash.toQueryString(params)) { + // when GET, append parameters to URL + if (this.method == 'get') + this.url += (this.url.include('?') ? '&' : '?') + params; + else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) + params += '&_='; + } + + try { + if (this.options.onCreate) this.options.onCreate(this.transport); + Ajax.Responders.dispatch('onCreate', this, this.transport); + + this.transport.open(this.method.toUpperCase(), this.url, + this.options.asynchronous); + + if (this.options.asynchronous) + setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10); + + this.transport.onreadystatechange = this.onStateChange.bind(this); + this.setRequestHeaders(); + + this.body = this.method == 'post' ? (this.options.postBody || params) : null; + this.transport.send(this.body); + + /* Force Firefox to handle ready state 4 for synchronous requests */ + if (!this.options.asynchronous && this.transport.overrideMimeType) + this.onStateChange(); + + } + catch (e) { + this.dispatchException(e); + } + }, + + onStateChange: function() { + var readyState = this.transport.readyState; + if (readyState > 1 && !((readyState == 4) && this._complete)) + this.respondToReadyState(this.transport.readyState); + }, + + setRequestHeaders: function() { + var headers = { + 'X-Requested-With': 'XMLHttpRequest', + 'X-Prototype-Version': Prototype.Version, + 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' + }; + + if (this.method == 'post') { + headers['Content-type'] = this.options.contentType + + (this.options.encoding ? '; charset=' + this.options.encoding : ''); + + /* Force "Connection: close" for older Mozilla browsers to work + * around a bug where XMLHttpRequest sends an incorrect + * Content-length header. See Mozilla Bugzilla #246651. + */ + if (this.transport.overrideMimeType && + (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005) + headers['Connection'] = 'close'; + } + + // user-defined headers + if (typeof this.options.requestHeaders == 'object') { + var extras = this.options.requestHeaders; + + if (typeof extras.push == 'function') + for (var i = 0, length = extras.length; i < length; i += 2) + headers[extras[i]] = extras[i+1]; + else + $H(extras).each(function(pair) { headers[pair.key] = pair.value }); + } + + for (var name in headers) + this.transport.setRequestHeader(name, headers[name]); + }, + + success: function() { + return !this.transport.status + || (this.transport.status >= 200 && this.transport.status < 300); + }, + + respondToReadyState: function(readyState) { + var state = Ajax.Request.Events[readyState]; + var transport = this.transport, json = this.evalJSON(); + + if (state == 'Complete') { + try { + this._complete = true; + (this.options['on' + this.transport.status] + || this.options['on' + (this.success() ? 'Success' : 'Failure')] + || Prototype.emptyFunction)(transport, json); + } catch (e) { + this.dispatchException(e); + } + + var contentType = this.getHeader('Content-type'); + if (contentType && contentType.strip(). + match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i)) + this.evalResponse(); + } + + try { + (this.options['on' + state] || Prototype.emptyFunction)(transport, json); + Ajax.Responders.dispatch('on' + state, this, transport, json); + } catch (e) { + this.dispatchException(e); + } + + if (state == 'Complete') { + // avoid memory leak in MSIE: clean up + this.transport.onreadystatechange = Prototype.emptyFunction; + } + }, + + getHeader: function(name) { + try { + return this.transport.getResponseHeader(name); + } catch (e) { return null } + }, + + evalJSON: function() { + try { + var json = this.getHeader('X-JSON'); + return json ? json.evalJSON() : null; + } catch (e) { return null } + }, + + evalResponse: function() { + try { + return eval((this.transport.responseText || '').unfilterJSON()); + } catch (e) { + this.dispatchException(e); + } + }, + + dispatchException: function(exception) { + (this.options.onException || Prototype.emptyFunction)(this, exception); + Ajax.Responders.dispatch('onException', this, exception); + } +}); + +Ajax.Updater = Class.create(); + +Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { + initialize: function(container, url, options) { + this.container = { + success: (container.success || container), + failure: (container.failure || (container.success ? null : container)) + } + + this.transport = Ajax.getTransport(); + this.setOptions(options); + + var onComplete = this.options.onComplete || Prototype.emptyFunction; + this.options.onComplete = (function(transport, param) { + this.updateContent(); + onComplete(transport, param); + }).bind(this); + + this.request(url); + }, + + updateContent: function() { + var receiver = this.container[this.success() ? 'success' : 'failure']; + var response = this.transport.responseText; + + if (!this.options.evalScripts) response = response.stripScripts(); + + if (receiver = $(receiver)) { + if (this.options.insertion) + new this.options.insertion(receiver, response); + else + receiver.update(response); + } + + if (this.success()) { + if (this.onComplete) + setTimeout(this.onComplete.bind(this), 10); + } + } +}); + +Ajax.PeriodicalUpdater = Class.create(); +Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), { + initialize: function(container, url, options) { + this.setOptions(options); + this.onComplete = this.options.onComplete; + + this.frequency = (this.options.frequency || 2); + this.decay = (this.options.decay || 1); + + this.updater = {}; + this.container = container; + this.url = url; + + this.start(); + }, + + start: function() { + this.options.onComplete = this.updateComplete.bind(this); + this.onTimerEvent(); + }, + + stop: function() { + this.updater.options.onComplete = undefined; + clearTimeout(this.timer); + (this.onComplete || Prototype.emptyFunction).apply(this, arguments); + }, + + updateComplete: function(request) { + if (this.options.decay) { + this.decay = (request.responseText == this.lastText ? + this.decay * this.options.decay : 1); + + this.lastText = request.responseText; + } + this.timer = setTimeout(this.onTimerEvent.bind(this), + this.decay * this.frequency * 1000); + }, + + onTimerEvent: function() { + this.updater = new Ajax.Updater(this.container, this.url, this.options); + } +}); +function $(element) { + if (arguments.length > 1) { + for (var i = 0, elements = [], length = arguments.length; i < length; i++) + elements.push($(arguments[i])); + return elements; + } + if (typeof element == 'string') + element = document.getElementById(element); + return Element.extend(element); +} + +if (Prototype.BrowserFeatures.XPath) { + document._getElementsByXPath = function(expression, parentElement) { + var results = []; + var query = document.evaluate(expression, $(parentElement) || document, + null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); + for (var i = 0, length = query.snapshotLength; i < length; i++) + results.push(query.snapshotItem(i)); + return results; + }; + + document.getElementsByClassName = function(className, parentElement) { + var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]"; + return document._getElementsByXPath(q, parentElement); + } + +} else document.getElementsByClassName = function(className, parentElement) { + var children = ($(parentElement) || document.body).getElementsByTagName('*'); + var elements = [], child; + for (var i = 0, length = children.length; i < length; i++) { + child = children[i]; + if (Element.hasClassName(child, className)) + elements.push(Element.extend(child)); + } + return elements; +}; + +/*--------------------------------------------------------------------------*/ + +if (!window.Element) var Element = {}; + +Element.extend = function(element) { + var F = Prototype.BrowserFeatures; + if (!element || !element.tagName || element.nodeType == 3 || + element._extended || F.SpecificElementExtensions || element == window) + return element; + + var methods = {}, tagName = element.tagName, cache = Element.extend.cache, + T = Element.Methods.ByTag; + + // extend methods for all tags (Safari doesn't need this) + if (!F.ElementExtensions) { + Object.extend(methods, Element.Methods), + Object.extend(methods, Element.Methods.Simulated); + } + + // extend methods for specific tags + if (T[tagName]) Object.extend(methods, T[tagName]); + + for (var property in methods) { + var value = methods[property]; + if (typeof value == 'function' && !(property in element)) + element[property] = cache.findOrStore(value); + } + + element._extended = Prototype.emptyFunction; + return element; +}; + +Element.extend.cache = { + findOrStore: function(value) { + return this[value] = this[value] || function() { + return value.apply(null, [this].concat($A(arguments))); + } + } +}; + +Element.Methods = { + visible: function(element) { + return $(element).style.display != 'none'; + }, + + toggle: function(element) { + element = $(element); + Element[Element.visible(element) ? 'hide' : 'show'](element); + return element; + }, + + hide: function(element) { + $(element).style.display = 'none'; + return element; + }, + + show: function(element) { + $(element).style.display = ''; + return element; + }, + + remove: function(element) { + element = $(element); + element.parentNode.removeChild(element); + return element; + }, + + update: function(element, html) { + html = typeof html == 'undefined' ? '' : html.toString(); + $(element).innerHTML = html.stripScripts(); + setTimeout(function() {html.evalScripts()}, 10); + return element; + }, + + replace: function(element, html) { + element = $(element); + html = typeof html == 'undefined' ? '' : html.toString(); + if (element.outerHTML) { + element.outerHTML = html.stripScripts(); + } else { + var range = element.ownerDocument.createRange(); + range.selectNodeContents(element); + element.parentNode.replaceChild( + range.createContextualFragment(html.stripScripts()), element); + } + setTimeout(function() {html.evalScripts()}, 10); + return element; + }, + + inspect: function(element) { + element = $(element); + var result = '<' + element.tagName.toLowerCase(); + $H({'id': 'id', 'className': 'class'}).each(function(pair) { + var property = pair.first(), attribute = pair.last(); + var value = (element[property] || '').toString(); + if (value) result += ' ' + attribute + '=' + value.inspect(true); + }); + return result + '>'; + }, + + recursivelyCollect: function(element, property) { + element = $(element); + var elements = []; + while (element = element[property]) + if (element.nodeType == 1) + elements.push(Element.extend(element)); + return elements; + }, + + ancestors: function(element) { + return $(element).recursivelyCollect('parentNode'); + }, + + descendants: function(element) { + return $A($(element).getElementsByTagName('*')).each(Element.extend); + }, + + firstDescendant: function(element) { + element = $(element).firstChild; + while (element && element.nodeType != 1) element = element.nextSibling; + return $(element); + }, + + immediateDescendants: function(element) { + if (!(element = $(element).firstChild)) return []; + while (element && element.nodeType != 1) element = element.nextSibling; + if (element) return [element].concat($(element).nextSiblings()); + return []; + }, + + previousSiblings: function(element) { + return $(element).recursivelyCollect('previousSibling'); + }, + + nextSiblings: function(element) { + return $(element).recursivelyCollect('nextSibling'); + }, + + siblings: function(element) { + element = $(element); + return element.previousSiblings().reverse().concat(element.nextSiblings()); + }, + + match: function(element, selector) { + if (typeof selector == 'string') + selector = new Selector(selector); + return selector.match($(element)); + }, + + up: function(element, expression, index) { + element = $(element); + if (arguments.length == 1) return $(element.parentNode); + var ancestors = element.ancestors(); + return expression ? Selector.findElement(ancestors, expression, index) : + ancestors[index || 0]; + }, + + down: function(element, expression, index) { + element = $(element); + if (arguments.length == 1) return element.firstDescendant(); + var descendants = element.descendants(); + return expression ? Selector.findElement(descendants, expression, index) : + descendants[index || 0]; + }, + + previous: function(element, expression, index) { + element = $(element); + if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element)); + var previousSiblings = element.previousSiblings(); + return expression ? Selector.findElement(previousSiblings, expression, index) : + previousSiblings[index || 0]; + }, + + next: function(element, expression, index) { + element = $(element); + if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element)); + var nextSiblings = element.nextSiblings(); + return expression ? Selector.findElement(nextSiblings, expression, index) : + nextSiblings[index || 0]; + }, + + getElementsBySelector: function() { + var args = $A(arguments), element = $(args.shift()); + return Selector.findChildElements(element, args); + }, + + getElementsByClassName: function(element, className) { + return document.getElementsByClassName(className, element); + }, + + readAttribute: function(element, name) { + element = $(element); + if (Prototype.Browser.IE) { + if (!element.attributes) return null; + var t = Element._attributeTranslations; + if (t.values[name]) return t.values[name](element, name); + if (t.names[name]) name = t.names[name]; + var attribute = element.attributes[name]; + return attribute ? attribute.nodeValue : null; + } + return element.getAttribute(name); + }, + + getHeight: function(element) { + return $(element).getDimensions().height; + }, + + getWidth: function(element) { + return $(element).getDimensions().width; + }, + + classNames: function(element) { + return new Element.ClassNames(element); + }, + + hasClassName: function(element, className) { + if (!(element = $(element))) return; + var elementClassName = element.className; + if (elementClassName.length == 0) return false; + if (elementClassName == className || + elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) + return true; + return false; + }, + + addClassName: function(element, className) { + if (!(element = $(element))) return; + Element.classNames(element).add(className); + return element; + }, + + removeClassName: function(element, className) { + if (!(element = $(element))) return; + Element.classNames(element).remove(className); + return element; + }, + + toggleClassName: function(element, className) { + if (!(element = $(element))) return; + Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className); + return element; + }, + + observe: function() { + Event.observe.apply(Event, arguments); + return $A(arguments).first(); + }, + + stopObserving: function() { + Event.stopObserving.apply(Event, arguments); + return $A(arguments).first(); + }, + + // removes whitespace-only text node children + cleanWhitespace: function(element) { + element = $(element); + var node = element.firstChild; + while (node) { + var nextNode = node.nextSibling; + if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) + element.removeChild(node); + node = nextNode; + } + return element; + }, + + empty: function(element) { + return $(element).innerHTML.blank(); + }, + + descendantOf: function(element, ancestor) { + element = $(element), ancestor = $(ancestor); + while (element = element.parentNode) + if (element == ancestor) return true; + return false; + }, + + scrollTo: function(element) { + element = $(element); + var pos = Position.cumulativeOffset(element); + window.scrollTo(pos[0], pos[1]); + return element; + }, + + getStyle: function(element, style) { + element = $(element); + style = style == 'float' ? 'cssFloat' : style.camelize(); + var value = element.style[style]; + if (!value) { + var css = document.defaultView.getComputedStyle(element, null); + value = css ? css[style] : null; + } + if (style == 'opacity') return value ? parseFloat(value) : 1.0; + return value == 'auto' ? null : value; + }, + + getOpacity: function(element) { + return $(element).getStyle('opacity'); + }, + + setStyle: function(element, styles, camelized) { + element = $(element); + var elementStyle = element.style; + + for (var property in styles) + if (property == 'opacity') element.setOpacity(styles[property]) + else + elementStyle[(property == 'float' || property == 'cssFloat') ? + (elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') : + (camelized ? property : property.camelize())] = styles[property]; + + return element; + }, + + setOpacity: function(element, value) { + element = $(element); + element.style.opacity = (value == 1 || value === '') ? '' : + (value < 0.00001) ? 0 : value; + return element; + }, + + getDimensions: function(element) { + element = $(element); + var display = $(element).getStyle('display'); + if (display != 'none' && display != null) // Safari bug + return {width: element.offsetWidth, height: element.offsetHeight}; + + // All *Width and *Height properties give 0 on elements with display none, + // so enable the element temporarily + var els = element.style; + var originalVisibility = els.visibility; + var originalPosition = els.position; + var originalDisplay = els.display; + els.visibility = 'hidden'; + els.position = 'absolute'; + els.display = 'block'; + var originalWidth = element.clientWidth; + var originalHeight = element.clientHeight; + els.display = originalDisplay; + els.position = originalPosition; + els.visibility = originalVisibility; + return {width: originalWidth, height: originalHeight}; + }, + + makePositioned: function(element) { + element = $(element); + var pos = Element.getStyle(element, 'position'); + if (pos == 'static' || !pos) { + element._madePositioned = true; + element.style.position = 'relative'; + // Opera returns the offset relative to the positioning context, when an + // element is position relative but top and left have not been defined + if (window.opera) { + element.style.top = 0; + element.style.left = 0; + } + } + return element; + }, + + undoPositioned: function(element) { + element = $(element); + if (element._madePositioned) { + element._madePositioned = undefined; + element.style.position = + element.style.top = + element.style.left = + element.style.bottom = + element.style.right = ''; + } + return element; + }, + + makeClipping: function(element) { + element = $(element); + if (element._overflow) return element; + element._overflow = element.style.overflow || 'auto'; + if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') + element.style.overflow = 'hidden'; + return element; + }, + + undoClipping: function(element) { + element = $(element); + if (!element._overflow) return element; + element.style.overflow = element._overflow == 'auto' ? '' : element._overflow; + element._overflow = null; + return element; + } +}; + +Object.extend(Element.Methods, { + childOf: Element.Methods.descendantOf, + childElements: Element.Methods.immediateDescendants +}); + +if (Prototype.Browser.Opera) { + Element.Methods._getStyle = Element.Methods.getStyle; + Element.Methods.getStyle = function(element, style) { + switch(style) { + case 'left': + case 'top': + case 'right': + case 'bottom': + if (Element._getStyle(element, 'position') == 'static') return null; + default: return Element._getStyle(element, style); + } + }; +} +else if (Prototype.Browser.IE) { + Element.Methods.getStyle = function(element, style) { + element = $(element); + style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize(); + var value = element.style[style]; + if (!value && element.currentStyle) value = element.currentStyle[style]; + + if (style == 'opacity') { + if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/)) + if (value[1]) return parseFloat(value[1]) / 100; + return 1.0; + } + + if (value == 'auto') { + if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none')) + return element['offset'+style.capitalize()] + 'px'; + return null; + } + return value; + }; + + Element.Methods.setOpacity = function(element, value) { + element = $(element); + var filter = element.getStyle('filter'), style = element.style; + if (value == 1 || value === '') { + style.filter = filter.replace(/alpha\([^\)]*\)/gi,''); + return element; + } else if (value < 0.00001) value = 0; + style.filter = filter.replace(/alpha\([^\)]*\)/gi, '') + + 'alpha(opacity=' + (value * 100) + ')'; + return element; + }; + + // IE is missing .innerHTML support for TABLE-related elements + Element.Methods.update = function(element, html) { + element = $(element); + html = typeof html == 'undefined' ? '' : html.toString(); + var tagName = element.tagName.toUpperCase(); + if (['THEAD','TBODY','TR','TD'].include(tagName)) { + var div = document.createElement('div'); + switch (tagName) { + case 'THEAD': + case 'TBODY': + div.innerHTML = '' + html.stripScripts() + '
'; + depth = 2; + break; + case 'TR': + div.innerHTML = '' + html.stripScripts() + '
'; + depth = 3; + break; + case 'TD': + div.innerHTML = '
' + html.stripScripts() + '
'; + depth = 4; + } + $A(element.childNodes).each(function(node) { element.removeChild(node) }); + depth.times(function() { div = div.firstChild }); + $A(div.childNodes).each(function(node) { element.appendChild(node) }); + } else { + element.innerHTML = html.stripScripts(); + } + setTimeout(function() { html.evalScripts() }, 10); + return element; + } +} +else if (Prototype.Browser.Gecko) { + Element.Methods.setOpacity = function(element, value) { + element = $(element); + element.style.opacity = (value == 1) ? 0.999999 : + (value === '') ? '' : (value < 0.00001) ? 0 : value; + return element; + }; +} + +Element._attributeTranslations = { + names: { + colspan: "colSpan", + rowspan: "rowSpan", + valign: "vAlign", + datetime: "dateTime", + accesskey: "accessKey", + tabindex: "tabIndex", + enctype: "encType", + maxlength: "maxLength", + readonly: "readOnly", + longdesc: "longDesc" + }, + values: { + _getAttr: function(element, attribute) { + return element.getAttribute(attribute, 2); + }, + _flag: function(element, attribute) { + return $(element).hasAttribute(attribute) ? attribute : null; + }, + style: function(element) { + return element.style.cssText.toLowerCase(); + }, + title: function(element) { + var node = element.getAttributeNode('title'); + return node.specified ? node.nodeValue : null; + } + } +}; + +(function() { + Object.extend(this, { + href: this._getAttr, + src: this._getAttr, + disabled: this._flag, + checked: this._flag, + readonly: this._flag, + multiple: this._flag + }); +}).call(Element._attributeTranslations.values); + +Element.Methods.Simulated = { + hasAttribute: function(element, attribute) { + var t = Element._attributeTranslations, node; + attribute = t.names[attribute] || attribute; + node = $(element).getAttributeNode(attribute); + return node && node.specified; + } +}; + +Element.Methods.ByTag = {}; + +Object.extend(Element, Element.Methods); + +if (!Prototype.BrowserFeatures.ElementExtensions && + document.createElement('div').__proto__) { + window.HTMLElement = {}; + window.HTMLElement.prototype = document.createElement('div').__proto__; + Prototype.BrowserFeatures.ElementExtensions = true; +} + +Element.hasAttribute = function(element, attribute) { + if (element.hasAttribute) return element.hasAttribute(attribute); + return Element.Methods.Simulated.hasAttribute(element, attribute); +}; + +Element.addMethods = function(methods) { + var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag; + if (arguments.length == 2) { + var tagName = methods; + methods = arguments[1]; + } + + if (!tagName) Object.extend(Element.Methods, methods || {}); + else { + if (tagName.constructor == Array) tagName.each(extend); + else extend(tagName); + } + + function extend(tagName) { + tagName = tagName.toUpperCase(); + if (!Element.Methods.ByTag[tagName]) + Element.Methods.ByTag[tagName] = {}; + Object.extend(Element.Methods.ByTag[tagName], methods); + } + + function copy(methods, destination, onlyIfAbsent) { + onlyIfAbsent = onlyIfAbsent || false; + var cache = Element.extend.cache; + for (var property in methods) { + var value = methods[property]; + if (!onlyIfAbsent || !(property in destination)) + destination[property] = cache.findOrStore(value); + } + } + + function findDOMClass(tagName) { + var klass; + var trans = { + "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph", + "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList", + "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading", + "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote", + "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION": + "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD": + "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR": + "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET": + "FrameSet", "IFRAME": "IFrame" + }; + if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element'; + if (window[klass]) return window[klass]; + klass = 'HTML' + tagName + 'Element'; + if (window[klass]) return window[klass]; + klass = 'HTML' + tagName.capitalize() + 'Element'; + if (window[klass]) return window[klass]; + + window[klass] = {}; + window[klass].prototype = document.createElement(tagName).__proto__; + return window[klass]; + } + + if (F.ElementExtensions) { + copy(Element.Methods, HTMLElement.prototype); + copy(Element.Methods.Simulated, HTMLElement.prototype, true); + } + + if (F.SpecificElementExtensions) { + for (var tag in Element.Methods.ByTag) { + var klass = findDOMClass(tag); + if (typeof klass == "undefined") continue; + copy(T[tag], klass.prototype); + } + } + + Object.extend(Element, Element.Methods); + delete Element.ByTag; +}; + +var Toggle = { display: Element.toggle }; + +/*--------------------------------------------------------------------------*/ + +Abstract.Insertion = function(adjacency) { + this.adjacency = adjacency; +} + +Abstract.Insertion.prototype = { + initialize: function(element, content) { + this.element = $(element); + this.content = content.stripScripts(); + + if (this.adjacency && this.element.insertAdjacentHTML) { + try { + this.element.insertAdjacentHTML(this.adjacency, this.content); + } catch (e) { + var tagName = this.element.tagName.toUpperCase(); + if (['TBODY', 'TR'].include(tagName)) { + this.insertContent(this.contentFromAnonymousTable()); + } else { + throw e; + } + } + } else { + this.range = this.element.ownerDocument.createRange(); + if (this.initializeRange) this.initializeRange(); + this.insertContent([this.range.createContextualFragment(this.content)]); + } + + setTimeout(function() {content.evalScripts()}, 10); + }, + + contentFromAnonymousTable: function() { + var div = document.createElement('div'); + div.innerHTML = '' + this.content + '
'; + return $A(div.childNodes[0].childNodes[0].childNodes); + } +} + +var Insertion = new Object(); + +Insertion.Before = Class.create(); +Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), { + initializeRange: function() { + this.range.setStartBefore(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.parentNode.insertBefore(fragment, this.element); + }).bind(this)); + } +}); + +Insertion.Top = Class.create(); +Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), { + initializeRange: function() { + this.range.selectNodeContents(this.element); + this.range.collapse(true); + }, + + insertContent: function(fragments) { + fragments.reverse(false).each((function(fragment) { + this.element.insertBefore(fragment, this.element.firstChild); + }).bind(this)); + } +}); + +Insertion.Bottom = Class.create(); +Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), { + initializeRange: function() { + this.range.selectNodeContents(this.element); + this.range.collapse(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.appendChild(fragment); + }).bind(this)); + } +}); + +Insertion.After = Class.create(); +Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), { + initializeRange: function() { + this.range.setStartAfter(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.parentNode.insertBefore(fragment, + this.element.nextSibling); + }).bind(this)); + } +}); + +/*--------------------------------------------------------------------------*/ + +Element.ClassNames = Class.create(); +Element.ClassNames.prototype = { + initialize: function(element) { + this.element = $(element); + }, + + _each: function(iterator) { + this.element.className.split(/\s+/).select(function(name) { + return name.length > 0; + })._each(iterator); + }, + + set: function(className) { + this.element.className = className; + }, + + add: function(classNameToAdd) { + if (this.include(classNameToAdd)) return; + this.set($A(this).concat(classNameToAdd).join(' ')); + }, + + remove: function(classNameToRemove) { + if (!this.include(classNameToRemove)) return; + this.set($A(this).without(classNameToRemove).join(' ')); + }, + + toString: function() { + return $A(this).join(' '); + } +}; + +Object.extend(Element.ClassNames.prototype, Enumerable); +/* Portions of the Selector class are derived from Jack Slocum’s DomQuery, + * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style + * license. Please see http://www.yui-ext.com/ for more information. */ + +var Selector = Class.create(); + +Selector.prototype = { + initialize: function(expression) { + this.expression = expression.strip(); + this.compileMatcher(); + }, + + compileMatcher: function() { + // Selectors with namespaced attributes can't use the XPath version + if (Prototype.BrowserFeatures.XPath && !(/\[[\w-]*?:/).test(this.expression)) + return this.compileXPathMatcher(); + + var e = this.expression, ps = Selector.patterns, h = Selector.handlers, + c = Selector.criteria, le, p, m; + + if (Selector._cache[e]) { + this.matcher = Selector._cache[e]; return; + } + this.matcher = ["this.matcher = function(root) {", + "var r = root, h = Selector.handlers, c = false, n;"]; + + while (e && le != e && (/\S/).test(e)) { + le = e; + for (var i in ps) { + p = ps[i]; + if (m = e.match(p)) { + this.matcher.push(typeof c[i] == 'function' ? c[i](m) : + new Template(c[i]).evaluate(m)); + e = e.replace(m[0], ''); + break; + } + } + } + + this.matcher.push("return h.unique(n);\n}"); + eval(this.matcher.join('\n')); + Selector._cache[this.expression] = this.matcher; + }, + + compileXPathMatcher: function() { + var e = this.expression, ps = Selector.patterns, + x = Selector.xpath, le, m; + + if (Selector._cache[e]) { + this.xpath = Selector._cache[e]; return; + } + + this.matcher = ['.//*']; + while (e && le != e && (/\S/).test(e)) { + le = e; + for (var i in ps) { + if (m = e.match(ps[i])) { + this.matcher.push(typeof x[i] == 'function' ? x[i](m) : + new Template(x[i]).evaluate(m)); + e = e.replace(m[0], ''); + break; + } + } + } + + this.xpath = this.matcher.join(''); + Selector._cache[this.expression] = this.xpath; + }, + + findElements: function(root) { + root = root || document; + if (this.xpath) return document._getElementsByXPath(this.xpath, root); + return this.matcher(root); + }, + + match: function(element) { + return this.findElements(document).include(element); + }, + + toString: function() { + return this.expression; + }, + + inspect: function() { + return "#"; + } +}; + +Object.extend(Selector, { + _cache: {}, + + xpath: { + descendant: "//*", + child: "/*", + adjacent: "/following-sibling::*[1]", + laterSibling: '/following-sibling::*', + tagName: function(m) { + if (m[1] == '*') return ''; + return "[local-name()='" + m[1].toLowerCase() + + "' or local-name()='" + m[1].toUpperCase() + "']"; + }, + className: "[contains(concat(' ', @class, ' '), ' #{1} ')]", + id: "[@id='#{1}']", + attrPresence: "[@#{1}]", + attr: function(m) { + m[3] = m[5] || m[6]; + return new Template(Selector.xpath.operators[m[2]]).evaluate(m); + }, + pseudo: function(m) { + var h = Selector.xpath.pseudos[m[1]]; + if (!h) return ''; + if (typeof h === 'function') return h(m); + return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m); + }, + operators: { + '=': "[@#{1}='#{3}']", + '!=': "[@#{1}!='#{3}']", + '^=': "[starts-with(@#{1}, '#{3}')]", + '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']", + '*=': "[contains(@#{1}, '#{3}')]", + '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]", + '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]" + }, + pseudos: { + 'first-child': '[not(preceding-sibling::*)]', + 'last-child': '[not(following-sibling::*)]', + 'only-child': '[not(preceding-sibling::* or following-sibling::*)]', + 'empty': "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]", + 'checked': "[@checked]", + 'disabled': "[@disabled]", + 'enabled': "[not(@disabled)]", + 'not': function(m) { + var e = m[6], p = Selector.patterns, + x = Selector.xpath, le, m, v; + + var exclusion = []; + while (e && le != e && (/\S/).test(e)) { + le = e; + for (var i in p) { + if (m = e.match(p[i])) { + v = typeof x[i] == 'function' ? x[i](m) : new Template(x[i]).evaluate(m); + exclusion.push("(" + v.substring(1, v.length - 1) + ")"); + e = e.replace(m[0], ''); + break; + } + } + } + return "[not(" + exclusion.join(" and ") + ")]"; + }, + 'nth-child': function(m) { + return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m); + }, + 'nth-last-child': function(m) { + return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m); + }, + 'nth-of-type': function(m) { + return Selector.xpath.pseudos.nth("position() ", m); + }, + 'nth-last-of-type': function(m) { + return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m); + }, + 'first-of-type': function(m) { + m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m); + }, + 'last-of-type': function(m) { + m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m); + }, + 'only-of-type': function(m) { + var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m); + }, + nth: function(fragment, m) { + var mm, formula = m[6], predicate; + if (formula == 'even') formula = '2n+0'; + if (formula == 'odd') formula = '2n+1'; + if (mm = formula.match(/^(\d+)$/)) // digit only + return '[' + fragment + "= " + mm[1] + ']'; + if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b + if (mm[1] == "-") mm[1] = -1; + var a = mm[1] ? Number(mm[1]) : 1; + var b = mm[2] ? Number(mm[2]) : 0; + predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " + + "((#{fragment} - #{b}) div #{a} >= 0)]"; + return new Template(predicate).evaluate({ + fragment: fragment, a: a, b: b }); + } + } + } + }, + + criteria: { + tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;', + className: 'n = h.className(n, r, "#{1}", c); c = false;', + id: 'n = h.id(n, r, "#{1}", c); c = false;', + attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;', + attr: function(m) { + m[3] = (m[5] || m[6]); + return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m); + }, + pseudo: function(m) { + if (m[6]) m[6] = m[6].replace(/"/g, '\\"'); + return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m); + }, + descendant: 'c = "descendant";', + child: 'c = "child";', + adjacent: 'c = "adjacent";', + laterSibling: 'c = "laterSibling";' + }, + + patterns: { + // combinators must be listed first + // (and descendant needs to be last combinator) + laterSibling: /^\s*~\s*/, + child: /^\s*>\s*/, + adjacent: /^\s*\+\s*/, + descendant: /^\s/, + + // selectors follow + tagName: /^\s*(\*|[\w\-]+)(\b|$)?/, + id: /^#([\w\-\*]+)(\b|$)/, + className: /^\.([\w\-\*]+)(\b|$)/, + pseudo: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|\s)/, + attrPresence: /^\[([\w]+)\]/, + attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\]]*?)\4|([^'"][^\]]*?)))?\]/ + }, + + handlers: { + // UTILITY FUNCTIONS + // joins two collections + concat: function(a, b) { + for (var i = 0, node; node = b[i]; i++) + a.push(node); + return a; + }, + + // marks an array of nodes for counting + mark: function(nodes) { + for (var i = 0, node; node = nodes[i]; i++) + node._counted = true; + return nodes; + }, + + unmark: function(nodes) { + for (var i = 0, node; node = nodes[i]; i++) + node._counted = undefined; + return nodes; + }, + + // mark each child node with its position (for nth calls) + // "ofType" flag indicates whether we're indexing for nth-of-type + // rather than nth-child + index: function(parentNode, reverse, ofType) { + parentNode._counted = true; + if (reverse) { + for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) { + node = nodes[i]; + if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++; + } + } else { + for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++) + if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++; + } + }, + + // filters out duplicates and extends all nodes + unique: function(nodes) { + if (nodes.length == 0) return nodes; + var results = [], n; + for (var i = 0, l = nodes.length; i < l; i++) + if (!(n = nodes[i])._counted) { + n._counted = true; + results.push(Element.extend(n)); + } + return Selector.handlers.unmark(results); + }, + + // COMBINATOR FUNCTIONS + descendant: function(nodes) { + var h = Selector.handlers; + for (var i = 0, results = [], node; node = nodes[i]; i++) + h.concat(results, node.getElementsByTagName('*')); + return results; + }, + + child: function(nodes) { + var h = Selector.handlers; + for (var i = 0, results = [], node; node = nodes[i]; i++) { + for (var j = 0, children = [], child; child = node.childNodes[j]; j++) + if (child.nodeType == 1 && child.tagName != '!') results.push(child); + } + return results; + }, + + adjacent: function(nodes) { + for (var i = 0, results = [], node; node = nodes[i]; i++) { + var next = this.nextElementSibling(node); + if (next) results.push(next); + } + return results; + }, + + laterSibling: function(nodes) { + var h = Selector.handlers; + for (var i = 0, results = [], node; node = nodes[i]; i++) + h.concat(results, Element.nextSiblings(node)); + return results; + }, + + nextElementSibling: function(node) { + while (node = node.nextSibling) + if (node.nodeType == 1) return node; + return null; + }, + + previousElementSibling: function(node) { + while (node = node.previousSibling) + if (node.nodeType == 1) return node; + return null; + }, + + // TOKEN FUNCTIONS + tagName: function(nodes, root, tagName, combinator) { + tagName = tagName.toUpperCase(); + var results = [], h = Selector.handlers; + if (nodes) { + if (combinator) { + // fastlane for ordinary descendant combinators + if (combinator == "descendant") { + for (var i = 0, node; node = nodes[i]; i++) + h.concat(results, node.getElementsByTagName(tagName)); + return results; + } else nodes = this[combinator](nodes); + if (tagName == "*") return nodes; + } + for (var i = 0, node; node = nodes[i]; i++) + if (node.tagName.toUpperCase() == tagName) results.push(node); + return results; + } else return root.getElementsByTagName(tagName); + }, + + id: function(nodes, root, id, combinator) { + var targetNode = $(id), h = Selector.handlers; + if (!nodes && root == document) return targetNode ? [targetNode] : []; + if (nodes) { + if (combinator) { + if (combinator == 'child') { + for (var i = 0, node; node = nodes[i]; i++) + if (targetNode.parentNode == node) return [targetNode]; + } else if (combinator == 'descendant') { + for (var i = 0, node; node = nodes[i]; i++) + if (Element.descendantOf(targetNode, node)) return [targetNode]; + } else if (combinator == 'adjacent') { + for (var i = 0, node; node = nodes[i]; i++) + if (Selector.handlers.previousElementSibling(targetNode) == node) + return [targetNode]; + } else nodes = h[combinator](nodes); + } + for (var i = 0, node; node = nodes[i]; i++) + if (node == targetNode) return [targetNode]; + return []; + } + return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : []; + }, + + className: function(nodes, root, className, combinator) { + if (nodes && combinator) nodes = this[combinator](nodes); + return Selector.handlers.byClassName(nodes, root, className); + }, + + byClassName: function(nodes, root, className) { + if (!nodes) nodes = Selector.handlers.descendant([root]); + var needle = ' ' + className + ' '; + for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) { + nodeClassName = node.className; + if (nodeClassName.length == 0) continue; + if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle)) + results.push(node); + } + return results; + }, + + attrPresence: function(nodes, root, attr) { + var results = []; + for (var i = 0, node; node = nodes[i]; i++) + if (Element.hasAttribute(node, attr)) results.push(node); + return results; + }, + + attr: function(nodes, root, attr, value, operator) { + if (!nodes) nodes = root.getElementsByTagName("*"); + var handler = Selector.operators[operator], results = []; + for (var i = 0, node; node = nodes[i]; i++) { + var nodeValue = Element.readAttribute(node, attr); + if (nodeValue === null) continue; + if (handler(nodeValue, value)) results.push(node); + } + return results; + }, + + pseudo: function(nodes, name, value, root, combinator) { + if (nodes && combinator) nodes = this[combinator](nodes); + if (!nodes) nodes = root.getElementsByTagName("*"); + return Selector.pseudos[name](nodes, value, root); + } + }, + + pseudos: { + 'first-child': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) { + if (Selector.handlers.previousElementSibling(node)) continue; + results.push(node); + } + return results; + }, + 'last-child': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) { + if (Selector.handlers.nextElementSibling(node)) continue; + results.push(node); + } + return results; + }, + 'only-child': function(nodes, value, root) { + var h = Selector.handlers; + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (!h.previousElementSibling(node) && !h.nextElementSibling(node)) + results.push(node); + return results; + }, + 'nth-child': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, formula, root); + }, + 'nth-last-child': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, formula, root, true); + }, + 'nth-of-type': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, formula, root, false, true); + }, + 'nth-last-of-type': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, formula, root, true, true); + }, + 'first-of-type': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, "1", root, false, true); + }, + 'last-of-type': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, "1", root, true, true); + }, + 'only-of-type': function(nodes, formula, root) { + var p = Selector.pseudos; + return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root); + }, + + // handles the an+b logic + getIndices: function(a, b, total) { + if (a == 0) return b > 0 ? [b] : []; + return $R(1, total).inject([], function(memo, i) { + if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i); + return memo; + }); + }, + + // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type + nth: function(nodes, formula, root, reverse, ofType) { + if (nodes.length == 0) return []; + if (formula == 'even') formula = '2n+0'; + if (formula == 'odd') formula = '2n+1'; + var h = Selector.handlers, results = [], indexed = [], m; + h.mark(nodes); + for (var i = 0, node; node = nodes[i]; i++) { + if (!node.parentNode._counted) { + h.index(node.parentNode, reverse, ofType); + indexed.push(node.parentNode); + } + } + if (formula.match(/^\d+$/)) { // just a number + formula = Number(formula); + for (var i = 0, node; node = nodes[i]; i++) + if (node.nodeIndex == formula) results.push(node); + } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b + if (m[1] == "-") m[1] = -1; + var a = m[1] ? Number(m[1]) : 1; + var b = m[2] ? Number(m[2]) : 0; + var indices = Selector.pseudos.getIndices(a, b, nodes.length); + for (var i = 0, node, l = indices.length; node = nodes[i]; i++) { + for (var j = 0; j < l; j++) + if (node.nodeIndex == indices[j]) results.push(node); + } + } + h.unmark(nodes); + h.unmark(indexed); + return results; + }, + + 'empty': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) { + // IE treats comments as element nodes + if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue; + results.push(node); + } + return results; + }, + + 'not': function(nodes, selector, root) { + var h = Selector.handlers, selectorType, m; + var exclusions = new Selector(selector).findElements(root); + h.mark(exclusions); + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (!node._counted) results.push(node); + h.unmark(exclusions); + return results; + }, + + 'enabled': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (!node.disabled) results.push(node); + return results; + }, + + 'disabled': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (node.disabled) results.push(node); + return results; + }, + + 'checked': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (node.checked) results.push(node); + return results; + } + }, + + operators: { + '=': function(nv, v) { return nv == v; }, + '!=': function(nv, v) { return nv != v; }, + '^=': function(nv, v) { return nv.startsWith(v); }, + '$=': function(nv, v) { return nv.endsWith(v); }, + '*=': function(nv, v) { return nv.include(v); }, + '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); }, + '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); } + }, + + matchElements: function(elements, expression) { + var matches = new Selector(expression).findElements(), h = Selector.handlers; + h.mark(matches); + for (var i = 0, results = [], element; element = elements[i]; i++) + if (element._counted) results.push(element); + h.unmark(matches); + return results; + }, + + findElement: function(elements, expression, index) { + if (typeof expression == 'number') { + index = expression; expression = false; + } + return Selector.matchElements(elements, expression || '*')[index || 0]; + }, + + findChildElements: function(element, expressions) { + var exprs = expressions.join(','), expressions = []; + exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) { + expressions.push(m[1].strip()); + }); + var results = [], h = Selector.handlers; + for (var i = 0, l = expressions.length, selector; i < l; i++) { + selector = new Selector(expressions[i].strip()); + h.concat(results, selector.findElements(element)); + } + return (l > 1) ? h.unique(results) : results; + } +}); + +function $$() { + return Selector.findChildElements(document, $A(arguments)); +} +var Form = { + reset: function(form) { + $(form).reset(); + return form; + }, + + serializeElements: function(elements, getHash) { + var data = elements.inject({}, function(result, element) { + if (!element.disabled && element.name) { + var key = element.name, value = $(element).getValue(); + if (value != null) { + if (key in result) { + if (result[key].constructor != Array) result[key] = [result[key]]; + result[key].push(value); + } + else result[key] = value; + } + } + return result; + }); + + return getHash ? data : Hash.toQueryString(data); + } +}; + +Form.Methods = { + serialize: function(form, getHash) { + return Form.serializeElements(Form.getElements(form), getHash); + }, + + getElements: function(form) { + return $A($(form).getElementsByTagName('*')).inject([], + function(elements, child) { + if (Form.Element.Serializers[child.tagName.toLowerCase()]) + elements.push(Element.extend(child)); + return elements; + } + ); + }, + + getInputs: function(form, typeName, name) { + form = $(form); + var inputs = form.getElementsByTagName('input'); + + if (!typeName && !name) return $A(inputs).map(Element.extend); + + for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) { + var input = inputs[i]; + if ((typeName && input.type != typeName) || (name && input.name != name)) + continue; + matchingInputs.push(Element.extend(input)); + } + + return matchingInputs; + }, + + disable: function(form) { + form = $(form); + Form.getElements(form).invoke('disable'); + return form; + }, + + enable: function(form) { + form = $(form); + Form.getElements(form).invoke('enable'); + return form; + }, + + findFirstElement: function(form) { + return $(form).getElements().find(function(element) { + return element.type != 'hidden' && !element.disabled && + ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); + }); + }, + + focusFirstElement: function(form) { + form = $(form); + form.findFirstElement().activate(); + return form; + }, + + request: function(form, options) { + form = $(form), options = Object.clone(options || {}); + + var params = options.parameters; + options.parameters = form.serialize(true); + + if (params) { + if (typeof params == 'string') params = params.toQueryParams(); + Object.extend(options.parameters, params); + } + + if (form.hasAttribute('method') && !options.method) + options.method = form.method; + + return new Ajax.Request(form.readAttribute('action'), options); + } +} + +Object.extend(Form, Form.Methods); + +/*--------------------------------------------------------------------------*/ + +Form.Element = { + focus: function(element) { + $(element).focus(); + return element; + }, + + select: function(element) { + $(element).select(); + return element; + } +} + +Form.Element.Methods = { + serialize: function(element) { + element = $(element); + if (!element.disabled && element.name) { + var value = element.getValue(); + if (value != undefined) { + var pair = {}; + pair[element.name] = value; + return Hash.toQueryString(pair); + } + } + return ''; + }, + + getValue: function(element) { + element = $(element); + var method = element.tagName.toLowerCase(); + return Form.Element.Serializers[method](element); + }, + + clear: function(element) { + $(element).value = ''; + return element; + }, + + present: function(element) { + return $(element).value != ''; + }, + + activate: function(element) { + element = $(element); + try { + element.focus(); + if (element.select && (element.tagName.toLowerCase() != 'input' || + !['button', 'reset', 'submit'].include(element.type))) + element.select(); + } catch (e) {} + return element; + }, + + disable: function(element) { + element = $(element); + element.blur(); + element.disabled = true; + return element; + }, + + enable: function(element) { + element = $(element); + element.disabled = false; + return element; + } +} + +Object.extend(Form.Element, Form.Element.Methods); +Object.extend(Element.Methods.ByTag, { + "FORM": Object.clone(Form.Methods), + "INPUT": Object.clone(Form.Element.Methods), + "SELECT": Object.clone(Form.Element.Methods), + "TEXTAREA": Object.clone(Form.Element.Methods) +}); + +/*--------------------------------------------------------------------------*/ + +var Field = Form.Element; +var $F = Form.Element.getValue; + +/*--------------------------------------------------------------------------*/ + +Form.Element.Serializers = { + input: function(element) { + switch (element.type.toLowerCase()) { + case 'checkbox': + case 'radio': + return Form.Element.Serializers.inputSelector(element); + default: + return Form.Element.Serializers.textarea(element); + } + }, + + inputSelector: function(element) { + return element.checked ? element.value : null; + }, + + textarea: function(element) { + return element.value; + }, + + select: function(element) { + return this[element.type == 'select-one' ? + 'selectOne' : 'selectMany'](element); + }, + + selectOne: function(element) { + var index = element.selectedIndex; + return index >= 0 ? this.optionValue(element.options[index]) : null; + }, + + selectMany: function(element) { + var values, length = element.length; + if (!length) return null; + + for (var i = 0, values = []; i < length; i++) { + var opt = element.options[i]; + if (opt.selected) values.push(this.optionValue(opt)); + } + return values; + }, + + optionValue: function(opt) { + // extend element because hasAttribute may not be native + return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text; + } +} + +/*--------------------------------------------------------------------------*/ + +Abstract.TimedObserver = function() {} +Abstract.TimedObserver.prototype = { + initialize: function(element, frequency, callback) { + this.frequency = frequency; + this.element = $(element); + this.callback = callback; + + this.lastValue = this.getValue(); + this.registerCallback(); + }, + + registerCallback: function() { + setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); + }, + + onTimerEvent: function() { + var value = this.getValue(); + var changed = ('string' == typeof this.lastValue && 'string' == typeof value + ? this.lastValue != value : String(this.lastValue) != String(value)); + if (changed) { + this.callback(this.element, value); + this.lastValue = value; + } + } +} + +Form.Element.Observer = Class.create(); +Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.Observer = Class.create(); +Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { + getValue: function() { + return Form.serialize(this.element); + } +}); + +/*--------------------------------------------------------------------------*/ + +Abstract.EventObserver = function() {} +Abstract.EventObserver.prototype = { + initialize: function(element, callback) { + this.element = $(element); + this.callback = callback; + + this.lastValue = this.getValue(); + if (this.element.tagName.toLowerCase() == 'form') + this.registerFormCallbacks(); + else + this.registerCallback(this.element); + }, + + onElementEvent: function() { + var value = this.getValue(); + if (this.lastValue != value) { + this.callback(this.element, value); + this.lastValue = value; + } + }, + + registerFormCallbacks: function() { + Form.getElements(this.element).each(this.registerCallback.bind(this)); + }, + + registerCallback: function(element) { + if (element.type) { + switch (element.type.toLowerCase()) { + case 'checkbox': + case 'radio': + Event.observe(element, 'click', this.onElementEvent.bind(this)); + break; + default: + Event.observe(element, 'change', this.onElementEvent.bind(this)); + break; + } + } + } +} + +Form.Element.EventObserver = Class.create(); +Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.EventObserver = Class.create(); +Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { + getValue: function() { + return Form.serialize(this.element); + } +}); +if (!window.Event) { + var Event = new Object(); +} + +Object.extend(Event, { + KEY_BACKSPACE: 8, + KEY_TAB: 9, + KEY_RETURN: 13, + KEY_ESC: 27, + KEY_LEFT: 37, + KEY_UP: 38, + KEY_RIGHT: 39, + KEY_DOWN: 40, + KEY_DELETE: 46, + KEY_HOME: 36, + KEY_END: 35, + KEY_PAGEUP: 33, + KEY_PAGEDOWN: 34, + + element: function(event) { + return $(event.target || event.srcElement); + }, + + isLeftClick: function(event) { + return (((event.which) && (event.which == 1)) || + ((event.button) && (event.button == 1))); + }, + + pointerX: function(event) { + return event.pageX || (event.clientX + + (document.documentElement.scrollLeft || document.body.scrollLeft)); + }, + + pointerY: function(event) { + return event.pageY || (event.clientY + + (document.documentElement.scrollTop || document.body.scrollTop)); + }, + + stop: function(event) { + if (event.preventDefault) { + event.preventDefault(); + event.stopPropagation(); + } else { + event.returnValue = false; + event.cancelBubble = true; + } + }, + + // find the first node with the given tagName, starting from the + // node the event was triggered on; traverses the DOM upwards + findElement: function(event, tagName) { + var element = Event.element(event); + while (element.parentNode && (!element.tagName || + (element.tagName.toUpperCase() != tagName.toUpperCase()))) + element = element.parentNode; + return element; + }, + + observers: false, + + _observeAndCache: function(element, name, observer, useCapture) { + if (!this.observers) this.observers = []; + if (element.addEventListener) { + this.observers.push([element, name, observer, useCapture]); + element.addEventListener(name, observer, useCapture); + } else if (element.attachEvent) { + this.observers.push([element, name, observer, useCapture]); + element.attachEvent('on' + name, observer); + } + }, + + unloadCache: function() { + if (!Event.observers) return; + for (var i = 0, length = Event.observers.length; i < length; i++) { + Event.stopObserving.apply(this, Event.observers[i]); + Event.observers[i][0] = null; + } + Event.observers = false; + }, + + observe: function(element, name, observer, useCapture) { + element = $(element); + useCapture = useCapture || false; + + if (name == 'keypress' && + (Prototype.Browser.WebKit || element.attachEvent)) + name = 'keydown'; + + Event._observeAndCache(element, name, observer, useCapture); + }, + + stopObserving: function(element, name, observer, useCapture) { + element = $(element); + useCapture = useCapture || false; + + if (name == 'keypress' && + (Prototype.Browser.WebKit || element.attachEvent)) + name = 'keydown'; + + if (element.removeEventListener) { + element.removeEventListener(name, observer, useCapture); + } else if (element.detachEvent) { + try { + element.detachEvent('on' + name, observer); + } catch (e) {} + } + } +}); + +/* prevent memory leaks in IE */ +if (Prototype.Browser.IE) + Event.observe(window, 'unload', Event.unloadCache, false); +var Position = { + // set to true if needed, warning: firefox performance problems + // NOT neeeded for page scrolling, only if draggable contained in + // scrollable elements + includeScrollOffsets: false, + + // must be called before calling withinIncludingScrolloffset, every time the + // page is scrolled + prepare: function() { + this.deltaX = window.pageXOffset + || document.documentElement.scrollLeft + || document.body.scrollLeft + || 0; + this.deltaY = window.pageYOffset + || document.documentElement.scrollTop + || document.body.scrollTop + || 0; + }, + + realOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.scrollTop || 0; + valueL += element.scrollLeft || 0; + element = element.parentNode; + } while (element); + return [valueL, valueT]; + }, + + cumulativeOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + } while (element); + return [valueL, valueT]; + }, + + positionedOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + if (element) { + if(element.tagName=='BODY') break; + var p = Element.getStyle(element, 'position'); + if (p == 'relative' || p == 'absolute') break; + } + } while (element); + return [valueL, valueT]; + }, + + offsetParent: function(element) { + if (element.offsetParent) return element.offsetParent; + if (element == document.body) return element; + + while ((element = element.parentNode) && element != document.body) + if (Element.getStyle(element, 'position') != 'static') + return element; + + return document.body; + }, + + // caches x/y coordinate pair to use with overlap + within: function(element, x, y) { + if (this.includeScrollOffsets) + return this.withinIncludingScrolloffsets(element, x, y); + this.xcomp = x; + this.ycomp = y; + this.offset = this.cumulativeOffset(element); + + return (y >= this.offset[1] && + y < this.offset[1] + element.offsetHeight && + x >= this.offset[0] && + x < this.offset[0] + element.offsetWidth); + }, + + withinIncludingScrolloffsets: function(element, x, y) { + var offsetcache = this.realOffset(element); + + this.xcomp = x + offsetcache[0] - this.deltaX; + this.ycomp = y + offsetcache[1] - this.deltaY; + this.offset = this.cumulativeOffset(element); + + return (this.ycomp >= this.offset[1] && + this.ycomp < this.offset[1] + element.offsetHeight && + this.xcomp >= this.offset[0] && + this.xcomp < this.offset[0] + element.offsetWidth); + }, + + // within must be called directly before + overlap: function(mode, element) { + if (!mode) return 0; + if (mode == 'vertical') + return ((this.offset[1] + element.offsetHeight) - this.ycomp) / + element.offsetHeight; + if (mode == 'horizontal') + return ((this.offset[0] + element.offsetWidth) - this.xcomp) / + element.offsetWidth; + }, + + page: function(forElement) { + var valueT = 0, valueL = 0; + + var element = forElement; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + + // Safari fix + if (element.offsetParent == document.body) + if (Element.getStyle(element,'position')=='absolute') break; + + } while (element = element.offsetParent); + + element = forElement; + do { + if (!window.opera || element.tagName=='BODY') { + valueT -= element.scrollTop || 0; + valueL -= element.scrollLeft || 0; + } + } while (element = element.parentNode); + + return [valueL, valueT]; + }, + + clone: function(source, target) { + var options = Object.extend({ + setLeft: true, + setTop: true, + setWidth: true, + setHeight: true, + offsetTop: 0, + offsetLeft: 0 + }, arguments[2] || {}) + + // find page position of source + source = $(source); + var p = Position.page(source); + + // find coordinate system to use + target = $(target); + var delta = [0, 0]; + var parent = null; + // delta [0,0] will do fine with position: fixed elements, + // position:absolute needs offsetParent deltas + if (Element.getStyle(target,'position') == 'absolute') { + parent = Position.offsetParent(target); + delta = Position.page(parent); + } + + // correct by body offsets (fixes Safari) + if (parent == document.body) { + delta[0] -= document.body.offsetLeft; + delta[1] -= document.body.offsetTop; + } + + // set position + if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; + if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; + if(options.setWidth) target.style.width = source.offsetWidth + 'px'; + if(options.setHeight) target.style.height = source.offsetHeight + 'px'; + }, + + absolutize: function(element) { + element = $(element); + if (element.style.position == 'absolute') return; + Position.prepare(); + + var offsets = Position.positionedOffset(element); + var top = offsets[1]; + var left = offsets[0]; + var width = element.clientWidth; + var height = element.clientHeight; + + element._originalLeft = left - parseFloat(element.style.left || 0); + element._originalTop = top - parseFloat(element.style.top || 0); + element._originalWidth = element.style.width; + element._originalHeight = element.style.height; + + element.style.position = 'absolute'; + element.style.top = top + 'px'; + element.style.left = left + 'px'; + element.style.width = width + 'px'; + element.style.height = height + 'px'; + }, + + relativize: function(element) { + element = $(element); + if (element.style.position == 'relative') return; + Position.prepare(); + + element.style.position = 'relative'; + var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); + var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); + + element.style.top = top + 'px'; + element.style.left = left + 'px'; + element.style.height = element._originalHeight; + element.style.width = element._originalWidth; + } +} + +// Safari returns margins on body which is incorrect if the child is absolutely +// positioned. For performance reasons, redefine Position.cumulativeOffset for +// KHTML/WebKit only. +if (Prototype.Browser.WebKit) { + Position.cumulativeOffset = function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + if (element.offsetParent == document.body) + if (Element.getStyle(element, 'position') == 'absolute') break; + + element = element.offsetParent; + } while (element); + + return [valueL, valueT]; + } +} + +Element.addMethods(); \ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/js/rico/rico.js b/NP_TrackBack/trunk/trackback/js/rico/rico.js new file mode 100644 index 0000000..00e187e --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/rico.js @@ -0,0 +1,214 @@ +/** + * + * Copyright 2005 Sabre Airline Solutions + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + **/ + + +// This module does NOT depend on prototype.js + +var Rico = { + Version: '2.0 beta2', + loadRequested: 1, + loadComplete: 2, + init : function() { + try { // fix IE background image flicker (credit: www.mister-pixel.com) + document.execCommand("BackgroundImageCache", false, true); + } catch(err) {} + this.preloadMsgs=''; + var elements = document.getElementsByTagName('script'); + this.baseHref= location.protocol + "//" + location.host; + this.loadedFiles={}; + this.loadQueue=[]; + this.windowIsLoaded=false; + this.onLoadCallbacks=[]; + for (var i=0; i 0) { + var callback=this.onLoadCallbacks.pop(); + if (callback) callback(); + } + } + }, + + onLoad: function(callback) { + this.onLoadCallbacks.push(callback); + this.checkIfComplete(); + }, + + isKonqueror : navigator.userAgent.toLowerCase().indexOf("konqueror") >= 0, + + // logging funtions + + startTime : new Date(), + + timeStamp: function() { + var stamp = new Date(); + return (stamp.getTime()-this.startTime.getTime())+": "; + }, + + setDebugArea: function(id, forceit) { + if (!this.debugArea || forceit) { + var newarea=document.getElementById(id); + if (!newarea) return; + this.debugArea=newarea; + newarea.value=''; + } + }, + + addPreloadMsg: function(msg) { + this.preloadMsgs+=Rico.timeStamp()+msg+"\n"; + }, + + writeDebugMsg: function(msg, resetFlag) { + if (this.debugArea) { + if (resetFlag) this.debugArea.value=''; + this.debugArea.value+=this.timeStamp()+msg+"\n"; + } + } + +} + +Rico.init(); diff --git a/NP_TrackBack/trunk/trackback/js/rico/ricoAjaxEngine.js b/NP_TrackBack/trunk/trackback/js/rico/ricoAjaxEngine.js new file mode 100644 index 0000000..5363991 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/ricoAjaxEngine.js @@ -0,0 +1,178 @@ +//-------------------- ricoAjaxEngine.js +Rico.AjaxEngine = Class.create(); + +Rico.AjaxEngine.prototype = { + + initialize: function() { + this.ajaxElements = new Array(); + this.ajaxObjects = new Array(); + this.requestURLS = new Array(); + this.options = {}; + }, + + registerAjaxElement: function( anId, anElement ) { + if ( !anElement ) + anElement = $(anId); + this.ajaxElements[anId] = anElement; + }, + + registerAjaxObject: function( anId, anObject ) { + this.ajaxObjects[anId] = anObject; + }, + + registerRequest: function (requestLogicalName, requestURL) { + this.requestURLS[requestLogicalName] = requestURL; + }, + + sendRequest: function(requestName, options) { + // Allow for backwards Compatibility + if ( arguments.length >= 2 ) + if (typeof arguments[1] == 'string') + options = {parameters: this._createQueryString(arguments, 1)}; + this.sendRequestWithData(requestName, null, options); + }, + + sendRequestWithData: function(requestName, xmlDocument, options) { + var requestURL = this.requestURLS[requestName]; + if ( requestURL == null ) + return; + + // Allow for backwards Compatibility + if ( arguments.length >= 3 ) + if (typeof arguments[2] == 'string') + options.parameters = this._createQueryString(arguments, 2); + + new Ajax.Request(requestURL, this._requestOptions(options,xmlDocument)); + }, + + sendRequestAndUpdate: function(requestName,container,options) { + // Allow for backwards Compatibility + if ( arguments.length >= 3 ) + if (typeof arguments[2] == 'string') + options.parameters = this._createQueryString(arguments, 2); + + this.sendRequestWithDataAndUpdate(requestName, null, container, options); + }, + + sendRequestWithDataAndUpdate: function(requestName,xmlDocument,container,options) { + var requestURL = this.requestURLS[requestName]; + if ( requestURL == null ) + return; + + // Allow for backwards Compatibility + if ( arguments.length >= 4 ) + if (typeof arguments[3] == 'string') + options.parameters = this._createQueryString(arguments, 3); + + var updaterOptions = this._requestOptions(options,xmlDocument); + + new Ajax.Updater(container, requestURL, updaterOptions); + }, + + // Private -- not part of intended engine API -------------------------------------------------------------------- + + _requestOptions: function(options,xmlDoc) { + var requestHeaders = ['X-Rico-Version', Rico.Version ]; + var sendMethod = 'post'; + if ( xmlDoc == null ) + if (Rico.prototypeVersion < 1.4) + requestHeaders.push( 'Content-type', 'text/xml' ); + else + sendMethod = 'get'; + (!options) ? options = {} : ''; + + if (!options._RicoOptionsProcessed){ + // Check and keep any user onComplete functions + if (options.onComplete) + options.onRicoComplete = options.onComplete; + // Fix onComplete + if (options.overrideOnComplete) + options.onComplete = options.overrideOnComplete; + else + options.onComplete = this._onRequestComplete.bind(this); + options._RicoOptionsProcessed = true; + } + + // Set the default options and extend with any user options + this.options = { + requestHeaders: requestHeaders, + parameters: options.parameters, + postBody: xmlDoc, + method: sendMethod, + onComplete: options.onComplete + }; + // Set any user options: + Object.extend(this.options, options); + return this.options; + }, + + _createQueryString: function( theArgs, offset ) { + var queryString = "" + for ( var i = offset ; i < theArgs.length ; i++ ) { + if ( i != offset ) + queryString += "&"; + + var anArg = theArgs[i]; + + if ( anArg.name != undefined && anArg.value != undefined ) { + queryString += anArg.name + "=" + escape(anArg.value); + } + else { + var ePos = anArg.indexOf('='); + var argName = anArg.substring( 0, ePos ); + var argValue = anArg.substring( ePos + 1 ); + queryString += argName + "=" + escape(argValue); + } + } + return queryString; + }, + + _onRequestComplete : function(request) { + if(!request) + return; + // User can set an onFailure option - which will be called by prototype + if (request.status != 200) + return; + + var response = request.responseXML.getElementsByTagName("ajax-response"); + if (response == null || response.length != 1) + return; + this._processAjaxResponse( response[0].childNodes ); + + // Check if user has set a onComplete function + var onRicoComplete = this.options.onRicoComplete; + if (onRicoComplete != null) + onRicoComplete(); + }, + + _processAjaxResponse: function( xmlResponseElements ) { + for ( var i = 0 ; i < xmlResponseElements.length ; i++ ) { + var responseElement = xmlResponseElements[i]; + + // only process nodes of type element..... + if ( responseElement.nodeType != 1 ) + continue; + + var responseType = responseElement.getAttribute("type"); + var responseId = responseElement.getAttribute("id"); + + if ( responseType == "object" ) + this._processAjaxObjectUpdate( this.ajaxObjects[ responseId ], responseElement ); + else if ( responseType == "element" ) + this._processAjaxElementUpdate( this.ajaxElements[ responseId ], responseElement ); + else + alert('unrecognized AjaxResponse type : ' + responseType ); + } + }, + + _processAjaxObjectUpdate: function( ajaxObject, responseElement ) { + ajaxObject.ajaxUpdate( responseElement ); + }, + + _processAjaxElementUpdate: function( ajaxElement, responseElement ) { + ajaxElement.innerHTML = RicoUtil.getContentAsString(responseElement); + } + +} + +Rico.includeLoaded('ricoAjaxEngine.js'); \ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/js/rico/ricoBehaviors.js b/NP_TrackBack/trunk/trackback/js/rico/ricoBehaviors.js new file mode 100644 index 0000000..ed5d572 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/ricoBehaviors.js @@ -0,0 +1,188 @@ +/** + * (c) 2005-2007 Richard Cowin (http://openrico.org) + * + * Rico is licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + **/ + + +Rico.selectionSet = function(set, options){ + new Rico.SelectionSet(set, options) +} + +Rico.SelectionSet = Class.create(); +Rico.SelectionSet.prototype = { + initialize: function(selectionSet, options){ + this.options = options || {} + if (typeof selectionSet == 'string') + selectionSet = $$(selectionSet) + this.previouslySelected = []; + this.selectionSet = selectionSet; + this.selectedClassName = this.options.selectedClass || "selected"; + this.selectNode = this.options.selectNode || function(e){return e}; + this.onSelect = this.options.onSelect; + this.onFirstSelect = this.options.onFirstSelect; + this.clickHandler = this.click.bind(this); + selectionSet.each(function(e) {Event.observe(e, "click", new Rico.EventWrapper(this.clickHandler,e).wrapper);}.bind(this)) + if (!this.options.noDefault) + this.selectIndex(this.options.selectedIndex || 0) + }, + reset: function(){ + this.previouslySelected = []; + this.notifySelected(this.selected); + }, + select: function(element){ + if (this.selected == element) + return; + + if (this.selected) + new Element.ClassNames(this.selectNode(this.selected)).remove(this.selectedClassName) + + this.notifySelected(element) + + this.selected = element; + new Element.ClassNames(this.selectNode(this.selected)).add(this.selectedClassName) + }, + notifySelected: function(element){ + var index = this.selectionSet.indexOf(element) + if (this.onFirstSelect && !this.previouslySelected[index]){ + this.onFirstSelect(element, index) + this.previouslySelected[index] = true; + } + if (this.onSelect) + try{ + this.onSelect(element, index) + } catch (e) {} + }, + selectIndex: function(index){ + this.select(this.selectionSet[index]) + }, + nextSelectItem: function(index){ + var index = this.selectionSet.indexOf(this.selected) + if (index + 1 >= this.selectionSet.length) + return this.selectionSet[index - 1]; + else + return this.selectionSet[index + 1]; + }, + selectNext: function(){ + var index = this.selectionSet.indexOf(this.selected) + if (index >= this.selectionSet.length) + this.selectIndex(index - 1) + else + this.selectIndex(index + 1) + }, + click: function(event,target) { + this.select(target); + }, + add: function(item){ + // this.selectionSet.push(item) + if (item.constructur == Array) + item.each(function(e){ + Event.observe(e, "click", new Rico.EventWrapper(this.clickHandler,item).wrapper); + }.bind(this)) + else + Event.observe(item, "click", new Rico.EventWrapper(this.clickHandler,item).wrapper); + }, + remove: function(item){ + this.selectionSet = this.selectionSet.without(item) + //Todo: need to cleanup all events on item - need to keep track of eventwrappers + }, + removeAll: function(){ + + } + } + +Rico.HoverSet = Class.create(); +Rico.HoverSet.prototype = { + initialize: function(hoverSet, options){ + options = options || []; + this.hoverSet = hoverSet; + this.hoverClassName = options.hoverClass || "hover"; + this.hoverNodes = options.hoverNodes || function(e){return [e]}; + this.listenerHover = this._onHover.bind(this) + this.listenerEndHover = this._onUnHover.bind(this) + + this.hoverSet.each((function(e) {Event.observe(e, "mousemove", new Rico.EventWrapper(this.listenerHover,e).wrapper);}).bind(this)) + this.hoverSet.each((function(e) {Event.observe(e, "mouseout", new Rico.EventWrapper(this.listenerEndHover,e).wrapper);}).bind(this)) + }, + _onHover: function(event,target) { + this.hover(target); + }, + _onUnHover: function(event,target) { + this.unHover(target); + }, + hover: function(target) { + this.hoverNodes(target).each((function(t){Element.classNames(t).add(this.hoverClassName)}).bind(this)); + }, + unHover: function(target) { + this.hoverNodes(target).each((function(t){Element.classNames(t).remove(this.hoverClassName)}).bind(this)); + }, + add: function(item){ + Event.observe(item, "mousemove", new Rico.EventWrapper(this.listenerHover,item).wrapper); + Event.observe(item, "mouseout", new Rico.EventWrapper(this.listenerEndHover,item).wrapper); + }, + remove: function(item){ + //Todo: need to cleanup all events on item - need to keep terack of eventwrappers + //stopObserving + //Event.stopObserving(e, "mousemove", new Rico.EventWrapper(this.listenerHover,e).wrapper);}).bind(this)) + //this.hoverSet.each((function(e) {Event.observe(e, "mouseout", new Rico.EventWrapper(this.listenerEndHover,e).wrapper);}).bind(this)) + //hoverSet + }, + removeAll: function(item){ + } +} + + +Rico.Hover = { + groups: {}, + clearCurrent: function(group) { + var last_hover = Rico.Hover.groups[group]; + if(!last_hover) return + clearTimeout(last_hover[0]) + last_hover[1].end() + Rico.Hover.groups[group] = null; + }, + end: function(group) { + Rico.Hover.groups[group][1].end(); + }, + endWith: function(hover, group) { + var timer = setTimeout('Rico.Hover.end("'+ group + '")', hover.exitDelay) + Rico.Hover.groups[group] = [timer, hover] + } +} + +Rico.HoverDisplay = Class.create(); +Rico.HoverDisplay.prototype = { + initialize: function(element, options) { + this.element = element; + this.options = options || {}; + this.group = this.options.group; + this.exitDelay = this.options.delay || 1000; + }, + begin: function() { + Rico.Hover.clearCurrent(this.group) + Element.show(this.element) + }, + end: function(delay) { + if(delay) + Rico.Hover.endWith(this, this.group); + else + Element.hide(this.element) + } +} + + +Rico.EventWrapper = Class.create(); +Rico.EventWrapper.prototype = { + initialize: function(handler, target){ + this.handler = handler; + this.target = target; + this.wrapper = this.wrapperCall.bindAsEventListener(this) + }, + wrapperCall: function(event){ + this.handler(event, this.target) + } +} + +Rico.includeLoaded('ricoBehaviors.js'); diff --git a/NP_TrackBack/trunk/trackback/js/rico/ricoCalendar.js b/NP_TrackBack/trunk/trackback/js/rico/ricoCalendar.js new file mode 100644 index 0000000..8aa596c --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/ricoCalendar.js @@ -0,0 +1,443 @@ +// By Matt Brown +// June-October 2006 +// email: dowdybrown@yahoo.com +// Implements a pop-up Gregorian calendar. +// Dates of adoption of the Gregorian calendar vary by country - accurate as a US & British calendar from 14 Sept 1752 to present. +// Mark special dates with calls to addHoliday() +// Inspired by code originally written by Tan Ling Wee on 2 Dec 2001 + +// Requires prototype.js and ricoCommon.js + +Rico.CalendarControl = Class.create(); + +Rico.CalendarControl.prototype = { + + initialize: function(id,options) { + this.id=id; + var today=new Date(); + Object.extend(this, new Rico.Popup({ignoreClicks:true})); + Object.extend(this.options, { + startAt : 0, // week starts with 0=sunday, 1=monday + showWeekNumber : 0, // show week number in first column? + showToday : 1, // show "Today is..." in footer? + cursorColor: '#FDD', // color used to highlight dates as the user moves their mouse + repeatInterval : 100, // when left/right arrow is pressed, repeat action every x milliseconds + dateFmt : 'ISO8601', // default is ISO-8601, 'rico'=use format stored in ricoTranslate object + selectedDateBorder : "#666666", // border to indicate currently selected date + minDate : new Date(today.getFullYear()-50,0,1), // default to +-50 yrs from current date + maxDate : new Date(today.getFullYear()+50,11,31) + }); + Object.extend(this.options, options || {}); + this.close=this.closePopup; + this.bPageLoaded=false; + this.img=new Array(); + this.Holidays={}; + this.todayString=RicoTranslate.getPhrase("Today is "); + this.weekString=RicoTranslate.getPhrase("Wk"); + if (this.options.dateFmt=='rico') this.options.dateFmt=RicoTranslate.dateFmt; + this.dateParts=new Array(); + this.re=/^\s*(\w+)(\W)(\w+)(\W)(\w+)/i; + if (this.re.exec(this.options.dateFmt)) { + this.dateParts[RegExp.$1]=0; + this.dateParts[RegExp.$3]=1; + this.dateParts[RegExp.$5]=2; + } + }, + + + // y=0 implies a repeating holiday + addHoliday : function(d, m, y, desc, bgColor, txtColor) { + this.Holidays[this.holidayKey(y,m-1,d)]={desc:desc, txtColor:txtColor, bgColor:bgColor || '#DDF'}; + }, + + holidayKey : function(y,m,d) { + return 'h'+y.toPaddedString(4)+m.toPaddedString(2)+d.toPaddedString(2); + }, + + atLoad : function() { + this.container=document.createElement("div"); + this.container.style.display="none" + this.container.id=this.id; + this.container.className='ricoCalContainer'; + + this.maintab=document.createElement("table"); + this.maintab.cellSpacing=0; + this.maintab.cellPadding=0; + this.maintab.border=0; + this.maintab.className='ricoCalTab'; + + for (var i=0; i<7; i++) { + var r=this.maintab.insertRow(-1); + r.className='row'+i; + for (var c=0; c<8; c++) + r.insertCell(-1); + } + this.tbody=this.maintab.tBodies[0]; + var r=this.tbody.rows[0]; + r.className='ricoCalDayNames'; + if (this.options.showWeekNumber) { + r.cells[0].innerHTML=this.weekString; + for (var i=0; i<7; i++) + this.tbody.rows[i].cells[0].className='ricoCalWeekNum'; + } + this.styles=[]; + for (var i=0; i<7; i++) { + var dow=(i+this.options.startAt) % 7; + r.cells[i+1].innerHTML=RicoTranslate.dayNames[dow].substring(0,3); + this.styles[i+1]='ricoCal'+dow; + } + + // table header (navigation controls) + this.thead=this.maintab.createTHead() + var r=this.thead.insertRow(-1); + var c=r.insertCell(-1); + c.colSpan=8; + var img=this.createNavArrow('decMonth','left'); + c.appendChild(document.createElement("a")).appendChild(img); + this.titleMonth=document.createElement("a"); + c.appendChild(this.titleMonth); + Event.observe(this.titleMonth,"click", this.popUpMonth.bindAsEventListener(this), false); + var img=this.createNavArrow('incMonth','right'); + c.appendChild(document.createElement("a")).appendChild(img); + var s=document.createElement("span"); + s.innerHTML=' '; + s.style.paddingLeft='3em'; + c.appendChild(s); + + var img=this.createNavArrow('decYear','left'); + c.appendChild(document.createElement("a")).appendChild(img); + this.titleYear=document.createElement("a"); + Event.observe(this.titleYear,"click", this.popUpYear.bindAsEventListener(this), false); + c.appendChild(this.titleYear); + var img=this.createNavArrow('incYear','right'); + c.appendChild(document.createElement("a")).appendChild(img); + + // table footer (today) + if (this.options.showToday) { + this.tfoot=this.maintab.createTFoot() + var r=this.tfoot.insertRow(-1); + this.todayCell=r.insertCell(-1); + this.todayCell.colSpan=8; + Event.observe(this.todayCell,"click", this.selectNow.bindAsEventListener(this), false); + } + + + this.container.appendChild(this.maintab); + + // close icon (upper right) + var img=document.createElement("img"); + img.src=Rico.imgDir+'close.gif'; + img.onclick=this.close.bind(this); + img.style.cursor='pointer'; + img.style.position='absolute'; + img.style.top='1px'; /* assumes a 1px border */ + img.style.right='1px'; + this.container.appendChild(img); + + // month selector + this.monthSelect=document.createElement("table"); + this.monthSelect.className='ricoCalMenu'; + this.monthSelect.cellPadding=2; + this.monthSelect.cellSpacing=0; + this.monthSelect.border=0; + for (var i=0; i<4; i++) { + var r=this.monthSelect.insertRow(-1); + for (var j=0; j<3; j++) { + var c=r.insertCell(-1); + var a=document.createElement("a"); + a.innerHTML=RicoTranslate.monthNames[i*3+j].substring(0,3); + a.name=i*3+j; + c.appendChild(a); + Event.observe(a,"click", this.selectMonth.bindAsEventListener(this), false); + } + } + this.monthSelect.style.display='none'; + this.container.appendChild(this.monthSelect); + + // fix anchors so they work in IE6 + var a=this.container.getElementsByTagName('a'); + for (var i=0; i this.options.maxDate.getFullYear()) return false; + if (yr == this.options.maxDate.getFullYear() && mo > this.options.maxDate.getMonth()) return false; + return true; + }, + + incMonth : function() { + var newMonth=this.monthSelected+1; + var newYear=this.yearSelected; + if (newMonth>11) { + newMonth=0; + newYear++; + } + if (!this.isValidMonth(newYear,newMonth)) return; + this.monthSelected=newMonth; + this.yearSelected=newYear; + this.constructCalendar() + }, + + decMonth : function() { + var newMonth=this.monthSelected-1; + var newYear=this.yearSelected; + if (newMonth<0) { + newMonth=11; + newYear--; + } + if (!this.isValidMonth(newYear,newMonth)) return; + this.monthSelected=newMonth; + this.yearSelected=newYear; + this.constructCalendar() + }, + + selectMonth : function(e) { + var el=Event.element(e); + this.monthSelected=parseInt(el.name); + this.constructCalendar(); + Event.stop(e); + }, + + popUpMonth : function() { + this.monthSelect.style.display=this.monthSelect.style.display=='none' ? 'block' : 'none'; + }, + + popDownMonth : function() { + this.monthSelect.style.display='none'; + }, + + /*** Year Pulldown ***/ + + popUpYear : function() { + var newYear=prompt(RicoTranslate.getPhrase("Year ("+this.options.minDate.getFullYear()+"-"+this.options.maxDate.getFullYear()+")"),this.yearSelected); + if (newYear==null) return; + newYear=parseInt(newYear); + if (isNaN(newYear) || newYearthis.options.maxDate.getFullYear()) { + alert(RicoTranslate.getPhrase("Invalid year")); + } else { + this.yearSelected=newYear; + this.constructCalendar(); + } + }, + + incYear : function() { + if (this.yearSelected>=this.options.maxDate.getFullYear()) return; + this.yearSelected++; + this.constructCalendar(); + }, + + decYear : function() { + if (this.yearSelected<=this.options.minDate.getFullYear()) return; + this.yearSelected--; + this.constructCalendar(); + }, + + // tried a number of different week number functions posted on the net + // this is the only one that produced consistent results when comparing week numbers for December and the following January + WeekNbr : function(year,month,day) { + var when = new Date(year,month,day); + var newYear = new Date(year,0,1); + var offset = 7 + 1 - newYear.getDay(); + if (offset == 8) offset = 1; + var daynum = ((Date.UTC(year,when.getMonth(),when.getDate(),0,0,0) - Date.UTC(year,0,1,0,0,0)) /1000/60/60/24) + 1; + var weeknum = Math.floor((daynum-offset+7)/7); + if (weeknum == 0) { + year--; + var prevNewYear = new Date(year,0,1); + var prevOffset = 7 + 1 - prevNewYear.getDay(); + if (prevOffset == 2 || prevOffset == 8) weeknum = 53; else weeknum = 52; + } + return weeknum; + }, + + constructCalendar : function() { + var aNumDays = Array (31,0,31,30,31,30,31,31,30,31,30,31) + var startDate = new Date (this.yearSelected,this.monthSelected,1) + var endDate,numDaysInMonth + + if (typeof this.monthSelected!='number' || this.monthSelected>=12 || this.monthSelected<0) { + alert('ERROR in calendar: monthSelected='+this.monthSelected); + return; + } + var today = new Date(); + this.dateNow = today.getDate(); + this.monthNow = today.getMonth(); + this.yearNow = today.getFullYear(); + + if (this.monthSelected==1) { + endDate = new Date (this.yearSelected,this.monthSelected+1,1); + endDate = new Date (endDate - (24*60*60*1000)); + numDaysInMonth = endDate.getDate() + } else { + numDaysInMonth = aNumDays[this.monthSelected]; + } + var dayPointer = startDate.getDay() - this.options.startAt + if (dayPointer<0) dayPointer+=7; + this.popDownMonth(); + + this.bgcolor=Element.getStyle(this.tbody,'background-color'); + this.bgcolor=this.bgcolor.replace(/\"/g,''); + if (this.options.showWeekNumber) { + for (var i=1; i<7; i++) + this.tbody.rows[i].cells[0].innerHTML=' '; + } + for ( var i=1; i<=dayPointer; i++ ) + this.resetCell(this.tbody.rows[1].cells[i]); + + for ( var datePointer=1,r=1; datePointer<=numDaysInMonth; datePointer++,dayPointer++ ) { + var colnum=dayPointer % 7 + 1; + if (this.options.showWeekNumber==1 && colnum==1) + this.tbody.rows[r].cells[0].innerHTML=this.WeekNbr(this.yearSelected,this.monthSelected,datePointer); + var dateClass=this.styles[colnum]; + if ((datePointer==this.dateNow)&&(this.monthSelected==this.monthNow)&&(this.yearSelected==this.yearNow)) + dateClass='ricoCalToday'; + var c=this.tbody.rows[r].cells[colnum]; + c.innerHTML=" " + datePointer + " "; + c.className=dateClass; + var bordercolor=(datePointer==this.odateSelected) && (this.monthSelected==this.omonthSelected) && (this.yearSelected==this.oyearSelected) ? this.options.selectedDateBorder : this.bgcolor; + c.style.border='1px solid '+bordercolor; + var h=this.Holidays[this.holidayKey(this.yearSelected,this.monthSelected,datePointer)]; + if (!h) h=this.Holidays[this.holidayKey(0,this.monthSelected,datePointer)]; + c.style.color=h ? h.txtColor : ''; + c.style.backgroundColor=h ? h.bgColor : ''; + c.title=h ? h.desc : ''; + if (colnum==7) r++; + } + while (dayPointer<42) { + var colnum=dayPointer % 7 + 1; + this.resetCell(this.tbody.rows[r].cells[colnum]); + dayPointer++; + if (colnum==7) r++; + } + + this.titleMonth.innerHTML = RicoTranslate.monthNames[this.monthSelected].substring(0,3); + this.titleYear.innerHTML = this.yearSelected; + if (this.options.showToday) + this.todayCell.innerHTML=this.todayString+''+this.dateNow + " " + RicoTranslate.monthNames[this.monthNow].substring(0,3) + " " + this.yearNow+''; + this.monthSelect.style.top=this.thead.offsetHeight+'px'; + this.monthSelect.style.left=this.titleMonth.offsetLeft+'px'; + }, + + resetCell: function(c) { + c.innerHTML=" "; + c.className='ricoCalEmpty'; + c.style.border='1px solid '+this.bgcolor; + c.style.color=''; + c.style.backgroundColor=''; + c.title=''; + }, + + saveAndClose : function(e) { + Event.stop(e); + var el=Event.element(e); + var s=el.innerHTML.replace(/ /g,''); + if (s=='' || el.className=='ricoCalWeekNum') return; + var day=parseInt(s); + if (isNaN(day)) return; + var d=new Date(this.yearSelected,this.monthSelected,day); + var dateStr=d.formatDate(this.options.dateFmt=='ISO8601' ? 'yyyy-mm-dd' : this.options.dateFmt); + if (this.returnValue) this.returnValue(dateStr); + this.close(); + }, + + open : function(curval) { + if (!this.bPageLoaded) return; + if (typeof curval=='object') { + this.dateSelected = curval.getDate(); + this.monthSelected = curval.getMonth(); + this.yearSelected = curval.getFullYear(); + } else if (this.options.dateFmt=='ISO8601') { + var d=new Date; + d.setISO8601(curval); + this.dateSelected = d.getDate(); + this.monthSelected = d.getMonth(); + this.yearSelected = d.getFullYear(); + } else if (this.re.exec(curval)) { + var aDate=new Array(RegExp.$1,RegExp.$3,RegExp.$5); + this.dateSelected = parseInt(aDate[this.dateParts['dd']], 10); + this.monthSelected = parseInt(aDate[this.dateParts['mm']], 10) - 1; + this.yearSelected = parseInt(aDate[this.dateParts['yyyy']], 10); + } else { + if (curval) alert('ERROR: invalid date passed to calendar ('+curval+')'); + this.dateSelected = this.dateNow + this.monthSelected = this.monthNow + this.yearSelected = this.yearNow + } + this.odateSelected=this.dateSelected + this.omonthSelected=this.monthSelected + this.oyearSelected=this.yearSelected + this.constructCalendar(); + this.openPopup(); + } +} + +Rico.includeLoaded('ricoCalendar.js'); diff --git a/NP_TrackBack/trunk/trackback/js/rico/ricoColor.js b/NP_TrackBack/trunk/trackback/js/rico/ricoColor.js new file mode 100644 index 0000000..84c3b98 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/ricoColor.js @@ -0,0 +1,29 @@ +function attachValueChangeListeners() { + $('red').onkeypress = colorChangedDeffered; + $('green').onkeypress = colorChangedDeffered; + $('blue').onkeypress = colorChangedDeffered; +} + +function colorChangedDeffered() { + setTimeout( colorChanged, 1 ); +} + +function colorChanged() { + var red = Math.min( parseInt($('red').value) || 0, 255); + var green = Math.min( parseInt($('green').value) || 0, 255); + var blue = Math.min( parseInt($('blue').value) || 0, 255); + + var color = new Rico.Color( red, green, blue ); + + var newIllustrateString = " var color = new Rico.Color( "; + newIllustrateString += red + ", "; + newIllustrateString += green + ", "; + newIllustrateString += blue + " ); // color.asHex() = "; + newIllustrateString += color.asHex(); + + $('rgbCode').innerHTML = newIllustrateString; + $('colorBox').style.backgroundColor = color.asHex(); + //$('colorBox').innerHTML = color.asHex(); +} + +Rico.includeLoaded('ricoColor.js'); diff --git a/NP_TrackBack/trunk/trackback/js/rico/ricoColorPicker.js b/NP_TrackBack/trunk/trackback/js/rico/ricoColorPicker.js new file mode 100644 index 0000000..86ab657 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/ricoColorPicker.js @@ -0,0 +1,75 @@ +// =================================================================== +// Original author: Matt Kruse +// WWW: http://www.mattkruse.com/ +// +// Adapted to Rico by Matt Brown +// =================================================================== + + +Rico.ColorPicker = Class.create(); + +Rico.ColorPicker.prototype = { + + initialize: function(id,options) { + this.id=id; + this.currentValue = "#FFFFFF"; + Object.extend(this, new Rico.Popup()); + Object.extend(this.options, { + showColorCode : false, + cellsPerRow : 18, + palette : [] + }); + var hexvals=['00','33','66','99','CC','FF']; + for (var g=0; g '; + if ( ((i+1)>=this.options.palette.length) || (((i+1) % width) == 0)) + cp_contents += ""; + } + var halfwidth = Math.floor(width/2); + if (this.options.showColorCode) + cp_contents += " #FFFFFF"; + else + cp_contents += " "; + cp_contents += ""; + this.container.innerHTML=cp_contents; + document.body.appendChild(this.container); + this.setDiv(this.container); + this.open=this.openPopup; + this.close=this.closePopup; + Event.observe(this.container,"mouseover", this.highlightColor.bindAsEventListener(this), false); + Event.observe(this.container,"click", this.selectColor.bindAsEventListener(this), false); + this.close(); + }, + + selectColor: function(e) { + if (this.returnValue) this.returnValue(this.currentValue); + this.close(); + }, + + // This function runs when you move your mouse over a color block, if you have a newer browser + highlightColor: function(e) { + var elem = Event.element(e); + if (!elem.tagName || elem.tagName.toLowerCase() != 'td') return; + var c=Rico.Color.createColorFromBackground(elem).toString(); + this.currentValue = c; + Element.setStyle('colorPickerSelectedColor',{'background-color':c}); + d = $("colorPickerSelectedColorValue"); + if (d) d.innerHTML = c; + } +} + +Rico.includeLoaded('ricoColorPicker.js'); diff --git a/NP_TrackBack/trunk/trackback/js/rico/ricoCommon.js b/NP_TrackBack/trunk/trackback/js/rico/ricoCommon.js new file mode 100644 index 0000000..0e6f4ea --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/ricoCommon.js @@ -0,0 +1,739 @@ +/** + * + * Copyright 2005 Sabre Airline Solutions + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + **/ + +if (typeof Rico=='undefined') + throw("Cannot find the Rico object"); +if (typeof Prototype=='undefined') + throw("Rico requires the Prototype JavaScript framework"); +Rico.prototypeVersion = parseFloat(Prototype.Version.split(".")[0] + "." + Prototype.Version.split(".")[1]); +if (Rico.prototypeVersion < 1.3) + throw("Rico requires Prototype JavaScript framework version 1.3 or greater"); + +/** @singleton */ +var RicoUtil = { + + getDirectChildrenByTag: function(e, tagName) { + var kids = new Array(); + var allKids = e.childNodes; + tagName=tagName.toLowerCase(); + for( var i = 0 ; i < allKids.length ; i++ ) + if ( allKids[i] && allKids[i].tagName && allKids[i].tagName.toLowerCase() == tagName ) + kids.push(allKids[i]); + return kids; + }, + + createXmlDocument : function() { + if (document.implementation && document.implementation.createDocument) { + var doc = document.implementation.createDocument("", "", null); + + if (doc.readyState == null) { + doc.readyState = 1; + doc.addEventListener("load", function () { + doc.readyState = 4; + if (typeof doc.onreadystatechange == "function") + doc.onreadystatechange(); + }, false); + } + + return doc; + } + + if (window.ActiveXObject) + return Try.these( + function() { return new ActiveXObject('MSXML2.DomDocument') }, + function() { return new ActiveXObject('Microsoft.DomDocument')}, + function() { return new ActiveXObject('MSXML.DomDocument') }, + function() { return new ActiveXObject('MSXML3.DomDocument') } + ) || false; + + return null; + }, + + getInnerText: function(el) { + if (typeof el == "string") return el; + if (typeof el == "undefined") { return el }; + var cs = el.childNodes; + var l = cs.length; + var str = ""; + for (var i = 0; i < l; i++) { + switch (cs[i].nodeType) { + case 1: //ELEMENT_NODE + if (Element.getStyle(cs[i],'display')=='none') continue; + switch (cs[i].tagName.toLowerCase()) { + case 'img': str += cs[i].alt || cs[i].title || cs[i].src; break; + case 'input': if (cs[i].type=='hidden') continue; + case 'select': + case 'textarea': str += $F(cs[i]) || ''; break; + default: str += this.getInnerText(cs[i]); break; + } + break; + case 3: //TEXT_NODE + str += cs[i].nodeValue; + break; + } + } + return str; + }, + + // For Konqueror 3.5, isEncoded must be true + getContentAsString: function( parentNode, isEncoded ) { + if (isEncoded) return this._getEncodedContent(parentNode); + if (typeof parentNode.xml != 'undefined') return this._getContentAsStringIE(parentNode); + return this._getContentAsStringMozilla(parentNode); + }, + + _getEncodedContent: function(parentNode) { + if (parentNode.innerHTML) return parentNode.innerHTML; + switch (parentNode.childNodes.length) { + case 0: return ""; + case 1: return parentNode.firstChild.nodeValue; + default: return parentNode.childNodes[1].nodeValue; + } + }, + + _getContentAsStringIE: function(parentNode) { + var contentStr = ""; + for ( var i = 0 ; i < parentNode.childNodes.length ; i++ ) { + var n = parentNode.childNodes[i]; + if (n.nodeType == 4) { + contentStr += n.nodeValue; + } + else { + contentStr += n.xml; + } + } + return contentStr; + }, + + _getContentAsStringMozilla: function(parentNode) { + var xmlSerializer = new XMLSerializer(); + var contentStr = ""; + for ( var i = 0 ; i < parentNode.childNodes.length ; i++ ) { + var n = parentNode.childNodes[i]; + if (n.nodeType == 4) { // CDATA node + contentStr += n.nodeValue; + } + else { + contentStr += xmlSerializer.serializeToString(n); + } + } + return contentStr; + }, + + docElement: function() { + return (document.compatMode && document.compatMode.indexOf("CSS")!=-1) ? document.documentElement : document.getElementsByTagName("body")[0]; + }, + +/** + * return available height - excludes scrollbar & margin + */ + windowHeight: function() { + return window.innerHeight? window.innerHeight : this.docElement().clientHeight; + //return this.docElement().clientHeight; + }, + +/** + * return available width - excludes scrollbar & margin + */ + windowWidth: function() { + return this.docElement().clientWidth; + }, + + docScrollLeft: function() { + if ( window.pageXOffset ) + return window.pageXOffset; + else if ( document.documentElement && document.documentElement.scrollLeft ) + return document.documentElement.scrollLeft; + else if ( document.body ) + return document.body.scrollLeft; + else + return 0; + }, + + docScrollTop: function() { + if ( window.pageYOffset ) + return window.pageYOffset; + else if ( document.documentElement && document.documentElement.scrollTop ) + return document.documentElement.scrollTop; + else if ( document.body ) + return document.body.scrollTop; + else + return 0; + }, + + nan2zero: function(n) { + if (typeof(n)=='string') n=parseInt(n); + return isNaN(n) || typeof(n)=='undefined' ? 0 : n; + }, + + eventKey: function(e) { + if( typeof( e.keyCode ) == 'number' ) { + return e.keyCode; //DOM + } else if( typeof( e.which ) == 'number' ) { + return e.which; //NS 4 compatible + } else if( typeof( e.charCode ) == 'number' ) { + return e.charCode; //also NS 6+, Mozilla 0.9+ + } + return -1; //total failure, we have no way of obtaining the key code + }, + +/** + * Return the previous sibling that has the specified tagName + */ + getPreviosSiblingByTagName: function(el,tagName) { + var sib=el.previousSibling; + while (sib) { + if ((sib.tagName==tagName) && (sib.style.display!='none')) return sib; + sib=sib.previousSibling; + } + return null; + }, + +/** + * Return the parent HTML element that has the specified tagName. + * @param className optional + */ + getParentByTagName: function(el,tagName,className) { + var par=el; + tagName=tagName.toLowerCase(); + while (par) { + if (par.tagName && par.tagName.toLowerCase()==tagName) + if (!className || par.className.indexOf(className)>=0) return par; + par=par.parentNode; + } + return null; + }, + +/** + * Wrap the children of a DOM element in a new element + * @param el the element whose children are to be wrapped + * @param cls class name of the wrapper (optional) + * @param id id of the wrapper (optional) + * @param wrapperTag type of wrapper element to be created (optional, defaults to DIV) + */ + wrapChildren: function(el,cls,id,wrapperTag) { + var tag=wrapperTag || 'div'; + var wrapper = document.createElement(tag); + if (id) wrapper.id=id; + if (cls) wrapper.className=cls; + while (el.firstChild) + wrapper.appendChild(el.firstChild); + el.appendChild(wrapper); + return wrapper; + }, + +/** + * Format a positive number + * @param decPlaces the number of digits to display after the decimal point + * @param thouSep the character to use as the thousands separator + * @param decPoint the character to use as the decimal point + */ + formatPosNumber: function(posnum,decPlaces,thouSep,decPoint) { + var a=posnum.toFixed(decPlaces).split(/\./); + if (thouSep) { + var rgx = /(\d+)(\d{3})/; + while (rgx.test(a[0])) + a[0]=a[0].replace(rgx, '$1'+thouSep+'$2'); + } + return a.join(decPoint); + }, + +/** + * Post condition - if childNodes[n] is refChild, than childNodes[n+1] is newChild. + */ + DOMNode_insertAfter: function(newChild,refChild) { + var parentx=refChild.parentNode; + if(parentx.lastChild==refChild) { return parentx.appendChild(newChild);} + else {return parentx.insertBefore(newChild,refChild.nextSibling);} + }, + + positionCtlOverIcon: function(ctl,icon) { + if (ctl.style.display=='none') ctl.style.display='block'; + var offsets=Position.page(icon); + var correction=Prototype.Browser.IE ? 1 : 2; // based on a 1px border + var lpad=this.nan2zero(Element.getStyle(icon,'padding-left')) + ctl.style.left = (offsets[0]+lpad+correction)+'px'; + var scrTop=this.docScrollTop(); + var newTop=offsets[1] + correction + scrTop; + var ctlht=ctl.offsetHeight; + var iconht=icon.offsetHeight; + if (newTop+iconht+ctlht < this.windowHeight()+scrTop) + newTop+=iconht; // display below icon + else + newTop=Math.max(newTop-ctlht,scrTop); // display above icon + ctl.style.top = newTop+'px'; + }, + + createFormField: function(parent,elemTag,elemType,id,name) { + if (typeof name!='string') name=id; + if (Prototype.Browser.IE) { + // IE cannot set NAME attribute on dynamically created elements + var s=elemTag+' id="'+id+'"'; + if (elemType) s+=' type="'+elemType+'"'; + if (elemTag.match(/^(form|input|select|textarea|object|button|img)$/)) s+=' name="'+name+'"'; + var field=document.createElement('<'+s+' />'); + } else { + var field=document.createElement(elemTag); + if (elemType) field.type=elemType; + field.id=id; + if (typeof field.name=='string') field.name=name; + } + parent.appendChild(field); + return field; + }, + +/** + * Gets the value of the specified cookie + */ + getCookie: function(itemName) { + var arg = itemName+'='; + var alen = arg.length; + var clen = document.cookie.length; + var i = 0; + while (i < clen) { + var j = i + alen; + if (document.cookie.substring(i, j) == arg) { + var endstr = document.cookie.indexOf (';', j); + if (endstr == -1) endstr=document.cookie.length; + return unescape(document.cookie.substring(j, endstr)); + } + i = document.cookie.indexOf(' ', i) + 1; + if (i == 0) break; + } + return null; + }, + +/** + * Write information to cookie. + * For cookies to be retained for the current session only, set daysToKeep=null. + * To erase a cookie, pass a negative daysToKeep value. + */ + setCookie: function(itemName,itemValue,daysToKeep,cookiePath,cookieDomain) { + var c = itemName+"="+escape(itemValue); + if (typeof(daysToKeep)=='number') { + var date = new Date(); + date.setTime(date.getTime()+(daysToKeep*24*60*60*1000)); + c+="; expires="+date.toGMTString(); + } + if (typeof(cookiePath)=='string') c+="; path="+cookiePath; + if (typeof(cookieDomain)=='string') c+="; domain="+cookieDomain; + document.cookie = c; + } + +}; + + +// Translation helper object +/** @singleton */ +var RicoTranslate = { + phrases : {}, + thouSep : ",", + decPoint: ".", + langCode: "en", + re : /^(\W*)\b(.*)\b(\W*)$/, + dateFmt : "mm/dd/yyyy", + timeFmt : "hh:nn:ss a/pm", + monthNames: ['January','February','March','April','May','June', + 'July','August','September','October','November','December'], + dayNames: ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'], + + addPhrase: function(fromPhrase, toPhrase) { + this.phrases[fromPhrase]=toPhrase; + }, + +/** + * fromPhrase may contain multiple words/phrases separated by tabs + * and each portion will be looked up separately. + * Punctuation & spaces at the beginning or + * ending of a phrase are ignored. + */ + getPhrase: function(fromPhrase) { + var words=fromPhrase.split(/\t/); + var transWord,translated = ''; + for (var i=0; iformat is an integer in the range 1-6:
+ *
1 (year)
+ *
YYYY (eg 1997)
+ *
2 (year and month)
+ *
YYYY-MM (eg 1997-07)
+ *
3 (complete date)
+ *
YYYY-MM-DD (eg 1997-07-16)
+ *
4 (complete date plus hours and minutes)
+ *
YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)
+ *
5 (complete date plus hours, minutes and seconds)
+ *
YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)
+ *
6 (complete date plus hours, minutes, seconds and a decimal + * fraction of a second)
+ *
YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)
+ *
+ * Based on: http://www.codeproject.com/jscript/dateformat.asp + */ + Date.prototype.toISO8601String = function (format, offset) { + if (!format) { var format = 6; } + if (!offset) { + var offset = 'Z'; + var date = this; + } else { + var d = offset.match(/([-+])([0-9]{2}):([0-9]{2})/); + var offsetnum = (Number(d[2]) * 60) + Number(d[3]); + offsetnum *= ((d[1] == '-') ? -1 : 1); + var date = new Date(Number(Number(this) + (offsetnum * 60000))); + } + + var zeropad = function (num) { return ((num < 10) ? '0' : '') + num; } + + var str = ""; + str += date.getUTCFullYear(); + if (format > 1) { str += "-" + zeropad(date.getUTCMonth() + 1); } + if (format > 2) { str += "-" + zeropad(date.getUTCDate()); } + if (format > 3) { + str += "T" + zeropad(date.getUTCHours()) + + ":" + zeropad(date.getUTCMinutes()); + } + if (format > 5) { + var secs = Number(date.getUTCSeconds() + "." + + ((date.getUTCMilliseconds() < 100) ? '0' : '') + + zeropad(date.getUTCMilliseconds())); + str += ":" + zeropad(secs); + } else if (format > 4) { str += ":" + zeropad(date.getUTCSeconds()); } + + if (format > 3) { str += offset; } + return str; + } +} + +if (!String.prototype.formatDate) { + String.prototype.formatDate = function(fmt) { + var s=this.replace(/-/g,'/'); + var d = new Date(s); + return isNaN(d) ? this : d.formatDate(fmt); + } +} + +if (!Number.prototype.formatNumber) { +/** + * Format a number according to the specs in assoc array 'fmt'. + * Result is a string, wrapped in a span element with a class of: negNumber, zeroNumber, posNumber + * These classes can be set in CSS to display negative numbers in red, for example. + * + *

fmt may contain:

+ *
multiplier
the original number is multiplied by this amount before formatting
+ *
decPlaces
number of digits to the right of the decimal point
+ *
decPoint
character to be used as the decimal point
+ *
thouSep
character to use as the thousands separator
+ *
prefix
string added to the beginning of the result (e.g. a currency symbol)
+ *
suffix
string added to the end of the result (e.g. % symbol)
+ *
negSign
specifies format for negative numbers: L=leading minus, T=trailing minus, P=parens
+ *
+ */ + Number.prototype.formatNumber = function(fmt) { + if (isNaN(this)) return 'NaN'; + var n=this; + if (typeof fmt.multiplier=='number') n*=fmt.multiplier; + var decPlaces=typeof fmt.decPlaces=='number' ? fmt.decPlaces : 0; + var thouSep=typeof fmt.thouSep=='string' ? fmt.thouSep : RicoTranslate.thouSep; + var decPoint=typeof fmt.decPoint=='string' ? fmt.decPoint : RicoTranslate.decPoint; + var prefix=fmt.prefix || ""; + var suffix=fmt.suffix || ""; + var negSign=typeof fmt.negSign=='string' ? fmt.negSign : "L"; + negSign=negSign.toUpperCase(); + var s,cls; + if (n<0.0) { + s=RicoUtil.formatPosNumber(-n,decPlaces,thouSep,decPoint); + if (negSign=="P") s="("+s+")"; + s=prefix+s; + if (negSign=="L") s="-"+s; + if (negSign=="T") s+="-"; + cls='negNumber'; + } else { + cls=n==0.0 ? 'zeroNumber' : 'posNumber'; + s=prefix+RicoUtil.formatPosNumber(n,decPlaces,thouSep,decPoint); + } + return ""+s+suffix+""; + } +} + +if (!String.prototype.formatNumber) { +/** + * Take a string that can be converted via parseFloat + * and format it according to the specs in assoc array 'fmt'. + */ + String.prototype.formatNumber = function(fmt) { + var n=parseFloat(this); + return isNaN(n) ? this : n.formatNumber(fmt); + } +} + +/** + * Fix select control bleed-thru on floating divs in IE. + * Based on technique published by Joe King at: + * http://dotnetjunkies.com/WebLog/jking/archive/2003/10/30/2975.aspx + */ +Rico.Shim = Class.create(); + +if (Prototype.Browser.IE) { + Rico.Shim.prototype = { + + initialize: function(DivRef) { + this.ifr = document.createElement('iframe'); + this.ifr.style.position="absolute"; + this.ifr.style.display = "none"; + this.ifr.src="javascript:false;"; + DivRef.parentNode.appendChild(this.ifr); + this.DivRef=DivRef; + }, + + hide: function() { + this.ifr.style.display = "none"; + }, + + show: function() { + this.ifr.style.width = this.DivRef.offsetWidth; + this.ifr.style.height = this.DivRef.offsetHeight; + this.ifr.style.top = this.DivRef.style.top; + this.ifr.style.left = this.DivRef.style.left; + this.ifr.style.zIndex = this.DivRef.currentStyle.zIndex - 1; + this.ifr.style.display = "block"; + } + } +} else { + Rico.Shim.prototype = { + initialize: function() {}, + hide: function() {}, + show: function() {} + } +} + + +/** + * Rico.Shadow is intended for positioned elements. + * Uses blur filter in IE, and alpha-transparent png images for all other browsers. + * Based on: http://www.positioniseverything.net/articles/dropshadows.html + */ +Rico.Shadow = Class.create(); + +Rico.Shadow.prototype = { + + initialize: function(DivRef) { + this.div = document.createElement('div'); + this.div.style.position="absolute"; + if (typeof this.div.style.filter=='undefined') { + new Image().src = Rico.imgDir+"shadow.png"; + new Image().src = Rico.imgDir+"shadow_ur.png"; + new Image().src = Rico.imgDir+"shadow_ll.png"; + this.createShadow(); + this.offset=5; + } else { + this.div.style.backgroundColor='#888'; + this.div.style.filter='progid:DXImageTransform.Microsoft.Blur(makeShadow=1, shadowOpacity=0.3, pixelRadius=3)'; + this.offset=0; // MS blur filter already does offset + } + this.div.style.display = "none"; + DivRef.parentNode.appendChild(this.div); + this.DivRef=DivRef; + }, + + createShadow: function() { + var tab = document.createElement('table'); + tab.style.height='100%'; + tab.style.width='100%'; + tab.cellSpacing=0; + tab.dir='ltr'; + + var tr1=tab.insertRow(-1); + tr1.style.height='8px'; + var td11=tr1.insertCell(-1); + td11.style.width='8px'; + var td12=tr1.insertCell(-1); + td12.style.background="transparent url("+Rico.imgDir+"shadow_ur.png"+") no-repeat right bottom" + + var tr2=tab.insertRow(-1); + var td21=tr2.insertCell(-1); + td21.style.background="transparent url("+Rico.imgDir+"shadow_ll.png"+") no-repeat right bottom" + var td22=tr2.insertCell(-1); + td22.style.background="transparent url("+Rico.imgDir+"shadow.png"+") no-repeat right bottom" + + this.div.appendChild(tab); + }, + + hide: function() { + this.div.style.display = "none"; + }, + + show: function() { + this.div.style.width = this.DivRef.offsetWidth + 'px'; + this.div.style.height= this.DivRef.offsetHeight + 'px'; + this.div.style.top = (parseInt(this.DivRef.style.top)+this.offset)+'px'; + this.div.style.left = (parseInt(this.DivRef.style.left)+this.offset)+'px'; + this.div.style.zIndex= parseInt(Element.getStyle(this.DivRef,'z-index')) - 1; + this.div.style.display = "block"; + } +} + + +Rico.Popup = Class.create(); + +Rico.Popup.prototype = { + + initialize: function(options,DivRef) { + this.options = { + hideOnEscape : true, + hideOnClick : true, + ignoreClicks : false, + position : 'absolute', + shadow : true + } + Object.extend(this.options, options || {}); + if (DivRef) this.setDiv(DivRef); + }, + + setDiv: function(DivRef,closeFunc) { + this.divPopup=$(DivRef); + var position=this.options.position == 'auto' ? Element.getStyle(this.divPopup,'position').toLowerCase() : this.options.position; + if (!this.divPopup || position != 'absolute') return; + this.closeFunc=closeFunc || this.closePopup.bindAsEventListener(this); + this.shim=new Rico.Shim(this.divPopup); + if (this.options.shadow) + this.shadow=new Rico.Shadow(this.divPopup); + if (this.options.hideOnClick) + Event.observe(document,"click", this.closeFunc); + if (this.options.hideOnEscape) + Event.observe(document,"keyup", this._checkKey.bindAsEventListener(this)); + if (this.options.ignoreClicks) this.ignoreClicks(); + }, + + ignoreClicks: function() { + Event.observe(this.divPopup,"click", this._ignoreClick.bindAsEventListener(this)); + }, + + _ignoreClick: function(e) { + if (e.stopPropagation) + e.stopPropagation(); + else + e.cancelBubble = true; + return true; + }, + + // event handler to process keyup events (hide menu on escape key) + _checkKey: function(e) { + if (RicoUtil.eventKey(e)==27) this.closeFunc(); + return true; + }, + + openPopup: function(left,top) { + if (typeof left=='number') this.divPopup.style.left=left+'px'; + if (typeof top=='number') this.divPopup.style.top=top+'px'; + this.divPopup.style.display="block"; + if (this.shim) this.shim.show(); + if (this.shadow) this.shadow.show(); + }, + + closePopup: function() { + if (this.shim) this.shim.hide(); + if (this.shadow) this.shadow.hide(); + this.divPopup.style.display="none" + } + +} + +Rico.includeLoaded('ricoCommon.js'); diff --git a/NP_TrackBack/trunk/trackback/js/rico/ricoComponents.js b/NP_TrackBack/trunk/trackback/js/rico/ricoComponents.js new file mode 100644 index 0000000..1db5830 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/ricoComponents.js @@ -0,0 +1,194 @@ +/** + * (c) 2005-2007 Richard Cowin (http://openrico.org) + * (c) 2005-2007 Matt Brown (http://dowdybrown.com) + * + * Rico is licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + **/ + + +Rico.ContentTransitionBase = function() {} +Rico.ContentTransitionBase.prototype = { + initialize: function(titles, contents, options) { + if (typeof titles == 'string') + titles = $$(titles) + if (typeof contents == 'string') + contents = $$(contents) + + this.titles = titles; + this.contents = contents; + this.options = Object.extend({ + duration:200, + steps:8, + rate:Rico.Effect.easeIn + }, options || {}); + this.hoverSet = new Rico.HoverSet(titles, options); + contents.each(function(p){ if (p) Element.hide(p)}) + this.selectionSet = new Rico.SelectionSet(titles, Object.extend(this.options, {onSelect: this.select.bind(this)})); + if (this.initContent) this.initContent(); + }, + reset: function(){ + this.selectionSet.reset(); + }, + select: function(title) { + if ( this.selected == this.contentOf(title)) return + var panel = this.contentOf(title); + if (this.transition){ + if (this.selected){ + var effect = this.transition(panel) + if (effect) Rico.animate(effect, this.options) + } + else + Element.show(panel); + }else{ + if (this.selected) + Element.hide(this.selected) + Element.show(panel); + } + this.selected = panel; + }, + add: function(title, content){ + this.titles.push(title); + this.contents.push(content); + this.hoverSet.add(title); + this.selectionSet.add(title); + this.selectionSet.select(title); + }, + remove: function(title){}, + removeAll: function(){ + this.hoverSet.removeAll(); + this.selectionSet.removeAll(); + }, + openByIndex: function(index){this.selectionSet.selectIndex(index)}, + contentOf: function(title){ return this.contents[this.titles.indexOf(title)]} +} + +Rico.ContentTransition = Class.create(); +Rico.ContentTransition.prototype = Object.extend(new Rico.ContentTransitionBase(),{}); + +Rico.SlidingPanel = Class.create(); +Rico.SlidingPanel.prototype = { + initialize: function(panel) { + this.panel = panel; + this.options = arguments[1] || {}; + this.closed = true; + this.showing = false + this.openEffect = this.options.openEffect; + this.closeEffect = this.options.closeEffect; + this.animator = new Rico.Effect.Animator(); + Element.makeClipping(this.panel) + }, + toggle: function () { + if(!this.showing){ + this.open(); + } else { + this.close(); + } + }, + open: function () { + if (this.closed){ + this.showing = true; + Element.show(this.panel); + this.options.disabler.disableNative(); + } + /*this.animator.stop();*/ + this.animator.play(this.openEffect, + { onFinish:function(){ Element.undoClipping($(this.panel))}.bind(this), + rate:Rico.Effect.easeIn}); + }, + close: function () { + Element.makeClipping(this.panel) + this.animator.stop(); + this.showing = false; + this.animator.play(this.closeEffect, + { onFinish:function(){ Element.hide(this.panel); + this.options.disabler.enableNative()}.bind(this), + rate:Rico.Effect.easeOut}); + } +} + + +//------------------------------------------- +// Example components +//------------------------------------------- + +Rico.Accordion = Class.create(); +Rico.Accordion.prototype = Object.extend(new Rico.ContentTransitionBase(), { + initContent: function() { + this.selected.style.height = this.options.panelHeight + "px"; + }, + transition: function(p){ + if (!this.options.noAnimate) + return new Rico.AccordionEffect(this.selected, p, this.options.panelHeight); + else{ + p.style.height = this.options.panelHeight + "px"; + if (this.selected) Element.hide(this.selected); + Element.show(p); + } + } +}) + + +Rico.TabbedPanel = Class.create(); +Rico.TabbedPanel.prototype = Object.extend(new Rico.ContentTransitionBase(), { + initContent: function() { + if (false && (this.options.panelHeight=='auto' || this.options.panelWidth=='auto')) { + // 'auto' is not working yet + var maxwi=0, maxht=0; + for (var i=0; i=0; i--) { + if (x >= Position.positionedOffset(this.cols[i])[0]) + return this.cols[i]; + } + return this.cols[0]; + }, + + destroy: function() { + try{ + for (var i=0; i= Position.positionedOffset(panels[insertPos+1])[1]) { + if (panels[insertPos + 2]) + newCol.insertBefore(this.insertionOutline, panels[insertPos+2]); + else + newCol.appendChild(this.insertionOutline); + } + this.insertionColumn = newCol; + }, + + _moveInsertion: function(column){ + if (this.insertionColumn != column) { + this.insertionColumn.removeChild(this.insertionOutline) + this.insertionColumn = column; + column.appendChild(this.insertionOutline); + } + }, + + columnPanels: function(column){ + var panels = []; + for (var i=0; i 0; + }, + + setStartDragFromElement: function( e, mouseDownElement ) { + this.origPos = RicoUtil.toDocumentPosition(mouseDownElement); + this.startx = e.screenX - this.origPos.x + this.starty = e.screenY - this.origPos.y + //this.startComponentX = e.layerX ? e.layerX : e.offsetX; + //this.startComponentY = e.layerY ? e.layerY : e.offsetY; + //this.adjustedForDraggableSize = false; + + this.interestedInMotionEvents = this.hasSelection(); + this._terminateEvent(e); + }, + + updateSelection: function( draggable, extendSelection ) { + if ( ! extendSelection ) + this.clearSelection(); + + if ( draggable.isSelected() ) { + this.currentDragObjects.removeItem(draggable); + draggable.deselect(); + if ( draggable == this.lastSelectedDraggable ) + this.lastSelectedDraggable = null; + } + else { + this.currentDragObjects[ this.currentDragObjects.length ] = draggable; + draggable.select(); + this.lastSelectedDraggable = draggable; + } + }, + + _mouseDownHandler: function(e) { + if ( arguments.length == 0 ) + e = event; + + // if not button 1 ignore it... + var nsEvent = e.which != undefined; + if ( (nsEvent && e.which != 1) || (!nsEvent && e.button != 1)) + return; + + var eventTarget = e.target ? e.target : e.srcElement; + var draggableObject = eventTarget.draggable; + + var candidate = eventTarget; + while (draggableObject == null && candidate.parentNode) { + candidate = candidate.parentNode; + draggableObject = candidate.draggable; + } + + if ( draggableObject == null ) + return; + + this.updateSelection( draggableObject, e.ctrlKey ); + + // clear the drop zones postion cache... + if ( this.hasSelection() ) + for ( var i = 0 ; i < this.dropZones.length ; i++ ) + this.dropZones[i].clearPositionCache(); + + this.setStartDragFromElement( e, draggableObject.getMouseDownHTMLElement() ); + }, + + + _mouseMoveHandler: function(e) { + var nsEvent = e.which != undefined; + if ( !this.interestedInMotionEvents ) { + //this._terminateEvent(e); + return; + } + + if ( ! this.hasSelection() ) + return; + + if ( ! this.currentDragObjectVisible ) + this._startDrag(e); + + if ( !this.activatedDropZones ) + this._activateRegisteredDropZones(); + + //if ( !this.adjustedForDraggableSize ) + // this._adjustForDraggableSize(e); + + this._updateDraggableLocation(e); + this._updateDropZonesHover(e); + + this._terminateEvent(e); + }, + + _makeDraggableObjectVisible: function(e) + { + if ( !this.hasSelection() ) + return; + + var dragElement; + if ( this.currentDragObjects.length > 1 ) + dragElement = this.currentDragObjects[0].getMultiObjectDragGUI(this.currentDragObjects); + else + dragElement = this.currentDragObjects[0].getSingleObjectDragGUI(); + + // go ahead and absolute position it... + if ( RicoUtil.getElementsComputedStyle(dragElement, "position") != "absolute" ) +/* if (Element.getStyle(dragElement,'position')=='absolute')*/ + dragElement.style.position = "absolute"; + + // need to parent him into the document... + if ( dragElement.parentNode == null || dragElement.parentNode.nodeType == 11 ) + document.body.appendChild(dragElement); + + this.dragElement = dragElement; + this._updateDraggableLocation(e); + + this.currentDragObjectVisible = true; + }, + + /** + _adjustForDraggableSize: function(e) { + var dragElementWidth = this.dragElement.offsetWidth; + var dragElementHeight = this.dragElement.offsetHeight; + if ( this.startComponentX > dragElementWidth ) + this.startx -= this.startComponentX - dragElementWidth + 2; + if ( e.offsetY ) { + if ( this.startComponentY > dragElementHeight ) + this.starty -= this.startComponentY - dragElementHeight + 2; + } + this.adjustedForDraggableSize = true; + }, + **/ + + _leftOffset: function(e) { + return e.offsetX ? document.body.scrollLeft : 0 + }, + + _topOffset: function(e) { + return e.offsetY ? document.body.scrollTop:0 + }, + + + _updateDraggableLocation: function(e) { + var dragObjectStyle = this.dragElement.style; + dragObjectStyle.left = (e.screenX + this._leftOffset(e) - this.startx) + "px" + dragObjectStyle.top = (e.screenY + this._topOffset(e) - this.starty) + "px"; + }, + + _updateDropZonesHover: function(e) { + var n = this.dropZones.length; + for ( var i = 0 ; i < n ; i++ ) { + if ( ! this._mousePointInDropZone( e, this.dropZones[i] ) ) + this.dropZones[i].hideHover(); + } + + for ( var i = 0 ; i < n ; i++ ) { + if ( this._mousePointInDropZone( e, this.dropZones[i] ) ) { + if ( this.dropZones[i].canAccept(this.currentDragObjects) ) + this.dropZones[i].showHover(); + } + } + }, + + _startDrag: function(e) { + for ( var i = 0 ; i < this.currentDragObjects.length ; i++ ) + this.currentDragObjects[i].startDrag(); + + this._makeDraggableObjectVisible(e); + }, + + _mouseUpHandler: function(e) { + if ( ! this.hasSelection() ) + return; + + var nsEvent = e.which != undefined; + if ( (nsEvent && e.which != 1) || (!nsEvent && e.button != 1)) + return; + + this.interestedInMotionEvents = false; + + if ( this.dragElement == null ) { + this._terminateEvent(e); + return; + } + + if ( this._placeDraggableInDropZone(e) ) + this._completeDropOperation(e); + else { + this._terminateEvent(e); + Rico.animate(new Rico.Effect.Position( this.dragElement, this.origPos.x, this.origPos.y), + {duration: 200, + steps: 20, + onFinish : this._doCancelDragProcessing.bind(this) } ); + } + + Event.stopObserving(document.body, "mousemove", this._mouseMove); + Event.stopObserving(document.body, "mouseup", this._mouseUp); + }, + + _retTrue: function () { + return true; + }, + + _completeDropOperation: function(e) { + if ( this.dragElement != this.currentDragObjects[0].getMouseDownHTMLElement() ) { + if ( this.dragElement.parentNode != null ) + this.dragElement.parentNode.removeChild(this.dragElement); + } + + this._deactivateRegisteredDropZones(); + this._endDrag(); + this.clearSelection(); + this.dragElement = null; + this.currentDragObjectVisible = false; + this._terminateEvent(e); + }, + + _doCancelDragProcessing: function() { + this._cancelDrag(); + + if ( this.dragElement != this.currentDragObjects[0].getMouseDownHTMLElement() && this.dragElement) + if ( this.dragElement.parentNode != null ) + this.dragElement.parentNode.removeChild(this.dragElement); + + + this._deactivateRegisteredDropZones(); + this.dragElement = null; + this.currentDragObjectVisible = false; + }, + + _placeDraggableInDropZone: function(e) { + var foundDropZone = false; + var n = this.dropZones.length; + for ( var i = 0 ; i < n ; i++ ) { + if ( this._mousePointInDropZone( e, this.dropZones[i] ) ) { + if ( this.dropZones[i].canAccept(this.currentDragObjects) ) { + this.dropZones[i].hideHover(); + this.dropZones[i].accept(this.currentDragObjects); + foundDropZone = true; + break; + } + } + } + + return foundDropZone; + }, + + _cancelDrag: function() { + for ( var i = 0 ; i < this.currentDragObjects.length ; i++ ) + this.currentDragObjects[i].cancelDrag(); + }, + + _endDrag: function() { + for ( var i = 0 ; i < this.currentDragObjects.length ; i++ ) + this.currentDragObjects[i].endDrag(); + }, + + _mousePointInDropZone: function( e, dropZone ) { + + var absoluteRect = dropZone.getAbsoluteRect(); + + return e.clientX > absoluteRect.left + this._leftOffset(e) && + e.clientX < absoluteRect.right + this._leftOffset(e) && + e.clientY > absoluteRect.top + this._topOffset(e) && + e.clientY < absoluteRect.bottom + this._topOffset(e); + }, + + _addMouseDownHandler: function( aDraggable ) + { + htmlElement = aDraggable.getMouseDownHTMLElement(); + if ( htmlElement != null ) { + htmlElement.draggable = aDraggable; + Event.observe(htmlElement , "mousedown", this._onmousedown.bindAsEventListener(this)); + Event.observe(htmlElement, "mousedown", this._mouseDown); + } + }, + + _activateRegisteredDropZones: function() { + var n = this.dropZones.length; + for ( var i = 0 ; i < n ; i++ ) { + var dropZone = this.dropZones[i]; + if ( dropZone.canAccept(this.currentDragObjects) ) + dropZone.activate(); + } + + this.activatedDropZones = true; + }, + + _deactivateRegisteredDropZones: function() { + var n = this.dropZones.length; + for ( var i = 0 ; i < n ; i++ ) + this.dropZones[i].deactivate(); + this.activatedDropZones = false; + }, + + _onmousedown: function () { + Event.observe(document.body, "mousemove", this._mouseMove); + Event.observe(document.body, "mouseup", this._mouseUp); + }, + + _terminateEvent: function(e) { + if ( e.stopPropagation != undefined ) + e.stopPropagation(); + else if ( e.cancelBubble != undefined ) + e.cancelBubble = true; + + if ( e.preventDefault != undefined ) + e.preventDefault(); + else + e.returnValue = false; + }, + + + initializeEventHandlers: function() { + if ( typeof document.implementation != "undefined" && + document.implementation.hasFeature("HTML", "1.0") && + document.implementation.hasFeature("Events", "2.0") && + document.implementation.hasFeature("CSS", "2.0") ) { + document.addEventListener("mouseup", this._mouseUpHandler.bindAsEventListener(this), false); + document.addEventListener("mousemove", this._mouseMoveHandler.bindAsEventListener(this), false); + } + else { + document.attachEvent( "onmouseup", this._mouseUpHandler.bindAsEventListener(this) ); + document.attachEvent( "onmousemove", this._mouseMoveHandler.bindAsEventListener(this) ); + } + } + } + + var dndMgr = new Rico.DragAndDrop(); + dndMgr.initializeEventHandlers(); + + +//-------------------- ricoDraggable.js +Rico.Draggable = Class.create(); + +Rico.Draggable.prototype = { + + initialize: function( type, htmlElement ) { + this.type = type; + this.htmlElement = $(htmlElement); + this.selected = false; + }, + + /** + * Returns the HTML element that should have a mouse down event + * added to it in order to initiate a drag operation + * + **/ + getMouseDownHTMLElement: function() { + return this.htmlElement; + }, + + select: function() { + this.selected = true; + + if ( this.showingSelected ) + return; + + var htmlElement = this.getMouseDownHTMLElement(); + + var color = Rico.Color.createColorFromBackground(htmlElement); + color.isBright() ? color.darken(0.033) : color.brighten(0.033); + + this.saveBackground = RicoUtil.getElementsComputedStyle(htmlElement, "backgroundColor", "background-color"); +// this.saveBackground = Element.getStyle(htmlElement,'backgroundColor') || Element.getStyle(htmlElement,'background-color') + htmlElement.style.backgroundColor = color.asHex(); + this.showingSelected = true; + }, + + deselect: function() { + this.selected = false; + if ( !this.showingSelected ) + return; + + var htmlElement = this.getMouseDownHTMLElement(); + + htmlElement.style.backgroundColor = this.saveBackground; + this.showingSelected = false; + }, + + isSelected: function() { + return this.selected; + }, + + startDrag: function() { + }, + + cancelDrag: function() { + }, + + endDrag: function() { + }, + + getSingleObjectDragGUI: function() { + return this.htmlElement; + }, + + getMultiObjectDragGUI: function( draggables ) { + return this.htmlElement; + }, + + getDroppedGUI: function() { + return this.htmlElement; + }, + + toString: function() { + return this.type + ":" + this.htmlElement + ":"; + } + +} + + +//-------------------- ricoDropzone.js +Rico.Dropzone = Class.create(); + +Rico.Dropzone.prototype = { + + initialize: function( htmlElement ) { + this.htmlElement = $(htmlElement); + this.absoluteRect = null; + }, + + getHTMLElement: function() { + return this.htmlElement; + }, + + clearPositionCache: function() { + this.absoluteRect = null; + }, + + getAbsoluteRect: function() { + if ( this.absoluteRect == null ) { + var htmlElement = this.getHTMLElement(); + var pos = RicoUtil.toViewportPosition(htmlElement); + + this.absoluteRect = { + top: pos.y, + left: pos.x, + bottom: pos.y + htmlElement.offsetHeight, + right: pos.x + htmlElement.offsetWidth + }; + } + return this.absoluteRect; + }, + + activate: function() { + var htmlElement = this.getHTMLElement(); + if (htmlElement == null || this.showingActive) + return; + + this.showingActive = true; + this.saveBackgroundColor = htmlElement.style.backgroundColor; + + var fallbackColor = "#ffea84"; + var currentColor = Rico.Color.createColorFromBackground(htmlElement); + if ( currentColor == null ) + htmlElement.style.backgroundColor = fallbackColor; + else { + currentColor.isBright() ? currentColor.darken(0.2) : currentColor.brighten(0.2); + htmlElement.style.backgroundColor = currentColor.asHex(); + } + }, + + deactivate: function() { + var htmlElement = this.getHTMLElement(); + if (htmlElement == null || !this.showingActive) + return; + + htmlElement.style.backgroundColor = this.saveBackgroundColor; + this.showingActive = false; + this.saveBackgroundColor = null; + }, + + showHover: function() { + var htmlElement = this.getHTMLElement(); + if ( htmlElement == null || this.showingHover ) + return; + + this.saveBorderWidth = htmlElement.style.borderWidth; + this.saveBorderStyle = htmlElement.style.borderStyle; + this.saveBorderColor = htmlElement.style.borderColor; + + this.showingHover = true; + htmlElement.style.borderWidth = "1px"; + htmlElement.style.borderStyle = "solid"; + //htmlElement.style.borderColor = "#ff9900"; + htmlElement.style.borderColor = "#ffff00"; + }, + + hideHover: function() { + var htmlElement = this.getHTMLElement(); + if ( htmlElement == null || !this.showingHover ) + return; + + htmlElement.style.borderWidth = this.saveBorderWidth; + htmlElement.style.borderStyle = this.saveBorderStyle; + htmlElement.style.borderColor = this.saveBorderColor; + this.showingHover = false; + }, + + canAccept: function(draggableObjects) { + return true; + }, + + accept: function(draggableObjects) { + var htmlElement = this.getHTMLElement(); + if ( htmlElement == null ) + return; + + n = draggableObjects.length; + for ( var i = 0 ; i < n ; i++ ) + { + var theGUI = draggableObjects[i].getDroppedGUI(); +/* if (Element.getStyle(theGUI,'position')=='absolute')*/ + if ( RicoUtil.getElementsComputedStyle( theGUI, "position" ) == "absolute" ) + { + theGUI.style.position = "static"; + theGUI.style.top = ""; + theGUI.style.top = ""; + } + htmlElement.appendChild(theGUI); + } + } +} + +RicoUtil = Object.extend(RicoUtil, { + getElementsComputedStyle: function ( htmlElement, cssProperty, mozillaEquivalentCSS) { + if ( arguments.length == 2 ) + mozillaEquivalentCSS = cssProperty; + + var el = $(htmlElement); + if ( el.currentStyle ) + return el.currentStyle[cssProperty]; + else + return document.defaultView.getComputedStyle(el, null).getPropertyValue(mozillaEquivalentCSS); + }, + + createXmlDocument : function() { + if (document.implementation && document.implementation.createDocument) { + var doc = document.implementation.createDocument("", "", null); + + if (doc.readyState == null) { + doc.readyState = 1; + doc.addEventListener("load", function () { + doc.readyState = 4; + if (typeof doc.onreadystatechange == "function") + doc.onreadystatechange(); + }, false); + } + + return doc; + } + + if (window.ActiveXObject) + return Try.these( + function() { return new ActiveXObject('MSXML2.DomDocument') }, + function() { return new ActiveXObject('Microsoft.DomDocument')}, + function() { return new ActiveXObject('MSXML.DomDocument') }, + function() { return new ActiveXObject('MSXML3.DomDocument') } + ) || false; + + return null; + }, + + getContentAsString: function( parentNode ) { + return parentNode.xml != undefined ? + this._getContentAsStringIE(parentNode) : + this._getContentAsStringMozilla(parentNode); + }, + + _getContentAsStringIE: function(parentNode) { + var contentStr = ""; + for ( var i = 0 ; i < parentNode.childNodes.length ; i++ ) { + var n = parentNode.childNodes[i]; + if (n.nodeType == 4) { + contentStr += n.nodeValue; + } + else { + contentStr += n.xml; + } + } + return contentStr; + }, + + _getContentAsStringMozilla: function(parentNode) { + var xmlSerializer = new XMLSerializer(); + var contentStr = ""; + for ( var i = 0 ; i < parentNode.childNodes.length ; i++ ) { + var n = parentNode.childNodes[i]; + if (n.nodeType == 4) { // CDATA node + contentStr += n.nodeValue; + } + else { + contentStr += xmlSerializer.serializeToString(n); + } + } + return contentStr; + }, + + toViewportPosition: function(element) { + return this._toAbsolute(element,true); + }, + + toDocumentPosition: function(element) { + return this._toAbsolute(element,false); + }, + + /** + * Compute the elements position in terms of the window viewport + * so that it can be compared to the position of the mouse (dnd) + * This is additions of all the offsetTop,offsetLeft values up the + * offsetParent hierarchy, ...taking into account any scrollTop, + * scrollLeft values along the way... + * + * IE has a bug reporting a correct offsetLeft of elements within a + * a relatively positioned parent!!! + **/ + _toAbsolute: function(element,accountForDocScroll) { + + if ( navigator.userAgent.toLowerCase().indexOf("msie") == -1 ) + return this._toAbsoluteMozilla(element,accountForDocScroll); + + var x = 0; + var y = 0; + var parent = element; + while ( parent ) { + + var borderXOffset = 0; + var borderYOffset = 0; + if ( parent != element ) { + var borderXOffset = parseInt(this.getElementsComputedStyle(parent, "borderLeftWidth" )); + var borderYOffset = parseInt(this.getElementsComputedStyle(parent, "borderTopWidth" )); + borderXOffset = isNaN(borderXOffset) ? 0 : borderXOffset; + borderYOffset = isNaN(borderYOffset) ? 0 : borderYOffset; + } + + x += parent.offsetLeft - parent.scrollLeft + borderXOffset; + y += parent.offsetTop - parent.scrollTop + borderYOffset; + parent = parent.offsetParent; + } + + if ( accountForDocScroll ) { + x -= this.docScrollLeft(); + y -= this.docScrollTop(); + } + + return { x:x, y:y }; + }, + + /** + * Mozilla did not report all of the parents up the hierarchy via the + * offsetParent property that IE did. So for the calculation of the + * offsets we use the offsetParent property, but for the calculation of + * the scrollTop/scrollLeft adjustments we navigate up via the parentNode + * property instead so as to get the scroll offsets... + * + **/ + _toAbsoluteMozilla: function(element,accountForDocScroll) { + var x = 0; + var y = 0; + var parent = element; + while ( parent ) { + x += parent.offsetLeft; + y += parent.offsetTop; + parent = parent.offsetParent; + } + + parent = element; + while ( parent && + parent != document.body && + parent != document.documentElement ) { + if ( parent.scrollLeft ) + x -= parent.scrollLeft; + if ( parent.scrollTop ) + y -= parent.scrollTop; + parent = parent.parentNode; + } + + if ( accountForDocScroll ) { + x -= this.docScrollLeft(); + y -= this.docScrollTop(); + } + + return { x:x, y:y }; + }, + + docScrollLeft: function() { + if ( window.pageXOffset ) + return window.pageXOffset; + else if ( document.documentElement && document.documentElement.scrollLeft ) + return document.documentElement.scrollLeft; + else if ( document.body ) + return document.body.scrollLeft; + else + return 0; + }, + + docScrollTop: function() { + if ( window.pageYOffset ) + return window.pageYOffset; + else if ( document.documentElement && document.documentElement.scrollTop ) + return document.documentElement.scrollTop; + else if ( document.body ) + return document.body.scrollTop; + else + return 0; + } +}); + +Rico.includeLoaded('ricoDragDrop.js'); diff --git a/NP_TrackBack/trunk/trackback/js/rico/ricoEffects.js b/NP_TrackBack/trunk/trackback/js/rico/ricoEffects.js new file mode 100644 index 0000000..608bb60 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/ricoEffects.js @@ -0,0 +1,389 @@ + /** + * (c) 2005-2007 Richard Cowin (http://openrico.org) + * + * Rico is licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + **/ + +Rico.animate = function(effect){ + new Rico.Effect.Animator().play(effect, arguments[1]); +} + +Rico.Effect = {} +Rico.Effect.easeIn = function(step){ + return Math.sqrt(step) +} +Rico.Effect.easeOut = function(step){ + return step*step +} +Rico.Stepping = {} +Rico.Stepping.easeIn = Rico.Effect.easeIn; +Rico.Stepping.easeOut = Rico.Effect.easeOut; + +Rico.Effect.Animator = Class.create(); +Rico.Effect.Animator.prototype = { + initialize : function(effect) { + this.animateMethod = this.animate.bind(this); + this.options = arguments[1] || {}; + this.stepsLeft = 0; + if (!effect) return; + this.reset(effect, arguments[1]); + }, + reset: function(effect){ + this.effect = effect; + if (arguments[1]) this.setOptions(arguments[1]); + this.stepsLeft = this.options.steps; + this.duration = this.options.duration; + }, + setOptions: function(options){ + this.options = Object.extend({ + steps: 10, + duration: 200, + rate: function(steps){ return steps;} + }, options|| {}); + }, + play: function(effect) { + this.setOptions(arguments[1]) + if (effect) + if (effect.step) + this.reset(effect, arguments[1]); + else{ + $H(effect).keys().each((function(e){ + var effectClass = {fadeOut:Rico.Effect.FadeOut}[e]; + this.reset(new effectClass(effect[e])); + }).bind(this)) + } + this.animate(); + }, + stop: function() { + this.stepsLeft = this.options.steps; + }, + pause: function() { + this.interupt = true; + }, + resume: function() { + this.interupt = false; + if (this.stepsLeft >0) + this.animate(); + }, + animate: function() { + if (this.interupt) + return; + if (this.stepsLeft <=0) { + if (this.effect.finish) this.effect.finish(); + if (this.options.onFinish) this.options.onFinish(); + return; + } + if (this.timer) + clearTimeout(this.timer); + this.effect.step(this.options.rate(this.stepsLeft)); + this.startNextStep(); + }, + startNextStep: function() { + var stepDuration = Math.round(this.duration/this.stepsLeft) ; + this.duration -= stepDuration; + this.stepsLeft--; + this.timer = setTimeout(this.animateMethod, stepDuration); + }, + isPlaying: function(){ + return this.stepsLeft != 0 && !this.interupt; + } +} + +Rico.Effect.Group = Class.create(); +Rico.Effect.Group.prototype = { + initialize: function(effects){ + this.effects = effects; + }, + step: function(stepsToGo){ + this.effects.each(function(e){e.step(stepsToGo)}); + }, + finish: function(){ + this.effects.each(function(e){if (e.finish) e.finish()}); + } +} + +Rico.Effect.SizeAndPosition = Class.create(); +Rico.Effect.SizeAndPosition.prototype = { + initialize: function(element, x, y, w, h) { + this.element = $(element); + this.x = x || this.element.offsetLeft; + this.y = y || this.element.offsetTop; + this.w = w || this.element.offsetWidth; + this.h = h || this.element.offsetHeight; + }, + step: function(stepsToGo) { + var left = this.element.offsetLeft + ((this.x - this.element.offsetLeft)/stepsToGo) + "px" + var top = this.element.offsetTop + ((this.y - this.element.offsetTop)/stepsToGo) + "px" + var width = this.element.offsetWidth + ((this.w - this.element.offsetWidth)/stepsToGo) + "px" + var height = this.element.offsetHeight + ((this.h - this.element.offsetHeight)/stepsToGo) + "px" + var style = this.element.style; + style.left = left; + style.top = top; + style.width = width; + style.height = height; + } +} + +Rico.AccordionEffect = Class.create(); +Rico.AccordionEffect.prototype = { + initialize: function(toClose, toOpen, height) { + this.toClose = toClose; + this.toOpen = toOpen; +/* if (!navigator.appVersion.match(/\bMSIE\b/)) {*/ + Element.makeClipping(toOpen); + Element.makeClipping(toClose); +/* }*/ + Rico.Controls.disableNativeControls(toClose); + Element.show(toOpen); + this.toOpen.style.height = "0px"; + this.endHeight = height; + }, + step: function(framesLeft) { + var cHeight = Math.max(1,this.toClose.offsetHeight - parseInt((parseInt(this.toClose.offsetHeight))/framesLeft)); + var closeHeight = cHeight + "px"; + var openHeight = (this.endHeight - cHeight) + "px" + this.toClose.style.height = closeHeight; + this.toOpen.style.height = openHeight; + }, + finish: function(){ + Element.hide(this.toClose) + this.toOpen.style.height = this.endHeight + "px"; + this.toClose.style.height = "0px"; +/* if (!navigator.appVersion.match(/\bMSIE\b/)) {*/ + Element.undoClipping(this.toOpen); + Element.undoClipping(this.toClose); +/* }*/ + + Rico.Controls.enableNativeControls(this.toOpen); + } +}; + +Rico.Effect.SizeFromBottom = Class.create() +Rico.Effect.SizeFromBottom.prototype = { + initialize: function(element, y, h) { + this.element = $(element); + this.y = y || this.element.offsetTop; + this.h = h || this.element.offsetHeight; + this.options = arguments[3] || {}; + }, + step: function(framesToGo) { + var top = this.element.offsetTop + ((this.y - this.element.offsetTop)/framesToGo) + "px" + var height = this.element.offsetHeight + ((this.h - this.element.offsetHeight)/framesToGo) + "px" + var style = this.element.style; + style.height = height; + style.top = top; + } +} + +Rico.Effect.Position = Class.create(); +Rico.Effect.Position.prototype = { + initialize: function(element, x, y) { + this.element = $(element); + this.x = x || this.element.offsetLeft; + this.destTop = y || this.element.offsetTop; + }, + step: function(stepsToGo) { + var left = this.element.offsetLeft + ((this.x - this.element.offsetLeft)/stepsToGo) + "px" + var top = this.element.offsetTop + ((this.destTop - this.element.offsetTop)/stepsToGo) + "px" + var style = this.element.style; + style.left = left; + style.top = top; + } +} + +Rico.Effect.FadeTo = Class.create() +Rico.Effect.FadeTo.prototype = { + initialize: function(element, value){ + this.element = element; + this.opacity = Element.getStyle(this.element, 'opacity') || 1.0; + this.target = Math.min(value, 1.0); + }, + step: function(framesLeft) { + var curOpacity = Element.getStyle(this.element, 'opacity'); + var newOpacity = curOpacity + (this.target - curOpacity)/framesLeft + Rico.Effect.setOpacity(this.element, Math.min(Math.max(0,newOpacity),1.0)); + } +} + +Rico.Effect.FadeOut = Class.create() +Rico.Effect.FadeOut.prototype = { + initialize: function(element){ + this.effect = new Rico.Effect.FadeTo(element, 0.0) + }, + step: function(framesLeft) { + this.effect.step(framesLeft); + } +} + +Rico.Effect.FadeIn = Class.create() +Rico.Effect.FadeIn.prototype = { + initialize: function(element){ + var options = arguments[1] || {} + var startValue = options.startValue || 0 + Element.setStyle(element, 'opacity', startValue); + this.effect = new Rico.Effect.FadeTo(element, 1.0) + }, + step: function(framesLeft) { + this.effect.step(framesLeft); + } +} + +Rico.Effect.setOpacity= function(element, value) { + element.style.filter = "alpha(opacity:"+Math.round(value*100)+")"; + element.style.opacity = value; +} + +Rico.Effect.SizeFromTop = Class.create() +Rico.Effect.SizeFromTop.prototype = { + initialize: function(element, scrollElement, y, h) { + this.element = $(element); + this.h = h || this.element.offsetHeight; + // element.style.top = y; + this.scrollElement = scrollElement; + this.options = arguments[4] || {}; + this.baseHeight = this.options.baseHeight || Math.max(this.h, this.element.offsetHeight) + }, + step: function(framesToGo) { + var rawHeight = this.element.offsetHeight + ((this.h - this.element.offsetHeight)/framesToGo); + var height = rawHeight + "px" + var scroll = (rawHeight - this.baseHeight) + "px"; + this.scrollElement.style.top = scroll; + this.element.style.height = height; + } +} + + +Rico.Effect.Height = Class.create() +Rico.Effect.Height.prototype = { + initialize: function(element, endHeight) { + this.element = element + this.endHeight = endHeight + }, + step: function(stepsLeft) { + if (this.element.constructor != Array){ + var height = this.element.offsetHeight + ((this.endHeight - this.element.offsetHeight)/stepsLeft) + "px" + this.element.style.height = height; + } else { + var height = this.element[0].offsetHeight + ((this.endHeight - this.element[0].offsetHeight)/stepsLeft) + "px" + this.element.each(function(e){e.style.height = height}) + } + } +} + +Rico.Effect.SizeWidth = Class.create(); +Rico.Effect.SizeWidth.prototype = { + initialize: function(element, endWidth) { + this.element = element + this.endWidth = endWidth + }, + step: function(stepsLeft) { + delta = Math.abs(this.endWidth - parseInt(this.element.offsetWidth))/(stepsLeft); + this.element.style.width = (this.element.offsetWidth - delta) + "px"; + } +} + +//these are to support non Safari browsers and keep controls from bleeding through on absolute positioned element. +Rico.Controls = { + editors: [], + scrollSelectors: [], + + disableNativeControls: function(element) { + Rico.Controls.defaultDisabler.disableNative(element); + }, + enableNativeControls: function(element){ + Rico.Controls.defaultDisabler.enableNative(element); + }, + prepareForSizing: function(element){ + Element.makeClipping(element) + Rico.Controls.disableNativeControls(element) + }, + resetSizing: function(element){ + Element.undoClipping(element) + Rico.Controls.enableNativeControls(element) + }, + registerScrollSelectors: function(selectorSet) { + selectorSet.each(function(s){Rico.Controls.scrollSelectors.push(Rico.selector(s))}); + } +} + +Rico.Controls.Disabler = Class.create(); +Rico.Controls.Disabler.prototype = { + initialize: function(){ + this.options = Object.extend({ + excludeSet: [], + hidables: Rico.Controls.editors + }, arguments[0] || {}); + }, + disableNative: function(element) { + if (!(/Konqueror|Safari|KHTML/.test(navigator.userAgent))){ + if (!navigator.appVersion.match(/\bMSIE\b/)) + this.blockControls(element).each(function(e){Element.makeClipping(e)}); + else + this.hidableControls(element).each(function(e){e.disable()}); + } + }, + enableNative: function(element){ + if (!(/Konqueror|Safari|KHTML/.test(navigator.userAgent))){ + if (!navigator.appVersion.match(/\bMSIE\b/)) + this.blockControls(element).each(function(e){Element.undoClipping(e)}); + else + this.hidableControls(element).each(function(e){e.enable()}); + } + }, + blockControls: function(element){ + try{ + var includes = []; + if (this.options.includeSet) + includes = this.options.includeSet; + else{ + var selectors = this.options.includeSelectors || Rico.Controls.scrollSelectors; + includes = selectors.map(function(s){return s.findAll(element)}).flatten(); + } + return includes.select(function(e){return (Element.getStyle(e, 'display') != 'none') && !this.options.excludeSet.include(e)}.bind(this)); + }catch(e) { return []} + }, + hidableControls: function(element){ + if (element) + return this.options.hidables.select(function(e){return Element.childOf(e, element)}); + else + return this.options.hidables; + } +} + +Rico.Controls.defaultDisabler = new Rico.Controls.Disabler(); +Rico.Controls.blankDisabler = new Rico.Controls.Disabler({includeSet:[],hidables:[]}); + +Rico.Controls.HidableInput = Class.create(); +Rico.Controls.HidableInput.prototype = { + initialize: function(field, view){ + this.field = field; + this.view = view; + this.enable(); + Rico.Controls.editors.push(this); + }, + enable: function(){ + Element.hide(this.view); + Element.show(this.field); + }, + disable: function(){ + this.view.value = $F(this.field); + if (this.field.offsetWidth > 1) { + this.view.style.width = parseInt(this.field.offsetWidth) + "px"; + Element.hide(this.field); + Element.show(this.view); + } + } +} + + + +Element.forceRefresh = function(item) { + try { + var n = document.createTextNode(' ') + item.appendChild(n); item.removeChild(n); + } catch(e) { } +}; + +Rico.includeLoaded('ricoEffects.js'); diff --git a/NP_TrackBack/trunk/trackback/js/rico/ricoGridCommon.js b/NP_TrackBack/trunk/trackback/js/rico/ricoGridCommon.js new file mode 100644 index 0000000..01f7392 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/ricoGridCommon.js @@ -0,0 +1,685 @@ +/** + * (c) 2005-2007 Richard Cowin (http://openrico.org) + * (c) 2005-2007 Matt Brown (http://dowdybrown.com) + * + * Rico is licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + **/ + + +if(typeof Rico=='undefined') throw("GridCommon requires the Rico JavaScript framework"); +if(typeof RicoUtil=='undefined') throw("GridCommon requires the RicoUtil Library"); + + +/** + * Define methods that are common to both SimpleGrid and LiveGrid + */ +Rico.GridCommon = function() {}; + +Rico.GridCommon.prototype = { + + baseInit: function() { + this.options = { + resizeBackground : 'resize.gif', + saveColumnInfo : {width:true, filter:false, sort:false}, // save info in cookies? + allowColResize : true, // allow user to resize columns + windowResize : true, // Resize grid on window.resize event? Set to false when embedded in an accordian. + click : null, + dblclick : null, + contextmenu : null, + useUnformattedColWidth : true, + menuEvent : 'dblclick', // event that triggers menus - click, dblclick, contextmenu, or none (no menus) + defaultWidth : 100, // in the absence of any other width info, columns will be this many pixels wide + scrollBarWidth : 19, // this is the value used in positioning calculations, it does not actually change the width of the scrollbar + minScrollWidth : 100, // min scroll area width when width of frozen columns exceeds window width + columnSpecs : [] + } + this.colWidths = new Array(); + this.hdrCells=new Array(); + this.headerColCnt=0; + this.headerRowIdx=0; + this.tabs=new Array(2); + this.thead=new Array(2); + this.tbody=new Array(2); + }, + + attachMenuEvents: function() { + if (!this.options.menuEvent || this.options.menuEvent=='none') return; + this.hideScroll=navigator.userAgent.match(/Macintosh\b.*\b(Firefox|Camino)\b/i) || Prototype.Browser.Opera; + this.options[this.options.menuEvent]=this.handleMenuClick.bindAsEventListener(this); + if (this.highlightDiv) { + switch (this.options.highlightElem) { + case 'cursorRow': + this.attachMenu(this.highlightDiv); + break; + case 'cursorCell': + for (var i=0; i<2; i++) + this.attachMenu(this.highlightDiv[i]); + break; + } + } + for (var i=0; i<2; i++) + this.attachMenu(this.tbody[i]); + }, + + attachMenu: function(elem) { + if (this.options.click) + Event.observe(elem, 'click', this.options.click, false); + if (this.options.dblclick) { + if (Prototype.Browser.WebKit || Prototype.Browser.Opera) + Event.observe(elem, 'click', this.handleDblClick.bindAsEventListener(this), false); + else + Event.observe(elem, 'dblclick', this.options.dblclick, false); + } + if (this.options.contextmenu) { + if (Prototype.Browser.Opera) + Event.observe(elem, 'click', this.handleContextMenu.bindAsEventListener(this), false); + else + Event.observe(elem, 'contextmenu', this.options.contextmenu, false); + } + }, + + // implement double-click for browsers that don't support a double-click event (e.g. Safari) + handleDblClick: function(e) { + var elem=Event.element(e); + if (this.dblClickElem == elem) { + this.options.dblclick(e); + } else { + this.dblClickElem = elem; + this.safariTimer=setTimeout(this.clearDblClick.bind(this),300); + } + }, + + clearDblClick: function() { + this.dblClickElem=null; + }, + + // implement right-click for browsers that don't support contextmenu event (e.g. Opera) + // use control-click instead + handleContextMenu: function(e) { + if( typeof( e.which ) == 'number' ) + var b = e.which; //Netscape compatible + else if( typeof( e.button ) == 'number' ) + var b = e.button; //DOM + else + return; + if (b==1 && e.ctrlKey) + this.options.contextmenu(e); + }, + + cancelMenu: function() { + if (this.menu && this.menu.isVisible()) this.menu.cancelmenu(); + }, + + // gather info from original headings + getColumnInfo: function(hdrSrc) { + Rico.writeDebugMsg("getColumnInfo start"); + //alert(hdrSrc.tagName+' '+hdrSrc.id+' len='+hdrSrc.length); + if (hdrSrc.length == 0) return; + this.headerRowCnt=hdrSrc.length; + var colcnt; + for (r=0; r= this.hdrCells.length) this.hdrCells[r]=new Array(); + for (c=0; c=0) ? this.columns[c].cell(r) : null; + }, + + availHt: function() { + var divPos=Position.page(this.outerDiv); + return RicoUtil.windowHeight()-divPos[1]-2*this.options.scrollBarWidth-15; // allow for scrollbar and some margin + }, + + handleScroll: function(e) { + var newTop=(this.hdrHt-this.scrollDiv.scrollTop)+'px'; + this.tabs[0].style.top=newTop; + this.setHorizontalScroll(); + }, + + setHorizontalScroll: function() { + var newLeft=(-this.scrollDiv.scrollLeft)+'px'; + this.hdrTabs[1].style.left=newLeft; + }, + + pluginScroll: function() { + if (this.scrollPluggedIn) return; + Event.observe(this.scrollDiv,"scroll",this.scrollEventFunc, false); + this.scrollPluggedIn=true; + }, + + unplugScroll: function() { + Event.stopObserving(this.scrollDiv,"scroll", this.scrollEventFunc , false); + this.scrollPluggedIn=false; + }, + + printVisible: function(exportType) { + this.exportStart(); + var limit=this.pageSize; + if (this.buffer && this.buffer.totalRows < limit) limit=this.buffer.totalRows; + for(var r=0; r < limit; r++) { + this.exportText+=""; + for (var c=0; c"+this.columns[c].getFormattedValue(r)+""; + } + this.exportText+=""; + } + this.exportFinish(exportType); + }, + + exportStart: function() { + this.exportText=""; + + for (var r=0; r 0) { + var divs=Element.getElementsByClassName(hdrcell.cell,'ricoLG_cell'); + var cell=divs && divs.length>0 ? divs[0] : hdrcell.cell; + this.exportText+=""; + } + } + this.exportText+=""; + } + + for (var c=0; c= this.columns.length) continue; + var col=this.columns[colnum]; + switch (v[0].charAt(0)) { + case 'w': + col.setColWidth(v[1]); + col.customWidth=true; + break; + case 'h': + if (v[1].toLowerCase()=='true') + col.showColumn(true); + else + col.hideColumn(true); + break; + case 's': + col.setSorted(v[1]); + break; + case 'f': + var filterTemp=v[1].split('~'); + col.filterOp=filterTemp.shift(); + col.filterValues = []; + col.filterType = Rico.TableColumn.USERFILTER; + for (var j=0; j 0) + RicoUtil.setCookie(this.tableId, cookieVals.join(','), this.options.cookieDays, this.options.cookiePath, this.options.cookieDomain); + } + +} + +Rico.TableColumn = Class.create(); + +Rico.TableColumn.UNFILTERED = 0; +Rico.TableColumn.SYSTEMFILTER = 1; /* system-generated filter, not shown to user */ +Rico.TableColumn.USERFILTER = 2; + +Rico.TableColumn.UNSORTED = 0; +Rico.TableColumn.SORT_ASC = "ASC"; +Rico.TableColumn.SORT_DESC = "DESC"; +Rico.TableColumn.MINWIDTH = 10; // min column width when user is resizing + +Rico.TableColumn.DOLLAR = {type:'number', prefix:'$', decPlaces:2, ClassName:'alignright'}; +Rico.TableColumn.EURO = {type:'number', prefix:'€', decPlaces:2, ClassName:'alignright'}; +Rico.TableColumn.PERCENT = {type:'number', suffix:'%', decPlaces:2, multiplier:100, ClassName:'alignright'}; +Rico.TableColumn.QTY = {type:'number', decPlaces:0, ClassName:'alignright'}; +Rico.TableColumn.DEFAULT = {type:"raw"}; + +Rico.TableColumn.prototype = { + + baseInit: function(liveGrid,colIdx,hdrInfo,tabIdx) { + Rico.writeDebugMsg("TableColumn.init index="+colIdx+" tabIdx="+tabIdx); + this.liveGrid = liveGrid; + this.index = colIdx; + this.hideWidth = Rico.isKonqueror || Prototype.Browser.WebKit || liveGrid.headerRowCnt>1 ? 5 : 2; // column width used for "hidden" columns. Anything less than 5 causes problems with Konqueror. Best to keep this greater than padding used inside cell. + this.options = liveGrid.options; + this.tabIdx = tabIdx; + this.hdrCell = hdrInfo.cell; + this.body = document.getElementsByTagName("body")[0]; // work around FireFox bug (document.body doesn't exist after XSLT) + this.displayName = this.getDisplayName(this.hdrCell); + var divs=this.hdrCell.getElementsByTagName('div'); + this.hdrColDiv=(divs.length<1) ? RicoUtil.wrapChildren(this.hdrCell,'ricoLG_col') : divs[0]; + this.hdrCellDiv=(divs.length<2) ? RicoUtil.wrapChildren(this.hdrColDiv,'ricoLG_cell') : divs[1]; + var sectionIndex= tabIdx==0 ? colIdx : colIdx-liveGrid.options.frozenColumns; + this.dataCell = liveGrid.tbody[tabIdx].rows[0].cells[sectionIndex]; + var divs=this.dataCell.getElementsByTagName('div'); + this.dataColDiv=(divs.length<1) ? RicoUtil.wrapChildren(this.dataCell,'ricoLG_col') : divs[0]; + + this.mouseDownHandler= this.handleMouseDown.bindAsEventListener(this); + this.mouseMoveHandler= this.handleMouseMove.bindAsEventListener(this); + this.mouseUpHandler = this.handleMouseUp.bindAsEventListener(this); + this.mouseOutHandler = this.handleMouseOut.bindAsEventListener(this); + + this.fieldName = 'col'+this.index; + var spec = liveGrid.options.columnSpecs[colIdx]; + this.format=Object.extend( {}, Rico.TableColumn.DEFAULT); + switch (typeof spec) { + case 'object': + if (typeof spec.format=='string') Object.extend(this.format, Rico.TableColumn[spec.format.toUpperCase()]); + Object.extend(this.format, spec); + break; + case 'string': + if (spec.slice(0,4)=='spec') spec=spec.slice(4).toUpperCase(); // for backwards compatibility + this.format=typeof Rico.TableColumn[spec]=='object' ? Rico.TableColumn[spec] : Rico.TableColumn.DEFAULT; + break; + } + this.dataColDiv.className += (this.format.ClassName) ? ' '+this.format.ClassName : ' '+liveGrid.tableId+'_col'+colIdx; + this.visible=true; + if (typeof this.format.visible=='boolean') this.visible=this.format.visible; + if (typeof this.format.type!='string') this.format.type='raw'; + Rico.writeDebugMsg("TableColumn.init index="+colIdx+" fieldName="+this.fieldName+' type='+this.format.type); + this.sortable = typeof this.format.canSort=='boolean' ? this.format.canSort : liveGrid.options.canSortDefault; + this.currentSort = Rico.TableColumn.UNSORTED; + this.filterable = typeof this.format.canFilter=='boolean' ? this.format.canFilter : liveGrid.options.canFilterDefault; + this.filterType = Rico.TableColumn.UNFILTERED; + this.hideable = typeof this.format.canHide=='boolean' ? this.format.canHide : liveGrid.options.canHideDefault; + if (typeof this.isNullable!='boolean') this.isNullable = /number|date/.test(this.format.type); + this.isText = /raw|text/.test(this.format.type); + + var wi=(typeof(this.format.width)=='number') ? this.format.width : hdrInfo.initWidth; + wi=(typeof(wi)=='number') ? Math.max(wi,Rico.TableColumn.MINWIDTH) : liveGrid.options.defaultWidth; + this.setColWidth(wi); + if (!this.visible) this.setDisplayNone(); + if (this.options.allowColResize && !this.format.noResize) this.insertResizer(); + }, + + insertResizer: function() { + this.hdrCell.style.width=''; + var resizer=this.hdrCellDiv.appendChild(document.createElement('div')); + resizer.className='ricoLG_Resize'; + resizer.style[this.liveGrid.align[1]]='0px'; + if (this.options.resizeBackground) { + var resizePath=Rico.imgDir+this.options.resizeBackground; + if (Prototype.Browser.IE) resizePath=location.protocol+resizePath; + resizer.style.backgroundImage='url('+resizePath+')'; + } + Event.observe(resizer,"mousedown", this.mouseDownHandler, false); + }, + + // get the display name of a column + getDisplayName: function(el) { + var anchors=el.getElementsByTagName("A"); + //Check the existance of A tags + if (anchors.length > 0) + return anchors[0].innerHTML; + else + return el.innerHTML.stripTags(); + }, + + _clear: function(gridCell) { + gridCell.innerHTML=' '; + }, + + clearCell: function(rowIndex) { + var gridCell=this.cell(rowIndex); + this._clear(gridCell,rowIndex); + if (!this.liveGrid.buffer) return; + var acceptAttr=this.liveGrid.buffer.options.acceptAttr; + for (var k=0; k0) this.edge+=RicoUtil.nan2zero(this.liveGrid.tabs[0].offsetWidth)-this.liveGrid.scrollDiv.scrollLeft; + } + this.liveGrid.resizeDiv.style.left=this.edge+"px"; + this.liveGrid.resizeDiv.style.display=""; + this.liveGrid.outerDiv.style.cursor='e-resize'; + this.tmpHighlight=this.liveGrid.highlightEnabled; + this.liveGrid.highlightEnabled=false; + this.pluginMouseEvents(); + Event.stop(e); + }, + + handleMouseMove: function(e) { + var delta=e.clientX-this.resizeStart; + var newWidth=(this.liveGrid.direction=='rtl') ? this.origWidth-delta : this.origWidth+delta; + if (newWidth < Rico.TableColumn.MINWIDTH) return; + this.liveGrid.resizeDiv.style.left=(this.edge+delta)+"px"; + this.colWidth=newWidth; + Event.stop(e); + }, + + handleMouseUp: function(e) { + this.unplugMouseEvents(); + Rico.writeDebugMsg('handleMouseUp '+this.liveGrid.tableId); + this.liveGrid.outerDiv.style.cursor=''; + this.liveGrid.resizeDiv.style.display="none"; + this.setColWidth(this.colWidth); + this.customWidth=true; + this.liveGrid.setCookie(); + this.liveGrid.highlightEnabled=this.tmpHighlight; + this.liveGrid.sizeDivs(); + Event.stop(e); + }, + + handleMouseOut: function(e) { + var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement; + while (reltg != null && reltg.nodeName.toLowerCase() != 'body') + reltg=reltg.parentNode; + if (reltg!=null && reltg.nodeName.toLowerCase() == 'body') return true; + this.handleMouseUp(e); + return true; + }, + + setDisplayNone: function() { + this.hdrCell.style.display='none'; + this.hdrColDiv.style.display='none'; + this.dataCell.style.display='none'; + this.dataColDiv.style.display='none'; + }, + + // recalcTableWidth defaults to true + hideColumn: function(noresize) { + Rico.writeDebugMsg('hideColumn '+this.liveGrid.tableId); + this.setDisplayNone(); + this.liveGrid.cancelMenu(); + this.visible=false; + this.customVisible=true; + if (noresize) return; + this.liveGrid.setCookie(); + this.liveGrid.sizeDivs(); + }, + + showColumn: function(noresize) { + Rico.writeDebugMsg('showColumn '+this.liveGrid.tableId); + this.hdrCell.style.display=''; + this.hdrColDiv.style.display=''; + this.dataCell.style.display=''; + this.dataColDiv.style.display=''; + this.liveGrid.cancelMenu(); + this.visible=true; + this.customVisible=true; + if (noresize) return; + this.liveGrid.setCookie(); + this.liveGrid.sizeDivs(); + }, + + setImage: function() { + if ( this.currentSort == Rico.TableColumn.SORT_ASC ) { + this.imgSort.style.display=''; + this.imgSort.src=Rico.imgDir+this.options.sortAscendImg; + } else if ( this.currentSort == Rico.TableColumn.SORT_DESC ) { + this.imgSort.style.display=''; + this.imgSort.src=Rico.imgDir+this.options.sortDescendImg; + } else { + this.imgSort.style.display='none'; + } + if (this.filterType == Rico.TableColumn.USERFILTER) { + this.imgFilter.style.display=''; + this.imgFilter.title=this.getFilterText(); + } else { + this.imgFilter.style.display='none'; + } + }, + + canHideShow: function() { + return this.hideable; + } + +}; + +Rico.includeLoaded('ricoGridCommon.js'); diff --git a/NP_TrackBack/trunk/trackback/js/rico/ricoLiveGrid.js b/NP_TrackBack/trunk/trackback/js/rico/ricoLiveGrid.js new file mode 100644 index 0000000..bc2af62 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/ricoLiveGrid.js @@ -0,0 +1,1806 @@ +/** + * (c) 2005-2007 Richard Cowin (http://openrico.org) + * (c) 2005-2007 Matt Brown (http://dowdybrown.com) + * + * Rico is licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + **/ + + +if(typeof Rico=='undefined') throw("LiveGrid requires the Rico JavaScript framework"); +if(typeof RicoUtil=='undefined') throw("LiveGrid requires the RicoUtil Library"); +if(typeof RicoTranslate=='undefined') throw("LiveGrid requires the RicoTranslate Library"); +if(typeof Rico.TableColumn=='undefined') throw("LiveGrid requires ricoGridCommon.js"); + + +Rico.Buffer = {}; + +/** + * Loads buffer with data that already exists in the document as an HTML table (no AJAX). + * Also serves as a base class for AJAX-enabled buffers. + */ +Rico.Buffer.Base = Class.create(); + +Rico.Buffer.Base.prototype = { + + initialize: function(dataTable, options) { + this.clear(); + this.updateInProgress = false; + this.lastOffset = 0; + this.rcvdRowCount = false; // true if an eof element was included in the last xml response + this.foundRowCount = false; // true if an xml response is ever received with eof true + this.totalRows = 0; + this.rowcntContent = ""; + this.rcvdOffset = -1; + this.options = { + fixedHdrRows : 0, + canFilter : false, // does buffer object support filtering? + isEncoded : true, // is the data received via ajax html encoded? + acceptAttr : [] // attributes that can be copied from original/ajax data (e.g. className, style, id) + } + Object.extend(this.options, options || {}); + if (dataTable) { + this.loadRowsFromTable(dataTable); + } else { + this.clear(); + } + }, + + registerGrid: function(liveGrid) { + this.liveGrid = liveGrid; + }, + + setTotalRows: function( newTotalRows ) { + if (this.totalRows == newTotalRows) return; + this.totalRows = newTotalRows; + if (this.liveGrid) { + Rico.writeDebugMsg("setTotalRows, newTotalRows="+newTotalRows); + if (this.liveGrid.sizeTo=='data') this.liveGrid.resizeWindow(); + this.liveGrid.updateHeightDiv(); + } + }, + + loadRowsFromTable: function(tableElement) { + this.rows = this.dom2jstable(tableElement,this.options.fixedHdrRows); + this.startPos = 0; + this.size = this.rows.length; + this.setTotalRows(this.size); + this.rowcntContent = this.size.toString(); + this.rcvdRowCount = true; + this.foundRowCount = true; + }, + + dom2jstable: function(rowsElement,firstRow) { + var newRows = new Array(); + var trs = rowsElement.getElementsByTagName("tr"); + var acceptAttr=this.options.acceptAttr; + for ( var i=firstRow || 0; i < trs.length; i++ ) { + var row = new Array(); + var cells = trs[i].getElementsByTagName("td"); + for ( var j=0; j < cells.length ; j++ ) { + row[j]={}; + row[j].content=RicoUtil.getContentAsString(cells[j],this.options.isEncoded); + for (var k=0; k= this.startPos) && (lastRow <= this.endPos()); // && (this.size != 0); + }, + + endPos: function() { + return this.startPos + this.rows.length; + }, + + fetch: function(offset) { + this.liveGrid.refreshContents(offset); + return; + }, + + exportAllRows: function(populate,finish) { + populate(this.getRows(0,this.totalRows)); + finish(); + }, + + setWindow: function(start, count) { + this.windowStart = start - this.startPos; + this.windowEnd = Math.min(this.windowStart + count,this.size); + this.windowPos = start; + }, + + isVisible: function(bufRow) { + return bufRow < this.rows.length && bufRow >= this.windowStart && bufRow < this.windowEnd; + }, + + getWindowCell: function(windowRow,col) { + var bufrow=this.windowStart+windowRow; + return this.isVisible(bufrow) && col < this.rows[bufrow].length ? this.rows[bufrow][col] : null; + }, + + getWindowValue: function(windowRow,col) { + var cell=this.getWindowCell(windowRow,col); + return cell ? cell.content : null; + }, + + setWindowValue: function(windowRow,col,newval) { + var bufRow=this.windowStart+windowRow; + if (bufRow >= this.windowEnd) return false; + return this.setValue(bufRow,col,newval); + }, + + getCell: function(bufRow,col) { + return bufRow < this.size ? this.rows[bufRow][col] : null; + }, + + getValue: function(bufRow,col) { + var cell=this.getCell(bufRow,col); + return cell ? cell.content : null; + }, + + setValue: function(bufRow,col,newval,newstyle) { + if (bufRow>=this.size) return false; + if (!this.rows[bufRow][col]) this.rows[bufRow][col]={}; + this.rows[bufRow][col].content=newval; + if (typeof newstyle=='string') this.rows[bufRow][col]._style=newstyle; + this.rows[bufRow][col].modified=true; + return true; + }, + + getRows: function(start, count) { + var begPos = start - this.startPos; + var endPos = Math.min(begPos + count,this.size); + var results = new Array(); + for ( var i=begPos; i < endPos; i++ ) + results.push(this.rows[i]); + return results + } + +}; + + +// Rico.LiveGrid ----------------------------------------------------- + +Rico.LiveGrid = Class.create(); + +Rico.LiveGrid.prototype = { + + initialize: function( tableId, buffer, options ) { + Object.extend(this, new Rico.GridCommon); + Object.extend(this, new Rico.LiveGridMethods); + this.baseInit(); + this.tableId = tableId; + this.buffer = buffer; + Rico.setDebugArea(tableId+"_debugmsgs"); // if used, this should be a textarea + + Object.extend(this.options, { + visibleRows : -1, // -1 or 'window'=size grid to client window; -2 or 'data'=size grid to min(window,data); -3 or 'body'=size so body does not have a scrollbar + frozenColumns : 0, + offset : 0, // first row to be displayed + prefetchBuffer : true, // load table on page load? + minPageRows : 1, + maxPageRows : 50, + canSortDefault : true, // can be overridden in the column specs + canFilterDefault : buffer.options.canFilter, // can be overridden in the column specs + canHideDefault : true, // can be overridden in the column specs + cookiePrefix : 'liveGrid.'+tableId, + + // highlight & selection parameters + highlightElem : 'none',// what gets highlighted/selected (cursorRow, cursorCell, menuRow, menuCell, selection, or none) + highlightSection : 3, // which section gets highlighted (frozen=1, scrolling=2, all=3, none=0) + highlightMethod : 'class', // outline, class, both (outline is less CPU intensive on the client) + highlightClass : 'ricoLG_selection', + + // export/print parameters + maxPrint : 1000, // max # of rows that can be printed/exported, 0=disable print/export feature + exportWindow : "height=300,width=500,scrollbars=1,menubar=1,resizable=1", + + // heading parameters + headingSort : 'link', // link: make headings a link that will sort column, hover: make headings a hoverset, none: events on headings are disabled + hdrIconsFirst : true, // true: put sort & filter icons before header text, false: after + sortAscendImg : 'sort_asc.gif', + sortDescendImg : 'sort_desc.gif', + filterImg : 'filtercol.gif' + }); + // other options: + // sortCol: initial sort column + + this.options.sortHandler = this.sortHandler.bind(this); + this.options.filterHandler = this.filterHandler.bind(this); + this.options.onRefreshComplete = this.bookmarkHandler.bind(this); + this.options.rowOverHandler = this.rowMouseOver.bindAsEventListener(this); + this.options.mouseDownHandler = this.selectMouseDown.bindAsEventListener(this); + this.options.mouseOverHandler = this.selectMouseOver.bindAsEventListener(this); + this.options.mouseUpHandler = this.selectMouseUp.bindAsEventListener(this); + Object.extend(this.options, options || {}); + + switch (typeof this.options.visibleRows) { + case 'string': + this.sizeTo=this.options.visibleRows; + this.options.visibleRows=-1; + break; + case 'number': + switch (this.options.visibleRows) { + case -1: this.sizeTo='window'; break; + case -2: this.sizeTo='data'; break; + case -3: this.sizeTo='body'; break; + } + break; + default: + this.sizeTo='window'; + this.options.visibleRows=-1; + } + this.highlightEnabled=this.options.highlightSection>0; + this.pageSize=0; + this.createTables(); + if (this.headerColCnt==0) { + alert('ERROR: no columns found in "'+this.tableId+'"'); + return; + } + this.createColumnArray(); + if (this.options.headingSort=='hover') + this.createHoverSet(); + + this.bookmark=$(this.tableId+"_bookmark"); + this.sizeDivs(); + this.createDataCells(this.options.visibleRows); + if (this.pageSize == 0) return; + this.buffer.registerGrid(this); + if (this.buffer.setBufferSize) this.buffer.setBufferSize(this.pageSize); + this.scrollTimeout = null; + this.lastScrollPos = 0; + this.attachMenuEvents(); + + // preload the images... + new Image().src = Rico.imgDir+this.options.filterImg; + new Image().src = Rico.imgDir+this.options.sortAscendImg; + new Image().src = Rico.imgDir+this.options.sortDescendImg; + Rico.writeDebugMsg("images preloaded"); + + this.setSortUI( this.options.sortCol, this.options.sortDir ); + this.setImages(); + if (this.listInvisible().length==this.columns.length) + this.columns[0].showColumn(); + this.sizeDivs(); + this.scrollDiv.style.display=""; + if (this.buffer.totalRows>0) + this.updateHeightDiv(); + if (this.options.prefetchBuffer) { + if (this.bookmark) this.bookmark.innerHTML = RicoTranslate.getPhrase("Loading..."); + if (this.options.canFilterDefault && this.options.getQueryParms) + this.checkForFilterParms(); + this.buffer.fetch(this.options.offset); + } + this.scrollEventFunc=this.handleScroll.bindAsEventListener(this); + this.wheelEventFunc=this.handleWheel.bindAsEventListener(this); + this.wheelEvent=(Prototype.Browser.IE || Prototype.Browser.Opera || Prototype.Browser.WebKit) ? 'mousewheel' : 'DOMMouseScroll'; + if (this.options.offset && this.options.offset < this.buffer.totalRows) + setTimeout(this.scrollToRow.bind(this,this.options.offset),50); // Safari requires a delay + this.pluginScroll(); + this.setHorizontalScroll(); + if (this.options.windowResize) + setTimeout(this.pluginWindowResize.bind(this),100); + } +}; + +Rico.LiveGridMethods = function() {}; + +Rico.LiveGridMethods.prototype = { + + createHoverSet: function() { + var hdrs=[]; + for( var c=0; c < this.headerColCnt; c++ ) + hdrs.push(this.columns[c].hdrCellDiv); + this.hoverSet = new Rico.HoverSet(hdrs); + }, + + checkForFilterParms: function() { + var s=window.location.search; + if (s.charAt(0)=='?') s=s.substring(1); + var pairs = s.split('&'); + for (var i=0; i 0; c++) + this.thead[c 0; c++) { + if (cells[0].className=='ricoFrozen') { + this.thead[0].rows[r].appendChild(cells[0]); + if (r==this.headerRowIdx) this.options.frozenColumns=c+1; + } else { + this.thead[1].rows[r].appendChild(cells[0]); + } + } + } + } + Rico.writeDebugMsg('loadHdrSrc end'); + }, + + sizeDivs: function() { + Rico.writeDebugMsg('sizeDivs: '+this.tableId); + this.cancelMenu(); + this.unhighlight(); + this.baseSizeDivs(); + if (this.pageSize == 0) return; + this.rowHeight = Math.round(this.dataHt/this.pageSize); + var scrHt=this.dataHt; + if (this.scrWi>0 || Prototype.Browser.IE || Prototype.Browser.WebKit) + scrHt+=this.options.scrollBarWidth; + this.scrollDiv.style.height=scrHt+'px'; + this.innerDiv.style.width=(this.scrWi-this.options.scrollBarWidth+1)+'px'; + this.resizeDiv.style.height=this.frozenTabs.style.height=this.innerDiv.style.height=(this.hdrHt+this.dataHt+1)+'px'; + Rico.writeDebugMsg('sizeDivs scrHt='+scrHt+' innerHt='+this.innerDiv.style.height+' rowHt='+this.rowHeight+' pageSize='+this.pageSize); + pad=(this.scrWi-this.scrTabWi < this.options.scrollBarWidth) ? 2 : 0; + this.shadowDiv.style.width=(this.scrTabWi+pad)+'px'; + this.outerDiv.style.height=(this.hdrHt+scrHt)+'px'; + this.setHorizontalScroll(); + }, + + setHorizontalScroll: function() { + var scrleft=this.scrollDiv.scrollLeft; + this.scrollTabs.style.left=(-scrleft)+'px'; + }, + + remainingHt: function() { + var winHt=RicoUtil.windowHeight(); + var margin=Prototype.Browser.IE ? 15 : 10; + switch (this.sizeTo) { + case 'window': + case 'data': + var divPos=Position.page(this.outerDiv); + var tabHt=Math.max(this.tabs[0].offsetHeight,this.tabs[1].offsetHeight); + Rico.writeDebugMsg("remainingHt, winHt="+winHt+' tabHt='+tabHt+' gridY='+divPos[1]); + return winHt-divPos[1]-tabHt-this.options.scrollBarWidth-margin; // allow for scrollbar and some margin + case 'body': + //Rico.writeDebugMsg("remainingHt, document.height="+document.height); + //Rico.writeDebugMsg("remainingHt, body.offsetHeight="+document.body.offsetHeight); + //Rico.writeDebugMsg("remainingHt, body.scrollHeight="+document.body.scrollHeight); + //Rico.writeDebugMsg("remainingHt, documentElement.scrollHeight="+document.documentElement.scrollHeight); + var bodyHt=Prototype.Browser.IE ? document.body.scrollHeight : document.body.offsetHeight; + var remHt=winHt-bodyHt-margin; + if (!Prototype.Browser.WebKit) remHt-=this.options.scrollBarWidth; + Rico.writeDebugMsg("remainingHt, winHt="+winHt+' pageHt='+bodyHt+' remHt='+remHt); + return remHt; + } + }, + + adjustPageSize: function() { + var remHt=this.remainingHt(); + Rico.writeDebugMsg('adjustPageSize remHt='+remHt+' lastRow='+this.lastRowPos); + if (remHt > this.rowHeight) + this.autoAppendRows(remHt); + else if (remHt < 0 || this.sizeTo=='data') + this.autoRemoveRows(-remHt); + }, + + pluginWindowResize: function() { + Event.observe(window, "resize", this.resizeWindow.bindAsEventListener(this), false); + }, + + resizeWindow: function() { + Rico.writeDebugMsg('resizeWindow '+this.tableId+' lastRow='+this.lastRowPos); + if (!this.sizeTo) { + this.sizeDivs(); + return; + } + var oldSize=this.pageSize; + this.adjustPageSize(); + if (this.pageSize > oldSize) { + this.isPartialBlank=true; + var adjStart=this.adjustRow(this.lastRowPos); + this.buffer.fetch(adjStart); + } + if (oldSize != this.pageSize) + setTimeout(this.finishResize.bind(this),50); + else + this.sizeDivs(); + Rico.writeDebugMsg('resizeWindow complete. old size='+oldSize+' new size='+this.pageSize); + }, + + finishResize: function() { + this.sizeDivs(); + this.updateHeightDiv(); + }, + + topOfLastPage: function() { + return Math.max(this.buffer.totalRows-this.pageSize,0); + }, + + updateHeightDiv: function() { + var notdisp=this.topOfLastPage(); + var ht = this.scrollDiv.clientHeight + this.rowHeight * notdisp; + //if (Prototype.Browser.Opera) ht+=this.options.scrollBarWidth-3; + Rico.writeDebugMsg("updateHeightDiv, ht="+ht+' scrollDiv.clientHeight='+this.scrollDiv.clientHeight+' rowsNotDisplayed='+notdisp); + this.shadowDiv.style.height=ht+'px'; + }, + + autoRemoveRows: function(overage) { + var removeCnt=Math.ceil(overage / this.rowHeight); + if (this.sizeTo=='data') + removeCnt=Math.max(removeCnt,this.pageSize-this.buffer.totalRows); + Rico.writeDebugMsg("autoRemoveRows overage="+overage+" removeCnt="+removeCnt); + for (var i=0; i= this.buffer.size) idx.onBlankRow=true; + return idx; + }, + + attachHighlightEvents: function(tBody) { + switch (this.options.highlightElem) { + case 'selection': + Event.observe(tBody,"mousedown", this.options.mouseDownHandler, false); + tBody.ondrag = function () { return false; }; + tBody.onselectstart = function () { return false; }; + break; + case 'cursorRow': + case 'cursorCell': + Event.observe(tBody,"mouseover", this.options.rowOverHandler, false); + break; + } + }, + + getVisibleSelection: function() { + var cellList=[]; + if (this.SelectIdxStart && this.SelectIdxEnd) { + var r1=Math.max(Math.min(this.SelectIdxEnd.row,this.SelectIdxStart.row),this.buffer.windowPos); + var r2=Math.min(Math.max(this.SelectIdxEnd.row,this.SelectIdxStart.row),this.buffer.windowEnd-1); + var c1=Math.min(this.SelectIdxEnd.column,this.SelectIdxStart.column); + var c2=Math.max(this.SelectIdxEnd.column,this.SelectIdxStart.column); + for (var r=r1; r<=r2; r++) + for (var c=c1; c<=c2; c++) + cellList.push({row:r-this.buffer.windowPos,column:c}); + } + if (this.SelectCtrl) { + for (var i=0; i=this.buffer.windowPos && this.SelectCtrl[i].row r2) { + this.HideSelection(); + return; + } + var c1=Math.min(this.SelectIdxEnd.column,this.SelectIdxStart.column); + var c2=Math.max(this.SelectIdxEnd.column,this.SelectIdxStart.column); + var top1=this.columns[c1].cell(r1-this.buffer.windowStart).offsetTop; + var cell2=this.columns[c1].cell(r2-this.buffer.windowStart); + var bottom2=cell2.offsetTop+cell2.offsetHeight; + var left1=this.columns[c1].dataCell.offsetLeft; + var left2=this.columns[c2].dataCell.offsetLeft; + var right2=left2+this.columns[c2].dataCell.offsetWidth; + //window.status='updateSelectOutline: '+r1+' '+r2+' top='+top1+' bot='+bottom2; + this.highlightDiv[0].style.top=this.highlightDiv[3].style.top=this.highlightDiv[1].style.top=(this.hdrHt+top1-1) + 'px'; + this.highlightDiv[2].style.top=(this.hdrHt+bottom2-1)+'px'; + this.highlightDiv[3].style.left=(left1-2)+'px'; + this.highlightDiv[0].style.left=this.highlightDiv[2].style.left=(left1-1)+'px'; + this.highlightDiv[1].style.left=(right2-1)+'px'; + this.highlightDiv[0].style.width=this.highlightDiv[2].style.width=(right2-left1-1) + 'px'; + this.highlightDiv[1].style.height=this.highlightDiv[3].style.height=(bottom2-top1) + 'px'; + //this.highlightDiv[0].style.right=this.highlightDiv[2].style.right=this.highlightDiv[1].style.right=()+'px'; + //this.highlightDiv[2].style.bottom=this.highlightDiv[3].style.bottom=this.highlightDiv[1].style.bottom=(this.hdrHt+bottom2) + 'px'; + for (var i=0; i<4; i++) + this.highlightDiv[i].style.display=''; + }, + + HideSelection: function(cellList) { + if (this.options.highlightMethod!='class') { + for (var i=0; i<4; i++) + this.highlightDiv[i].style.display='none'; + } + if (this.options.highlightMethod!='outline') { + var cellList=this.getVisibleSelection(); + for (var i=0; i= 0) { + sortDirection=this.columns[colnum].getSortDirection(); + } else { + if (typeof sortDirection!='string') { + sortDirection=Rico.TableColumn.SORT_ASC; + } else { + sortDirection=sortDirection.toUpperCase(); + if (sortDirection != Rico.TableColumn.SORT_DESC) sortDirection=Rico.TableColumn.SORT_ASC; + } + switch (typeof columnNameOrNum) { + case 'string': + colnum=this.findColumnName(columnNameOrNum); + break; + case 'number': + colnum=columnNameOrNum; + break; + } + } + if (typeof(colnum)!='number' || colnum < 0) return; + this.clearSort(); + this.columns[colnum].setSorted(sortDirection); + this.buffer.sortBuffer(colnum,sortDirection,this.columns[colnum].format.type,this.columns[colnum]._sortfunc); + }, + +/** + * clear sort flag on all columns + */ + clearSort: function() { + for (var x=0;x"; + for (var c=0; c"; + } + this.exportText+=""; + } + } + +}; + + +Object.extend(Rico.TableColumn.prototype, { + +initialize: function(liveGrid,colIdx,hdrInfo,tabIdx) { + this.baseInit(liveGrid,colIdx,hdrInfo,tabIdx); + Rico.writeDebugMsg(" sortable="+this.sortable+" filterable="+this.filterable+" hideable="+this.hideable+" isNullable="+this.isNullable+' isText='+this.isText); + this.fixHeaders(this.liveGrid.tableId, this.options.hdrIconsFirst); + if (this.format.type=='control' && this.format.control) { + // copy all properties/methods that start with '_' + if (typeof this.format.control=='string') + this.format.control=eval(this.format.control); + for (var property in this.format.control) + if (property.charAt(0)=='_') { + Rico.writeDebugMsg("Copying control property "+property); + this[property] = this.format.control[property]; + } + } else if (this['format_'+this.format.type]) { + this._format=this['format_'+this.format.type].bind(this); + } +}, + +sortAsc: function() { + this.setColumnSort(Rico.TableColumn.SORT_ASC); +}, + +sortDesc: function() { + this.setColumnSort(Rico.TableColumn.SORT_DESC); +}, + +setColumnSort: function(direction) { + this.liveGrid.clearSort(); + this.setSorted(direction); + if (this.liveGrid.options.saveColumnInfo.sort) + this.liveGrid.setCookie(); + if (this.options.sortHandler) + this.options.sortHandler(); +}, + +isSortable: function() { + return this.sortable; +}, + +isSorted: function() { + return this.currentSort != Rico.TableColumn.UNSORTED; +}, + +getSortDirection: function() { + return this.currentSort; +}, + +toggleSort: function() { + if (this.liveGrid.buffer && this.liveGrid.buffer.totalRows==0) return; + if (this.currentSort == Rico.TableColumn.SORT_ASC) + this.sortDesc(); + else + this.sortAsc(); +}, + +setUnsorted: function() { + this.setSorted(Rico.TableColumn.UNSORTED); +}, + +/** + * direction must be one of Rico.TableColumn.UNSORTED, .SORT_ASC, or .SORT_DESC + */ +setSorted: function(direction) { + this.currentSort = direction; +}, + +canFilter: function() { + return this.filterable; +}, + +getFilterText: function() { + var vals=[]; + for (var i=0; i(.*)<\/span>/i)) + vals.push(RegExp.leftContext); + else + vals.push(v); + } + switch (this.filterOp) { + case 'EQ': return vals[0]; + case 'NE': return 'not: '+vals.join(', '); + case 'LE': return '<= '+vals[0]; + case 'GE': return '>= '+vals[0]; + case 'LIKE': return 'like: '+vals[0]; + case 'NULL': return ''; + case 'NOTNULL': return ''; + } + return '?'; +}, + +getFilterQueryParm: function() { + if (this.filterType == Rico.TableColumn.UNFILTERED) return ''; + var retval='&f['+this.index+'][op]='+this.filterOp; + retval+='&f['+this.index+'][len]='+this.filterValues.length + for (var i=0; i/g,'>'); +}, + +format_number: function(v) { + if (typeof v=='undefined' || v=='' || v==null) + return ' '; + else + return v.formatNumber(this.format); +}, + +format_datetime: function(v) { + if (typeof v=='undefined' || v=='' || v==null) + return ' '; + else { + var d=new Date; + d.setISO8601(v); + return d.formatDate(this.format.dateFmt || 'translateDateTime'); + } +}, + +format_date: function(v) { + if (typeof v=='undefined' || v==null || v=='') + return ' '; + else { + var d=new Date; + if (!d.setISO8601(v)) return v; + return d.formatDate(this.format.dateFmt || 'translateDate'); + } +}, + +fixHeaders: function(prefix, iconsfirst) { + if (this.sortable) { + switch (this.options.headingSort) { + case 'link': + var a=RicoUtil.wrapChildren(this.hdrCellDiv,'ricoSort',undefined,'a') + a.href = "#"; + a.onclick = this.toggleSort.bindAsEventListener(this); + break; + case 'hover': + this.hdrCellDiv.onclick = this.toggleSort.bindAsEventListener(this); + break; + } + } + this.imgFilter = document.createElement('img'); + this.imgFilter.style.display='none'; + this.imgFilter.src=Rico.imgDir+this.options.filterImg; + this.imgFilter.className='ricoLG_HdrIcon'; + this.imgSort = document.createElement('img'); + this.imgSort.style.display='none'; + this.imgSort.className='ricoLG_HdrIcon'; + if (iconsfirst) { + this.hdrCellDiv.insertBefore(this.imgSort,this.hdrCellDiv.firstChild); + this.hdrCellDiv.insertBefore(this.imgFilter,this.hdrCellDiv.firstChild); + } else { + this.hdrCellDiv.appendChild(this.imgFilter); + this.hdrCellDiv.appendChild(this.imgSort); + } +}, + +getValue: function(windowRow) { + return this.liveGrid.buffer.getWindowValue(windowRow,this.index); +}, + +getFormattedValue: function(windowRow) { + return this._format(this.getValue(windowRow)); +}, + +getBufferCell: function(windowRow) { + return this.liveGrid.buffer.getWindowCell(windowRow,this.index); +}, + +setValue: function(windowRow,newval) { + this.liveGrid.buffer.setWindowValue(windowRow,this.index,newval); +}, + +_format: function(v) { + return v; +}, + +_display: function(v,gridCell) { + gridCell.innerHTML=this._format(v); +}, + +displayValue: function(windowRow) { + var bufCell=this.getBufferCell(windowRow); + if (!bufCell) { + this.clearCell(windowRow); + return; + } + var gridCell=this.cell(windowRow); + this._display(bufCell.content,gridCell,windowRow); + var acceptAttr=this.liveGrid.buffer.options.acceptAttr; + for (var k=0; k').replace(/ /g,' '); + }, + + _getdesc: function(v) { + var desc=this._map[v]; + return (typeof desc=='string') ? desc : this._defaultDesc; + }, + + _display: function(v,gridCell,windowRow) { + this._codes[windowRow].value=v; + this._descriptions[windowRow].innerHTML=this._getdesc(v); + } + +} + +Rico.includeLoaded('ricoLiveGrid.js'); diff --git a/NP_TrackBack/trunk/trackback/js/rico/ricoLiveGridAjax.js b/NP_TrackBack/trunk/trackback/js/rico/ricoLiveGridAjax.js new file mode 100644 index 0000000..ab193ff --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/ricoLiveGridAjax.js @@ -0,0 +1,412 @@ +if(typeof Rico=='undefined') throw("LiveGridAjax requires the Rico JavaScript framework"); +if(typeof RicoUtil=='undefined') throw("LiveGridAjax requires the RicoUtil object"); +if(typeof Rico.Buffer=='undefined') throw("LiveGridAjax requires the Rico.Buffer object"); + + +/** + * Data source is a static XML file located on the server + */ +Rico.Buffer.AjaxXML = Class.create(); + +Rico.Buffer.AjaxXML.prototype = { + + initialize: function(url,options,ajaxOptions) { + Object.extend(this, new Rico.Buffer.Base()); + Object.extend(this, new Rico.Buffer.AjaxXMLMethods); + this.dataSource=url; + this.options.bufferTimeout = 20000; // time to wait for ajax response (milliseconds) + this.options.requestParameters = []; + Object.extend(this.options, options || {}); + this.ajaxOptions = { parameters: null, method : 'get' }; + Object.extend(this.ajaxOptions, ajaxOptions || {}); + this.requestCount=0; + this.processingRequest=false; + this.pendingRequest=-1; + } +} + +Rico.Buffer.AjaxXMLMethods = function() {}; + +Rico.Buffer.AjaxXMLMethods.prototype = { + + fetch: function(offset) { + if ( this.isInRange(offset) ) { + Rico.writeDebugMsg("AjaxXML fetch: in buffer"); + this.liveGrid.refreshContents(offset); + return; + } + this.processingRequest=true + Rico.writeDebugMsg("AjaxXML fetch, offset="+offset); + this.liveGrid.showMsg("Waiting for data..."); + this.timeoutHandler = setTimeout( this.handleTimedOut.bind(this), this.options.bufferTimeout); + this.sendAjaxRequest(offset,0,this.ajaxUpdate.bind(this,offset)); + }, + +/** + * Server did not respond in time... assume that there could have been + * an error, and allow requests to be processed again. + */ + handleTimedOut: function() { + Rico.writeDebugMsg("Request Timed Out"); + this.liveGrid.showMsg("Request for data timed out!"); + }, + + formQueryHash: function(startPos,fetchSize) { + if (typeof fetchSize!='number') fetchSize=this.totalRows; + var queryHash= { + id: this.liveGrid.tableId, + page_size: fetchSize, + offset: startPos + }; + if (!this.foundRowCount) queryHash['get_total']='true'; + if (this.options.requestParameters) { + for ( var i=0; i < this.options.requestParameters.length; i++ ) { + var anArg = this.options.requestParameters[i]; + if ( anArg.name != undefined && anArg.value != undefined ) { + queryHash[anArg.name]=anArg.value; + } else { + var ePos = anArg.indexOf('='); + var argName = anArg.substring( 0, ePos ); + var argValue = anArg.substring( ePos + 1 ); + queryHash[argName]=argValue; + } + } + } + + // sort + Object.extend(queryHash,this.sortParm); + + // filters + for (n=0; n=0) { + var offset=this.pendingRequest; + Rico.writeDebugMsg("ajaxUpdate: found pending request for offset="+offset); + this.pendingRequest=-1; + this.fetch(offset); + } + }, + + CheckRowCount: function(ajaxResponse,offset) { + //try { + Rico.writeDebugMsg("CheckRowCount, size="+this.size+' rcv cnt type='+typeof(this.rowcntContent)); + if (this.rcvdRowCount==true) { + Rico.writeDebugMsg("found row cnt: "+this.rowcntContent); + var eofrow=parseInt(this.rowcntContent); + var lastTotalRows=this.totalRows; + if (!isNaN(eofrow) && eofrow!=lastTotalRows) { + this.setTotalRows(eofrow); + var newpos=Math.min(this.liveGrid.topOfLastPage(),offset); + Rico.writeDebugMsg("CheckRowCount: new rowcnt="+eofrow+" newpos="+newpos); + if (lastTotalRows==0 && this.liveGrid.sizeTo=='data') + this.liveGrid.adjustPageSize(); + //this.lastRowPos=-1; + this.liveGrid.scrollToRow(newpos); + if ( this.isInRange(newpos) ) { + this.liveGrid.refreshContents(newpos); + } else { + this.fetch(newpos); + } + return; + } + } else { + var lastbufrow=offset+this.rcvdRows; + if (lastbufrow>this.totalRows) { + var newcnt=lastbufrow; + Rico.writeDebugMsg("extending totrows to "+newcnt); + this.setTotalRows(newcnt); + } + } + var newpos=this.liveGrid.pixeltorow(this.liveGrid.scrollDiv.scrollTop); + Rico.writeDebugMsg("CheckRowCount: newpos="+newpos); + this.liveGrid.refreshContents(newpos); + //} + //catch(err) { + // alert("Error in CheckRowCount:"+err.message); + //} + }, + + updateBuffer: function(ajaxResponse, start) { + Rico.writeDebugMsg("updateBuffer: "+start); + this.rcvdRows = 0; + var newRows = this.loadRows(ajaxResponse); + if (newRows==null) return; + this.rcvdRows = newRows.length; + Rico.writeDebugMsg("updateBuffer: # of rows="+this.rcvdRows); + if (this.rows.length == 0) { // initial load + this.rows = newRows; + this.startPos = start; + } else if (start > this.startPos) { //appending + if (this.startPos + this.rows.length < start) { + this.rows = newRows; + this.startPos = start;// + } else { + this.rows = this.rows.concat( newRows.slice(0, newRows.length)); + if (this.rows.length > this.maxBufferSize) { + var fullSize = this.rows.length; + this.rows = this.rows.slice(this.rows.length - this.maxBufferSize, this.rows.length) + this.startPos = this.startPos + (fullSize - this.rows.length); + } + } + } else { //prepending + if (start + newRows.length < this.startPos) { + this.rows = newRows; + } else { + this.rows = newRows.slice(0, this.startPos).concat(this.rows); + if (this.maxBufferSize && this.rows.length > this.maxBufferSize) + this.rows = this.rows.slice(0, this.maxBufferSize) + } + this.startPos = start; + } + this.size = this.rows.length; + }, + + loadRows: function(ajaxResponse) { + Rico.writeDebugMsg("loadRows"); + this.rcvdRowCount = false; + var debugtags = ajaxResponse.getElementsByTagName('debug'); + for (var i=0; i 0) { + var msg=RicoUtil.getContentAsString(error[0],this.options.isEncoded); + alert("Data provider returned an error:\n"+msg); + Rico.writeDebugMsg("Data provider returned an error:\n"+msg); + return null; + } + var rowsElement = ajaxResponse.getElementsByTagName('rows')[0]; + var rowcnttags = ajaxResponse.getElementsByTagName('rowcount'); + if (rowcnttags && rowcnttags.length==1) { + this.rowcntContent = RicoUtil.getContentAsString(rowcnttags[0],this.options.isEncoded); + this.rcvdRowCount = true; + this.foundRowCount = true; + Rico.writeDebugMsg("loadRows, found RowCount="+this.rowcntContent); + } + this.updateUI = rowsElement.getAttribute("update_ui") == "true"; + this.rcvdOffset = rowsElement.getAttribute("offset"); + Rico.writeDebugMsg("loadRows, rcvdOffset="+this.rcvdOffset); + return this.dom2jstable(rowsElement); + } + +}; + + + +Rico.Buffer.AjaxSQL = Class.create(); + +Rico.Buffer.AjaxSQL.prototype = { + + initialize: function(url,options,ajaxOptions) { + Object.extend(this, new Rico.Buffer.AjaxXML()); + Object.extend(this, new Rico.Buffer.AjaxSQLMethods()); + this.dataSource=url; + this.options.canFilter=true; + this.options.largeBufferSize = 7.0; // 7 pages + this.options.nearLimitFactor = 1.0; // 1 page + Object.extend(this.options, options || {}); + Object.extend(this.ajaxOptions, ajaxOptions || {}); + this.sortParm={}; + } +} + +Rico.Buffer.AjaxSQLMethods = function() {}; + +Rico.Buffer.AjaxSQLMethods.prototype = { + + registerGrid: function(liveGrid) { + this.liveGrid = liveGrid; + this.sessionExpired=false; + this.timerMsg=$(liveGrid.tableId+'_timer'); + if (this.options.TimeOut && this.timerMsg) { + if (!this.timerMsg.title) this.timerMsg.title=RicoTranslate.getPhrase("minutes before your session expires") + this.restartSessionTimer(); + } + }, + + setBufferSize: function(pageSize) { + this.maxFetchSize = Math.max(50,parseInt(this.options.largeBufferSize * pageSize)); + this.nearLimit = parseInt(this.options.nearLimitFactor * pageSize); + this.maxBufferSize = this.maxFetchSize * 3; + }, + + restartSessionTimer: function() { + if (this.sessionExpired==true) return; + this.timeRemaining=this.options.TimeOut+1; + if (this.sessionTimer) clearTimeout(this.sessionTimer); + this.updateSessionTimer(); + }, + + updateSessionTimer: function() { + if (--this.timeRemaining<=0) { + this.displaySessionTimer(RicoTranslate.getPhrase("EXPIRED")); + this.timerMsg.style.backgroundColor="red"; + this.sessionExpired=true; + } else { + this.displaySessionTimer(this.timeRemaining); + this.sessionTimer=setTimeout(this.updateSessionTimer.bind(this),60000); + } + }, + + displaySessionTimer: function(msg) { + this.timerMsg.innerHTML=' '+msg+' '; + }, + + refresh: function() { + this.fetch(this.lastOffset); + }, + + /** + * Fetch data from database. + * @param offset position (row) within the dataset (-1=clear existing buffer before issuing request) + */ + fetch: function(offset) { + Rico.writeDebugMsg("AjaxSQL fetch, offset="+offset+' lastOffset='+this.lastOffset); + if (this.processingRequest) { + Rico.writeDebugMsg("AjaxSQL fetch: queue request"); + this.pendingRequest=offset; + return; + } + if (offset < 0) { + this.clear(); + this.setTotalRows(0); + this.foundRowCount = false; + offset=0; + } + var lastOffset = this.lastOffset; + this.lastOffset = offset; + var inRange=this.isInRange(offset); + if (inRange) { + Rico.writeDebugMsg("AjaxSQL fetch: in buffer"); + this.liveGrid.refreshContents(offset); + if (offset > lastOffset) { + if (offset+this.liveGrid.pageSize < this.endPos()-this.nearLimit) return; + if (this.endPos()==this.totalRows && this.foundRowCount) return; + } else if (offset < lastOffset) { + if (offset > this.startPos+this.nearLimit) return; + if (this.startPos==0) return; + } else return; + } + if (offset >= this.totalRows && this.foundRowCount) return; + + this.processingRequest=true + Rico.writeDebugMsg("AjaxSQL fetch, processing offset="+offset); + var bufferStartPos = this.getFetchOffset(offset); + var fetchSize = this.getFetchSize(bufferStartPos); + var partialLoaded = false; + + if (!inRange) this.liveGrid.showMsg("Waiting for data..."); + this.timeoutHandler = setTimeout( this.handleTimedOut.bind(this), this.options.bufferTimeout); + this.sendAjaxRequest(bufferStartPos,fetchSize,this.ajaxUpdate.bind(this,bufferStartPos)); + }, + + getFetchSize: function(adjustedOffset) { + var adjustedSize = 0; + if (adjustedOffset >= this.startPos) { //appending + var endFetchOffset = this.maxFetchSize + adjustedOffset; + adjustedSize = endFetchOffset - adjustedOffset; + if(adjustedOffset == 0 && adjustedSize < this.maxFetchSize) + adjustedSize = this.maxFetchSize; + Rico.writeDebugMsg("getFetchSize/append, adjustedSize="+adjustedSize+" adjustedOffset="+adjustedOffset+' endFetchOffset='+endFetchOffset); + } else { //prepending + adjustedSize = Math.min(this.startPos - adjustedOffset,this.maxFetchSize); + } + return adjustedSize; + }, + + getFetchOffset: function(offset) { + var adjustedOffset = offset; + if (offset > this.startPos) + adjustedOffset = Math.max(offset, this.endPos()); //appending + else if (offset + this.maxFetchSize >= this.startPos) + adjustedOffset = Math.max(this.startPos - this.maxFetchSize, 0); //prepending + return adjustedOffset; + }, + + sortBuffer: function(colnum,sortdir,coltype) { + this.sortParm={}; + if (this.options.sortParmFmt && this.options.sortParmFmt=='displayName') { + this.sortParm['sort_col']=this.liveGrid.columns[colnum].displayName.toLowerCase(); + this.sortParm['sort_dir']=sortdir; + }else{ + this.sortParm['s'+colnum]=sortdir; + } + this.clear(); + }, + + exportAllRows: function(populate,finish) { + this.exportPopulate=populate; + this.exportFinish=finish; + this.liveGrid.showMsg("Waiting for data..."); + this.sendExportRequest(0); + }, + +/** + * Make ajax request for print window data + */ + sendExportRequest: function(offset) { + this.timeoutHandler = setTimeout(this.exportTimedOut.bind(this), this.options.bufferTimeout); + this.sendAjaxRequest(offset,200,this.exportAppend.bind(this,offset)); + }, + + exportTimedOut: function() { + Rico.writeDebugMsg("Print Request Timed Out"); + this.liveGrid.showMsg("Request for data timed out!"); + this.exportFinish(); + }, + + exportAppend: function(startPos,request) { + this.clearTimer(); + var response = request.responseXML.getElementsByTagName("ajax-response"); + if (response == null || response.length != 1) return; + var rowsElement = response[0].getElementsByTagName('rows')[0]; + var rows=this.dom2jstable(rowsElement); + this.exportPopulate(rows); + if (rows.length==0) + this.exportFinish(); + else + this.sendExportRequest(startPos+rows.length); + } + +}; + +Rico.includeLoaded('ricoLiveGridAjax.js'); diff --git a/NP_TrackBack/trunk/trackback/js/rico/ricoLiveGridForms.js b/NP_TrackBack/trunk/trackback/js/rico/ricoLiveGridForms.js new file mode 100644 index 0000000..3e60c45 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/ricoLiveGridForms.js @@ -0,0 +1,830 @@ +if(typeof Rico=='undefined') throw("LiveGridForms requires the Rico JavaScript framework"); +if(typeof RicoUtil=='undefined') throw("LiveGridForms requires the RicoUtil object"); +if(typeof RicoTranslate=='undefined') throw("LiveGridForms requires the RicoTranslate object"); + + +Rico.TableEdit = Class.create(); + +Rico.TableEdit.prototype = { + + initialize: function(liveGrid) { + Rico.writeDebugMsg('Rico.TableEdit initialize: '+liveGrid.tableId); + this.grid=liveGrid; + this.options = { + maxDisplayLen : 20, // max displayed text field length + panelHeight : 200, // size of tabbed panels + panelWidth : 500, + hoverClass : 'tabHover', + selectedClass : 'tabSelected', + compact : false, // compact corners + RecordName : 'record', + readOnlyColor : '#AAA', // read-only fields displayed using this color + showSaveMsg : 'errors' // disposition of database update responses (full - show full response, errors - show full response for errors and short response otherwise) + } + Object.extend(this.options, liveGrid.options); + this.menu=liveGrid.menu; + this.menu.options.dataMenuHandler=this.editMenu.bind(this); + this.menu.ignoreClicks(); + RicoEditControls.atLoad(); + this.createEditDiv(); + this.saveMsg=$(liveGrid.tableId+'_savemsg'); + Event.observe(document,"click", this.clearSaveMsg.bindAsEventListener(this), false); + this.TEerror=false; + this.extraMenuItems=new Array(); + this.responseHandler=this.processResponse.bind(this); + }, + + createEditDiv: function() { + + // create editDiv (form) + + this.requestCount=1; + this.editDiv = this.grid.createDiv('edit',document.body); + this.editDiv.style.display='none'; + if (this.options.canEdit || this.options.canAdd) { + this.startForm(); + this.createForm(this.form); + } else { + var button=this.createButton("Close"); + Event.observe(button,"click", this.cancelEdit.bindAsEventListener(this), false); + this.createForm(this.editDiv); + } + this.editDivCreated=true; + this.formPopup=new Rico.Popup({ignoreClicks:true},this.editDiv); + + // create responseDialog + + this.responseDialog = this.grid.createDiv('editResponse',document.body); + this.responseDialog.style.display='none'; + + var button = document.createElement('button'); + button.appendChild(document.createTextNode('OK')); + button.onclick=this.ackResponse.bindAsEventListener(this); + this.responseDialog.appendChild(button); + + this.responseDiv = this.grid.createDiv('editResponseText',this.responseDialog); + + if (this.panelGroup) { + Rico.writeDebugMsg("createEditDiv complete, requestCount="+this.requestCount); + setTimeout(this.initPanelGroup.bind(this),50); + } + }, + + initPanelGroup: function() { + this.requestCount--; + Rico.writeDebugMsg("initPanelGroup: "+this.requestCount); + if (this.requestCount>0) return; + var wi=parseInt(this.options.panelWidth); + this.form.style.width=(wi+10)+'px'; + if (Prototype.Browser.WebKit) this.editDiv.style.display='block'; // this causes display to flash briefly + this.options.bgColor = Rico.Color.createColorFromBackground(this.form); + this.editDiv.style.display='none'; + this.options.panelHdrWidth=(Math.floor(wi / this.options.panels.length)-4)+'px'; + this.Accordion=new Rico.TabbedPanel(this.panelHdr.findAll(this.notEmpty), this.panelContent.findAll(this.notEmpty), this.options); + }, + + notEmpty: function(v) { + return typeof(v)!='undefined'; + }, + + startForm: function() { + this.form = document.createElement('form'); + this.form.onsubmit=function() {return false;}; + this.editDiv.appendChild(this.form); + + var tab = document.createElement('table'); + var row = tab.insertRow(-1); + var cell = row.insertCell(-1); + var button=cell.appendChild(this.createButton("Save \t"+this.options.RecordName)); + Event.observe(button,"click", this.TESubmit.bindAsEventListener(this), false); + var cell = row.insertCell(-1); + var button=cell.appendChild(this.createButton("Cancel")); + Event.observe(button,"click", this.cancelEdit.bindAsEventListener(this), false); + this.form.appendChild(tab); + + // hidden fields + this.hiddenFields = document.createElement('div'); + this.hiddenFields.style.display='none'; + this.action = this.appendHiddenField(this.grid.tableId+'__action',''); + for (var i=0; i"+buttonLabel.substr(1); + button.accessKey=buttonLabel.charAt(0); + return button; + }, + + createPanel: function(i) { + var hasFields=false; + for (var j=0; j=0; i--) + if (this.createPanel(i)) + tables[i]=this.createFormTable(this.panelContent[i],'tabContent'); + } else { + for (var i=0; i 0) { + Rico.writeDebugMsg("Data provider returned an error:\n"+RicoUtil.getContentAsString(error[0],this.grid.buffer.isEncoded)); + alert(RicoTranslate.getPhrase("The request returned an error")+":\n"+RicoUtil.getContentAsString(error[0],this.grid.buffer.isEncoded)); + return null; + } + response=response.getElementsByTagName('response')[0]; + var id = response.getAttribute("id").slice(0,-8); + var rowsElement = response.getElementsByTagName('rows')[0]; + var rows = this.grid.buffer.dom2jstable(rowsElement); + var elem=$(id); + //alert('selectValuesUpdate:'+id+' '+elem.tagName); + Rico.writeDebugMsg("selectValuesUpdate: id="+id+' rows='+rows.length); + for (var i=0; i0) { + var c0=rows[i][0].content; + var c1=(rows[i].length>1) ? rows[i][1].content : c0; + this.addSelectOption(elem,c0,c1,i); + } + } + if ($('textnew__'+id)) + this.addSelectOption(elem,this.options.TableSelectNew,"(new value)"); + if (this.panelGroup) + setTimeout(this.initPanelGroup.bind(this),50); + }, + + addSelectOption: function(elem,value,text,idx) { + switch (elem.tagName.toLowerCase()) { + case 'div': + var opt=RicoUtil.createFormField(elem,'input','radio',elem.id+'_'+idx,elem.id); + opt.value=value; + var lbl=document.createElement('label'); + lbl.innerHTML=text; + lbl.htmlFor=opt.id; + elem.appendChild(lbl); + break; + case 'select': + var opt=document.createElement('option'); + opt.value=value; + opt.text=text; + //elem.options.add(opt); + if (Prototype.Browser.IE) + elem.add(opt); + else + elem.add(opt,null); + break; + } + }, + + clearSaveMsg: function() { + if (this.saveMsg) this.saveMsg.innerHTML=""; + }, + + addMenuItem: function(menuText,menuAction,enabled) { + this.extraMenuItems.push({menuText:menuText,menuAction:menuAction,enabled:enabled}); + }, + + editMenu: function(grid,r,c,onBlankRow) { + this.clearSaveMsg(); + if (this.grid.buffer.sessionExpired==true || this.grid.buffer.startPos<0) return; + this.rowIdx=r; + var elemTitle=$('pageTitle'); + var pageTitle=elemTitle ? elemTitle.innerHTML : document.title; + this.menu.addMenuHeading(pageTitle); + for (var i=0; i(.*)<\/span>/i)) + return [RegExp.$2,RegExp.leftContext]; + else + return [value,value]; + }, + + // use with care: Prototype 1.5 does not include disabled fields in the post-back + setReadOnly: function(addFlag) { + for (var i=0; i=0; i--) { + if (ch[i].nodeType==1 && ch[i].nodeName!='P' && ch[i].nodeName!='DIV' && ch[i].nodeName!='BR') + this.responseDiv.removeChild(ch[i]); + } + var responseText=this.responseDiv.innerHTML; + if (responseText.toLowerCase().indexOf('error')==-1 && this.options.showSaveMsg!='full') { + this.hideResponse(''); + this.grid.resetContents(); + this.grid.buffer.foundRowCount = false; + this.grid.buffer.fetch(this.grid.lastRowPos || 0); + if (this.saveMsg) this.saveMsg.innerHTML=' '+responseText.stripTags()+' '; + } + this.processCallback(this.options.onSubmitResponse); + }, + + processCallback: function(callback) { + switch (typeof callback) { + case 'string': eval(callback); break; + case 'function': callback(); break; + } + }, + + // called when ok pressed on error response message + ackResponse: function() { + this.hideResponse(''); + this.grid.highlightEnabled=true; + }, + + editRecord: function(e) { + this.grid.highlightEnabled=false; + this.menu.hidemenu(); + this.hideResponse('Saving...'); + this.grid.outerDiv.style.cursor = 'auto'; + this.action.value="upd"; + for (var i=0; i winWi) + this.editDiv.style.left=(winWi-editWi)+'px'; + else + this.editDiv.style.left=(odOffset[0]+1)+'px'; + + // set top position + var scrTop=RicoUtil.docScrollTop(); + var editHt=this.editDiv.offsetHeight; + var newTop=odOffset[1]+this.grid.hdrHt+scrTop; + var bottom=RicoUtil.windowHeight()+scrTop; + if (row >= 0) { + newTop+=(row+1)*this.grid.rowHeight; + if (newTop+editHt>bottom) newTop-=(editHt+this.grid.rowHeight); + } else { + if (newTop+editHt>bottom) newTop=bottom-editHt; + } + this.processCallback(this.options.formOpen); + this.formPopup.openPopup(null,Math.max(newTop,scrTop)); + this.editDiv.style.visibility='visible'; + if (this.initialized) return; + for (i = 0; i < this.grid.columns.length; i++) { + spec=this.grid.columns[i].format; + if (!spec || !spec.EntryType || !spec.FieldName) continue; + switch (spec.EntryType) { + case 'tinyMCE': + if (typeof tinyMCE!='undefined') tinyMCE.execCommand('mceAddControl', true, spec.FieldName); + break; + } + } + this.formPopup.openPopup(); // tinyMCE may have changed the dimensions of the form + this.initialized=true; + }, + + makeFormInvisible: function() { + this.editDiv.style.visibility='hidden'; + this.formPopup.closePopup(); + this.processCallback(this.options.formClose); + }, + + getConfirmDesc: function(rowIdx) { + var desc=this.grid.columns[this.options.ConfirmDeleteCol].cell(rowIdx).innerHTML; + desc=this.getLookupValue(desc)[1]; + return desc.stripTags(); + }, + + deleteRecord: function() { + this.menu.hidemenu(); + var desc; + if (this.options.ConfirmDeleteCol < 0) { + desc=RicoTranslate.getPhrase("this "+this.options.RecordName); + } else { + desc=this.getConfirmDesc(this.rowIdx); + if (desc.length>50) desc=desc.substring(0,50)+'...'; + desc='\"' + desc + '\"' + } + if (!this.options.ConfirmDelete.valueOf || confirm(RicoTranslate.getPhrase("Are you sure you want to delete ") + desc + " ?")) { + this.hideResponse('Deleting...'); + this.showResponse(); + var parms=this.action.name+"=del"+this.getKey(); + //alert(parms); + new Ajax.Updater(this.responseDiv, window.location.pathname, {parameters:parms,onComplete:this.processResponse.bind(this)}); + } + this.menu.cancelmenu(); + }, + + getKey: function() { + var key=''; + for (var i=0; i= totrows; + var column=this.liveGrid.columns[c]; + if (this.options.dataMenuHandler) { + var showMenu=this.options.dataMenuHandler(this.liveGrid,r,c,onBlankRow); + if (!showMenu) return false; + } + + // menu items for sorting + if (column.sortable && totrows>0) { + this.sortmenu.clearMenu(); + this.addSubMenuItem(RicoTranslate.getPhrase("Sort by")+": "+column.displayName, this.sortmenu, false); + this.sortmenu.addMenuItem("Ascending", column.sortAsc.bind(column), true); + this.sortmenu.addMenuItem("Descending", column.sortDesc.bind(column), true); + } + + // menu items for filtering + if (column.canFilter() && (!onBlankRow || column.filterType == Rico.TableColumn.USERFILTER)) { + this.filtermenu.clearMenu(); + this.addSubMenuItem(RicoTranslate.getPhrase("Filter by")+": "+column.displayName, this.filtermenu, false); + column.userFilter=column.getValue(r); + if (column.filterType == Rico.TableColumn.USERFILTER) { + this.filtermenu.addMenuItem("Remove filter", column.setUnfiltered.bind(column), true); + this.filtermenu.addMenuItem("Refresh", this.liveGrid.filterHandler.bind(this.liveGrid), true); + if (column.filterOp=='LIKE') + this.filtermenu.addMenuItem("Change keyword...", column.setFilterKW.bind(column), true); + if (column.filterOp=='NE' && !onBlankRow) + this.filtermenu.addMenuItem("Exclude this value also", column.addFilterNE.bind(column), true); + } else if (!onBlankRow) { + this.filtermenu.addMenuItem("Include only this value", column.setFilterEQ.bind(column), true); + this.filtermenu.addMenuItem("Greater than or equal to this value", column.setFilterGE.bind(column), column.userFilter!=''); + this.filtermenu.addMenuItem("Less than or equal to this value", column.setFilterLE.bind(column), column.userFilter!=''); + if (column.isText) + this.filtermenu.addMenuItem("Contains keyword...", column.setFilterKW.bind(column), true); + this.filtermenu.addMenuItem("Exclude this value", column.setFilterNE.bind(column), true); + } + if (this.liveGrid.filterCount() > 0) + this.filtermenu.addMenuItem("Remove all filters", this.liveGrid.clearFilters.bind(this.liveGrid), true); + } + + // menu items for Print/Export + if (this.liveGrid.options.maxPrint > 0 && totrows>0) { + this.exportmenu.clearMenu(); + this.addSubMenuItem('Print\t/Export',this.exportmenu); + this.exportmenu.addMenuItem("Visible rows to web page", this.liveGrid.printVisible.bind(this.liveGrid,'plain'), true); + this.exportmenu.addMenuItem("All rows to web page", this.liveGrid.printAll.bind(this.liveGrid,'plain'), this.liveGrid.buffer.totalRows <= this.liveGrid.options.maxPrint); + if (Prototype.Browser.IE) { + this.exportmenu.addMenuBreak(); + this.exportmenu.addMenuItem("Visible rows to spreadsheet", this.liveGrid.printVisible.bind(this.liveGrid,'owc'), true); + this.exportmenu.addMenuItem("All rows to spreadsheet", this.liveGrid.printAll.bind(this.liveGrid,'owc'), this.liveGrid.buffer.totalRows <= this.liveGrid.options.maxPrint); + } + } + + // menu items for hide/unhide + var hiddenCols=this.liveGrid.listInvisible(); + for (var showableCnt=0,x=0; x 0 || column.canHideShow()) { + this.hideshowmenu.clearMenu(); + this.addSubMenuItem('Hide\t/Show',this.hideshowmenu); + var visibleCnt=this.liveGrid.columns.length-hiddenCols.length; + var enabled=(visibleCnt>1 && column.visible && column.canHideShow()); + this.hideshowmenu.addMenuItem(RicoTranslate.getPhrase('Hide')+': '+column.displayName, column.hideColumn.bind(column), enabled); + for (var cnt=0,x=0; x 1) + this.hideshowmenu.addMenuItem(RicoTranslate.getPhrase('Show All'), this.liveGrid.showAll.bind(this.liveGrid)); + } + return true; +} + +} + +Rico.includeLoaded('ricoLiveGridMenu.js'); diff --git a/NP_TrackBack/trunk/trackback/js/rico/ricoMenu.js b/NP_TrackBack/trunk/trackback/js/rico/ricoMenu.js new file mode 100644 index 0000000..544d3e8 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/ricoMenu.js @@ -0,0 +1,197 @@ +Rico.Menu = Class.create(); + +Rico.Menu.prototype = { + + initialize: function(options) { + Object.extend(this, new Rico.Popup()); + Object.extend(this.options, { + width : "15em", + margin : 6 // account for shadow + }); + if (typeof options=='string') + this.options.width=options; + else + Object.extend(this.options, options || {}); + this.hideFunc=null; + this.highlightElem=null; + new Image().src = Rico.imgDir+'left.gif'; + new Image().src = Rico.imgDir+'right.gif'; + }, + + createDiv: function(parentNode) { + if (this.div) return; + this.div = document.createElement('div'); + this.div.className = Prototype.Browser.WebKit ? 'ricoMenuSafari' : 'ricoMenu'; + this.div.style.position="absolute"; + this.div.style.width=this.options.width; + if (!parentNode) parentNode = document.getElementsByTagName("body")[0]; + parentNode.appendChild(this.div); + this.width=this.div.offsetWidth + this.setDiv(this.div,this.cancelmenu.bindAsEventListener(this)); + this.direction=Element.getStyle(this.div,'direction') || 'ltr'; + this.direction=this.direction.toLowerCase(); // ltr or rtl + this.hidemenu(); + this.itemCount=0; + }, + + showmenu: function(e,hideFunc){ + Event.stop(e); + this.hideFunc=hideFunc; + if (this.div.childNodes.length==0) { + this.cancelmenu(); + return false; + } + this.openmenu(e.clientX,e.clientY,0,0); + }, + + openmenu: function(x,y,clickItemWi,clickItemHt) { + var newLeft=RicoUtil.docScrollLeft()+x; + //window.status='openmenu: newLeft='+newLeft+' width='+this.width+' windowWi='+RicoUtil.windowWidth(); + if (this.direction == 'rtl') { + if (newLeft > this.width+clickItemWi) newLeft-=this.width+clickItemWi; + } else { + if (x+this.width+this.options.margin > RicoUtil.windowWidth()) newLeft-=this.width+clickItemWi; + } + var newTop=RicoUtil.docScrollTop()+y; + this.div.style.visibility="hidden"; + this.div.style.display="block"; + var contentHt=this.div.offsetHeight; + if (y+contentHt+this.options.margin > RicoUtil.windowHeight()) + newTop=Math.max(newTop-contentHt+clickItemHt,0); + this.openPopup(newLeft,newTop); + this.div.style.visibility ="visible"; + return false; + }, + + clearMenu: function() { + this.div.innerHTML=""; + this.defaultAction=null; + this.itemCount=0; + }, + + addMenuHeading: function(hdg,translate) { + var el=document.createElement('div') + el.innerHTML =(translate==null || translate==true) ? RicoTranslate.getPhrase(hdg) : hdg; + el.className='ricoMenuHeading'; + this.div.appendChild(el); + }, + + addMenuBreak: function() { + var brk=document.createElement('div'); + brk.className="ricoMenuBreak"; + this.div.appendChild(brk); + }, + + addSubMenuItem: function(menutext, submenu, translate) { + var dir=this.direction=='rtl' ? 'left' : 'right'; + var a=this.addMenuItem(menutext,null,true,null,translate); + a.className='ricoSubMenu'; + a.style.backgroundImage='url('+Rico.imgDir+dir+'.gif)'; + a.style.backgroundRepeat='no-repeat'; + a.style.backgroundPosition=dir; + a.onmouseover=this.showSubMenu.bind(this,a,submenu); + a.onmouseout=this.subMenuOut.bindAsEventListener(this); + }, + + showSubMenu: function(a,submenu) { + if (this.openSubMenu) this.hideSubMenu(); + this.openSubMenu=submenu; + this.openMenuAnchor=a; + var pos=Position.page(a); + if (a.className=='ricoSubMenu') a.className='ricoSubMenuOpen'; + submenu.openmenu(pos[0]+a.offsetWidth, pos[1], a.offsetWidth-2, a.offsetHeight+2); + }, + + subMenuOut: function(e) { + if (!this.openSubMenu) return; + Event.stop(e); + var elem=Event.element(e); + var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement; + try { + while (reltg != null && reltg != this.openSubMenu.div) + reltg=reltg.parentNode; + } catch(err) {} + if (reltg == this.openSubMenu.div) return; + this.hideSubMenu(); + }, + + hideSubMenu: function() { + if (this.openMenuAnchor) { + this.openMenuAnchor.className='ricoSubMenu'; + this.openMenuAnchor=null; + } + if (this.openSubMenu) { + this.openSubMenu.hidemenu(); + this.openSubMenu=null; + } + }, + + addMenuItem: function(menutext,action,enabled,title,translate,target) { + this.itemCount++; + if (translate==null) translate=true; + var a = document.createElement(typeof action=='string' ? 'a' : 'div'); + if ( arguments.length < 3 || enabled ) { + switch (typeof action) { + case 'function': + a.onclick = action; + break; + case 'string' : + a.href = action; + if (target) a.target = target; + break + } + a.className = 'enabled'; + if (this.defaultAction==null) this.defaultAction=action; + } else { + a.disabled = true; + a.className = 'disabled'; + } + a.innerHTML = translate ? RicoTranslate.getPhrase(menutext) : menutext; + if (typeof title=='string') + a.title = translate ? RicoTranslate.getPhrase(title) : title; + a=this.div.appendChild(a); + Event.observe(a,"mouseover", this.mouseOver.bindAsEventListener(this)); + Event.observe(a,"mouseout", this.mouseOut.bindAsEventListener(this)); + return a; + }, + + mouseOver: function(e) { + if (this.highlightElem && this.highlightElem.className=='enabled-hover') { + // required for Safari + this.highlightElem.className='enabled'; + this.highlightElem=null; + } + var elem=Event.element(e); + if (this.openMenuAnchor && this.openMenuAnchor!=elem) + this.hideSubMenu(); + if (elem.className=='enabled') { + elem.className='enabled-hover'; + this.highlightElem=elem; + } + }, + + mouseOut: function(e) { + var elem=Event.element(e); + if (elem.className=='enabled-hover') elem.className='enabled'; + if (this.highlightElem==elem) this.highlightElem=null; + }, + + isVisible: function() { + return this.div && Element.visible(this.div); + }, + + cancelmenu: function() { + if (this.hideFunc) this.hideFunc(); + this.hideFunc=null; + this.hidemenu(); + }, + + hidemenu: function() { + if (!this.div) return; + if (this.openSubMenu) this.openSubMenu.hidemenu(); + this.closePopup(); + } + +}; + +Rico.includeLoaded('ricoMenu.js'); diff --git a/NP_TrackBack/trunk/trackback/js/rico/ricoSheet.js b/NP_TrackBack/trunk/trackback/js/rico/ricoSheet.js new file mode 100644 index 0000000..97faef6 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/ricoSheet.js @@ -0,0 +1,1577 @@ +Object.extend(Rico.SimpleGrid.prototype, { + +initSheet: function() { + this.highlightDiv=[]; + for (var i=0; i<4; i++) { + this.highlightDiv[i] = this.createDiv("highlight",this.scrollDiv); + this.highlightDiv[i].style.display="none"; + this.highlightDiv[i].id+=i; + this.highlightDiv[i].style[i % 2==0 ? 'height' : 'width']="0px"; + } + for (var c=1; c s.r2) { + this.HideSelection(); + return; + } + var top1=this.columns[s.c1].cell(s.r1).offsetTop; + var cell2=this.columns[s.c1].cell(s.r2); + var bottom2=cell2.offsetTop+cell2.offsetHeight; + var left1=this.columns[s.c1].dataCell.offsetLeft; + var left2=this.columns[s.c2].dataCell.offsetLeft; + var right2=left2+this.columns[s.c2].dataCell.offsetWidth; + //window.status='updateSelectOutline: '+s.r1+' '+s.r2+' top='+top1+' bot='+bottom2; + this.highlightDiv[0].style.top=this.highlightDiv[3].style.top=this.highlightDiv[1].style.top=(top1-3) + 'px'; + this.highlightDiv[2].style.top=(bottom2-2)+'px'; + this.highlightDiv[3].style.left=(left1-2)+'px'; + this.highlightDiv[0].style.left=this.highlightDiv[2].style.left=(left1-1)+'px'; + this.highlightDiv[1].style.left=(right2-1)+'px'; + this.highlightDiv[0].style.width=this.highlightDiv[2].style.width=(right2-left1-1) + 'px'; + this.highlightDiv[1].style.height=this.highlightDiv[3].style.height=(bottom2-top1) + 'px'; + for (var i=0; i<4; i++) + this.highlightDiv[i].style.display=''; +}, + +isSelected: function(r,c) { + var s=this.getSelection(); + return s ? (s.r1 <= r) && (r <= s.r2) && (s.c1 <= c) && (c <= s.c2) : false; +}, + +HideSelection: function(cellList) { + for (var i=0; i<4; i++) + this.highlightDiv[i].style.display='none'; +}, + +ShowSelection: function() { + this.updateSelectOutline(); +}, + +/* + * @param what valid values are: null, 'all', 'formats', 'formulas', 'values' + */ +clearSelection: function() { + var s=this.getSelection(); + if (!s) return; + var args=$A(arguments); + var what=args.shift(); + if (typeof what=='object') what=args.shift(); // in case first arg is an event object + var v=(!what || what=='all') ? 1 : 0; + var whatobj={formats:v,formulas:v,values:v}; + if (typeof what=='string') whatobj[what]=1; + if (whatobj.values) whatobj.formulas=1; + for (var r=s.r1; r<=s.r2; r++) { + for (var c=s.c1; c<=s.c2; c++) { + var gridcell=this.columns[c].cell(r); + if (whatobj.formats) { + gridcell.style.cssText=''; + gridcell.RicoFormat={}; + } + if (whatobj.formulas) gridcell.RicoFormula=null; + if (whatobj.values) gridcell.RicoValue=null; + this.formatCell(gridcell); + } + } +}, + +selectCellRC: function(r,c,adjFlag) { + if (r < 0 || r >= this.columns[0].numRows()) return; + this.HideSelection(); + if (adjFlag) { + if (this.SelectIdxStart.tabIdx == this.columns[c].tabIdx) + this.SelectIdxEnd={row:r, column:c, tabIdx:this.columns[c].tabIdx}; + } else { + this.SelectIdxStart=this.SelectIdxEnd={row:r, column:c, tabIdx:this.columns[c].tabIdx}; + this.columns[c].cell(r).focus(); // causes IE to scroll cell into view (but not FF) + } + this.ShowSelection(); +}, + +moveSelection: function(dr,dc,adjFlag,e) { + var selIdx=adjFlag ? this.SelectIdxEnd : this.SelectIdxStart; + var newr=selIdx.row+dr; + var newc=selIdx.column+dc; + if (newr>=0 && newr=1 && newcs.c1) clipstr+="\t"; + clipstr+=this.columns[c].cell(r).RicoValue; + } + clipstr+="\r\n"; + } + this.clipBox.style.display='block'; + this.clipBox.value=clipstr; + this.clipBox.select(); +}, + +copySelection: function() { + var s=this.getSelection(); + if (!s) return; + var clipArray=[]; + for (var r=s.r1; r<=s.r2; r++) { + var cliprow=[]; + for (var c=s.c1; c<=s.c2; c++) { + var clipcell={}; + var gridcell=this.columns[c].cell(r); + clipcell.value=gridcell.RicoValue; + clipcell.style=gridcell.style.cssText; + if (gridcell.RicoFormat) + clipcell.format=Object.extend({}, gridcell.RicoFormat || {}); + if (gridcell.RicoFormula) + clipcell.formula=Object.extend({}, gridcell.RicoFormula); + cliprow[c-s.c1]=clipcell; + } + clipArray[r-s.r1]=cliprow; + } + return clipArray; +}, + +pasteSelection: function(clipArray,pasteType) { + var s=this.getSelection(); + if (!s || !clipArray) return; + pasteType=pasteType || 'all'; + var clipclen=clipArray[0].length; + if (s.r1==s.r2 && s.c1==s.c2) { + s.r2=Math.min(s.r1+clipArray.length,this.columns[0].numRows())-1; + s.c2=Math.min(s.c1+clipclen,this.columns.length)-1; + } + for (var r=s.r1,clipr=0; r<=s.r2; r++) { + var arow=clipArray[clipr]; + for (var c=s.c1,clipc=0; c<=s.c2; c++) { + var clipcell=arow[clipc]; + var gridcell=this.columns[c].cell(r); + this.updateDependencies(gridcell,'remove'); + gridcell.RicoFormula=null; + if (clipcell.formula) { + gridcell.RicoFormula=Object.extend({}, clipcell.formula); + gridcell.RicoFormula.cell=gridcell; + gridcell.RicoValue = gridcell.RicoFormula.eval(); + this.updateDependencies(gridcell,'add'); + } else { + gridcell.RicoValue=clipcell.value; + } + gridcell.style.cssText=clipcell.style; + if (clipcell.format) + gridcell.RicoFormat=Object.extend({}, clipcell.format); + this.formatCell(gridcell); + this.checkDependencies(gridcell); + clipc=(clipc+1) % clipclen; + } + clipr=(clipr+1) % clipArray.length; + } +}, + +formatSelection: function(newFormat) { + var s=this.getSelection(); + if (!s) return; + for (var r=s.r1; r<=s.r2; r++) { + for (var c=s.c1; c<=s.c2; c++) { + var gridcell=this.cell(r,c); + gridcell.RicoFormat=newFormat; + this.formatCell(gridcell); + } + } +}, + +handleCtrlKey: function(e) { + switch (e.keyCode) { + // Ctrl-C + case 67: + this.clip=this.copySelection(); + window.status='copy: '+this.clip.length; + Event.stop(e); + break; + + // Ctrl-X + case 88: + this.clip=this.copySelection(); + this.clearSelection(); + Event.stop(e); + break; + + // Ctrl-V + case 86: + window.status='paste: '+this.clip.length; + this.pasteSelection(this.clip); + Event.stop(e); + break; + + // Ctrl-B + case 66: + this.toggleAttr('font-weight','normal','bold'); + Event.stop(e); + break; + + // Ctrl-I + case 73: + this.toggleAttr('font-style','normal','italic'); + Event.stop(e); + break; + } +}, + +handleNormalKey: function(e) { + switch (e.keyCode) { + case 91: + case 16: + case 17: + case 18: + case 20: + case 27: return; + + // tab + case 9: this.moveSelection(0,e.shiftKey ? -1 : 1,false,e); break; + // enter/return + case 13: this.moveSelection(1,0,false,e); break; + // arrow keys + case 37: this.moveSelection(0,-1,e.shiftKey,e); break; + case 38: this.moveSelection(-1,0,e.shiftKey,e); break; + case 39: this.moveSelection(0,1,e.shiftKey,e); break; + case 40: this.moveSelection(1,0,e.shiftKey,e); break; + // home + case 36: this.selectCellRC(this.SelectIdxStart.row,1); Event.stop(e); break; + // F2 + case 113: this.showInputArea(false,e); break; + + default: this.showInputArea(true,e); break; + } + return false; +}, + +gridKeydown: function(e) { + if (e.altKey) return; + var elem=Event.element(e); + if (elem.id=='inputArea') return true; + //window.status='gridKeydown keyCode='+e.keyCode; + if (e.ctrlKey) + this.handleCtrlKey(e); + else + this.handleNormalKey(e); +}, + +toggleAttr: function(attr,v1,v2) { + var v=this.getStyle(this.SelectIdxStart.row,this.SelectIdxStart.column,attr); + v=v==v2 ? v1 : v2; + this.updateSelectionStyle(attr,v); +}, + +getStyle: function(row,col,attr) { + var csstxt=this.columns[col].cell(row).style.cssText; + if (!csstxt) return; + if (csstxt.charAt(csstxt.length-1)!=';') csstxt+=';'; // opera + csstxt=' '+csstxt; + var re=new RegExp("[ ;]"+attr+"\\s*:\\s*([^ ;]*)\\s*;","i"); + if (re.test(csstxt)) + return RegExp.$1; + else + return; +}, + +updateStyleText: function(csstxt,attr,value) { + var newval=attr+':'+value+';'; + if (!csstxt) return newval; + csstxt=' '+csstxt.strip(); + if (csstxt.charAt(csstxt.length-1)!=';') csstxt+=';'; // opera + var re=new RegExp("([ ;])"+attr+"\\s*:\\s*([^ ;]*)\\s*;","i"); + // safari must process the regexp twice, everyone else can run it once + if (re.test(csstxt)) + return Prototype.Browser.WebKit ? csstxt.replace(re,"$1"+newval) : RegExp.leftContext+RegExp.$1+newval+RegExp.rightContext; + else + return csstxt+newval; +}, + +updateSelectionStyle: function(attr,newVal) { + var s=this.getSelection(); + if (!s) return; + for (var c=s.c1; c<=s.c2; c++) { + var col=this.columns[c]; + for (var r=s.r1; r<=s.r2; r++) + col.cell(r).style.cssText=this.updateStyleText(col.cell(r).style.cssText,attr,newVal); + } +}, + +showHelp: function() { + var msg="Rico Spreadsheet\n\n"; + msg+="Ctrl-C = copy, Ctrl-X = cut, Ctrl-V = paste (only from/to cells on this grid)\n\n"; + msg+="Formulas starting with '=' are supported\n"; + msg+="Formulas may contain parentheses and the following operators: + - * / & % = > < <= >= <>\n"; + msg+="'+' follows javascript rules regarding type conversion (which are slightly different from Excel)\n"; + msg+="Formulas may refer to cells using 'A1' notation (and 'A1:B2' for ranges).\n"; + msg+="The following functions are supported in formulas:\n\n"; + var funclist=[]; + for (var funcname in Rico.Formula.prototype) + if (funcname.substring(0,5)=='eval_') funclist.push(funcname.substring(5)); + funclist.sort(); + var funcstr=funclist.join(', '); + var i=funcstr.indexOf(' ',Math.floor(funcstr.length/2)); + msg+=funcstr.substring(0,i)+"\n"+funcstr.substring(i+1); + msg+="\n\nFormula parsing based on code originally published by E. W. Bachtal at http://ewbi.blogs.com/develops/"; + msg+="\nFuture functionality may include copy/paste from external applications, load/save, number & date formatting, and support for additional functions."; + alert(msg); +} + +}); + + +Rico.Formula = Class.create(); + +Rico.Formula.TOK_TYPE_NOOP = "noop"; +Rico.Formula.TOK_TYPE_OPERAND = "operand"; +Rico.Formula.TOK_TYPE_FUNCTION = "function"; +Rico.Formula.TOK_TYPE_SUBEXPR = "subexpression"; +Rico.Formula.TOK_TYPE_ARGUMENT = "argument"; +Rico.Formula.TOK_TYPE_OP_PRE = "operator-prefix"; +Rico.Formula.TOK_TYPE_OP_IN = "operator-infix"; +Rico.Formula.TOK_TYPE_OP_POST = "operator-postfix"; +Rico.Formula.TOK_TYPE_WSPACE = "white-space"; +Rico.Formula.TOK_TYPE_UNKNOWN = "unknown"; + +Rico.Formula.TOK_SUBTYPE_START = "start"; +Rico.Formula.TOK_SUBTYPE_STOP = "stop"; + +Rico.Formula.TOK_SUBTYPE_TEXT = "text"; +Rico.Formula.TOK_SUBTYPE_NUMBER = "number"; +Rico.Formula.TOK_SUBTYPE_LOGICAL = "logical"; +Rico.Formula.TOK_SUBTYPE_ERROR = "error"; +Rico.Formula.TOK_SUBTYPE_RANGE = "range"; + +Rico.Formula.TOK_SUBTYPE_MATH = "math"; +Rico.Formula.TOK_SUBTYPE_CONCAT = "concatenate"; +Rico.Formula.TOK_SUBTYPE_INTERSECT = "intersect"; +Rico.Formula.TOK_SUBTYPE_UNION = "union"; + +Rico.Formula.prototype = { + +initialize: function(grid,cell) { + this.grid=grid; + this.cell=cell; +}, + +// 'A' -> 1, 'AA' -> 27 +colLetter2Num: function(colstr) { + colstr=colstr.toUpperCase(); + switch (colstr.length) { + case 1: return colstr.charCodeAt(0)-64; + case 2: return (colstr.charCodeAt(0)-64) * 26 + colstr.charCodeAt(1)-64; + default: return -1; + } +}, + +// 1 -> 'A', 27 -> 'AA' +colNum2Letter: function(colnum) { + if (colnum <= 26) return String.fromCharCode(64+colnum); + colnum-=1; + return String.fromCharCode(64+Math.floor(colnum / 26),65+(colnum % 26)); +}, + + +toHTML: function() { + var indentCount = 0; + + var indent = function() { + var s = "|"; + for (var i = 0; i < indentCount; i++) { + s += "   |"; + } + return s; + }; + + var tokensHtml = "
1) this.exportText+=" colspan='"+newSpan+"'"; + this.exportText+=">"+RicoUtil.getInnerText(cell)+"
"; + tokensHtml += ""; + tokensHtml += ""; + tokensHtml += ""; + tokensHtml += ""; + tokensHtml += ""; + tokensHtml += ""; + + this.tokens.reset(); + while (this.tokens.moveNext()) { + + var token = this.tokens.current(); + + if (token.subtype == Rico.Formula.TOK_SUBTYPE_STOP) + indentCount -= ((indentCount > 0) ? 1 : 0); + + tokensHtml += ""; + + tokensHtml += ""; + tokensHtml += ""; + tokensHtml += ""; + tokensHtml += ""; + tokensHtml += ""; + + tokensHtml += ""; + + if (token.subtype == Rico.Formula.TOK_SUBTYPE_START) indentCount++; + } + tokensHtml += "
indextypesubtypetokentoken tree
" + (this.tokens.index + 1) + "" + token.type + "" + ((token.subtype.length == 0) ? " " : token.subtype) + "" + ((token.value.length == 0) ? " " : token.value).split(" ").join(" ") + "" + indent() + ((token.value.length == 0) ? " " : token.value).split(" ").join(" ") + "
"; + return tokensHtml; +}, + + +parseCellRef: function(refString) { + if (!refString) return null; + if (!refString.match(/^(\$?)([a-z]*)(\$?)(\d*)$/i)) return null; + var abscol=(RegExp.$1=='$'); + var absrow=(RegExp.$3=='$'); + var r=null,c=null; + if (RegExp.$2) { + c=this.colLetter2Num(RegExp.$2); + if (c<0 || c>=this.grid.columns.length) return null; + if (!abscol) c-=this.cell.RicoCol; + } + if (RegExp.$4) { + r=parseInt(RegExp.$4); + if (!absrow) r-=this.cell.RicoRow; + } + //alert('parseCellRef: '+refString+"\n"+'r='+r+' c='+c+' absrow='+absrow+' abscol='+abscol); + return {row:r, col:c, absRow:absrow, absCol:abscol}; +}, + + +resolveCellRef: function(cellRef) { + var r=cellRef.row; + var c=cellRef.col; + if (!cellRef.absRow) r+=this.cell.RicoRow; + if (!cellRef.absCol) c+=this.cell.RicoCol; + return {row:r, col:c}; +}, + + +resolveRange: function(token) { + if (!token.rangeStart) return null; + var a1=this.resolveCellRef(token.rangeStart); + var a2=this.resolveCellRef(token.rangeEnd); + //alert('resolveRange: '+a1.row+','+a1.col+' '+a2.row+','+a2.col); + var r1=Math.min(a1.row,a2.row); + var r2=Math.max(a1.row,a2.row); + var c1=Math.min(a1.col,a2.col) || 0; + var c2=Math.max(a1.col,a2.col) || this.grid.columns.length-1; + return [r1,c1,r2,c2]; +}, + + +range2evalstr: function(token) { + var rng=this.resolveRange(token); + return rng ? rng.join(',') : ''; +}, + + +cellref2str: function(cellRef) { + var ref=this.resolveCellRef(cellRef); + var c=this.colNum2Letter(ref.col); + if (cellRef.absCol) c='$'+c; + var r=ref.row.toString(); + if (cellRef.absRow) r='$'+r; + return c+r; +}, + + +range2str: function(token) { + var s1=this.cellref2str(token.rangeStart); + var s2=this.cellref2str(token.rangeEnd); + return (s1==s2) ? s1 : s1+':'+s2; +}, + + +GetRange: function(r1,c1,r2,c2) { + if (typeof r1=='undefined' || typeof c1=='undefined') return NaN; + if (r1==r2 && c1==c2) return this.grid.columns[c1].cell(r1-1).RicoValue; + var result=[]; + for (var r=r1; r<=r2; r++) { + var newRow=[]; + for (var c=c1; c<=c2; c++) + newRow.push(this.grid.columns[c].cell(r-1).RicoValue); + result.push(newRow); + } + return result; +}, + + +getRanges: function() { + var result=[]; + this.tokens.reset(); + while (this.tokens.moveNext()) { + var token = this.tokens.current(); + if (token.subtype=='range') result.push(this.resolveRange(token)); + } + return result; +}, + + +eval_sum: function() { + var result=0; + for (var i=0; i') + evalstr+='!='; + else + evalstr+=token.value; + break; + case 'operator-postfix': + if (token.value=='%') + evalstr+='/100'; + else + evalstr+=token.value; + break; + case 'operand': + if (token.subtype=='range') + evalstr+='this.GetRange('+this.range2evalstr(token)+')'; + else if (token.subtype=='text') + evalstr+='"'+token.value+'"'; + else + evalstr+=token.value; + break; + default: + evalstr+=token.value; + break; + } + } + this.lastEval=evalstr; + //window.status=evalstr; + try { + var result=eval(evalstr) + return result; + } catch(e) { alert(e.message); return '#ERROR'; } +}, + + +toEditString: function() { + var s='='; + this.tokens.reset(); + while (this.tokens.moveNext()) { + var token = this.tokens.current(); + switch (token.type) { + case 'function': + if (token.subtype=='start') + s+=token.value+'('; + else + s+=')'; + break; + case 'subexpression': + if (token.subtype=='start') + s+='('; + else + s+=')'; + break; + case 'operand': + if (token.subtype=='range') + s+=this.range2str(token); + else if (token.subtype=='text') + s+='"'+token.value+'"'; + else + s+=token.value; + break; + default: + s+=token.value; + } + } + return s; +}, + + +// Excel formula parser +// from http://ewbi.blogs.com/develops/2004/12/excel_formula_p.html +parse: function(formula) { + var tokens = new Rico.Formula.f_tokens(); + var tokenStack = new Rico.Formula.f_tokenStack(); + + var offset = 0; + + var currentChar = function() { return formula.substr(offset, 1); }; + var doubleChar = function() { return formula.substr(offset, 2); }; + var nextChar = function() { return formula.substr(offset + 1, 1); }; + var EOF = function() { return (offset >= formula.length); }; + + var token = ""; + + var inString = false; + var inPath = false; + var inRange = false; + var inError = false; + + while (formula.length > 0) { + if (formula.substr(0, 1) == " ") + formula = formula.substr(1); + else { + if (formula.substr(0, 1) == "=") + formula = formula.substr(1); + break; + } + } + + while (!EOF()) { + + // state-dependent character evaluation (order is important) + + // double-quoted strings + // embeds are doubled + // end marks token + + if (inString) { + if (currentChar() == "\"") { + if (nextChar() == "\"") { + token += "\""; + offset += 1; + } else { + inString = false; + tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND, Rico.Formula.TOK_SUBTYPE_TEXT); + token = ""; + } + } else { + token += currentChar(); + } + offset += 1; + continue; + } + + // single-quoted strings (links) + // embeds are double + // end does not mark a token + + if (inPath) { + if (currentChar() == "'") { + if (nextChar() == "'") { + token += "'"; + offset += 1; + } else { + inPath = false; + } + } else { + token += currentChar(); + } + offset += 1; + continue; + } + + // bracked strings (range offset or linked workbook name) + // no embeds (changed to "()" by Excel) + // end does not mark a token + + if (inRange) { + if (currentChar() == "]") { + inRange = false; + } + token += currentChar(); + offset += 1; + continue; + } + + // error values + // end marks a token, determined from absolute list of values + + if (inError) { + token += currentChar(); + offset += 1; + if ((",#NULL!,#DIV/0!,#VALUE!,#REF!,#NAME?,#NUM!,#N/A,").indexOf("," + token + ",") != -1) { + inError = false; + tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND, Rico.Formula.TOK_SUBTYPE_ERROR); + token = ""; + } + continue; + } + + // independent character evaulation (order not important) + + // establish state-dependent character evaluations + + if (currentChar() == "\"") { + if (token.length > 0) { + // not expected + tokens.add(token, Rico.Formula.TOK_TYPE_UNKNOWN); + token = ""; + } + inString = true; + offset += 1; + continue; + } + + if (currentChar() == "'") { + if (token.length > 0) { + // not expected + tokens.add(token, Rico.Formula.TOK_TYPE_UNKNOWN); + token = ""; + } + inPath = true; + offset += 1; + continue; + } + + if (currentChar() == "[") { + inRange = true; + token += currentChar(); + offset += 1; + continue; + } + + if (currentChar() == "#") { + if (token.length > 0) { + // not expected + tokens.add(token, Rico.Formula.TOK_TYPE_UNKNOWN); + token = ""; + } + inError = true; + token += currentChar(); + offset += 1; + continue; + } + + // mark start and end of arrays and array rows + + if (currentChar() == "{") { + if (token.length > 0) { + // not expected + tokens.add(token, Rico.Formula.TOK_TYPE_UNKNOWN); + token = ""; + } + tokenStack.push(tokens.add("ARRAY", Rico.Formula.TOK_TYPE_FUNCTION, Rico.Formula.TOK_SUBTYPE_START)); + tokenStack.push(tokens.add("ARRAYROW", Rico.Formula.TOK_TYPE_FUNCTION, Rico.Formula.TOK_SUBTYPE_START)); + offset += 1; + continue; + } + + if (currentChar() == ";") { + if (token.length > 0) { + tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND); + token = ""; + } + tokens.addRef(tokenStack.pop()); + tokens.add(",", Rico.Formula.TOK_TYPE_ARGUMENT); + tokenStack.push(tokens.add("ARRAYROW", Rico.Formula.TOK_TYPE_FUNCTION, Rico.Formula.TOK_SUBTYPE_START)); + offset += 1; + continue; + } + + if (currentChar() == "}") { + if (token.length > 0) { + tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND); + token = ""; + } + tokens.addRef(tokenStack.pop()); + tokens.addRef(tokenStack.pop()); + offset += 1; + continue; + } + + // trim white-space + + if (currentChar() == " ") { + if (token.length > 0) { + tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND); + token = ""; + } + tokens.add("", Rico.Formula.TOK_TYPE_WSPACE); + offset += 1; + while ((currentChar() == " ") && (!EOF())) { + offset += 1; + } + continue; + } + + // multi-character comparators + + if ((",>=,<=,<>,").indexOf("," + doubleChar() + ",") != -1) { + if (token.length > 0) { + tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND); + token = ""; + } + tokens.add(doubleChar(), Rico.Formula.TOK_TYPE_OP_IN, Rico.Formula.TOK_SUBTYPE_LOGICAL); + offset += 2; + continue; + } + + // standard infix operators + + if (("+-*/^&=><").indexOf(currentChar()) != -1) { + if (token.length > 0) { + tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND); + token = ""; + } + tokens.add(currentChar(), Rico.Formula.TOK_TYPE_OP_IN); + offset += 1; + continue; + } + + // standard postfix operators + + if (("%").indexOf(currentChar()) != -1) { + if (token.length > 0) { + tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND); + token = ""; + } + tokens.add(currentChar(), Rico.Formula.TOK_TYPE_OP_POST); + offset += 1; + continue; + } + + // start subexpression or function + + if (currentChar() == "(") { + if (token.length > 0) { + tokenStack.push(tokens.add(token, Rico.Formula.TOK_TYPE_FUNCTION, Rico.Formula.TOK_SUBTYPE_START)); + token = ""; + } else { + tokenStack.push(tokens.add("", Rico.Formula.TOK_TYPE_SUBEXPR, Rico.Formula.TOK_SUBTYPE_START)); + } + offset += 1; + continue; + } + + // function, subexpression, array parameters + + if (currentChar() == ",") { + if (token.length > 0) { + tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND); + token = ""; + } + if (!(tokenStack.type() == Rico.Formula.TOK_TYPE_FUNCTION)) { + tokens.add(currentChar(), Rico.Formula.TOK_TYPE_OP_IN, Rico.Formula.TOK_SUBTYPE_UNION); + } else { + tokens.add(currentChar(), Rico.Formula.TOK_TYPE_ARGUMENT); + } + offset += 1; + continue; + } + + // stop subexpression + + if (currentChar() == ")") { + if (token.length > 0) { + tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND); + token = ""; + } + tokens.addRef(tokenStack.pop()); + offset += 1; + continue; + } + + // token accumulation + + token += currentChar(); + offset += 1; + + } + + // dump remaining accumulation + + if (token.length > 0) tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND); + + // move all tokens to a new collection, excluding all unnecessary white-space tokens + + var tokens2 = new Rico.Formula.f_tokens(); + + while (tokens.moveNext()) { + + token = tokens.current(); + + if (token.type == Rico.Formula.TOK_TYPE_WSPACE) { + if ((tokens.BOF()) || (tokens.EOF())) {} + else if (!( + ((tokens.previous().type == Rico.Formula.TOK_TYPE_FUNCTION) && (tokens.previous().subtype == Rico.Formula.TOK_SUBTYPE_STOP)) || + ((tokens.previous().type == Rico.Formula.TOK_TYPE_SUBEXPR) && (tokens.previous().subtype == Rico.Formula.TOK_SUBTYPE_STOP)) || + (tokens.previous().type == Rico.Formula.TOK_TYPE_OPERAND) + ) + ) {} + else if (!( + ((tokens.next().type == Rico.Formula.TOK_TYPE_FUNCTION) && (tokens.next().subtype == Rico.Formula.TOK_SUBTYPE_START)) || + ((tokens.next().type == Rico.Formula.TOK_TYPE_SUBEXPR) && (tokens.next().subtype == Rico.Formula.TOK_SUBTYPE_START)) || + (tokens.next().type == Rico.Formula.TOK_TYPE_OPERAND) + ) + ) {} + else + tokens2.add(token.value, Rico.Formula.TOK_TYPE_OP_IN, Rico.Formula.TOK_SUBTYPE_INTERSECT); + continue; + } + + tokens2.addRef(token); + + } + + // switch infix "-" operator to prefix when appropriate, switch infix "+" operator to noop when appropriate, identify operand + // and infix-operator subtypes, pull "@" from in front of function names + + while (tokens2.moveNext()) { + + token = tokens2.current(); + + if ((token.type == Rico.Formula.TOK_TYPE_OP_IN) && (token.value == "-")) { + if (tokens2.BOF()) + token.type = Rico.Formula.TOK_TYPE_OP_PRE; + else if ( + ((tokens2.previous().type == Rico.Formula.TOK_TYPE_FUNCTION) && (tokens2.previous().subtype == Rico.Formula.TOK_SUBTYPE_STOP)) || + ((tokens2.previous().type == Rico.Formula.TOK_TYPE_SUBEXPR) && (tokens2.previous().subtype == Rico.Formula.TOK_SUBTYPE_STOP)) || + (tokens2.previous().type == Rico.Formula.TOK_TYPE_OP_POST) || + (tokens2.previous().type == Rico.Formula.TOK_TYPE_OPERAND) + ) + token.subtype = Rico.Formula.TOK_SUBTYPE_MATH; + else + token.type = Rico.Formula.TOK_TYPE_OP_PRE; + continue; + } + + if ((token.type == Rico.Formula.TOK_TYPE_OP_IN) && (token.value == "+")) { + if (tokens2.BOF()) + token.type = Rico.Formula.TOK_TYPE_NOOP; + else if ( + ((tokens2.previous().type == Rico.Formula.TOK_TYPE_FUNCTION) && (tokens2.previous().subtype == Rico.Formula.TOK_SUBTYPE_STOP)) || + ((tokens2.previous().type == Rico.Formula.TOK_TYPE_SUBEXPR) && (tokens2.previous().subtype == Rico.Formula.TOK_SUBTYPE_STOP)) || + (tokens2.previous().type == Rico.Formula.TOK_TYPE_OP_POST) || + (tokens2.previous().type == Rico.Formula.TOK_TYPE_OPERAND) + ) + token.subtype = Rico.Formula.TOK_SUBTYPE_MATH; + else + token.type = Rico.Formula.TOK_TYPE_NOOP; + continue; + } + + if ((token.type == Rico.Formula.TOK_TYPE_OP_IN) && (token.subtype.length == 0)) { + if (("<>=").indexOf(token.value.substr(0, 1)) != -1) + token.subtype = Rico.Formula.TOK_SUBTYPE_LOGICAL; + else if (token.value == "&") + token.subtype = Rico.Formula.TOK_SUBTYPE_CONCAT; + else + token.subtype = Rico.Formula.TOK_SUBTYPE_MATH; + continue; + } + + if ((token.type == Rico.Formula.TOK_TYPE_OPERAND) && (token.subtype.length == 0)) { + if (isNaN(parseFloat(token.value))) + if ((token.value == 'TRUE') || (token.value == 'FALSE')) + token.subtype = Rico.Formula.TOK_SUBTYPE_LOGICAL; + else { + token.subtype = Rico.Formula.TOK_SUBTYPE_RANGE; + var a=token.value.split(':'); + token.rangeStart=this.parseCellRef(a[0]); + token.rangeEnd=a.length>1 ? this.parseCellRef(a[1]) : token.rangeStart; + } + else + token.subtype = Rico.Formula.TOK_SUBTYPE_NUMBER; + continue; + } + + if (token.type == Rico.Formula.TOK_TYPE_FUNCTION) { + if (token.value.substr(0, 1) == "@") + token.value = token.value.substr(1); + continue; + } + + } + + tokens2.reset(); + + // move all tokens to a new collection, excluding all noops + + this.tokens = new Rico.Formula.f_tokens(); + + while (tokens2.moveNext()) { + if (tokens2.current().type != Rico.Formula.TOK_TYPE_NOOP) + this.tokens.addRef(tokens2.current()); + } +} + +} + + +Rico.Formula.f_token = Class.create(); +Rico.Formula.f_token.prototype = { + initialize: function(value, type, subtype) { + this.value = value; + this.type = type; + this.subtype = subtype; + } +} + + +Rico.Formula.f_tokens = Class.create(); +Rico.Formula.f_tokens.prototype = { + initialize: function() { + this.items = new Array(); + this.index = -1; + }, + + addRef: function(token) { + this.items.push(token); + }, + + add: function(value, type, subtype) { + if (!subtype) subtype = ""; + var token = new Rico.Formula.f_token(value, type, subtype); + this.addRef(token); + return token; + }, + + reset: function() { + this.index = -1; + }, + + BOF: function() { + return (this.index <= 0); + }, + + EOF: function() { + return (this.index >= (this.items.length - 1)); + }, + + moveNext: function() { + if (this.EOF()) return false; this.index++; return true; + }, + + current: function() { + if (this.index == -1) return null; return (this.items[this.index]); + }, + + next: function() { + if (this.EOF()) return null; return (this.items[this.index + 1]); + }, + + previous: function() { + if (this.index < 1) return null; return (this.items[this.index - 1]); + } +} + + +Rico.Formula.f_tokenStack = Class.create(); +Rico.Formula.f_tokenStack.prototype = { + initialize: function() { + this.items = new Array(); + }, + + push: function(token) { + this.items.push(token); + }, + + pop: function() { + var token = this.items.pop(); + return (new Rico.Formula.f_token("", token.type, Rico.Formula.TOK_SUBTYPE_STOP)); + }, + + token: function() { + return ((this.items.length > 0) ? this.items[this.items.length - 1] : null); + }, + + value: function() { + return ((this.token()) ? this.token().value : ""); + }, + + type: function() { + return ((this.token()) ? this.token().type : ""); + }, + + subtype: function() { + return ((this.token()) ? this.token().subtype : ""); + } +} + + +Rico.Formula.f_dependencies = Class.create(); +Rico.Formula.f_dependencies.prototype = { + initialize: function() { + this.items = []; + }, + + add: function(cell) { + if (!this.items.include(cell)) this.items.push(cell); + }, + + remove: function(cell) { + this.items=this.items.select(function(item) { return (item != cell); }); + }, + + find: function(cell) { + return this.items.detect(function(item) { return (item==cell); }); + }, + + clear: function() { + this.items.clear(); + } +} + + +Object.extend(Rico.Menu.prototype, { + +showSheetMenu: function(e,hideFunc) { + var elem=this.showSimpleMenu(e,hideFunc); + if (!this.grid) return; + var newIdx=this.grid.cellIndex(elem); + if (!this.grid.isSelected(newIdx.row,newIdx.column)) + this.grid.selectCellRC(newIdx.row,newIdx.column,false); +} + +}); + + +Rico.includeLoaded('ricoSheet.js'); diff --git a/NP_TrackBack/trunk/trackback/js/rico/ricoSimpleGrid.js b/NP_TrackBack/trunk/trackback/js/rico/ricoSimpleGrid.js new file mode 100644 index 0000000..a6b407e --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/ricoSimpleGrid.js @@ -0,0 +1,160 @@ +/** + * (c) 2005-2007 Richard Cowin (http://openrico.org) + * (c) 2005-2007 Matt Brown (http://dowdybrown.com) + * + * Rico is licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + **/ + + +if(typeof Rico=='undefined') throw("SimpleGrid requires the Rico JavaScript framework"); +if(typeof RicoUtil=='undefined') throw("SimpleGrid requires the RicoUtil Library"); +if(typeof RicoTranslate=='undefined') throw("SimpleGrid requires the RicoTranslate Library"); + +Rico.SimpleGrid = Class.create(); + +Rico.SimpleGrid.prototype = { + + initialize: function( tableId, options ) { + Object.extend(this, new Rico.GridCommon); + this.baseInit(tableId); + Rico.setDebugArea(tableId+"_debugmsgs"); // if used, this should be a textarea + Object.extend(this.options, options || {}); + this.tableId = tableId; + this.createDivs(); + this.hdrTabs=new Array(2); + for (var i=0; i<2; i++) { + this.tabs[i]=$(tableId+'_tab'+i); + this.hdrTabs[i]=$(tableId+'_tab'+i+'h'); + if (i==0) this.tabs[i].style.position='absolute'; + if (i==0) this.tabs[i].style.left='0px'; + this.hdrTabs[i].style.position='absolute'; + this.hdrTabs[i].style.top='0px'; + this.hdrTabs[i].style.zIndex=1; + this.thead[i]=this.hdrTabs[i]; + this.tbody[i]=this.tabs[i]; + this.headerColCnt = this.getColumnInfo(this.hdrTabs[i].rows); + if (i==0) this.options.frozenColumns=this.headerColCnt; + } + if (this.headerColCnt==0) { + alert('ERROR: no columns found in "'+this.tableId+'"'); + return; + } + this.hdrHt=Math.max(RicoUtil.nan2zero(this.hdrTabs[0].offsetHeight),this.hdrTabs[1].offsetHeight); + for (var i=0; i<2; i++) + if (i==0) this.tabs[i].style.top=this.hdrHt+'px'; + this.createColumnArray(); + this.pageSize=this.columns[0].dataColDiv.childNodes.length; + this.sizeDivs(); + this.attachMenuEvents(); + this.scrollEventFunc=this.handleScroll.bindAsEventListener(this); + this.pluginScroll(); + if (this.options.windowResize) + Event.observe(window,"resize", this.sizeDivs.bindAsEventListener(this), false); + }, + + /** + * Register a menu that will only be used in the scrolling part of the grid. + * If submenus are used, they must be registered after the main menu. + */ + registerScrollMenu: function(menu) { + if (!this.menu) this.menu=menu; + menu.grid=this; + menu.showmenu=menu.showSimpleMenu; + menu.showSubMenu=menu.showSimpleSubMenu; + menu.createDiv(this.scrollDiv); + }, + + handleMenuClick: function(e) { + this.cancelMenu(); + this.menuCell=RicoUtil.getParentByTagName(Event.element(e),'div'); + this.highlightEnabled=false; + if (this.hideScroll) this.scrollDiv.style.overflow="hidden"; + if (this.menu.buildGridMenu) this.menu.buildGridMenu(this.menuCell); + this.menu.showmenu(e,this.closeMenu.bind(this)); + }, + + closeMenu: function() { + if (this.hideScroll) this.scrollDiv.style.overflow=""; + this.highlightEnabled=true; + }, + + sizeDivs: function() { + if (this.outerDiv.offsetParent.style.display=='none') return; + this.baseSizeDivs(); + var maxHt=Math.max(this.options.maxHt || this.availHt(), 50); + var totHt=Math.min(this.hdrHt+this.dataHt, maxHt); + Rico.writeDebugMsg('sizeDivs '+this.tableId+': hdrHt='+this.hdrHt+' dataHt='+this.dataHt); + this.dataHt=totHt-this.hdrHt; + if (this.scrWi>0) this.dataHt+=this.options.scrollBarWidth; + this.scrollDiv.style.height=this.dataHt+'px'; + var divAdjust=2; + this.innerDiv.style.width=(this.scrWi-this.options.scrollBarWidth+divAdjust)+'px'; + this.innerDiv.style.height=this.hdrHt+'px'; + totHt+=divAdjust; + this.resizeDiv.style.height=this.frozenTabs.style.height=totHt+'px'; + this.outerDiv.style.height=(totHt+this.options.scrollBarWidth)+'px'; + this.setHorizontalScroll(); + } + +}; + +if (Rico.Menu) { +Object.extend(Rico.Menu.prototype, { + +showSimpleMenu: function(e,hideFunc) { + Event.stop(e); + this.hideFunc=hideFunc; + if (this.div.childNodes.length==0) { + this.cancelmenu(); + return false; + } + this.clientX=Event.pointerX(e); + this.clientY=Event.pointerY(e); + var elem=Event.element(e); + while (elem && !Element.hasClassName(elem,'ricoLG_cell')) + elem=elem.parentNode; + if (!elem) return false; + var td=RicoUtil.getParentByTagName(elem,'td'); + + var newLeft=Math.floor(td.offsetLeft+td.offsetWidth/2); + if (this.direction == 'rtl') { + if (newLeft > this.width) newLeft-=this.width; + } else { + if (newLeft+this.width+this.options.margin > this.grid.scrollDiv.scrollLeft+this.grid.scrollDiv.clientWidth) newLeft-=this.width; + } + this.div.style.visibility="hidden"; + this.div.style.display="block"; + var contentHt=this.div.offsetHeight; + var newTop=Math.floor(elem.offsetTop+elem.offsetHeight/2); + if (newTop+contentHt+this.options.margin > this.grid.scrollDiv.scrollTop+this.grid.scrollDiv.clientHeight) + newTop=Math.max(newTop-contentHt,0); + this.openPopup(newLeft,newTop); + this.div.style.visibility ="visible"; + return elem; +}, + +showSimpleSubMenu: function(a,submenu) { + if (this.openSubMenu) this.hideSubMenu(); + this.openSubMenu=submenu; + this.openMenuAnchor=a; + if (a.className=='ricoSubMenu') a.className='ricoSubMenuOpen'; + var top=parseInt(this.div.style.top); + var left=parseInt(this.div.style.left); + submenu.openPopup(left+a.offsetWidth,top+a.offsetTop); + submenu.div.style.visibility ="visible"; +} + +}); +} + +Object.extend(Rico.TableColumn.prototype, { + +initialize: function(grid,colIdx,hdrInfo,tabIdx) { + this.baseInit(grid,colIdx,hdrInfo,tabIdx); +} + +}); + +Rico.includeLoaded('ricoSimpleGrid.js'); diff --git a/NP_TrackBack/trunk/trackback/js/rico/ricoSimpleGrid.xsl b/NP_TrackBack/trunk/trackback/js/rico/ricoSimpleGrid.xsl new file mode 100644 index 0000000..f3c0dc2 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/ricoSimpleGrid.xsl @@ -0,0 +1,285 @@ + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +ricoLG_outerDiv + + + + + + +ricoLG_frozenTabsDiv + + + + + + + + + + + + + + + + + + + +ricoLG_innerDiv + + + +ricoLG_scrollTabsDiv + + + + + + + + + + + + + +ricoLG_scrollDiv + + + + + + + + + + + + + + + + + + + + + + + +ricoLG_table ricoLG_top +ricoLG_left +ricoLG_right + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ricoLG_hdg + + + +
+ + ricoLG_cell + + +
+
+
+
+
+ + + + + + + + + + + +ricoLG_table ricoLG_bottom +ricoLG_left +ricoLG_right + + + + + + + +
+ + + ricoLG_cell + + + +
+ +
+
+ +
+
+
+ +
diff --git a/NP_TrackBack/trunk/trackback/js/rico/ricoSimpleGrid2xl.xsl b/NP_TrackBack/trunk/trackback/js/rico/ricoSimpleGrid2xl.xsl new file mode 100644 index 0000000..f04b2e1 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/ricoSimpleGrid2xl.xsl @@ -0,0 +1,160 @@ + + + + + + + progid="Excel.Sheet" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + + + + + + + + + + s22 + + + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/js/rico/ricoStyles.js b/NP_TrackBack/trunk/trackback/js/rico/ricoStyles.js new file mode 100644 index 0000000..34af1aa --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/ricoStyles.js @@ -0,0 +1,469 @@ +/** + * + * Copyright 2005 Sabre Airline Solutions + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + **/ + +//-------------------- ricoColor.js +Rico.Color = Class.create(); + +Rico.Color.prototype = { + + initialize: function(red, green, blue) { + this.rgb = { r: red, g : green, b : blue }; + }, + + setRed: function(r) { + this.rgb.r = r; + }, + + setGreen: function(g) { + this.rgb.g = g; + }, + + setBlue: function(b) { + this.rgb.b = b; + }, + + setHue: function(h) { + + // get an HSB model, and set the new hue... + var hsb = this.asHSB(); + hsb.h = h; + + // convert back to RGB... + this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, hsb.b); + }, + + setSaturation: function(s) { + // get an HSB model, and set the new hue... + var hsb = this.asHSB(); + hsb.s = s; + + // convert back to RGB and set values... + this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, hsb.b); + }, + + setBrightness: function(b) { + // get an HSB model, and set the new hue... + var hsb = this.asHSB(); + hsb.b = b; + + // convert back to RGB and set values... + this.rgb = Rico.Color.HSBtoRGB( hsb.h, hsb.s, hsb.b ); + }, + + darken: function(percent) { + var hsb = this.asHSB(); + this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, Math.max(hsb.b - percent,0)); + }, + + brighten: function(percent) { + var hsb = this.asHSB(); + this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, Math.min(hsb.b + percent,1)); + }, + + blend: function(other) { + this.rgb.r = Math.floor((this.rgb.r + other.rgb.r)/2); + this.rgb.g = Math.floor((this.rgb.g + other.rgb.g)/2); + this.rgb.b = Math.floor((this.rgb.b + other.rgb.b)/2); + }, + + isBright: function() { + var hsb = this.asHSB(); + return this.asHSB().b > 0.5; + }, + + isDark: function() { + return ! this.isBright(); + }, + + asRGB: function() { + return "rgb(" + this.rgb.r + "," + this.rgb.g + "," + this.rgb.b + ")"; + }, + + asHex: function() { + return "#" + this.rgb.r.toColorPart() + this.rgb.g.toColorPart() + this.rgb.b.toColorPart(); + }, + + asHSB: function() { + return Rico.Color.RGBtoHSB(this.rgb.r, this.rgb.g, this.rgb.b); + }, + + toString: function() { + return this.asHex(); + } + +}; + +Rico.Color.createFromHex = function(hexCode) { + if(hexCode.length==4) { + var shortHexCode = hexCode; + var hexCode = '#'; + for(var i=1;i<4;i++) + hexCode += (shortHexCode.charAt(i) + shortHexCode.charAt(i)); + } + if ( hexCode.indexOf('#') == 0 ) + hexCode = hexCode.substring(1); + var red = hexCode.substring(0,2); + var green = hexCode.substring(2,4); + var blue = hexCode.substring(4,6); + return new Rico.Color( parseInt(red,16), parseInt(green,16), parseInt(blue,16) ); +} + +/** + * Factory method for creating a color from the background of + * an HTML element. + */ +Rico.Color.createColorFromBackground = function(elem) { + + var actualColor = Element.getStyle(elem, "background-color"); + + // if color is tranparent, check parent + // Safari returns "rgba(0, 0, 0, 0)", which means transparent + if ( actualColor.match(/^(transparent|rgba\(0,\s*0,\s*0,\s*0\))$/i) && elem.parentNode ) + return Rico.Color.createColorFromBackground(elem.parentNode); + + if ( actualColor == null ) + return new Rico.Color(255,255,255); + + if ( actualColor.indexOf("rgb(") == 0 ) { + var colors = actualColor.substring(4, actualColor.length - 1 ); + var colorArray = colors.split(","); + return new Rico.Color( parseInt( colorArray[0] ), + parseInt( colorArray[1] ), + parseInt( colorArray[2] ) ); + + } + else if ( actualColor.indexOf("#") == 0 ) { + return Rico.Color.createFromHex(actualColor); + } + else + return new Rico.Color(255,255,255); +} + +Rico.Color.HSBtoRGB = function(hue, saturation, brightness) { + + var red = 0; + var green = 0; + var blue = 0; + + if (saturation == 0) { + red = parseInt(brightness * 255.0 + 0.5); + green = red; + blue = red; + } + else { + var h = (hue - Math.floor(hue)) * 6.0; + var f = h - Math.floor(h); + var p = brightness * (1.0 - saturation); + var q = brightness * (1.0 - saturation * f); + var t = brightness * (1.0 - (saturation * (1.0 - f))); + + switch (parseInt(h)) { + case 0: + red = (brightness * 255.0 + 0.5); + green = (t * 255.0 + 0.5); + blue = (p * 255.0 + 0.5); + break; + case 1: + red = (q * 255.0 + 0.5); + green = (brightness * 255.0 + 0.5); + blue = (p * 255.0 + 0.5); + break; + case 2: + red = (p * 255.0 + 0.5); + green = (brightness * 255.0 + 0.5); + blue = (t * 255.0 + 0.5); + break; + case 3: + red = (p * 255.0 + 0.5); + green = (q * 255.0 + 0.5); + blue = (brightness * 255.0 + 0.5); + break; + case 4: + red = (t * 255.0 + 0.5); + green = (p * 255.0 + 0.5); + blue = (brightness * 255.0 + 0.5); + break; + case 5: + red = (brightness * 255.0 + 0.5); + green = (p * 255.0 + 0.5); + blue = (q * 255.0 + 0.5); + break; + } + } + + return { r : parseInt(red), g : parseInt(green) , b : parseInt(blue) }; +} + +Rico.Color.RGBtoHSB = function(r, g, b) { + + var hue; + var saturation; + var brightness; + + var cmax = (r > g) ? r : g; + if (b > cmax) + cmax = b; + + var cmin = (r < g) ? r : g; + if (b < cmin) + cmin = b; + + brightness = cmax / 255.0; + if (cmax != 0) + saturation = (cmax - cmin)/cmax; + else + saturation = 0; + + if (saturation == 0) + hue = 0; + else { + var redc = (cmax - r)/(cmax - cmin); + var greenc = (cmax - g)/(cmax - cmin); + var bluec = (cmax - b)/(cmax - cmin); + + if (r == cmax) + hue = bluec - greenc; + else if (g == cmax) + hue = 2.0 + redc - bluec; + else + hue = 4.0 + greenc - redc; + + hue = hue / 6.0; + if (hue < 0) + hue = hue + 1.0; + } + + return { h : hue, s : saturation, b : brightness }; +} + +//-------------------- ricoCorner.js +Rico.Corner = { + + round: function(e, options) { + var e = $(e); + this._setOptions(options); + var color = this.options.color == "fromElement" ? this._background(e) : this.options.color; + var bgColor = this.options.bgColor == "fromParent" ? this._background(e.parentNode) : this.options.bgColor; + this._roundCornersImpl(e, color, bgColor); + }, + + _roundCornersImpl: function(e, color, bgColor) { + if(this.options.border) + this._renderBorder(e,bgColor); + if(this._isTopRounded()) + this._roundTopCorners(e,color,bgColor); + if(this._isBottomRounded()) + this._roundBottomCorners(e,color,bgColor); + }, + + _renderBorder: function(el,bgColor) { + var borderValue = "1px solid " + this._borderColor(bgColor); + var borderL = "border-left: " + borderValue; + var borderR = "border-right: " + borderValue; + var style = "style='" + borderL + ";" + borderR + "'"; + el.innerHTML = "
" + el.innerHTML + "
" + }, + + _roundTopCorners: function(el, color, bgColor) { + var corner = this._createCorner(bgColor); + for(var i=0 ; i < this.options.numSlices ; i++ ) + corner.appendChild(this._createCornerSlice(color,bgColor,i,"top")); + el.style.paddingTop = '0px'; + el.insertBefore(corner,el.firstChild); + }, + + _roundBottomCorners: function(el, color, bgColor) { + var corner = this._createCorner(bgColor); + for(var i=(this.options.numSlices-1) ; i >= 0 ; i-- ) + corner.appendChild(this._createCornerSlice(color,bgColor,i,"bottom")); + el.style.paddingBottom = 0; + el.appendChild(corner); + }, + + _createCorner: function(bgColor) { + var corner = document.createElement("div"); + corner.style.backgroundColor = (this._isTransparent() ? "transparent" : bgColor); + return corner; + }, + + _createCornerSlice: function(color,bgColor, n, position) { + var slice = document.createElement("span"); + + var inStyle = slice.style; + inStyle.backgroundColor = color; + inStyle.display = "block"; + inStyle.height = "1px"; + inStyle.overflow = "hidden"; + inStyle.fontSize = "1px"; + + var borderColor = this._borderColor(color,bgColor); + if ( this.options.border && n == 0 ) { + inStyle.borderTopStyle = "solid"; + inStyle.borderTopWidth = "1px"; + inStyle.borderLeftWidth = "0px"; + inStyle.borderRightWidth = "0px"; + inStyle.borderBottomWidth = "0px"; + inStyle.height = "0px"; // assumes css compliant box model + inStyle.borderColor = borderColor; + } + else if(borderColor) { + inStyle.borderColor = borderColor; + inStyle.borderStyle = "solid"; + inStyle.borderWidth = "0px 1px"; + } + + if ( !this.options.compact && (n == (this.options.numSlices-1)) ) + inStyle.height = "2px"; + + this._setMargin(slice, n, position); + this._setBorder(slice, n, position); + return slice; + }, + + _setOptions: function(options) { + this.options = { + corners : "all", + color : "fromElement", + bgColor : "fromParent", + blend : true, + border : false, + compact : false + } + Object.extend(this.options, options || {}); + + this.options.numSlices = this.options.compact ? 2 : 4; + if ( this._isTransparent() ) + this.options.blend = false; + }, + + _whichSideTop: function() { + if ( this._hasString(this.options.corners, "all", "top") ) + return ""; + + if ( this.options.corners.indexOf("tl") >= 0 && this.options.corners.indexOf("tr") >= 0 ) + return ""; + + if (this.options.corners.indexOf("tl") >= 0) + return "left"; + else if (this.options.corners.indexOf("tr") >= 0) + return "right"; + return ""; + }, + + _whichSideBottom: function() { + if ( this._hasString(this.options.corners, "all", "bottom") ) + return ""; + + if ( this.options.corners.indexOf("bl")>=0 && this.options.corners.indexOf("br")>=0 ) + return ""; + + if(this.options.corners.indexOf("bl") >=0) + return "left"; + else if(this.options.corners.indexOf("br")>=0) + return "right"; + return ""; + }, + + _borderColor : function(color,bgColor) { + if ( color == "transparent" ) + return bgColor; + else if ( this.options.border ) + return this.options.border; + else if ( this.options.blend ) + return this._blend( bgColor, color ); + else + return ""; + }, + + + _setMargin: function(el, n, corners) { + var marginSize = this._marginSize(n); + var whichSide = corners == "top" ? this._whichSideTop() : this._whichSideBottom(); + + if ( whichSide == "left" ) { + el.style.marginLeft = marginSize + "px"; el.style.marginRight = "0px"; + } + else if ( whichSide == "right" ) { + el.style.marginRight = marginSize + "px"; el.style.marginLeft = "0px"; + } + else { + el.style.marginLeft = marginSize + "px"; el.style.marginRight = marginSize + "px"; + } + }, + + _setBorder: function(el,n,corners) { + var borderSize = this._borderSize(n); + var whichSide = corners == "top" ? this._whichSideTop() : this._whichSideBottom(); + if ( whichSide == "left" ) { + el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = "0px"; + } + else if ( whichSide == "right" ) { + el.style.borderRightWidth = borderSize + "px"; el.style.borderLeftWidth = "0px"; + } + else { + el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = borderSize + "px"; + } + if (this.options.border != false) + el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = borderSize + "px"; + }, + + _marginSize: function(n) { + if ( this._isTransparent() ) + return 0; + + var marginSizes = [ 5, 3, 2, 1 ]; + var blendedMarginSizes = [ 3, 2, 1, 0 ]; + var compactMarginSizes = [ 2, 1 ]; + var smBlendedMarginSizes = [ 1, 0 ]; + + if ( this.options.compact && this.options.blend ) + return smBlendedMarginSizes[n]; + else if ( this.options.compact ) + return compactMarginSizes[n]; + else if ( this.options.blend ) + return blendedMarginSizes[n]; + else + return marginSizes[n]; + }, + + _borderSize: function(n) { + var transparentBorderSizes = [ 5, 3, 2, 1 ]; + var blendedBorderSizes = [ 2, 1, 1, 1 ]; + var compactBorderSizes = [ 1, 0 ]; + var actualBorderSizes = [ 0, 2, 0, 0 ]; + + if ( this.options.compact && (this.options.blend || this._isTransparent()) ) + return 1; + else if ( this.options.compact ) + return compactBorderSizes[n]; + else if ( this.options.blend ) + return blendedBorderSizes[n]; + else if ( this.options.border ) + return actualBorderSizes[n]; + else if ( this._isTransparent() ) + return transparentBorderSizes[n]; + return 0; + }, + + _hasString: function(str) { for(var i=1 ; i= 0) return true; return false; }, + _blend: function(c1, c2) { var cc1 = Rico.Color.createFromHex(c1); cc1.blend(Rico.Color.createFromHex(c2)); return cc1; }, + _background: function(el) { try { return Rico.Color.createColorFromBackground(el).asHex(); } catch(err) { return "#ffffff"; } }, + _isTransparent: function() { return this.options.color == "transparent"; }, + _isTopRounded: function() { return this._hasString(this.options.corners, "all", "top", "tl", "tr"); }, + _isBottomRounded: function() { return this._hasString(this.options.corners, "all", "bottom", "bl", "br"); }, + _hasSingleTextChild: function(el) { return el.childNodes.length == 1 && el.childNodes[0].nodeType == 3; } +} + +Rico.includeLoaded('ricoStyles.js'); diff --git a/NP_TrackBack/trunk/trackback/js/rico/ricoTree.js b/NP_TrackBack/trunk/trackback/js/rico/ricoTree.js new file mode 100644 index 0000000..45f7a95 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/ricoTree.js @@ -0,0 +1,318 @@ +// Rico Tree Control +// by Matt Brown +// Oct 2006 +// email: dowdybrown@yahoo.com + +// Requires prototype.js and ricoCommon.js + +// each node in nodeIndex is an Array with 6+n positions +// node[0] is 0/1 when the node is closed/open +// node[1] is 0/1 when the folder is closed/open +// node[2] is 1 if the node is a leaf node +// node[3] is the node id +// node[4] is the node description +// node[5] is 1 when the node is selectable, 0 otherwise +// node[6]...node[6+n] are the child nodes + +Rico.TreeControl = Class.create(); + +Rico.TreeControl.prototype = { + + initialize: function(id,url,options) { + Object.extend(this, new Rico.Popup({ignoreClicks:true})); + Object.extend(this.options, { + nodeIdDisplay:'none', // first, last, tooltip, or none + showCheckBox: false, + showFolders: false, + showPlusMinus: true, + defaultAction: this.nodeClick.bindAsEventListener(this), + height: '300px', + width: '300px', + leafIcon: Rico.imgDir+'doc.gif' + }); + Object.extend(this.options, options || {}); + this.img=[]; + this.FirstChildNode=6; + this.nodeIndex={}; + this.nodeCount=0; + this.foldersTree=0; + this.timeOutId=0; + this.id=id; + this.dataSource=url; + this.close=this.closePopup; + }, + + atLoad : function() { + var imgsrc = new Array("node.gif","nodelast.gif","folderopen.gif","folderclosed.gif"); + for (i=0;inot selectable, 1->selectable (use default action), otherwise the node is selectable and cells[4] contains the action + var content=[]; + for (var j=0; j0) { + var suffix=lastNode ? 'last' : ''; + if (this.options.showPlusMinus && foldersNode[2]) + this.showPlusMinus(row.insertCell(-1),foldersNode,suffix); + else + this.NodeImage(row.insertCell(-1),suffix) + newLeft.push(lastNode ? "nodeblank" : "nodeline") + } + if (this.options.showFolders) + this.showFolders(row.insertCell(-1),foldersNode); + if (this.options.showCheckBox && foldersNode[5]) + this.showCheckBox(row.insertCell(-1),foldersNode); + this.displayLabel(row,foldersNode) + this.treeDiv.appendChild(tab) + + if (foldersNode.length > this.FirstChildNode && foldersNode[0]) { + //there are sub-nodes and the folder is open + for (var i=this.FirstChildNode; i this.FirstChildNode) + img.onclick=this.openBranch.bindAsEventListener(this); + else + img.onclick=this.getChildren.bindAsEventListener(this); + var prefix=foldersNode[1] ? "nodem" : "nodep" + img.src=Rico.imgDir+prefix+suffix+".gif"; + td.appendChild(img) + }, + + showFolders: function(td,foldersNode) { + var img = document.createElement("img") + if (!foldersNode[2]) { + img.src=this.options.leafIcon; + } else { + img.name=foldersNode[3]; + img.style.cursor='pointer'; + if (foldersNode.length > this.FirstChildNode) + img.onclick=this.openBranch.bindAsEventListener(this); + else + img.onclick=this.getChildren.bindAsEventListener(this); + img.src=Rico.imgDir+(foldersNode[1] ? "folderopen.gif" : "folderclosed.gif"); + } + td.appendChild(img) + }, + + showCheckBox: function(td,foldersNode) { + var inp=document.createElement("input") + inp.type="checkbox" + inp.name=foldersNode[3] + td.appendChild(inp) + }, + + displayLabel: function(row,foldersNode) { + if (foldersNode[5]) { + var span=document.createElement('a'); + span.href='#'; + span.onclick=this.options.defaultAction; + } else { + var span=document.createElement('p'); + } + span.id=this.id+"__"+foldersNode[3]; + var desc=foldersNode[4]; + switch (this.options.nodeIdDisplay) { + case 'last': desc+=' ('+foldersNode[3]+')'; break; + case 'first': desc=foldersNode[3]+' - '+desc; break; + case 'tooltip': span.title=foldersNode[3]; break; + } + span.appendChild(document.createTextNode(desc)) + var td=row.insertCell(-1) + td.appendChild(span) + }, + + //when a parent is closed all children also are + closeFolders: function(foldersNode) { + var i=0 + if (foldersNode[2]) { + for (i=this.FirstChildNode; i< foldersNode.length; i++) + this.closeFolders(foldersNode[i]) + } + foldersNode[0] = 0 + foldersNode[1] = 0 + }, + + nodeClick: function(e) { + var node=Event.element(e); + if (this.returnValue) { + var v=node.id; + var i=v.indexOf('__'); + if (i>=0) v=v.substr(i+2); + this.returnValue(v,node.innerHTML); + } + this.close(); + }, + + //recurse over the tree structure + //called by openbranch + clickOnFolderRec: function(foldersNode, folderName) { + var i=0 + if (foldersNode[3] == folderName) { + if (foldersNode[0]) { + this.closeFolders(foldersNode) + } else { + foldersNode[0] = 1 + foldersNode[1] = 1 + } + } else if (foldersNode[2]) { + for (i=this.FirstChildNode; i< foldersNode.length; i++) + this.clickOnFolderRec(foldersNode[i], folderName) + } + }, + + openBranch: function(e) { + var node=Event.element(e); + this.clickOnFolderRec(this.foldersTree, node.name) + this.timeOutId = setTimeout(this.redrawTree.bind(this),100) + }, + + getChildren: function(e) { + var node=Event.element(e); + this.loadXMLDoc(node.name) + this.openBranch(e) + } + +} + +Rico.includeLoaded('ricoTree.js'); diff --git a/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_de.js b/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_de.js new file mode 100644 index 0000000..530820a --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_de.js @@ -0,0 +1,86 @@ +/***************************************************************** + Page : livegrid_DE.js + Description : LiveGrid text for German menus + Translator: rainer@langheiter@.com + Version 0.1 - please send corrections to dowdybrown@yahoo.com +******************************************************************/ +// 2007-02-09, made some improvements - debach@gmx.de + +RicoTranslate.addPhrase("Sort by","Sortiert nach") +RicoTranslate.addPhrase("Filter by","Gefiltert nach") +RicoTranslate.addPhrase("Hide","Verbergen") +RicoTranslate.addPhrase("Show","Zeige") +RicoTranslate.addPhrase("Show All","Alle zeigen") +RicoTranslate.addPhrase("Ascending","Aufsteigend") +RicoTranslate.addPhrase("Descending","Absteigend") + +RicoTranslate.addPhrase("Include only this value","Nur diesen Wert einbeziehen") +RicoTranslate.addPhrase("Exclude this value","Diesen Wert ausschließen") +RicoTranslate.addPhrase("Exclude this value also","Diesen Wert ebenfalls ausschließen") +RicoTranslate.addPhrase("Greater than or equal to this value","Größer oder gleich diesem Wert") +RicoTranslate.addPhrase("Less than or equal to this value","Kleiner oder gleich diesem wert") +RicoTranslate.addPhrase("Contains keyword","Enthält Schlüsselwort") +RicoTranslate.addPhrase("Change keyword","Schlüsselwort ändern ") +RicoTranslate.addPhrase("Enter keyword to search for","Schlüsselwort eintragen, nach dem gesucht werden soll") +RicoTranslate.addPhrase("use * as a wildcard","verwende * als Wildcard") +RicoTranslate.addPhrase("Remove filter","Entferne Filter") + +RicoTranslate.addPhrase("Waiting for data","Warte auf Daten") +RicoTranslate.addPhrase("Request for data timed out","Zeitüberschreitung") + +RicoTranslate.addPhrase("No matching records","Keine übereinstimmenden Einträge") +RicoTranslate.addPhrase("Listing records","Zeige Einträge") +RicoTranslate.addPhrase("of","von") +RicoTranslate.addPhrase("of about","von ungefähr") + +RicoTranslate.monthNames=["Januar", "Februar", "März", "April", "Mai","Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"] +RicoTranslate.dayNames=["Sonntag", "Montag","Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"] + +RicoTranslate.thouSep="." +RicoTranslate.decPoint="," +RicoTranslate.dateFmt="dd.mm.yyyy" + +// added for 22 August release + +RicoTranslate.addPhrase("Print","Druck") +RicoTranslate.addPhrase("Export","Exportiert") +RicoTranslate.addPhrase("Visible rows","Sichtbare Zeilen") +RicoTranslate.addPhrase("All rows","Alle Zeilen") + +// added for Feb 2007 release + +RicoTranslate.addPhrase("Loading","Lade") +RicoTranslate.addPhrase("minutes before your session expires","Minuten, bevor Ihre Sitzung abläuft") // formal +//RicoTranslate.addPhrase("minutes before your session expires","Minuten, bevor deine Sitzung abläuft") // informal +//RicoTranslate.addPhrase("minutes before your session expires","Minuten, bevor die Sitzung abläuft") // indirect +RicoTranslate.addPhrase("EXPIRED","ABGELAUFEN") +RicoTranslate.addPhrase("Close","Schließen") +RicoTranslate.addPhrase("Cancel","Abbrechen") +RicoTranslate.addPhrase("Save","Speichere") +RicoTranslate.addPhrase("Add","Erstelle") +RicoTranslate.addPhrase("Edit","Bearbeite") +RicoTranslate.addPhrase("Delete","Lösche") +RicoTranslate.addPhrase("Are you sure you want to delete","Möchten Sie dies wirklich löschen:") // formal +//RicoTranslate.addPhrase("Are you sure you want to delete","Möchtest du das wirklich löschen:") // informal +//RicoTranslate.addPhrase("Are you sure you want to delete","Wirklich löschen:") // indirect +RicoTranslate.addPhrase("record","Eintrag") +RicoTranslate.addPhrase("this record","diesen Eintrag") // "dieser"? +RicoTranslate.addPhrase("new record","neuen Eintrag") // "neuer"? +RicoTranslate.addPhrase("Please enter","Bitte eingeben") +RicoTranslate.addPhrase("a value for","einen Wert für") +RicoTranslate.addPhrase("an integer value for","einen ganzzahligen Wert für") +RicoTranslate.addPhrase("a positive integer value for","einen positiven ganzzahligen Wert für") +RicoTranslate.addPhrase("The request returned an error","Die Anfrage ergab einen Fehler") + +// for demo only: + +RicoTranslate.addPhrase("Show orders for","Zeige Bestellungen für") +RicoTranslate.addPhrase("Show order detail","Zeige Bestelldetails") +RicoTranslate.addPhrase("order","Bestellung") +RicoTranslate.addPhrase("this order","diese Bestellung") +RicoTranslate.addPhrase("new order","neue Bestellung") + +// add your own here: + +RicoTranslate.addPhrase("Visible rows to web page","Sichtbare Zeilen auf eine Webseite") +RicoTranslate.addPhrase("All rows to web page","Alle Zeilen auf eine Webseite") \ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_es.js b/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_es.js new file mode 100644 index 0000000..dc5b8f6 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_es.js @@ -0,0 +1,79 @@ +/***************************************************************** + Page : livegrid_es.js + Description : LiveGrid text for Spanish menus + Version 0.2 (by Marco Scarnatto) + If you have better translations, or would like to include + translations for another language, please send them to dowdybrown@yahoo.com +******************************************************************/ + +RicoTranslate.addPhrase("Sort by","Ordenar por") +RicoTranslate.addPhrase("Filter by","Filtrar por") +RicoTranslate.addPhrase("Hide","Ocultar") +RicoTranslate.addPhrase("Show","Mostrar") +RicoTranslate.addPhrase("Show All","Mostrar todo") +RicoTranslate.addPhrase("Ascending","Ascendente") +RicoTranslate.addPhrase("Descending","Descendente") + +RicoTranslate.addPhrase("Include only this value","Incluir solo este valor") +RicoTranslate.addPhrase("Exclude this value","Excluir este valor") +RicoTranslate.addPhrase("Exclude this value also","Excluir este valor también") +RicoTranslate.addPhrase("Greater than or equal to this value","Mayor o igual a este valor") +RicoTranslate.addPhrase("Less than or equal to this value","Menor o igual a este valor") +RicoTranslate.addPhrase("Contains keyword","Contiene el texto") +RicoTranslate.addPhrase("Change keyword","Cambiar texto") +RicoTranslate.addPhrase("Enter keyword to search for","Ingrese texto a buscar") +RicoTranslate.addPhrase("use * as a wildcard","use * como un comodín") +RicoTranslate.addPhrase("Remove filter","Quitar filtro") + +RicoTranslate.addPhrase("Waiting for data","Esperando datos") +RicoTranslate.addPhrase("Request for data timed out","Tiempo excedido en recibir datos ") + +RicoTranslate.addPhrase("No matching records","No hay datos coincidentes") +RicoTranslate.addPhrase("Listing records","Mostrando datos") +RicoTranslate.addPhrase("of","de") +RicoTranslate.addPhrase("of about","de alrededor de") + +RicoTranslate.thouSep="," +RicoTranslate.decPoint="." +RicoTranslate.dateFmt="dd/mm/yyyy" + +RicoTranslate.monthNames=['Enero','Febrero', 'Marzo', 'Abril', 'Mayo','Junio', 'Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'] +RicoTranslate.dayNames=['Domingo','Lunes','Martes','Miércoles','Jueves','Viernes','Sábado'] + +// added for Aug 2006 release + +RicoTranslate.addPhrase("Print","Imprimir") +RicoTranslate.addPhrase("Export","Exportar") +RicoTranslate.addPhrase("Visible rows","Filas visibles") +RicoTranslate.addPhrase("All rows","Todas las filas") + +// added for Feb 2007 release + +RicoTranslate.addPhrase("Loading","Cargar") +RicoTranslate.addPhrase("minutes before your session expires","minutos antes de su sesión expiran") +RicoTranslate.addPhrase("EXPIRED","EXPIRADO") +RicoTranslate.addPhrase("Close","Cerrar") +RicoTranslate.addPhrase("Cancel","Cancelar") +RicoTranslate.addPhrase("Save","Guardar") +RicoTranslate.addPhrase("Add","Añadir") +RicoTranslate.addPhrase("Edit","Editar") +RicoTranslate.addPhrase("Delete","Borrar") +RicoTranslate.addPhrase("Are you sure you want to delete","¿Está seguro de que quiere borrar") +RicoTranslate.addPhrase("record","expediente") +RicoTranslate.addPhrase("this record","este expediente") +RicoTranslate.addPhrase("new record","expediente nuevo") +RicoTranslate.addPhrase("Please enter","Introduzca") +RicoTranslate.addPhrase("a value for","un valor para") +RicoTranslate.addPhrase("an integer value for","un valor del número entero para") +RicoTranslate.addPhrase("a positive integer value for","un valor positivo del número entero para") +RicoTranslate.addPhrase("The request returned an error","Un error ocurrió mientras que recibía datos") + +// for demo only: + +RicoTranslate.addPhrase("Show orders for","Mostrar las ordenes de") +RicoTranslate.addPhrase("Show order detail","Mostrar detalle de la orden") +RicoTranslate.addPhrase("order","la orden") +RicoTranslate.addPhrase("this order","esta orden") +RicoTranslate.addPhrase("new order","nueva orden") + +// add your own here: diff --git a/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_fr.js b/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_fr.js new file mode 100644 index 0000000..7f92442 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_fr.js @@ -0,0 +1,79 @@ +/***************************************************************** + Page : livegrid_FR.js + Description : LiveGrid text for French menus + Version 0.3 (revisions by Pierre Grellet) + If you have better translations, or would like to include + translations for another language, please send them to dowdybrown@yahoo.com +******************************************************************/ + +RicoTranslate.addPhrase("Sort by","Trier par") +RicoTranslate.addPhrase("Filter by","Filtrer par") +RicoTranslate.addPhrase("Hide","Masquer") +RicoTranslate.addPhrase("Show","Afficher") +RicoTranslate.addPhrase("Show All","Afficher tous") +RicoTranslate.addPhrase("Ascending","Croissant") +RicoTranslate.addPhrase("Descending","Décroissant") + +RicoTranslate.addPhrase("Include only this value","Inclure seulement cette valeur") +RicoTranslate.addPhrase("Exclude this value","Exclure cette valeur aussi") +RicoTranslate.addPhrase("Exclude this value also","Exclure cette valeur") +RicoTranslate.addPhrase("Greater than or equal to this value","Supérieur ou égal à cette valeur") +RicoTranslate.addPhrase("Less than or equal to this value","Inférieur ou égal à cette valeur") +RicoTranslate.addPhrase("Contains keyword","Contenant le mot-clé") +RicoTranslate.addPhrase("Change keyword","Changer le mot-clé") +RicoTranslate.addPhrase("Enter keyword to search for","Écrivez le mot-clé à rechercher") +RicoTranslate.addPhrase("use * as a wildcard","utiliser * comme caractère générique") +RicoTranslate.addPhrase("Remove filter","Enlever le filtre") + +RicoTranslate.addPhrase("Waiting for data","En attente des données") +RicoTranslate.addPhrase("Request for data timed out","La requête a atteint sa limite de temps ") + +RicoTranslate.addPhrase("No matching records","Aucun articles ne correspond") +RicoTranslate.addPhrase("Listing records","Résultats") +RicoTranslate.addPhrase("of","de") +RicoTranslate.addPhrase("of about","sur un total d'environ") + +RicoTranslate.thouSep="'" +RicoTranslate.decPoint="." +RicoTranslate.dateFmt="dd.mm.yyyy" + +RicoTranslate.monthNames=['Janvier','Février', 'Mars', 'Avril', 'Mai','Juin', 'Juillet','Août','Septembre','Octobre','Novembre','Décembre'] +RicoTranslate.dayNames=['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'] + +// added for 22 August release + +RicoTranslate.addPhrase("Print","Imprimer") +RicoTranslate.addPhrase("Export","Exporter") +RicoTranslate.addPhrase("Visible rows","Rangs visible") +RicoTranslate.addPhrase("All rows","Tous les rangs") + +// added for Feb 2007 release + +RicoTranslate.addPhrase("Loading","Chargement") +RicoTranslate.addPhrase("minutes before your session expires","minutes avant votre session expire") +RicoTranslate.addPhrase("EXPIRED","EXPIRÉ") +RicoTranslate.addPhrase("Close","Fermer") +RicoTranslate.addPhrase("Cancel","Annuler") +RicoTranslate.addPhrase("Save","Sauvegarder") +RicoTranslate.addPhrase("Add","Ajouter") +RicoTranslate.addPhrase("Edit","Éditer") +RicoTranslate.addPhrase("Delete","Supprimer") +RicoTranslate.addPhrase("Are you sure you want to delete","Êtes-vous sûr de vouloir supprimer") +RicoTranslate.addPhrase("record","enregistrement") +RicoTranslate.addPhrase("this record","cet enregistrement") +RicoTranslate.addPhrase("new record","nouvel enregistrement") +RicoTranslate.addPhrase("Please enter","Veuillez saisir") +RicoTranslate.addPhrase("a value for","une valeur pour") +RicoTranslate.addPhrase("an integer value for","un nombre entier pour") +RicoTranslate.addPhrase("a positive integer value for","un nombre positif pour") +RicoTranslate.addPhrase("The request returned an error","La requête a renvoyé une erreur") + +// for demo only: + +RicoTranslate.addPhrase("Show orders for","Montrer les commandes pour") +RicoTranslate.addPhrase("Show order detail","Montrer les détails de la commande") +RicoTranslate.addPhrase("order","la commande") +RicoTranslate.addPhrase("this order","cette commande") +RicoTranslate.addPhrase("new order","nouvelle commande") + +// add your own here: diff --git a/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_it.js b/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_it.js new file mode 100644 index 0000000..efc7124 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_it.js @@ -0,0 +1,80 @@ +/***************************************************************** + Page : livegrid_IT.js + Description : LiveGrid text for Italian menus + Version 0.1 (these are guesses based mostly on babelfish results) + If you have better translations, or would like to include + translations for another language, please send them to dowdybrown@yahoo.com +******************************************************************/ + +RicoTranslate.addPhrase("Sort by","Ordina per") +RicoTranslate.addPhrase("Filter by","Filtra per") +RicoTranslate.addPhrase("Hide","Nascondi") +RicoTranslate.addPhrase("Show","Mostra") +RicoTranslate.addPhrase("Show All","Mostra Tutte") +RicoTranslate.addPhrase("Ascending","Crescente") +RicoTranslate.addPhrase("Descending","Decrescente") + +RicoTranslate.addPhrase("Include only this value","Ritieni soltanto questo valore") +RicoTranslate.addPhrase("Exclude this value","Escludi questo valore") +RicoTranslate.addPhrase("Exclude this value also","Escludi questo valore anche") +RicoTranslate.addPhrase("Greater than or equal to this value","Superiore o uguale a questo valore") +RicoTranslate.addPhrase("Less than or equal to this value","Inferiore o uguale a questo valore") +RicoTranslate.addPhrase("Contains keyword","Contiene la parola chiave") +RicoTranslate.addPhrase("Change keyword","Cambia la parola chiave") +RicoTranslate.addPhrase("Enter keyword to search for","Entra la parola chiave da cercare") +RicoTranslate.addPhrase("use * as a wildcard","usa * come \"jolly\"") +RicoTranslate.addPhrase("Remove filter","Rimuovi filtro") + +RicoTranslate.addPhrase("Waiting for data","Attendere per i dati") +RicoTranslate.addPhrase("Request for data timed out","La richiesta dei dati ha raggiunto il limite di tempo") + +RicoTranslate.addPhrase("No matching records","Nessun articoli corrispondenti") +RicoTranslate.addPhrase("Listing records","Risultati") +RicoTranslate.addPhrase("of","di") +RicoTranslate.addPhrase("of about","di circa") + +RicoTranslate.monthNames=["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"] +RicoTranslate.dayNames=["Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato"] + +RicoTranslate.thouSep="." +RicoTranslate.decPoint="," +RicoTranslate.dateFmt="dd/mm/yyyy" + +// added for Feb 2007 release + +RicoTranslate.addPhrase("Loading","Caricamento") +RicoTranslate.addPhrase("minutes before your session expires","minuti prima che la vostra sessione termini") +RicoTranslate.addPhrase("EXPIRED","TERMINATA") +RicoTranslate.addPhrase("Close","Chiudi") +RicoTranslate.addPhrase("Cancel","Annulla") +RicoTranslate.addPhrase("Save","Salva") +RicoTranslate.addPhrase("Add","Aggiungi") +RicoTranslate.addPhrase("Edit","Modifica") +RicoTranslate.addPhrase("Delete","Cancella") +RicoTranslate.addPhrase("Are you sure you want to delete","Siete sicuri che volete cancellare") +RicoTranslate.addPhrase("record","registrazione") +RicoTranslate.addPhrase("this record","qesta registrazione") +RicoTranslate.addPhrase("new record","nuova registrazione") +RicoTranslate.addPhrase("Please enter","Per favore inserire") +RicoTranslate.addPhrase("a value for","un valore per") +RicoTranslate.addPhrase("an integer value for","un numero intero per") +RicoTranslate.addPhrase("a positive integer value for","un numero intero positivo per") +RicoTranslate.addPhrase("The request returned an error","La richiesta ha generato un errore") + +// for demo only: + +RicoTranslate.addPhrase("Show orders for","Mostra gli ordini per") +RicoTranslate.addPhrase("Show order detail","Mostra i dettagli dell'ordine") +RicoTranslate.addPhrase("order","ordine") +RicoTranslate.addPhrase("this order","questo ordine") +RicoTranslate.addPhrase("new order","nuovo ordine") + +// added for 22 August release + +RicoTranslate.addPhrase("Print","Stampa") +RicoTranslate.addPhrase("Export","Esporta") +RicoTranslate.addPhrase("Visible rows","Righe visibili") +RicoTranslate.addPhrase("All rows","Tutte le righe") + +// add your own here: + diff --git a/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_ja.js b/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_ja.js new file mode 100644 index 0000000..479f9e2 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_ja.js @@ -0,0 +1,49 @@ +/***************************************************************** + Page : livegrid_ja.js + Description : LiveGrid text for Japanese menus + Translator: hsur +******************************************************************/ + +RicoTranslate.addPhrase("Sort by","ソート") +RicoTranslate.addPhrase("Filter by","絞込み") +RicoTranslate.addPhrase("Hide","隠す") +RicoTranslate.addPhrase("Show","表示") +RicoTranslate.addPhrase("Ascending","昇順") +RicoTranslate.addPhrase("Descending","降順") + +RicoTranslate.addPhrase("Include only this value","この値を含む") +RicoTranslate.addPhrase("Exclude this value","この値を除く") +RicoTranslate.addPhrase("Greater than or equal to this value","これ以上の値") +RicoTranslate.addPhrase("Less than or equal to this value","これ以下の値") +RicoTranslate.addPhrase("Contains keyword","このキーワードを含む") +RicoTranslate.addPhrase("Change keyword","キーワードを変更") +RicoTranslate.addPhrase("Enter keyword to search for","キーワードを入力してください") +RicoTranslate.addPhrase("use * as a wildcard","ワイルドカードとして*を使います") +RicoTranslate.addPhrase("also","も") +RicoTranslate.addPhrase("Remove filter","絞込みを削除") + +RicoTranslate.addPhrase("Waiting for data","データ取得中") +RicoTranslate.addPhrase("Request for data timed out","タイムアウトしました") + +RicoTranslate.addPhrase("No matching records","一致するレコードはありません") +RicoTranslate.addPhrase("Listing records","") +RicoTranslate.addPhrase("of","of") +RicoTranslate.addPhrase("of about","of about") + +RicoTranslate.monthNames=["1月", "2月", "3月", "4月", "5月","6月", "7月", "8月", "9月", "10月", "11月", "12月"] +RicoTranslate.dayNames=["月","火", "æ°´","木", "金", "土", "日"] + +RicoTranslate.thouSep="." +RicoTranslate.decPoint="," +RicoTranslate.dateFmt="yyyy/mm/dd" +RicoTranslate.timeFmt="HH:nn:ss" + +// added for 22 August release + +RicoTranslate.addPhrase("Print","印刷") +RicoTranslate.addPhrase("Export","抽出") +RicoTranslate.addPhrase("Visible rows","Visible rows") +RicoTranslate.addPhrase("All rows","全ての行") + +// add your own here: + diff --git a/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_pt.js b/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_pt.js new file mode 100644 index 0000000..bdaa9d2 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_pt.js @@ -0,0 +1,55 @@ +/***************************************************************** + Page : livegrid_pt.js (brazilian) + Description : LiveGrid text for Brazilian Portuguese menus + Version 0.1 (by Adriano Accorsi - adriano@token.com.br) + If you have better translations, or would like to include + translations for another language, please send them to dowdybrown@yahoo.com +******************************************************************/ + +RicoTranslate.addPhrase("Sort by","Ordenar por") +RicoTranslate.addPhrase("Filter by","Filtrar por") +RicoTranslate.addPhrase("Hide","Ocultar") +RicoTranslate.addPhrase("Show","Exibir") +RicoTranslate.addPhrase("Show All","Exibir tudo") +RicoTranslate.addPhrase("Ascending","Ascendente") +RicoTranslate.addPhrase("Descending","Descendente") + +RicoTranslate.addPhrase("Include only this value","Incluir apenas este valor") +RicoTranslate.addPhrase("Exclude this value","Excluir este valor") +RicoTranslate.addPhrase("Greater than or equal to this value","Maior ou igual a este valor") +RicoTranslate.addPhrase("Less than or equal to this value","Menor ou igual a este valor") +RicoTranslate.addPhrase("Contains keyword","Contém texto") +RicoTranslate.addPhrase("Change keyword","Alterar texto") +RicoTranslate.addPhrase("Enter keyword to search for","Informe texto a ser pesquisado") +RicoTranslate.addPhrase("use * as a wildcard","use * como 'coringa'") +RicoTranslate.addPhrase("also","também") +RicoTranslate.addPhrase("Remove filter","Remover filtro") + +RicoTranslate.addPhrase("Waiting for data","Aguardando dados") +RicoTranslate.addPhrase("Request for data timed out","Tempo esgotado para espera de dados") + +RicoTranslate.addPhrase("No matching records","Nenhum registro encontrado.") +RicoTranslate.addPhrase("Listing records","Listar registros") +RicoTranslate.addPhrase("of","de") +RicoTranslate.addPhrase("of about","de aproximadamente") + +RicoTranslate.thouSep="." +RicoTranslate.decPoint="," +RicoTranslate.dateFmt="dd/mm/yyyy" + +RicoTranslate.monthNames=["Janeiro", "Fevereiro", "Março", "Abril", "Maio","Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"] +RicoTranslate.dayNames=["Domingo", "Segunda","Terça", "Quarta", "Quinta", "Sexta", "Sábado"] + +// added for 22 August release + +RicoTranslate.addPhrase("Print","Imprimir") +RicoTranslate.addPhrase("Export","Exportar") +RicoTranslate.addPhrase("Visible rows","Fileiras visíveis") +RicoTranslate.addPhrase("All rows","Todas as fileiras") + +// for demo only: + +RicoTranslate.addPhrase("Show orders for","Exibir pedidos de") +RicoTranslate.addPhrase("Show order detail","Exibir detalhes do pedido") + +// add your own here: diff --git a/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_ru.js b/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_ru.js new file mode 100644 index 0000000..c4ceea7 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_ru.js @@ -0,0 +1,82 @@ +/***************************************************************** + Page : livegrid_ru.js + Description : LiveGrid text for Russian menus + Version 0.2 (by Illiya Gannitskiy,Alexey Uvarov) + If you have better translations, or would like to include + translations for another language, please send them to dowdybrown@yahoo.com +******************************************************************/ + +RicoTranslate.addPhrase("Sort by","Ñîðòèðîâêà ïî") +RicoTranslate.addPhrase("Filter by","Ôèëüòðàöèÿ ïî") +RicoTranslate.addPhrase("Hide","Ñïðÿòàòü") +RicoTranslate.addPhrase("Show","Ïîêàçàòü") +RicoTranslate.addPhrase("Show All","Ïîêàçàòü âñå") +RicoTranslate.addPhrase("Ascending","Âîçðàñòàþùàÿ") +RicoTranslate.addPhrase("Descending","Óáûâàþùàÿ") + +RicoTranslate.addPhrase("Include only this value","Âêëþ÷èòü òîëüêî ýòî çíà÷åíèå") +RicoTranslate.addPhrase("Exclude this value","Èñêëþ÷èòü ýòî çíà÷åíèå") +RicoTranslate.addPhrase("Greater than or equal to this value","Áîëüøå èëè ðàâíî äàííîìó çíà÷åíèþ") +RicoTranslate.addPhrase("Less than or equal to this value","Ìåíüøå èëè ðàâíî äàííîìó çíà÷åíèþ") +RicoTranslate.addPhrase("Contains keyword","Ñîäåðæèò çíà÷åíèå") +RicoTranslate.addPhrase("Change keyword","Èçìåíèòü çíà÷åíèå") +RicoTranslate.addPhrase("Enter keyword to search for","Èñêàòü ïî êëþ÷ó") +RicoTranslate.addPhrase("use * as a wildcard","Èñïîëüçîâàòü * äëÿ âñåõ çàïèñåé") +RicoTranslate.addPhrase("also","òàêæå") +RicoTranslate.addPhrase("Remove filter","Óáðàòü ôèëüòð") + +RicoTranslate.addPhrase("Waiting for data","Îæèäàíèå äàííûõ") +RicoTranslate.addPhrase("Request for data timed out","Ïðåâûøåí èíòåðâàë îæèäàíèÿ äàííûõ") + +RicoTranslate.addPhrase("No matching records","Íåò ñîâïàäåíèé") +RicoTranslate.addPhrase("Listing records","Ïðîñìîòð çàïèñåé") +RicoTranslate.addPhrase("of","èç") +RicoTranslate.addPhrase("of about","èç î") + +RicoTranslate.thouSep="," +RicoTranslate.decPoint="." +RicoTranslate.dateFmt="dd/mm/yyyy" + +RicoTranslate.monthNames=['ßíâàðü','Ôåâðàëü', 'Ìàðò', 'Àïðåëü', 'Ìàé','Èþíü', 'Èþëü','Àâãóñò','Ñåíòÿáðü','Îòêòÿáðü','Íîÿáðü','Äåêàáðü'] +RicoTranslate.dayNames=['Ïîíåäåëüíèê','Âòîðíèê','Ñðåäà','×åòâåðã','Ïÿòíèöà','Ñóááîòà','Âîñêðåñåíüå'] + +// added for 22 August release + +RicoTranslate.addPhrase("Print","Ïå÷àòü") +RicoTranslate.addPhrase("Export","Ýêñïîðò") +RicoTranslate.addPhrase("Visible rows","Âèäèìûå çàïèñè") +RicoTranslate.addPhrase("All rows","Âñå çàïèñè") + +// added for Feb 2007 release + +RicoTranslate.addPhrase("Loading","Çàãðóçêà") +RicoTranslate.addPhrase("minutes before your session expires","ìèíóò äî èñòå÷åíèÿ ñåññèè") +RicoTranslate.addPhrase("EXPIRED","ÈÑÒÅÊËÎ") +RicoTranslate.addPhrase("Close","Çàêðûòî") +RicoTranslate.addPhrase("Cancel","Îòìåíà") +RicoTranslate.addPhrase("Save","Ñîõðàíèòü") +RicoTranslate.addPhrase("Add","Äîáàâèòü") +RicoTranslate.addPhrase("Edit","Ðåäàêòèðîâàòü") +RicoTranslate.addPhrase("Delete","Óäàëèòü") +RicoTranslate.addPhrase("Are you sure you want to delete","Âû óâåðåííû,÷òî õîòèòå óäàëèòü") +RicoTranslate.addPhrase("record","çàïèñü") +RicoTranslate.addPhrase("this record","ýòà çàïèñü") +RicoTranslate.addPhrase("new record","íîâàÿ çàïèñü") +RicoTranslate.addPhrase("Please enter","Ïîæàëóéñòà ââåäèòå") +RicoTranslate.addPhrase("a value for","çíà÷åíèå äëÿ") +RicoTranslate.addPhrase("an integer value for","öåëîå çíà÷åíèå äëÿ") +RicoTranslate.addPhrase("a positive integer value for","ïîëîæèòåëüíîå öåëîå çíà÷åíèå äëÿ") +RicoTranslate.addPhrase("The request returned an error","Çàïðîñ âîçâðàòèë îøèáêó") + + + +// for demo only: + +RicoTranslate.addPhrase("Show orders for","Ïîêàçàòü çíà÷åíèÿ äëÿ") +RicoTranslate.addPhrase("Show order detail","Ïîêàçàòü çíà÷åíèÿ ïîäðîáíî") +RicoTranslate.addPhrase("order","çíà÷åíèå") +RicoTranslate.addPhrase("this order","ýòî çíà÷åíèå") +RicoTranslate.addPhrase("new order","íîâîå çíà÷åíèå") + + +// add your own here: diff --git a/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_ua.js b/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_ua.js new file mode 100644 index 0000000..18206c8 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_ua.js @@ -0,0 +1,82 @@ +/***************************************************************** + Page : livegrid_ua.js + Description : LiveGrid text for Ukrainian menus + Version 0.1 (by Illiya Gannitskiy,Alexey Uvarov) + If you have better translations, or would like to include + translations for another language, please send them to dowdybrown@yahoo.com +******************************************************************/ + +RicoTranslate.addPhrase("Sort by","Cîðòóâàííÿ ïî") +RicoTranslate.addPhrase("Filter by","Ô³ëüòðàö³ÿ ïî") +RicoTranslate.addPhrase("Hide","Ñõîâàòè") +RicoTranslate.addPhrase("Show","Ïîêàçàòè") +RicoTranslate.addPhrase("Show All","Ïîêàçàòè âñå") +RicoTranslate.addPhrase("Ascending","Çðîñòàþ÷à") +RicoTranslate.addPhrase("Descending","Óáóâàþ÷à") + +RicoTranslate.addPhrase("Include only this value","Âêëþ÷èòè ò³ëüêè öå çíà÷åííÿ") +RicoTranslate.addPhrase("Exclude this value","Âèêëþ÷èòè öå çíà÷åííÿ") +RicoTranslate.addPhrase("Greater than or equal to this value","Á³ëüøå àáî ð³âíî äàíîìó çíà÷åííþ") +RicoTranslate.addPhrase("Less than or equal to this value","Ìåíøå àáî ð³âíî äàíîìó çíà÷åííþ") +RicoTranslate.addPhrase("Contains keyword","̳ñòèòü çíà÷åííÿ") +RicoTranslate.addPhrase("Change keyword","Çì³íèòè çíà÷åííÿ") +RicoTranslate.addPhrase("Enter keyword to search for","Øóêàòè ïî êëþ÷ó") +RicoTranslate.addPhrase("use * as a wildcard","Âèêîðèñòîâóâàòè * äëÿ âñ³õ çàïèñ³â") +RicoTranslate.addPhrase("also","òàêîæ") +RicoTranslate.addPhrase("Remove filter","Ïðèáðàòè ô³ëüòð") + +RicoTranslate.addPhrase("Waiting for data","Î÷³êóâàííÿ äàíèõ") +RicoTranslate.addPhrase("Request for data timed out","Ïåðåâèùåíèé ³íòåðâàë î÷³êóâàííÿ äàíèõ") + +RicoTranslate.addPhrase("No matching records","Íåìຠçá³ã³â") +RicoTranslate.addPhrase("Listing records","Ïåðåãëÿä çàïèñ³â") +RicoTranslate.addPhrase("of","ç") +RicoTranslate.addPhrase("of about","ç î") + +RicoTranslate.thouSep="," +RicoTranslate.decPoint="." +RicoTranslate.dateFmt="dd/mm/yyyy" + +RicoTranslate.monthNames=['ѳ÷åíü','Ëþòèé', 'Áåðåçåíü', 'Êâ³òåíü', 'Òðàâåíü','×åðâåíü', 'Ëèïåíü','Ñåðïåíü','Âåðåñåíü','Æîâòåíü','Ëèñòîïàä','Ãðóäåíü'] +RicoTranslate.dayNames=['Ïîíåä³ëîê','³âòîðîê','Ñåðåäà','×åòâåð','Ï'ÿòíèöÿ','Ñóáîòà','Íåä³ëÿ'] + +// added for 22 August release + +RicoTranslate.addPhrase("Print","Äðóê") +RicoTranslate.addPhrase("Export","Åêñïîðò") +RicoTranslate.addPhrase("Visible rows","Âèäèì³ çàïèñè") +RicoTranslate.addPhrase("All rows","Âñ³ çàïèñè") + +// added for Feb 2007 release + +RicoTranslate.addPhrase("Loading","Çàâàíòàæåííÿ") +RicoTranslate.addPhrase("minutes before your session expires","õâèëèí äî çàê³í÷åííÿ ñåñ³¿") +RicoTranslate.addPhrase("EXPIRED","ÇÀʲÍ×ÈËÎÑß") +RicoTranslate.addPhrase("Close","Çàêðèòî") +RicoTranslate.addPhrase("Cancel","³äì³íà") +RicoTranslate.addPhrase("Save","Çáåðåãòè") +RicoTranslate.addPhrase("Add","Äîäàòè") +RicoTranslate.addPhrase("Edit","Ðåäàãóâàòè") +RicoTranslate.addPhrase("Delete","Âèäàëèòè") +RicoTranslate.addPhrase("Are you sure you want to delete","Âè óïåâíåí³,ùî áàæàºòå âèäàëèòè") +RicoTranslate.addPhrase("record","çàïèñ") +RicoTranslate.addPhrase("this record","öåé çàïèñ") +RicoTranslate.addPhrase("new record","íîâèé çàïèñ") +RicoTranslate.addPhrase("Please enter","Áóäü ëàñêà, ââåä³òü") +RicoTranslate.addPhrase("a value for","çíà÷åííÿ äëÿ") +RicoTranslate.addPhrase("an integer value for","ö³ëå çíà÷åííÿ äëÿ") +RicoTranslate.addPhrase("a positive integer value for","ïîçèòèâíå ö³ëå çíà÷åííÿ äëÿ") +RicoTranslate.addPhrase("The request returned an error","Çàïèò ïîâåðíóâ ïîìèëêó") + + + +// for demo only: + +RicoTranslate.addPhrase("Show orders for","Ïîêàçàòè çíà÷åííÿ") +RicoTranslate.addPhrase("Show order detail","Ïîêàçàòè çíà÷åííÿ äåòàëüíî") +RicoTranslate.addPhrase("order","Çíà÷åííÿ") +RicoTranslate.addPhrase("this order","öå çíà÷åííÿ") +RicoTranslate.addPhrase("new order","íîâå çíà÷åííÿ") + + +// add your own here: diff --git a/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_zh.js b/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_zh.js new file mode 100644 index 0000000..96b9a78 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/js/rico/translations/livegrid_zh.js @@ -0,0 +1,55 @@ +/***************************************************************** + Page : livegrid_zh.js + Description : LiveGrid text for CHINA menus + Translator: Sam Shan at gz_shanming@yahoo.com + Version 0.1 - please send corrections to dowdybrown@yahoo.com + Version 0.2 - Updated based on Xinjun liu's comments. +******************************************************************/ + +RicoTranslate.addPhrase("Sort by","排序") +RicoTranslate.addPhrase("Filter by","过滤") +RicoTranslate.addPhrase("Hide","隐藏") +RicoTranslate.addPhrase("Show","显示") +RicoTranslate.addPhrase("Ascending","升序") +RicoTranslate.addPhrase("Descending","降序") + +RicoTranslate.addPhrase("Include only this value","只包含此值") +RicoTranslate.addPhrase("Exclude this value","不包含此值") +RicoTranslate.addPhrase("Greater than or equal to this value","大于等于") +RicoTranslate.addPhrase("Less than or equal to this value","小于等于") +RicoTranslate.addPhrase("Contains keyword","包含关键字") +RicoTranslate.addPhrase("Change keyword","更改关键字") +RicoTranslate.addPhrase("Enter keyword to search for","输入关键字") +RicoTranslate.addPhrase("use * as a wildcard","使用*通配符") +RicoTranslate.addPhrase("also","也") +RicoTranslate.addPhrase("Remove filter","移除过滤器") + +RicoTranslate.addPhrase("Waiting for data","等待接收数据") +RicoTranslate.addPhrase("Request for data timed out","等待数据超时") + +RicoTranslate.addPhrase("No matching records","没有匹配的数据") +RicoTranslate.addPhrase("Listing records","列出纪录") +RicoTranslate.addPhrase("of","共") +RicoTranslate.addPhrase("of about","大约") + +RicoTranslate.monthNames=["一月", "二月", "三月", "四月", "五月","六月", "七月", "八月", "九月", "十月", "十一月", "十二月"] +RicoTranslate.dayNames=["星期日","星期一", "星期二","星期三", "星期四", "星期五", "星期六"] + +RicoTranslate.thouSep="." +RicoTranslate.decPoint="," +RicoTranslate.dateFmt="yyyy/mm/dd" + +// added for 22 August release + +RicoTranslate.addPhrase("Print","打印") +RicoTranslate.addPhrase("Export","输出") +RicoTranslate.addPhrase("Visible rows","当前显示记录") +RicoTranslate.addPhrase("All rows","所有记录") + +// for demo only: + +RicoTranslate.addPhrase("Show orders for","显示订单") +RicoTranslate.addPhrase("Show order detail","显示订单详情") + +// add your own here: + diff --git a/NP_TrackBack/trunk/trackback/language/english.php b/NP_TrackBack/trunk/trackback/language/english.php new file mode 100644 index 0000000..54f2aaf --- /dev/null +++ b/NP_TrackBack/trunk/trackback/language/english.php @@ -0,0 +1,52 @@ + for ID <%tb_id%>. Below are the full details:\n\nURL:\t<%url%>\nTitle:\t<%title%>\nExcerpt:\t<%excerpt%>\nBlogname:\t<%blogname%>"); +define('_TB_NORTIFICATION_MAIL_TITLE', "New Trackback received for ID <%tb_id%>"); + +define('_TB_AcceptPing', 'Accept pings'); +define('_TB_SendPings', 'Allow sending pings'); +define('_TB_AutoXMLHttp', 'Auto-detect Trackback URLs as you type'); +define('_TB_CheckIDs', 'Only allow valid itemids as trackback-ids'); + +define('_TB_tplHeader', 'Header'); +define('_TB_tplEmpty', 'Empty'); +define('_TB_tplItem', 'Item'); +define('_TB_tplFooter', 'Footer'); + +define('_TB_tplHeader_VAL', "
"); + +define('_TB_tplLocalHeader_VAL', "
\n\t
Local Trackback
\n\n"); +define('_TB_tplLocalEmpty_VAL', ""); +define('_TB_tplLocalItem_VAL', "\t
\n\t\t
\n\t\t\t<%delete%> \"><%title%>: <%excerpt%>\n\t\t
\n\t\t
\n\t\t\t<%timestamp%>\n\t\t
\n\t
\n\n"); +define('_TB_tplLocalFooter_VAL', "\t
"); + +define('_TB_tplLocalHeader', 'Header (Local)'); +define('_TB_tplLocalEmpty', 'Empty (Local)'); +define('_TB_tplLocalItem', 'Item (Local)'); +define('_TB_tplLocalFooter', 'Footer (Local)'); + +define('_TB_tplTbNone', 'Trackback count (none)'); +define('_TB_tplTbOne', 'Trackback count (one)'); +define('_TB_tplTbMore', 'Trackback count (more)'); + +define('_TB_dateFormat', 'Date format'); +define('_TB_dateFormat_VAL', "%e/%m/%g"); + +define('_TB_ajaxEnabled', 'Enable Ajax ?'); +define('_TB_NotifyEmail', 'Which e-mail address to send these notification to?'); +define('_TB_NotifyEmailBlog', 'Which e-mail address to send these notification to?'); + +define('_TB_DropTable', 'Clear the database when uninstalling'); +define('_TB_HideUrl', 'Hide external URL'); +define('_TB_ItemAcceptPing', 'Accept pings'); +define('_TB_isAcceptWOLink', 'Accept pings w/o link ?'); +define('_TB_isAcceptWOLinkDef', 'Accept pings w/o link ? (blog default)'); +define('_TB_AllowTrackBack', 'Accept pings to this blog'); + +define('_TB_isAcceptWOLink_VAL', 'default|default|yes|yes|no|no'); +define('_TB_isAcceptWOLinkDef_VAL', 'yes|yes|no (block)|block|no (ignore)|ignore'); diff --git a/NP_TrackBack/trunk/trackback/language/japanese-euc.php b/NP_TrackBack/trunk/trackback/language/japanese-euc.php new file mode 100644 index 0000000..38467a3 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/language/japanese-euc.php @@ -0,0 +1,51 @@ + ¤«¤é ID:<%tb_id%> ¤Îµ­»ö¤ËÂФ·¤Æ¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤ò¼õ¿®¤·¤Þ¤·¤¿¡£ ¾ÜºÙ¤Ï²¼µ­¤Î¤È¤ª¤ê¤Ç¤¹:\n\nURL:\t<%url%>\n¥¿¥¤¥È¥ë:\t<%title%>\n³µÍ×:\t<%excerpt%>\n¥Ö¥í¥°Ì¾:\t<%blogname%>"); +define('_TB_NORTIFICATION_MAIL_TITLE', "¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤ò¼õ¿®¤·¤Þ¤·¤¿ ID:<%tb_id%>"); + +define('_TB_AcceptPing', '¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤Î¼õÉÕ¤ò¤¹¤ë¤«?'); +define('_TB_SendPings', '¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤ÎÁ÷¿®¤ò²Äǽ¤Ë¤¹¤ë¤«?'); +define('_TB_AutoXMLHttp', 'autodiscoveryµ¡Ç½(µ­»öÆâ¤Î¥ê¥ó¥¯Àè¤ÎTrackbackURL¤Î¼«Æ°¸¡ÃÎ)¤ò»È¤¦¤«?'); +define('_TB_CheckIDs', 'ping¼õÉÕ»þ¤ËÍ­¸ú¤Êitemid¤«¤É¤¦¤«¤ò¥Á¥§¥Ã¥¯¤¹¤ë¤«?'); + +define('_TB_tplHeader', 'TB°ìÍ÷¥Æ¥ó¥×¥ì¡¼¥È(¥Ø¥Ã¥ÀÉô)'); +define('_TB_tplEmpty', 'TB°ìÍ÷¥Æ¥ó¥×¥ì¡¼¥È(0·ï¤Î¤È¤­)'); +define('_TB_tplItem', 'TB°ìÍ÷¥Æ¥ó¥×¥ì¡¼¥È(¥¢¥¤¥Æ¥àÉô)'); +define('_TB_tplFooter', 'TB°ìÍ÷¥Æ¥ó¥×¥ì¡¼¥È(¥Õ¥Ã¥¿Éô)'); + +define('_TB_tplHeader_VAL', "
\n\t
¥È¥é¥Ã¥¯¥Ð¥Ã¥¯
<%admin%>\n\n"); +define('_TB_tplEmpty_VAL', "\t
\n\t\t¤³¤Î¥¨¥ó¥È¥ê¤Ë¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤Ï¤¢¤ê¤Þ¤»¤ó\n\t
\n\n"); +define('_TB_tplItem_VAL', "\t
\n\t\t
<%name%>
\n\t\t
\n\t\t\t\"><%title%>: <%excerpt%>\n\t\t
\n\t\t
\n\t\t\t<%date%>\n\t\t
\n\t
\n\n"); +define('_TB_tplFooter_VAL', "\t
\n\t\t¤³¤Î\">¥È¥é¥Ã¥¯¥Ð¥Ã¥¯URL¤ò»È¤Ã¤Æ¤³¤Îµ­»ö¤Ë¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤òÁ÷¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£\n\t\t¤â¤·¤¢¤Ê¤¿¤Î¥Ö¥í¥°¤¬¥È¥é¥Ã¥¯¥Ð¥Ã¥¯Á÷¿®¤ËÂбþ¤·¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ë¤Ï\" onclick=\"window.open(this.href, 'trackback', 'scrollbars=yes,width=600,height=340,left=10,top=10,status=yes,resizable=yes'); return false;\">¤³¤Á¤é¤Î¥Õ¥©¡¼¥à¤«¤é¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤òÁ÷¿®¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£.\n\t
\n
"); + +define('_TB_tplLocalHeader', '¥í¡¼¥«¥ëTB°ìÍ÷¥Æ¥ó¥×¥ì¡¼¥È(¥Ø¥Ã¥ÀÉô)'); +define('_TB_tplLocalEmpty', '¥í¡¼¥«¥ëTB°ìÍ÷¥Æ¥ó¥×¥ì¡¼¥È(0·ï¤Î¤È¤­)'); +define('_TB_tplLocalItem', '¥í¡¼¥«¥ëTB°ìÍ÷¥Æ¥ó¥×¥ì¡¼¥È(¥¢¥¤¥Æ¥àÉô)'); +define('_TB_tplLocalFooter', '¥í¡¼¥«¥ëTB°ìÍ÷¥Æ¥ó¥×¥ì¡¼¥È(¥Õ¥Ã¥¿Éô)'); + +define('_TB_tplLocalHeader_VAL', "
\n\t
¥í¡¼¥«¥ë¥È¥é¥Ã¥¯¥Ð¥Ã¥¯
\n\n"); +define('_TB_tplLocalEmpty_VAL', ""); +define('_TB_tplLocalItem_VAL', "\t
\n\t\t
\n\t\t\t<%delete%> \"><%title%>: <%excerpt%>\n\t\t
\n\t\t
\n\t\t\t<%timestamp%>\n\t\t
\n\t
\n\n"); +define('_TB_tplLocalFooter_VAL', "\t
"); + +define('_TB_tplTbNone', 'TB¿ôɽ¼¨·Á¼°(0·ï)'); +define('_TB_tplTbOne', 'TB¿ôɽ¼¨·Á¼°(1·ï)'); +define('_TB_tplTbMore', 'TB¿ôɽ¼¨·Á¼°(2·ï°Ê¾å)'); +define('_TB_dateFormat', 'ÆüÉդηÁ¼°'); +define('_TB_dateFormat_VAL', "%Y/%m/%d %H:%I"); + +define('_TB_ajaxEnabled', '´ÉÍý²èÌ̤ÇAjax¤òÍ­¸ú¤Ë¤¹¤ë¤«'); +define('_TB_NotifyEmail', 'ping¼õÉÕ»þ¤Î¥á¡¼¥ëÁ÷¿®Àè(;¤Ç¶èÀڤäÆÊ£¿ôÆþÎϲÄǽ)'); +define('_TB_NotifyEmailBlog', 'ping¼õÉÕ»þ¤Î¥á¡¼¥ëÁ÷¿®Àè(;¤Ç¶èÀڤäÆÊ£¿ôÆþÎϲÄǽ)'); + +define('_TB_DropTable', '¥×¥é¥°¥¤¥ó¤Îºï½ü»þ¤Ë¥Ç¡¼¥¿¤òºï½ü¤¹¤ë¤«?'); +define('_TB_HideUrl', '°ìÍ÷ɽ¼¨¤ÎºÝ¤Ë³°Éô¤ÎURL¤ò¥ê¥À¥¤¥ì¥¯¥È¤ËÊÑ´¹¤¹¤ë¤«?'); +define('_TB_ItemAcceptPing', 'TB¤ò¼õÉÕ¤¹¤ë¤«?'); +define('_TB_isAcceptWOLink', '¸ÀµÚ¥ê¥ó¥¯¤¬¤Ê¤¯¤Æ¤âTB¤ò¼õÉÕ¤¹¤ë¤«?'); +define('_TB_isAcceptWOLinkDef', '¸ÀµÚ¥ê¥ó¥¯¤¬¤Ê¤¯¤Æ¤âTB¤ò¼õÉÕ¤¹¤ë¤«? (blog¥Ç¥Õ¥©¥ë¥È)'); +define('_TB_AllowTrackBack', '¤³¤Î¥Ö¥í¥°¤ÇTB¤ò¼õÉÕ¤¹¤ë¤«?'); + +define('_TB_isAcceptWOLink_VAL', '¥Ö¥í¥°¥Ç¥Õ¥©¥ë¥È¤Ë½¾¤¦|default|¤Ï¤¤|yes|¤¤¤¤¤¨|no'); +define('_TB_isAcceptWOLinkDef_VAL', '¤Ï¤¤|yes|¤¤¤¤¤¨(ÊÝα)|block|¤¤¤¤¤¨(̵»ë)|ignore'); diff --git a/NP_TrackBack/trunk/trackback/language/japanese-utf8.php b/NP_TrackBack/trunk/trackback/language/japanese-utf8.php new file mode 100644 index 0000000..1d18999 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/language/japanese-utf8.php @@ -0,0 +1,52 @@ + から ID:<%tb_id%> の記事に対してトラックバックを受信しました。 詳細は下記のとおりです:\n\nURL:\t<%url%>\nタイトル:\t<%title%>\n概要:\t<%excerpt%>\nブログ名:\t<%blogname%>"); +define('_TB_NORTIFICATION_MAIL_TITLE', "トラックバックを受信しました ID:<%tb_id%>"); + +define('_TB_AcceptPing', 'トラックバックの受付をするか?'); +define('_TB_SendPings', 'トラックバックの送信を可能にするか?'); +define('_TB_AutoXMLHttp', 'autodiscovery機能(記事内のリンク先のTrackbackURLの自動検知)を使うか?'); +define('_TB_CheckIDs', 'ping受付時に有効なitemidかどうかをチェックするか?'); + +define('_TB_tplHeader', 'TB一覧テンプレート(ヘッダ部)'); +define('_TB_tplEmpty', 'TB一覧テンプレート(0件のとき)'); +define('_TB_tplItem', 'TB一覧テンプレート(アイテム部)'); +define('_TB_tplFooter', 'TB一覧テンプレート(フッタ部)'); + +define('_TB_tplHeader_VAL', "
\n\t
トラックバック
<%admin%>\n\n"); +define('_TB_tplEmpty_VAL', "\t
\n\t\tこのエントリにトラックバックはありません\n\t
\n\n"); +define('_TB_tplItem_VAL', "\t
\n\t\t
<%name%>
\n\t\t
\n\t\t\t\"><%title%>: <%excerpt%>\n\t\t
\n\t\t
\n\t\t\t<%date%>\n\t\t
\n\t
\n\n"); +define('_TB_tplFooter_VAL', "\t
\n\t\tこの\">トラックバックURLを使ってこの記事にトラックバックを送ることができます。\n\t\tもしあなたのブログがトラックバック送信に対応していない場合には\" onclick=\"window.open(this.href, 'trackback', 'scrollbars=yes,width=600,height=340,left=10,top=10,status=yes,resizable=yes'); return false;\">こちらのフォームからトラックバックを送信することができます。.\n\t
\n
"); + +define('_TB_tplLocalHeader', 'ローカルTB一覧テンプレート(ヘッダ部)'); +define('_TB_tplLocalEmpty', 'ローカルTB一覧テンプレート(0件のとき)'); +define('_TB_tplLocalItem', 'ローカルTB一覧テンプレート(アイテム部)'); +define('_TB_tplLocalFooter', 'ローカルTB一覧テンプレート(フッタ部)'); + +define('_TB_tplLocalHeader_VAL', "
\n\t
ローカルトラックバック
\n\n"); +define('_TB_tplLocalEmpty_VAL', ""); +define('_TB_tplLocalItem_VAL', "\t
\n\t\t
\n\t\t\t<%delete%> \"><%title%>: <%excerpt%>\n\t\t
\n\t\t
\n\t\t\t<%timestamp%>\n\t\t
\n\t
\n\n"); +define('_TB_tplLocalFooter_VAL', "\t
"); + +define('_TB_tplTbNone', 'TB数表示形式(0件)'); +define('_TB_tplTbOne', 'TB数表示形式(1件)'); +define('_TB_tplTbMore', 'TB数表示形式(2件以上)'); +define('_TB_dateFormat', '日付の形式'); +define('_TB_dateFormat_VAL', "%Y/%m/%d %H:%I"); + + +define('_TB_ajaxEnabled', '管理画面でAjaxを有効にするか'); +define('_TB_NotifyEmail', 'ping受付時のメール送信先(;で区切って複数入力可能)'); +define('_TB_NotifyEmailBlog', 'ping受付時のメール送信先(;で区切って複数入力可能)'); + +define('_TB_DropTable', 'プラグインの削除時にデータを削除するか?'); +define('_TB_HideUrl', '一覧表示の際に外部のURLをリダイレクトに変換するか?'); +define('_TB_ItemAcceptPing', 'TBを受付するか?'); +define('_TB_isAcceptWOLink', '言及リンクがなくてもTBを受付するか?'); +define('_TB_isAcceptWOLinkDef', '言及リンクがなくてもTBを受付するか? (blogデフォルト)'); +define('_TB_AllowTrackBack', 'このブログでTBを受付するか?'); + +define('_TB_isAcceptWOLink_VAL', 'ブログデフォルトに従う|default|はい|yes|いいえ|no'); +define('_TB_isAcceptWOLinkDef_VAL', 'はい|yes|いいえ(保留)|block|いいえ(無視)|ignore'); diff --git a/NP_TrackBack/trunk/trackback/mkeuc.sh b/NP_TrackBack/trunk/trackback/mkeuc.sh new file mode 100644 index 0000000..d9f44be --- /dev/null +++ b/NP_TrackBack/trunk/trackback/mkeuc.sh @@ -0,0 +1,11 @@ +#!/bin/bash -x + +FILES=`find japanese-utf8.templates -name '*ml'` + +for utf8file in $FILES +do + eucfile=`echo $utf8file | sed 's/japanese-utf8/japanese-euc/'` + nkf -e -W -d < $utf8file > $eucfile +done + +nkf -e -W -d < japanese-utf8.help.html > japanese-euc.help.html diff --git a/NP_TrackBack/trunk/trackback/silk/accept.png b/NP_TrackBack/trunk/trackback/silk/accept.png new file mode 100644 index 0000000000000000000000000000000000000000..f1037591430e75798fa9a175c7456c7cdd48af7c GIT binary patch literal 1012 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vk7#JAu2Ka=y z{{R2~@4vr){{H^*>(j@dAKrd{{qo1tm*1a0|N8LRm&Z>&J$(G};e&S%9=>__;Pr!R z?=IbZbLI5g1E=5YKk#Jd{>M8GKHj$P@wV*`*KdEgVc-3&8y?T!`f%Nr`)jt|U$g7> z)-88eZN0r>`^~Lu@6X;riPxd{U!OSZO7Hwj6XsuZ4uZL?0bPdU*)>v;RLykCv95%Bnn>U3Wac^GI3Q$;_hDp%eD>wI3=fJ&{pzBBSU;M)C2qi97oXj;Gcg z%*;QQ(!4J>?`U$#;grH7$$3YTGEaErA5N@1n38uSv36g2{-MN@LyyW>IQ+eo=O@f^UR^k%56pd)b=vKn<5XT^vIy<|HQ^V7sxzDLa~bi$y}s z!7DknqN0y~`2}*suQ(KV=fK^&4!4qGc3sh`KeJUMjEH=hL#+h=Vz=VsPso}3%H z>|D+QhuN)>lf;dg7Y92po%=duK||&4nyQui8+^UJw^qeV1T?HRkJ-9n4-@0|{q@6D|ZQ7Kv|Nq8~8#ip&Flo!Zb?erxUAs1J=l_)}SGKLayJE$PWy_W= zS+XQ()Bi<_7F935vvA?Us%3Y279N{Fe}2`H+f_?$RW71Xn%oz9tZGH=SMf{6!nCY{LWJDk>iAf;np za{J!I*4+uMyW*R7#x-t_soN4$w>7F}Q$+Q~h^h_YmFvRF)`pa>4k=v|T)Z;4cvWEG z%D|$Pi7m7C0KFer666=m0Q5gqLDuHJJfPv61s;*b3=CW!K$y{KjmZq4plXS0L`iUd zT1k0gQ7VIPVscS_ZfZ(qqJmpyQEGX9QFgI{Z-j!8fq_YT*_!h}4RbwR978JRq@K^_ zZ)A{Ydl;RidRo(sZ=vorjmfEgyu~M^p8fwXWg>s%>(_htZ1w*Hy_%M4Iq&&z#|<+y zF08AGZk#G~$e=WVTX~hoB%Rf(mSw&<_;ZWTBL+F&qMuGHm%Q#}Q=d_{X@bS!p15TZ z>m+qAzxlrNz?||k`#Kh#5S`Y;diO;MJM;C@orkTqK4$!;##6rgv0>MvA7z{W*Zuv@ Y67*g$Dk&_V3FuG;Pgg&ebxsLQ0J2wWE&u=k literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/silk/cross.png b/NP_TrackBack/trunk/trackback/silk/cross.png new file mode 100644 index 0000000000000000000000000000000000000000..2802c2cfea10ee6e559506f987070f1dff8798d9 GIT binary patch literal 820 zcmcgo`%h8<6uv%ZEYq#6X}QMQTxuDbEPp8l1Otu?pi)?@baK`G1UTn4^M(R{$=Ubv_0KhfEDzVF-F&UVgsQ4Q!X1A0P9}dlQ?Q*S+~s9$bF*9-JQs(%#m@Mf&fa3NH`7?I zE9rljmo}KGzZuCJiHz063(nZHq1LfLDtrT4m{)`x#{J*RHPv;Ry5NYGFV!OmZRfB9 zI9BE(Y8Z?1Bxq4{4QiC@)JU#escUXjtLo(R%sQRg*sQy%r{_xO7n72hy#}j|T6its zvc;`WmDQ|3t7zcCDbAj-kB!aGm(vGq(*-4wu62Tgp%<^aQ=Q^ r{5}5XkSDeR+Hy(~pR?t-t9ToT1leQe(lmp|sSgkVFONIKsqX#<5sL5?JIw-oc($E%(wIBf1W<_=lHJo zr;fcldHDUwqi;_h{&9HU^CLTd?OOM9=lUPpR(#mD?ZeisU$(4zy?OoD^-F)OU-D|h znonz2eOtZg*Xp_7S1b_5`dpD{7?c}}>6YIb9HU8)+``B0Y zuBY)sPx-s9(jRRF@7wC$wbXuSE%?@w^P#!=RdemPri_>M6_4v{9@W==u1tPeUGSo+ z^ig%`r}E@Sm6eYxDxXvo-m5IRTT%SEIQCIN+Qa;U$9c(D3RB-@#ofuvyqBHzI6LuL zUdo;9j8|zf@6v*9XQqBg344$l^D;U5WOmr`?2tF{A!jopp2tR>Neg`y6L2jdaof?h`YUXKktlH&6$((i0S;IjyyXJG-)!hCLrdGC*L*can)AkuzcnB|!u zn**V?7yRw^2U{HpFxeGka?sb9uP$&kFuvMLg8YIRfH5=(0GGh=M4*#63p^r=85p=e zfH0%e8j~47LDdr1h?3y^w370~qErUo#N?v<+|-oJLS?-v|XG0|S%x zvNh*{8g_fSIEGZrNlrMxCZW0~S=edG%*2{`4&I4*aVtMm)M?l|&2tV3j&D7`J%C}2 zoyXM6Cr({Ea>UKXsGC(o;pMrd`L7;uvDj_$edWNYFX{T*$ADwQHy?JcBOQ{v9eA|+ z%raPlPI~pp1vI)Gu2K-qN|y`cVa)rt)PZqlR_hcMgZ&<>UHLT*h=?wqGjn!ySlF_; z;fL8SX+_Li^=!(tw`-y=X)zi4Xe>W?{*cm+wP7sJB*S`pc0H?+En8#9&Jb^{Q>Lu* RkP+w&22WQ%mvv4FO#rNU2+IHf literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/silk/exclamation.png b/NP_TrackBack/trunk/trackback/silk/exclamation.png new file mode 100644 index 0000000000000000000000000000000000000000..39d45928ae125037c9e09600278b43be5f463ca9 GIT binary patch literal 890 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vk7#J9v1AIbU z|NsC0@7?SF?_U3X^YYiL=ii?{{`TzAx2F$(-Msww`new$PkcLf?Bl6}?~m{QdwA=w z{hNO5+xY6>&fj}izC5_&*PazWcP{&}ZQ+ltOMh%x@O?87E%~rz#n%msKd)c*WzE9Z z>lb}mIsfAdAe#MU*`$w4XMSEb@yFt>AB#F4FQ4^eVaLNI)88$a`eAo#-ztBrEeQEKQ*Mj zY0P=ql=Y<{>2qD;=bD6L_a7_ zcv=+sGC%%xUevvU$mcn+uW};q7R25thrnrVOF z2rzaUOM?7@8G!LIpx}s|RuRxKoCO|{#S9EwA3&JVX^qJYprC4rYeY$Kep*R+Vo@rC zZ(?#$er{??W}<>yW>IQ+eo=O@f^UR^k%56pd)b=vKn)i>T^vIy<|HQ^V4Ly7C+6;2 z))|R4e%$$~oSat!?DaJ6ANBA!d(t!Zh|xspBk5ZV#XfyXO5orVEA2>TZ%}S5soW{9lgHSCZ9cZs(70g6PJg&hpKwIk-?Lvq8d}O7+E8NY*IFDI&+4LOGIha zO$WY*nxCf@pE*|++>;~FVlj35jthR#xA!dylXxZ>*86GKFR$9NHFoR_1%+Bd?E6f2 Q0sY3{>FVdQ&MBb@09cy?jsO4v literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/silk/help.png b/NP_TrackBack/trunk/trackback/silk/help.png new file mode 100644 index 0000000000000000000000000000000000000000..477a0152c98cf873f426f54c3cc126becec79571 GIT binary patch literal 1016 zcmd5(`%hX27`^IT8A-P$-I8V97WQaYlWDuEzbx5eQ9D_tHpMMjeT z>uj*jwoxo?!P44Evk_;gu$H^>roNyE2yziBaCu&-B6tB6=jea2FFEHVCppP?a#+VJ zzS@m_2MYkeZbDhfiL~x{2~1X+59Yo>OiNY^o=}CsU>4n#E&#}I9sj1PbZ2KLvH35$ zu^mrtp~-DDnL?9W(fDR$eRCz2M53wiS|YTzg+$`PmAEgw?tYQ-hu7g{6b{GXaMBY- zVI;bQB-}{M8HzhX8%rV78H_uENk;&M{4u*P3i;9;vwBg;8=Z&OEuJ;2Ct`tD&F)o` zYsKga&plt6exB4jR&@?!#vW4JlXDCpY;NMz3rRR?NZw82mDWNBYbUKJ!TR@ME2KLjOXlb4hfb ziCORX3^F$5{X=0FDB%&MS0IB%pFnq?KwNNX7+m6k?h$a|p47?(owq;-S8V2rO>8m5 zeh6Kkuns)54~`pHW40dQ!WE&JDO~7!VCfOeG9MU!9i8qPHFgM07k)Q(+&6UJ)wc8J zTKR_aylMKdp2pMBZfnopnxx&FJjEbn%Jr)wt_mSXke>< z98}d0DC@5&>#oTuS7m3e%If{R^0*s*vLy{ z;DrU8w7H*AdXhnGu4A;5=oFxwM5Z@4QO-1waK{?xl=fyiwFOsx5_jbA;eyL;LPI)W zB9t7h`iV=fQM~$gHbbA=N2#vq%qz~x*^i6tWk$}wt8K;SAMxb+)c22e9@s@NhhHJN zUHC)dgRk?uMWP=na`x@&XdEo1m(=RRNHWubui%uf%eQ z3NEcGoUo_l;>x_*{Y8Dd@-HmQYT8xPu(Rs;((=w7*{$2MTDPSY@62l2n%=NEv2ky7)4~r;4Lde9_}J8tV^e~TO%6OZIjCf{ z|FMYyM<)30nHYMw*L!zw=%H?p{H3-TOWij1#H20tm@r{N?qc(a{k;b}+_M*(@9%U@ zTI{yF({)d$W5yzj_=V2%OkRcXNaN?mC-|4bIWC zHFs860Y-?(2qPrp&mAZRQl$l%Pytu&5xnIn+ zPkefIm~}V5c?V~7Y2=g?8?OpCyK1YxL`$7!UX5mMttKwrM%Ib3mKu%B7G=gNwH$KQ z%vBERZ<_bM0;YteB|(0{48XV_^nmMc_Z6UnISV`@iy0WWK7cTz(;AZ*Kta_K*NBqf z{Irtt#G+IN-^Api{M^)(%tQsZ%%art{G#k)1>Xn-BLf4I_OdnSff}B8x;TbZ%t=mQ zV0Pm(b7NCE5OMRONVm$N8!}l*FQoa!6W8!xyL|a_fqzSvK^W_+Un1hwS?s0_t`eu2 zw(Obg;(FTo%x852=ASF;X03bqXwRNQv0MH2ex4~Iv&ZDlrXxFc?$~jN>$mbU|1^O! zUsnh}VEwdn(%YzX-H8ba0-O31pK^7dTTw9a>wFc?ZE9U}ZT-Bw!mc?O)@X5iD6~&D z_P=%G(5Y)~Ycm*``#Un1bEPkyvuDzzrCCpMSlP1Om7k0K`?jw$*z1b$vnx6&2B*)> wFY+^I#|X4-nh&D%YL--C(aS+CjByi+n#K>sp$y85}Sb4q9e0Nhbh2LJ#7 literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/silk/link.png b/NP_TrackBack/trunk/trackback/silk/link.png new file mode 100644 index 0000000000000000000000000000000000000000..93d4f0e694bfcfc6eb6d2c44b99dd204b3c3a64c GIT binary patch literal 504 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vkfZRm^J|V9E z|NsB<=g+TSzkdAq@%{Vvj~_q2c=6)?{rh+C-o1VM_N`mDZrr$W`SRuS=g*%zckalM zBZm$hI(YElfddEj?%lh4_wG%bHf`9jVcoiQYuBz_xpL*adGlt^o;`i~^eI!OOqw)l z;>3v)CQRtS?-v|XG0|S%xvNh*{ z8mc^9978JRtUc$>)MOyy8aPWz#lzH##VNz-h3fD7v+ipqzk4(HV(^q;BPYMlw_Ahd zr2elBEOV9neP`m~6>JZ#hi&wGSsvA${+2mK_1g9a5BHhNPM360dE<2|^=4{nHwQy6 yr{czpN8+AtEDL6RzVKBpZ+D{E)#5(+-;8s;xxzmETKxj(3I*vp(KYsoD@$>JOAAi4p|NiOgpN}6uK7RY_;j5o7Uc9*d z{Kvf~-|s&8e&fmaM~@!ezkmPg-LH4=-o1VM_NCijZr!?d);zCU^P+pwo-ysGDXY01z{PKE- zYky35Xm#h?|M`sU3NjWKZfDQh!uoHb%DUjE37Ts5efHTsFTH23@7cbCz)4zS_d{7DeNim&r6ptdwyGGBM0-{mCqH_IRuuJzMWatxX0nV z%SW!;v2!ju$u01cZOi0}Fb(#3?!vg_anYT3&JlUrj(0cLgl?BURret~d~N!=8}1kR k!`c0MOqWgj^87M;>U}Ah0}K-{1KrQy>FVdQ&MBb@0NnwnMgRZ+ literal 0 HcmV?d00001 diff --git a/NP_TrackBack/trunk/trackback/silk/plugin_edit.png b/NP_TrackBack/trunk/trackback/silk/plugin_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..80c9a62344daf4c863e09f3a5313db96a75f9bce GIT binary patch literal 985 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vk7#J8Y2Ka=y z{{R2~+n=w0zaRhq`RU(phyH#$^8eF=Umu@+fB*FB+s8j2Z~F7#$d5;{-ycPPe;D=s ze)6}wIbZKbzq_&V>z%l-cjCWYUiabBmQUBJ-d|et@k;fZt92hPSH8Vc^A1Q}sQ7tu z;?Lt#o}Vs%dn$L?&DqOu&RKF}=HeSO7u}e?==zLBH)brnK5OCi=?kw#`t|;K zSEtUsI{Ep5?m1T`&%89@`M&ZQ7yGAQ>YaA6ciM&isTX>tobQ@^zI*EV?n&pnCZ6xu za6GN=Y}>`{6Phnn_MBz2DMHF0OyiP_PYX1H~%^FA{zGIdMb zm8njXm&IP2>U?yDXX5&(x)qMGtHUCf2kqjMZgI;}C80Tfg%ag8Vm&QB{TPb^Ah@J&oE%Fj(r$xKvm%PdMQ&o9a@ zR`88bFfuSOX)jxI9;o5Cr;B4q#hm1X16*Hhn72&$*>g{8R-=Yi&6Tq{4`kHU|1S{8 zZC-I@k5)&+?oFH8+V<^RxiU1i$9<^)bMyRJv%(`x1a8dkF!a7+Y{1g~OX}#cwDjfP zg_2!G%NtBmrP5PH(@$*R(l~m(pn=8fEI0S()R`_7N4wRSc3M6ayq22V<#VWJQm^nb zCe~BAIYN_SB7RgZnSJx%HM1L`<~yxkahc-@Nhm>a{nQ4?o(s^Y+%Q*EX#@w{+#{ zr4uf-%s(}&|6soH_Tz%y}nf_MUHCbYy<-xrXlZ^>dHU=sZ`~b*{esY)$9c z+V(TmZD(p)Pggdbu4p|`)qJv|^<-7s$;!r4Wlg8b8&8(iohYe1kXyDlr)+O_>E4{& zEy=lClXEvG=WI&K+LVyBAt7^peDa3KjCFD8YhzN@L?#W zF^fZD76(Ty3W{717(U-WaF(ZgpMyiIrG2xdZL_&ulZ9=gxlMzab-k%oorz_wu~n_f zitqnvk>CUB6-JqD6c8JI)_SS*N}rEos53S5HoJ8TMQ}7~tmSeE4R+Xqrv;?5WGPb=w;s vauO?dzs{gy$ILuCTtSdJDx>H?esD?sNC~;rZN?7wGSOz~rzA zK@bOgDC8i$o9)rqP_MSf-wD>6VXB8uh_SKpv&n#$1Yuww=ojJ%J$7}_ZR>P8>}+9Y zTMumii|x&=olR_QZ0hID^^L7J*m#XM%UEB=+9FmL*VosvI*-+bm6a7NzF1mX!oma= zUSReKW*_5~7Bi!Bb94A-1k)N!4q53ZvAm-hB{QBNW2uAnX*wP}^Ad`K@tl2+NBU#`qW zO$us~QT+p|lOalKXlN)=uy8MdugHQZ4x(7zUzswQ48nK_;vmp#3dq&-b-CSp;H~=hr zus#Kglvd>$C-OqNEkkscA#{xqQEW_z$?D$)OVHV80Dn!yJzSXj?op45fyIq zJC0$cpIqeI29+H1=AQ87yiYE&C9};bznYT^?avgLeU@wHl5660qG2IrhJ`B5GKoee9J@P%-1hJWO{}&gBdZ*w8)fbf*MIr zVI)OI#Yb9s#ivB4F;Ws!t*D_^PA5+~-}q57q(9j5A-jkCR7R%}23Jo7Yl-)$UmDp4 zt~qJ7TKR_G2$5=W*}?DmF>4Nq(>9{uXBy1&cOpWknHotqwJXz~2}k7y8n z`@;uaTI1Z#@#ts0)3c(I^EI42@v9PlI%Oy!>H>{ViXDE`yD#{({~TTYcq)=c3o|?X zJ6m1mnkcsHlIHYTKXYsOc#V5};_cajck6up272clZp+Kf9bRf5#!Tc4*xQ-c&KRxE ti2J`7file = ($prefix ? $prefix . '/' : '') . $file; + $this->prefix = $prefix; + } + + function set($name, $value) { + $this->vars[$name] = is_object($value) ? $value->fetch() : $value; + } + + function template($file = null) { + $language = ereg_replace( '[\\|/]', '', getLanguageName()); + $this->file = (file_exists(($this->prefix ? $this->prefix . '/' : '') . $language.'.'.$file))? ($this->prefix ? $this->prefix . '/' : '') . $language.'.'.$file: ($this->prefix ? $this->prefix . '/' : '') . $file; + } + + function fetch($file = null) { + if(!$file) $file = $this->file; + else ($prefix ? $prefix . '/' : '') . $file; + + if ($file != null) + { + if (is_array($this->vars)) extract($this->vars); + + ob_start(); + include($file); + $contents = ob_get_contents(); + ob_end_clean(); + + return $contents; + } + } +} diff --git a/NP_TrackBack/trunk/trackback/templates/all.html b/NP_TrackBack/trunk/trackback/templates/all.html new file mode 100644 index 0000000..56c75b1 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/templates/all.html @@ -0,0 +1,106 @@ + +

+ All trackbacks + $amount): ?> + (Page of ) + +

+ + + $amount): ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateStoryTitle, Blog and ExcerptActions
+ + + + + Visit + + ()
+ +
+ Block + + Delete +
+ + $amount): ?> + + + + + + + + \ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/templates/all_ajax.html b/NP_TrackBack/trunk/trackback/templates/all_ajax.html new file mode 100644 index 0000000..cb19843 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/templates/all_ajax.html @@ -0,0 +1,128 @@ + +

+ All trackbacks +

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
 idDateStoryTitle, Blog and Excerpt 
+With selected: +Delete +Block +
+ + + + diff --git a/NP_TrackBack/trunk/trackback/templates/blocked.html b/NP_TrackBack/trunk/trackback/templates/blocked.html new file mode 100644 index 0000000..15b98de --- /dev/null +++ b/NP_TrackBack/trunk/trackback/templates/blocked.html @@ -0,0 +1,119 @@ + +

+ Blocked trackbacks + $amount): ?> + (Page of ) + +

+ + + + + $amount): ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateStoryTitle, Blog and ExcerptActions
+ + + + + ">Visit + + () + ' : + '';?> + ';?> +
+ +
+ Unblock + + Delete +
+ + $amount): ?> + + + + + + + + + diff --git a/NP_TrackBack/trunk/trackback/templates/blocked_ajax.html b/NP_TrackBack/trunk/trackback/templates/blocked_ajax.html new file mode 100644 index 0000000..394a603 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/templates/blocked_ajax.html @@ -0,0 +1,133 @@ + +

+ Blocked Trackbacks +

+ + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
 idDateStoryTitle, Blog and Excerpt 
+With selected: +Unblock +Delete +
+ + + + diff --git a/NP_TrackBack/trunk/trackback/templates/form.html b/NP_TrackBack/trunk/trackback/templates/form.html new file mode 100644 index 0000000..ba61b48 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/templates/form.html @@ -0,0 +1,56 @@ + + + + Add TrackBack + + + + +

TrackBack Ping

+ +

+ Your trackback has been received properly. +

+ + +

+ +

+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Article URL
Article Title
Excerpt from article
Your Blog Name
Add TrackBack
+
+ +
+ + + \ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/templates/index.html b/NP_TrackBack/trunk/trackback/templates/index.html new file mode 100644 index 0000000..15a2ce4 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/templates/index.html @@ -0,0 +1,34 @@ + +

Overview of all items

+ + + + + + + + + + + + + + + + + + + + + + + + +
Blog: TotalAction
+ + + + + Trackbacks +
+ \ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/templates/list.html b/NP_TrackBack/trunk/trackback/templates/list.html new file mode 100644 index 0000000..0fcf3c3 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/templates/list.html @@ -0,0 +1,107 @@ + +

+ All trackbacks for "" + $amount): ?> + (Page of ) + +

+ + + $amount): ?> + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateTitle, Blog and ExcerptActions
+ + + Visit + + ()
+ +
+ Block + + Delete +
+ + $amount): ?> + + + + + + + + + diff --git a/NP_TrackBack/trunk/trackback/templates/menu.html b/NP_TrackBack/trunk/trackback/templates/menu.html new file mode 100644 index 0000000..92fa7e1 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/templates/menu.html @@ -0,0 +1,33 @@ + + + + + +

Trackback

+ + \ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/templates/ping.html b/NP_TrackBack/trunk/trackback/templates/ping.html new file mode 100644 index 0000000..91216ce --- /dev/null +++ b/NP_TrackBack/trunk/trackback/templates/ping.html @@ -0,0 +1,50 @@ + +

Manually ping another weblog

+ +
+ + + + addTicketHidden(); ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Manually Ping
Your URL + +
Your Title + +
Your Excerpt + +
Your Blog Name + +
External Ping URL + +
Send Ping
+ +
\ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/templates/response_all.xml b/NP_TrackBack/trunk/trackback/templates/response_all.xml new file mode 100644 index 0000000..7a160ad --- /dev/null +++ b/NP_TrackBack/trunk/trackback/templates/response_all.xml @@ -0,0 +1,35 @@ +';?> + + + + + + + + + 0 + + + + + + + + + + + + + + + + diff --git a/NP_TrackBack/trunk/trackback/templates/response_blocked.xml b/NP_TrackBack/trunk/trackback/templates/response_blocked.xml new file mode 100644 index 0000000..d085390 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/templates/response_blocked.xml @@ -0,0 +1,41 @@ +';?> + + + + + + + + + 0 + + + + + + + + + + + + + + + + diff --git a/NP_TrackBack/trunk/trackback/templates/response_doblock.xml b/NP_TrackBack/trunk/trackback/templates/response_doblock.xml new file mode 100644 index 0000000..a53f37c --- /dev/null +++ b/NP_TrackBack/trunk/trackback/templates/response_doblock.xml @@ -0,0 +1,8 @@ +';?> + + + + + + + \ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/templates/response_dodelete.xml b/NP_TrackBack/trunk/trackback/templates/response_dodelete.xml new file mode 100644 index 0000000..a53f37c --- /dev/null +++ b/NP_TrackBack/trunk/trackback/templates/response_dodelete.xml @@ -0,0 +1,8 @@ +';?> + + + + + + + \ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/templates/response_dounblock.xml b/NP_TrackBack/trunk/trackback/templates/response_dounblock.xml new file mode 100644 index 0000000..a53f37c --- /dev/null +++ b/NP_TrackBack/trunk/trackback/templates/response_dounblock.xml @@ -0,0 +1,8 @@ +';?> + + + + + + + \ No newline at end of file diff --git a/NP_TrackBack/trunk/trackback/templates/updatetable.html b/NP_TrackBack/trunk/trackback/templates/updatetable.html new file mode 100644 index 0000000..113e9e6 --- /dev/null +++ b/NP_TrackBack/trunk/trackback/templates/updatetable.html @@ -0,0 +1,9 @@ + +
Table update:
+
+ + + addTicketHidden(); ?> +
+
+ diff --git a/NP_TrackBack/trunk/trackback/templates/updatetablefinished.html b/NP_TrackBack/trunk/trackback/templates/updatetablefinished.html new file mode 100644 index 0000000..d94969e --- /dev/null +++ b/NP_TrackBack/trunk/trackback/templates/updatetablefinished.html @@ -0,0 +1,5 @@ + +
+Table update done ! +
+ -- 2.11.0
\n\t
Trackback
<%admin%>\n\n"); +define('_TB_tplEmpty_VAL', "\t
\n\t\tThere are currently no trackbacks for this item.\n\t
\n\n"); +define('_TB_tplItem_VAL', "\t
\n\t\t
<%name%>
\n\t\t
\n\t\t\t\"><%title%>: <%excerpt%>\n\t\t
\n\t\t
\n\t\t\t<%date%>\n\t\t
\n\t
\n\n"); +define('_TB_tplFooter_VAL', "\t
\n\t\tUse this \">TrackBack url to ping this item (right-click, copy link target).\n\t\tIf your blog does not support Trackbacks you can manually add your trackback by using \" onclick=\"window.open(this.href, 'trackback', 'scrollbars=yes,width=600,height=340,left=10,top=10,status=yes,resizable=yes'); return false;\">this form.\n\t
\n
\n\t
Trackback
<%admin%>\n\n"); +define('_TB_tplEmpty_VAL', "\t
\n" + . "\t\tThere are currently no trackbacks for this item.\n\t
\n\n"); +define('_TB_tplItem_VAL', "\t
\n\t\t
<%name%>
\n" + . "\t\t
\n\t\t\t\"><%title%>: <%excerpt%>\n" + . "\t\t
\n\t\t
\n\t\t\t<%date%>\n\t\t
\n\t
\n\n"); +define('_TB_tplFooter_VAL', "\t
\n\t\tUse this \">TrackBack url " + . "to ping this item (right-click, copy link target).\n" + . "\t\tIf your blog does not support Trackbacks you can manually add your trackback by using " + . "\" onclick=\"window.open(this.href, 'trackback', 'scrollbars=yes,width=600,height=340,left=10,top=10,status=yes,resizable=yes'); return false;\">" + . "this form.\n\t
\n