From dd5320d1d56ca7603747dd68871e72eee99d9e67 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Sat, 16 Jul 2005 04:27:41 +0000 Subject: [PATCH] Added admin media to the Django distribution git-svn-id: http://code.djangoproject.com/svn/django/trunk@96 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- media/css/base.css | 3 + media/css/changelists.css | 59 ++++ media/css/global.css | 398 +++++++++++++++++++++++++ media/img/calendar.gif | Bin 0 -> 192 bytes media/img/changelist-bg.gif | Bin 0 -> 58 bytes media/img/chooser-bg.gif | Bin 0 -> 199 bytes media/img/chooser_stacked-bg.gif | Bin 0 -> 212 bytes media/img/default-bg-reverse.gif | Bin 0 -> 843 bytes media/img/default-bg.gif | Bin 0 -> 844 bytes media/img/icon-no.gif | Bin 0 -> 176 bytes media/img/icon-yes.gif | Bin 0 -> 299 bytes media/img/icon_addlink.gif | Bin 0 -> 119 bytes media/img/icon_alert.gif | Bin 0 -> 145 bytes media/img/icon_calendar.gif | Bin 0 -> 192 bytes media/img/icon_changelink.gif | Bin 0 -> 119 bytes media/img/icon_clock.gif | Bin 0 -> 390 bytes media/img/icon_deletelink.gif | Bin 0 -> 181 bytes media/img/icon_error.gif | Bin 0 -> 319 bytes media/img/icon_searchbox.gif | Bin 0 -> 681 bytes media/img/icon_success.gif | Bin 0 -> 342 bytes media/img/nav-bg-grabber.gif | Bin 0 -> 116 bytes media/img/nav-bg-grabber2.gif | Bin 0 -> 268 bytes media/img/nav-bg-reverse.gif | Bin 0 -> 186 bytes media/img/nav-bg.gif | Bin 0 -> 273 bytes media/img/selector-add.gif | Bin 0 -> 606 bytes media/img/selector-addall.gif | Bin 0 -> 358 bytes media/img/selector-remove.gif | Bin 0 -> 398 bytes media/img/selector-removeall.gif | Bin 0 -> 355 bytes media/img/selector-search.gif | Bin 0 -> 552 bytes media/img/selector_stacked-add.gif | Bin 0 -> 612 bytes media/img/selector_stacked-remove.gif | Bin 0 -> 401 bytes media/img/tool-left.gif | Bin 0 -> 197 bytes media/img/tool-left_over.gif | Bin 0 -> 203 bytes media/img/tool-right.gif | Bin 0 -> 198 bytes media/img/tool-right_over.gif | Bin 0 -> 200 bytes media/img/tooltag-add.gif | Bin 0 -> 932 bytes media/img/tooltag-add_over.gif | Bin 0 -> 336 bytes media/img/tooltag-arrowright.gif | Bin 0 -> 351 bytes media/img/tooltag-arrowright_over.gif | Bin 0 -> 354 bytes media/js/SelectBox.js | 110 +++++++ media/js/SelectFilter.js | 81 +++++ media/js/SelectFilter2.js | 129 ++++++++ media/js/admin/CollapsedFieldsets.js | 82 +++++ media/js/admin/DateTimeShortcuts.js | 204 +++++++++++++ media/js/admin/RelatedObjectLookups.js | 33 ++ media/js/admin/add_calendars.js | 158 ++++++++++ media/js/admin/ordering.js | 137 +++++++++ media/js/calendar.js | 139 +++++++++ media/js/core.js | 138 +++++++++ media/js/dateparse.js | 227 ++++++++++++++ media/js/getElementsBySelector.js | 167 +++++++++++ media/js/timeparse.js | 94 ++++++ media/js/urlify.js | 16 + 53 files changed, 2175 insertions(+) create mode 100644 media/css/base.css create mode 100644 media/css/changelists.css create mode 100644 media/css/global.css create mode 100644 media/img/calendar.gif create mode 100644 media/img/changelist-bg.gif create mode 100644 media/img/chooser-bg.gif create mode 100644 media/img/chooser_stacked-bg.gif create mode 100644 media/img/default-bg-reverse.gif create mode 100644 media/img/default-bg.gif create mode 100644 media/img/icon-no.gif create mode 100644 media/img/icon-yes.gif create mode 100644 media/img/icon_addlink.gif create mode 100644 media/img/icon_alert.gif create mode 100644 media/img/icon_calendar.gif create mode 100644 media/img/icon_changelink.gif create mode 100644 media/img/icon_clock.gif create mode 100644 media/img/icon_deletelink.gif create mode 100644 media/img/icon_error.gif create mode 100644 media/img/icon_searchbox.gif create mode 100644 media/img/icon_success.gif create mode 100644 media/img/nav-bg-grabber.gif create mode 100644 media/img/nav-bg-grabber2.gif create mode 100644 media/img/nav-bg-reverse.gif create mode 100644 media/img/nav-bg.gif create mode 100644 media/img/selector-add.gif create mode 100644 media/img/selector-addall.gif create mode 100644 media/img/selector-remove.gif create mode 100644 media/img/selector-removeall.gif create mode 100644 media/img/selector-search.gif create mode 100644 media/img/selector_stacked-add.gif create mode 100644 media/img/selector_stacked-remove.gif create mode 100644 media/img/tool-left.gif create mode 100644 media/img/tool-left_over.gif create mode 100644 media/img/tool-right.gif create mode 100644 media/img/tool-right_over.gif create mode 100644 media/img/tooltag-add.gif create mode 100644 media/img/tooltag-add_over.gif create mode 100644 media/img/tooltag-arrowright.gif create mode 100644 media/img/tooltag-arrowright_over.gif create mode 100644 media/js/SelectBox.js create mode 100644 media/js/SelectFilter.js create mode 100644 media/js/SelectFilter2.js create mode 100644 media/js/admin/CollapsedFieldsets.js create mode 100644 media/js/admin/DateTimeShortcuts.js create mode 100644 media/js/admin/RelatedObjectLookups.js create mode 100644 media/js/admin/add_calendars.js create mode 100644 media/js/admin/ordering.js create mode 100644 media/js/calendar.js create mode 100644 media/js/core.js create mode 100644 media/js/dateparse.js create mode 100644 media/js/getElementsBySelector.js create mode 100644 media/js/timeparse.js create mode 100644 media/js/urlify.js diff --git a/media/css/base.css b/media/css/base.css new file mode 100644 index 0000000000..2a91c1d6f3 --- /dev/null +++ b/media/css/base.css @@ -0,0 +1,3 @@ +@import url('global.css'); +@import url('changelists.css'); + diff --git a/media/css/changelists.css b/media/css/changelists.css new file mode 100644 index 0000000000..197b5b66d2 --- /dev/null +++ b/media/css/changelists.css @@ -0,0 +1,59 @@ +/* + ______________________________ + WORLD ONLINE PUBLISHING SYSTEM + Admin Changelist Styles + + Extends global.css + + by World Online, Copyright 2004 + + 645 New Hampshire + Lawrence, KS 66044 + + webmaster@ljworld.com + +*/ + +#changelist {position:relative; width:100%;} +#changelist table {width:100%;} +.change-list .filtered table { border-right:1px solid #ddd; } +.change-list .filtered {min-height:400px; _height:400px;} +.change-list .filtered {background:white url(../img/admin/changelist-bg.gif) top right repeat-y !important;} +.change-list .filtered table, .filtered .paginator, .filtered #toolbar, .filtered div.xfull {margin-right:160px !important; width:auto !important; } +.change-list .filtered table tbody th {padding-right:10px;} +#changelist .toplinks {border-bottom:1px solid #ccc !important;} +#changelist .paginator { color:#666; border-top:1px solid #eee; border-bottom:1px solid #eee; background:white url(../img/admin/nav-bg.gif) 0 180% repeat-x; overflow:hidden;} +.change-list .filtered .paginator { border-right:1px solid #ddd; } + +/* CHANGELIST TABLES */ + +#changelist table thead th {white-space:nowrap;} +#changelist table tbody td {border-left: 1px solid #ddd;} +#changelist table tfoot {color: #666;} + +/* TOOLBAR */ + +#changelist #toolbar {padding:3px; border-bottom:1px solid #ddd; background:#e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x; color:#666;} +#changelist #toolbar form input {font-size:11px; padding:1px 2px;} +#changelist #toolbar form #searchbar {padding:2px;} +#changelist #changelist-search img {vertical-align:middle;} + +/* FILTER COLUMN */ + +#changelist-filter {position:absolute; top:0; right:0; z-index:1000; width:160px; border-left:1px solid #ddd; background:#efefef; margin:0;} +#changelist-filter h2 {font-size:11px; padding:2px 5px; border-bottom:1px solid #ddd;} +#changelist-filter h3 {font-size:12px; margin-bottom:0;} +#changelist-filter ul {padding-left:0;margin-left:10px;_margin-right:-10px;} +#changelist-filter li {list-style-type:none; margin-left:0; padding-left:0;} +#changelist-filter a {color:#999;} +#changelist-filter a:hover {color:#036;} +#changelist-filter li.selected {border-left:5px solid #ccc; padding-left:5px;margin-left:-10px;} +#changelist-filter li.selected a {color:#5b80b2 !important;} + +/* DATE DRILLDOWN */ + +.change-list ul.toplinks {display:block; background:white url(../img/admin/nav-bg-reverse.gif) 0 -10px repeat-x; border-top:1px solid white; float:left; padding:0 !important; margin:0 !important; width:100%;} +.change-list ul.toplinks li {float: left; width: 9em; padding:3px 6px; font-weight: bold; list-style-type:none;} +.change-list ul.toplinks .date-back a {color:#999;} +.change-list ul.toplinks .date-back a:hover {color:#036;} + diff --git a/media/css/global.css b/media/css/global.css new file mode 100644 index 0000000000..4d60bc6b01 --- /dev/null +++ b/media/css/global.css @@ -0,0 +1,398 @@ +/* + ______________________________ + DJANGO + Admin Master Styles + + Extends base.css + + by World Online + Copyright 2004-2005 + + 645 New Hampshire + Lawrence, KS 66044 + + webmaster@ljworld.com + + ______________________________ + SITE DIMENSIONS + + Site Width: 768px + Content Width: 750px + Main Column: 580px + Sidebar: 220px + + ______________________________ + COLORS + + Blue #5b80b2 + Dark Blue #036 + +*/ + +body { margin:0; padding:0; font-family:"Lucida Grande","Bitstream Vera Sans",Verdana,Arial,sans-serif; color:#333; } + +/* LINKS */ + +a:link, a:visited { color: #5b80b2; text-decoration:none; } +a:hover { color: #036; } +a img { border:none; } + +/* GLOBAL DEFAULTS */ + +p, ol, ul, dl { margin:.2em 0 .8em 0; font-size:12px; } +p { padding:0; line-height:140%; } + +h1,h2,h3,h4,h5 { font-weight:bold; } +h1 { font-size:18px; color:#666; padding:0 6px 0 0; margin:0 0 .2em 0; } +h2 { font-size:16px; margin:1em 0 .5em 0; } +h2.subhead { font-weight:normal;margin-top:0; } +h3 { font-size:14px; margin:.8em 0 .3em 0; color:#666; font-weight:bold; } +h4 { font-size:12px; margin:1em 0 .8em 0; padding-bottom:3px; } +h5 { font-size:10px; margin:1.5em 0 .5em 0; color:#666; text-transform:uppercase; letter-spacing:1px; } + +ul li { list-style-type:square; padding:1px 0; } +ul.plainlist { margin-left:0 !important; } +ul.plainlist li { list-style-type:none; } +li ul { margin-bottom:0; } +li, dt, dd { font-size:11px; line-height:14px; } +dt { font-weight:bold; margin-top:4px; } +dd { margin-left:0; } + +form { margin:0; padding:0; } +fieldset { margin:0; padding:0; } + +blockquote { font-size:11px; color:#777; margin-left:2px; padding-left:10px; border-left:5px solid #ddd; } +code, pre { font-family:"Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace; background:inherit; color:#666; font-size:11px; } +pre.literal-block { margin:10px; background:#eee; padding:6px 8px; } +code strong { color:#930; } +hr { clear:both; color:#eee; background-color:#eee; height:1px; border:none; margin:0; padding:0; font-size:1px; line-height:1px; } + +/* PAGE STRUCTURE */ + +#container { position:relative; width:100%; min-width:720px; } +#header { text-align:left; min-height:55px; _height:55px; } +#content { margin:10px 15px; } +#content-main { float:left; } +#content-related { float:right; } +#footer { clear:both; padding:10px; } + +/* COLUMN TYPES */ +/* + colM = Main | M | + colMS = Main, Sidebar | M |S| + colSM = Sidebar, Main |S| M | + flex = single-column, liquid width + superwide = single-column, extra-wide fixed width +*/ +.colMS, .colM, .colSM, .colM #content-main, .colM #content-main .xfull { width:758px; } /* master site width for fixed-width pages */ +.colMS #content-main, .colSM #content-main, .colMS #content-main .xfull, .colSM #content-main .xfull { width:519px; } /* main column width for 2-column pages */ +.colMS #content-related, .colSM #content-related, .colSMS #content-related { width:220px; } /* sidebar column width */ +.colSM #content-related { float:left; } .colSM #content-main { float:right; } /* swaps left and right columns */ +.colSMS #content-main { width:298px; } +.popup .colM { width:95%; } +.popup #content-main, .flex #content-main, .flex .xfull { width:100% !important; } /* main column width for liquid-width pages */ +.popup .flex #content-main, .popup .colM #content-main { width:100% !important; } +.subcol { float:left; width:46%; margin-right:15px; } + +/* WIDTHS */ + +.x50 { width:50px; } +.x75 { width:75px; } +.x100 { width:100px; } +.x150 { width:150px; } +.x200 { width:200px; } +.x250 { width:250px; } +.x300 { width:300px; } +.x400 { width:400px; } +.x500 { width:500px; } + +/* HEADER */ + +#header { background:#417690; color:#ffc; } +#header a:link, #header a:visited { color:white; } +#header a:hover { text-decoration:underline; } +#branding { float:left; width:480px; } +#branding h1 /* client name */ { padding:8px 0 0 10px; margin:0; font-size:18px; font-weight:normal; color:#f4f379; } +#branding h2 /* site name */ { font-size:14px; padding:0 0 8px 10px; margin:0; font-weight:normal; color:#ffc; } +#user-tools { font-size:11px; padding:8px 8px 0 5px; text-align:right; } + + +/* SIDEBAR */ + +#content-related h3 { font-size:12px; color:#666; margin-bottom:3px; } +#content-related h4 { font-size:11px; } + +/* TABLES */ + +table { border-collapse:collapse; border-color:#ccc; } +td, th { font-size:11px; line-height:13px; border-bottom:1px solid #eee; vertical-align:top; padding:5px; font-family:"Lucida Grande", Verdana, Arial, sans-serif; } +th { text-align:left; font-size:12px; } +thead th { font-weight:bold; color:#666; padding:2px 5px; font-size:11px; background:#e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x; border-left:1px solid #ddd; border-bottom:1px solid #ddd; } +thead th:first-child { border-left:none !important; } +.superwide table th, .superwide table td, .superwide table input, .superwide table select { font-size:10px; } +.module table { border-collapse: collapse; } +thead th.optional { font-weight:normal !important; } +#home-page table.module tr:hover { background:#EDF3FE; } +fieldset table { border-right:1px solid #eee; } +tr.row-label td { font-size:9px; padding-top:2px; padding-bottom:0; border-bottom:none; color:#666; margin-top:-1px; } +tr.alt { background:#f6f6f6; } +.row1 { background:#EDF3FE; } +.row2 { background:white; } +table#change-history { width:100%; } +table#change-history tbody th { width:16em; } + +/* TABLE SORTING */ + +thead th a:link, thead th a:visited { color:#666; display:block; } +table thead th.sorted { background-position:bottom left !important; } +table thead th.sorted a { padding-right:13px; } +table thead th.ascending a { background:url(../img/admin/arrow-down.gif) right .4em no-repeat; } +table thead th.descending a { background:url(../img/admin/arrow-up.gif) right .4em no-repeat; } + +/* MODULES */ + +.module { border:1px solid #ccc; margin-bottom:5px; background:white; } +.module p, .module ul, .module h3, .module h4, .module dl, .module pre { padding-left:10px; padding-right:10px; } +.module blockquote { margin-left:12px; } +.module ul, .module ol { margin-left:1.5em; } +.module h2, .module caption { margin:0; padding:2px 5px 3px 5px; font-size:11px; text-align:left; font-weight:bold; color:#666; } +.module caption { border:1px solid #ccc; border-bottom:none; } +.module h2, .module caption { background:#7CA0C7 url(../img/admin/default-bg.gif) top left repeat-x; color:white; } +.module h3 { margin-top:.6em; } +#content-related .module h2 { background:#eee url(../img/admin/nav-bg.gif) bottom left repeat-x; color:#666; } +#content-main .verbose .actionlist { float:right; font-size:10px; width:17em; position:relative; top:-1.6em; margin:0 8px; } +.dashboard .module table { width:100%; } + +/* RECENT ACTIONS MODULE */ + +.module ul.actionlist { margin-left:0; } +ul.actionlist li { list-style-type:none; } + +/* FORM DEFAULTS */ + +input, textarea, select { margin:2px 0; padding:2px 3px; vertical-align:middle; border:1px solid #ccc; font-family:"Lucida Grande", Verdana, Arial, sans-serif; font-weight:normal; font-size:11px; } +textarea { vertical-align:top !important; } +input[type=checkbox], input[type=radio] { border:none; } + +/* FORM BUTTONS */ + +input[type=submit], input[type=button], .submit-row input { background:white url(../img/admin/nav-bg.gif) bottom repeat-x; } +input[type=submit]:active, input[type=button]:active { background-image:url(../img/admin/nav-bg-reverse.gif); background-position:top; } +input[type=submit].default, .submit-row input.default { border:2px solid #5b80b2; padding:3px; background:white url(../img/admin/default-bg.gif) bottom repeat-x; font-weight:bold; color:white; } +input[type=submit].default:active { background-image:url(../img/admin/default-bg-reverse.gif); background-position:top; } +.submit-row { padding:5px 7px; text-align:right; background:#ffc; border:1px solid #ccc; margin:5px 0; } +.submit-row input { margin:0 0 0 5px; } + +/* FORM ROWS */ + +.form-row { clear:both; padding:8px 12px; font-size:11px; } +html>body .form-row { border-bottom:1px solid #eee; } +.form-row:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } +.form-row img, .form-row input { vertical-align:middle; } +form .form-row p { padding-left:0; font-size:11px; } + +/* FORM LABELS */ + +form h4 { margin:0 !important; padding:0 !important; border:none !important; } +label { font-weight:normal !important; color:#666; font-size:12px; } +label.inline { margin-left:20px; } +.required label, label.required { font-weight:bold !important; color:#333 !important; } + +/* RADIO BUTTONS */ + +form ul.radiolist li { list-style-type:none; } +form ul.radiolist label { float:none; display:inline; } +form ul.inline { margin-left:0; padding:0; } +form ul.inline li { float:left; padding-right:7px; } + +/* ALIGNED FIELDSETS */ + +.aligned label { display:block; padding:0 1em 3px 0; float:left; text-align:left; width:8em; } +.aligned label.inline { display:inline; float:none; } +.colMS .aligned .vLargeTextField, .colMS .aligned .vXMLLargeTextField { width:350px; } +form .aligned p, form .aligned ul { margin-left:7em; padding-left:30px; } +form .aligned table p { margin-left:0; padding-left:0; } +form .aligned p.help { padding-left:38px; } +.aligned .vCheckboxLabel { float:none !important; display:inline; } +.colM .aligned .vLargeTextField, colM .aligned .vXMLLargeTextField { width:610px; } +.checkbox-row p.help { margin-left:0; padding-left:0 !important; } + +/* WIDE FIELDSETS */ + +.wide label { width:15em !important; } +form .wide p { margin-left:15em; } +form .wide p.help { padding-left:38px; } +.colM fieldset.wide .vLargeTextField, .colM fieldset.wide .vXMLLargeTextField { width:450px; } + +/* COLLAPSED FIELDSETS */ + +fieldset.collapsed * { display:none; } +fieldset.collapsed h2, fieldset.collapsed .collapse-toggle { display:block !important; } +fieldset.collapsed h2 { background-image:url(../img/admin/nav-bg.gif); background-position:bottom left; color:#999; } +fieldset.collapsed .collapse-toggle { padding:3px 5px !important; background:#efefef; } +fieldset.collapsed .collapse-toggle a { display:inline !important; } + +/* MESSAGES & ERRORS */ + +ul.messagelist { padding:0 0 5px 0; margin:0; } +ul.messagelist li { font-size:12px; display:block; padding:4px 5px 4px 25px; margin:0 0 3px 0; border-bottom:1px solid #ddd; color:#666; background:#ffc url(../img/admin/icon_success.gif) 5px .3em no-repeat; } +.errornote { font-size:12px !important; display:block; padding:4px 5px 4px 25px; margin:0 0 3px 0; border:1px solid red; color:red;background:#ffc url(../img/admin/icon_error.gif) 5px .3em no-repeat; } +ul.errorlist { margin:0 !important; padding:0 !important; } +.errorlist li { font-size:12px !important; display:block; padding:4px 5px 4px 25px; margin:0 0 3px 0; border:1px solid red; color:white; background:red url(../img/admin/icon_alert.gif) 5px .3em no-repeat; } +td ul.errorlist { margin:0 !important; padding:0 !important; } +td ul.errorlist li { margin:0 !important; } +.error { background:#ffc; } +.error input, .error select { border:1px solid red; } + +/* ACTION ICONS */ + +.addlink { padding-left:12px; background:url(../img/admin/icon_addlink.gif) 0 .2em no-repeat; } +.changelink { padding-left:12px; background:url(../img/admin/icon_changelink.gif) 0 .2em no-repeat; } +.deletelink { padding-left:12px; background:url(../img/admin/icon_deletelink.gif) 0 50% no-repeat; } +a.deletelink:link, a.deletelink:visited { color:#CC3434; } +a.deletelink:hover { color:#993333; } + +/* OBJECT TOOLS */ + +.object-tools { font-size:10px; font-weight:bold; font-family:Arial,Helvetica,sans-serif; padding-left:0; margin-bottom:5px; float:right; position:relative; margin-top:-2.4em; margin-bottom:-2em; } +.form-row .object-tools { margin-top:0; margin-bottom:0; } +.object-tools li { display:block; float:left; background:url(../img/admin/tool-left.gif) 0 0 no-repeat; padding:0 0 0 8px; margin-left:2px; height:16px; } +.object-tools li:hover { background:url(../img/admin/tool-left_over.gif) 0 0 no-repeat; } +.object-tools a:link, .object-tools a:visited { display:block; float:left; color:white; padding:.1em 14px .1em 8px; height:14px; background:#999 url(../img/admin/tool-right.gif) 100% 0 no-repeat; } +.object-tools a:hover, .object-tools li:hover a { background:#5b80b2 url(../img/admin/tool-right_over.gif) 100% 0 no-repeat; } +.object-tools a.viewsitelink, .object-tools a.golink { background:#999 url(../img/admin/tooltag-arrowright.gif) top right no-repeat; padding-right:28px; } +.object-tools a.viewsitelink:hover, .object-tools a.golink:hover { background:#5b80b2 url(../img/admin/tooltag-arrowright_over.gif) top right no-repeat; } +.object-tools a.addlink { background:#999 url(../img/admin/tooltag-add.gif) top right no-repeat; padding-right:28px; } +.object-tools a.addlink:hover { background:#5b80b2 url(../img/admin/tooltag-add_over.gif) top right no-repeat; } + +/* INLINE CONTROLS */ + +#inline-controls { font-weight:bold; font-size:12px; } +#inline-specific-controls { margin-left:6px; padding:0 8px; border-left:6px solid #ccc; } + +/* BREADCRUMBS */ + +p.breadcrumbs { font-size:11px; color:#ccc;text-align:left; } /* old breadcrumbs style */ +div.breadcrumbs { background:white url(../img/admin/nav-bg-reverse.gif) 0 -10px repeat-x; padding:2px 8px 3px 8px; font-size:11px; color:#999; border-top:1px solid white; border-bottom:1px solid #ccc; text-align:left; } + +/* SELECTOR (FILTER INTERFACE) */ + +.selector { width:580px; float:left; } +.selector select { width:270px; height:170px; } +.selector-available, .selector-chosen { float:left; width:270px; text-align:center; margin-bottom:5px; } +.selector-available h2, .selector-chosen h2 { border:1px solid #ccc; } +.selector .selector-available h2 { background:white url(../img/admin/nav-bg.gif) bottom left repeat-x; color:#666; } +.selector .selector-filter { background:white; border:1px solid #ccc; border-width:0 1px; padding:3px; color:#999; font-size:10px; margin:0; text-align:left; } +.selector .selector-chosen .selector-filter { padding:4px 5px; } +.selector .selector-available input { width:230px; } +.selector ul.selector-chooser { float:left; width:22px; height:50px; background:url(../img/admin/chooser-bg.gif) top center no-repeat; margin:13% 3px 0 3px; padding:0; } +.selector-chooser li { margin:0; padding:3px; list-style-type:none; } +.selector select { margin-bottom:5px; margin-top:0; } +.selector-add, .selector-remove { width:16px; height:16px; display:block; text-indent:-3000px; } +.selector-add { background:url(../img/admin/selector-add.gif) top center no-repeat; margin-bottom:2px; } +.selector-remove { background:url(../img/admin/selector-remove.gif) top center no-repeat; } +a.selector-chooseall, a.selector-clearall { display:block; width:6em; text-align:left; margin-left:auto; margin-right:auto; font-weight:bold; color:#666; padding:3px 0 3px 18px; } +a.selector-chooseall:hover, a.selector-clearall:hover { color:#036; } +a.selector-chooseall { width:7em; background:url(../img/admin/selector-addall.gif) left center no-repeat; } +a.selector-clearall { background:url(../img/admin/selector-removeall.gif) left center no-repeat; } + +/* Stacked selectors for long items */ + +.stacked { float:left; width:500px; } +.stacked select { width:480px; height:100px; } +.stacked .selector-available, .stacked .selector-chosen { width:480px; } +.stacked .selector-available { margin-bottom:0; } +.stacked .selector-available input { width:442px; } +.stacked ul.selector-chooser { height:22px; width:50px; margin:0 0 3px 40%; background:url(../img/admin/chooser_stacked-bg.gif) top center no-repeat; } +.stacked .selector-chooser li { float:left; padding:3px 3px 3px 5px; } +.stacked .selector-chooseall, .stacked .selector-clearall { display:none; } +.stacked .selector-add { background-image:url(../img/admin/selector_stacked-add.gif); } +.stacked .selector-remove { background-image:url(../img/admin/selector_stacked-remove.gif); } + +/* DATE AND TIME */ + +p.datetime { line-height:20px; margin:0; padding:0; color:#666; font-size:11px; font-weight:bold; } +.datetime span { font-size:11px; font-weight:normal; white-space:nowrap; } +.vDateField { margin-left:4px; } +table p.datetime { font-size:10px; margin-left:0; padding-left:0; } + +/* FILE UPLOADS */ + +p.file-upload { line-height:20px; margin:0; padding:0; color:#666; font-size:11px; font-weight:bold; } +.file-upload a { font-weight:normal; } +.file-upload .deletelink { margin-left:5px; } + +/* CALENDARS & CLOCKS */ + +.calendarbox, .clockbox { margin:5px auto; width: 10em; text-align: center; background:white; position:relative; } +.clockbox { width:6em; } +.calendar { margin:0; padding: 0; } +.calendar table { margin: 0; padding: 0; border-collapse:collapse; background:white; width:99%; } +.calendar caption, .calendarbox h2 { margin: 0; font-size:11px; text-align:center; border-top:none; } +.calendar th { font-size:10px; color:#666; padding:2px 3px; text-align:center; background:#e1e1e1 url(../img/admin/nav-bg.gif) 0 50% repeat-x; border-bottom:1px solid #ddd; } +.calendar td { font-size:11px; text-align: center; padding: 0; border-top:1px solid #eee; border-bottom:none; } +.calendar td.selected a { background: #C9DBED; } +.calendar td.nonday { background:#efefef; } +.calendar td.today a { background:#ffc; } +.calendar td a, .timelist a { display: block; font-weight:bold; padding:4px; text-decoration: none; color:#444; } +.calendar td a:hover, .timelist a:hover { background: #5b80b2; color:white; } +.calendar td a:active, .timelist a:active { background: #036; color:white; } +.calendarnav { font-size:10px; text-align: center; color:#ccc; margin:0; padding:1px 3px; } +.calendarnav a:link, #calendarnav a:visited, #calendarnav a:hover { color: #999; } +.calendar-shortcuts { background:white; font-size:10px; line-height:11px; border-top:1px solid #eee; padding:3px 0 4px; color:#ccc; } +.calendarbox .calendarnav-previous, .calendarbox .calendarnav-next { display:block; position:absolute; font-weight:bold; font-size:12px; background:#C9DBED url(../img/admin/default-bg.gif) bottom left repeat-x; padding:1px 4px 2px 4px; color:white; } +.calendarnav-previous:hover, .calendarnav-next:hover { background:#036; } +.calendarnav-previous { top:0; left:0; } +.calendarnav-next { top:0; right:0; } +.calendar-cancel { margin:0 !important; padding:0; font-size:10px; background:#e1e1e1 url(../img/admin/nav-bg.gif) 0 50% repeat-x; border-top:1px solid #ddd; } +.calendar-cancel a { padding:2px; color:#999; } +ul.timelist, .timelist li { list-style-type:none; margin:0; padding:0; } +.timelist a { padding:2px; } + +/* OLD ORDERING WIDGET */ + +ul#orderthese { padding:0; margin:0; list-style-type:none; } +ul#orderthese li { list-style-type:none; display:block; padding:0; margin:6px 0; width:214px; background:#f6f6f6; white-space:nowrap; overflow:hidden; } +ul#orderthese li span { display:block; border:1px solid #e7e7e7; background:transparent url(../img/admin/nav-bg-grabber.gif) top left repeat-y; font-size:10px !important; padding:4px 6px 4px 12px; } +ul#orderthese span:hover { background-color:#efefef; } + +/* PAGINATOR */ + +.paginator { font-size:11px; padding-top:10px; padding-bottom:10px; line-height:22px; margin:0; border-top:1px solid #ddd; } +.paginator a:link, .paginator a:visited { padding:2px 6px; border:solid 1px #ccc; background:white; text-decoration:none; } +.paginator a.showall { padding:0 !important; border:none !important; } +.paginator a.showall:hover { color:#036 !important; background:transparent !important; } +.paginator .end { border-width:2px !important; margin-right:6px; } +.paginator .this-page { padding:2px 6px; font-weight:bold; font-size:13px; vertical-align:top; } +.paginator a:hover { color:white; background:#5b80b2; border-color:#036; } + +/* TEXT STYLES & MODIFIERS */ + +.small { font-size:11px; } +.tiny { font-size:10px; } +p.tiny { margin-top:-2px; } +.mini { font-size:9px; } +p.mini { margin-top:-3px; } +.help, p.help { font-size:10px !important; color:#999; } +p img, h1 img, h2 img, h3 img, h4 img, td img { vertical-align:middle; } +.quiet, a.quiet:link, a.quiet:visited { color:#999 !important;font-weight:normal !important; } +.quiet strong { font-weight:bold !important; } +.float-right { float:right; } +.float-left { float:left; } +.clear { clear:both; } +.align-left { text-align:left; } +.align-right { text-align:right; } +.example { margin:10px 0; padding:5px 10px; background:#efefef; } +.nowrap { white-space:nowrap; } + +/* CUSTOM FORM FIELDS */ + +.vSelectMultipleField { vertical-align:top !important; } +.vCheckboxField { border:none; } +.vDateField, .vTimeField { margin-right:2px; } +.vFileUploadField { border:none; } +.vURLField { width:380px; } +.vLargeTextField, .vXMLLargeTextField { width:480px; } +.colM .vLargeTextField, .colM .vXMLLargeTextField { width:720px; } +body.core-flatfile #id_content { height: 400px; } +.module table .vPositiveSmallIntegerField { width: 22px; } diff --git a/media/img/calendar.gif b/media/img/calendar.gif new file mode 100644 index 0000000000000000000000000000000000000000..7587b305a4ee702cbed3bee1ae17c78feb85d00b GIT binary patch literal 192 zcmV;x06+gnNk%w1VGsZi0J8u9nVFf2iHY^~_4)bv@bK{4+uQ&D|FN{U?d|Qf&F0D5 z?Wd=w{QUgs>FMX^=l}ozA^8LW000jFEC2ui01yBW000DS@X1N*1UPGamH(iU1QH+` z43ii};vPZqm~L$+una7G@AI)4YnU1cj)Wk05dFE&t*2MMY9TZUv9~%Sp!>_)cW&ci3#* zUhC5m*S~nZz=*>R=VoO!-wlwA$Z`-01 q@~q#j3=%veq*@rvq^WHhU}-`1SSm{{H^+^Yi-p`uF$u@bK{c{r&s< z`||Sg^z`)c@$vTd_5c6?A^8LV00000EC2ui05AX-000DmFvuy15jgA3yCGB Oo}Zwd4gw#T5db^5xM#Bf literal 0 HcmV?d00001 diff --git a/media/img/default-bg-reverse.gif b/media/img/default-bg-reverse.gif new file mode 100644 index 0000000000000000000000000000000000000000..0873281e51bdcfd1e7eb5bbfbde3a09c4cbc943e GIT binary patch literal 843 zcmV-R1GM}{Nk%w1VG#fy0OkMyywd5g$>Wc((SfDPyV2;h%;kux&VHiEgQv@Yq{*Sa z+l{W!qQ2X>&*yuf#)zuThN#S(y4aey*L$GHimcC{yxF9{+^)ysgs01&yxO+S=DE=5 zq`=*$!rrpW%Ia#o)Ef<&3V-tHt57%Hx^1)~CYVyVB@=p~tMo;ew{h zv&!VG#o?8+)Qqmrnz+`6sm*|+$&#|ts>I*7&E~4Z;GetNkg(B_veJR3%8#$nw9VzU z&E=W6*PXi9oVwYCsLX|_%&NoRhN#WD(ddt_(zwp%xX$ON!QH9E;Dn~jv&-bS&gP%H z*|yE)hN;YZp~kn*=6s;Xx6kLIz1xql(y__nrNG^btIvL;$&0MdA^8LV00000EC2ui z01*Hm000O7fOifPgAR3s6N!Zm4lp*4BuykFJTOf*l}$X9EG!3~2cDpzoqh=-BB!UR zRtX8Ms!u=zUbD1M1G%=j2p9;zy>Gw17{$G1Xb@%)%w}{DRc2LX%n%O-*9O`T+}qs- z6yY>9I~3y-JAD*?=sPhn3-R$WM@RDTQ%3>JcA0syKJpvRw!9yxMc>2a`&3xzov zx=8UshKv*xrBwWoF@=l|HCC*s;bR3396o&D2#Io}gqKQ&P@xj@r5G_1lt>sdX2ggH z5q<(4L&hf=pb;u$$grh?Ql=T4R*EFeIr5KLGLmcd%i6bbUe36dy_8@~t=1<8vdNG`N! zQKH3#5}!MR)_mbYfB-X2r#`*swCdC*JV5b~Bz9~MxJ{UV0|gEkBL#wo0UoA+5ir4% zYY4HNd5A1o;>^)NJp}VL4YJ!gaiT$Y@80pSX|Q3#jTWc((SfDPyV2;h%;kux&VHiEgQv@Yq{*Sa z+l{W!qQ2X>&*yuf#)zuThN#S(y4aey*L$GHimcC{yxF9{+^)ysgs01&yxO+S=DE=5 zq`=*$!rrpW%Ia#o)Ef<&3V-tHt57%Hx^1)~CYVyVB@=p~tMo;ew{h zv&!VG#o?8+)Qqmrnz+`6sm*|+$&#|ts>I*7&E~4Z;GetNkg(B_veJR3%8#$nw9VzU z&E=W6*PXi9oVwYCsLX|_%&NoRhN#WD(ddt_(zwp%xX$ON!QH9E;Dn~jv&-bS&gP%H z*|yE)hN;YZp~kn*=6s;Xx6kLIz1xql(y__nrNG^btIvL;$&0MdA^8LV00000EC2ui z01*Hm000O7fB=GngoT0x1WZIsh=@c4X^)Hq8yhz_C@7YhmN%6fC~FO)b|)tdr>LlS zYz-PAudpFmS#fh3xFN7$Mg_iMy zEiEN27bWH6=HM3>ML{o4NKx(YFF{dAFGWZyZdf27DgX-9f+e7qGeUGM>CmP_hlM&i z=nx`A;t~!VesHj0A)^I895r&}pnw5`k|<3oSa~uJg9;fkY^eZKW(JxS@T~!jKv(R@CsZ0tXHsK5$_Dsx`$288T9sm2&pO z+7vRWKDg+SBgd5`H-TFR%!C^)o_GDj!gPtK1gc27Dv@$SQ0{~`FJvsmY literal 0 HcmV?d00001 diff --git a/media/img/icon-yes.gif b/media/img/icon-yes.gif new file mode 100644 index 0000000000000000000000000000000000000000..73992827403791d6c1a75a079880e41dce7e0214 GIT binary patch literal 299 zcmZ?wbhEHbb?NhTQ$x_deWPc4O)NkN2|oXRf%p{M+wuUw(Z# z`TWGXJ8Mf07p=Or^7yl3mtJ2C+~V)C-fh~&DX}}E_C4PF@Y93ee}B)tGUw-?pC_Il zZ#vO%{oS?y|Nqw=uUUR`+4?){5_iQh&Q{xM6OkFieY2o T4)tf0@^WEj=4)bdWUvMRbX#E6 literal 0 HcmV?d00001 diff --git a/media/img/icon_addlink.gif b/media/img/icon_addlink.gif new file mode 100644 index 0000000000000000000000000000000000000000..ee70e1adba52480cc6aedbee650000c5d55b0088 GIT binary patch literal 119 zcmZ?wbhEHb(s)E@aY^3 F)&O8RB1ZrK literal 0 HcmV?d00001 diff --git a/media/img/icon_alert.gif b/media/img/icon_alert.gif new file mode 100644 index 0000000000000000000000000000000000000000..a1dde2625445b76d041ae02ccfcb83481ca63c5e GIT binary patch literal 145 zcmV;C0B-+BNk%w1VGsZi0J9GO|G@+Q!3O`;RR7pu|IkAJ%Ps%YPXF0v|INcdJ{u&=}=IXLDhr+J%S1nrq(gCL;wIgri4F* literal 0 HcmV?d00001 diff --git a/media/img/icon_calendar.gif b/media/img/icon_calendar.gif new file mode 100644 index 0000000000000000000000000000000000000000..7587b305a4ee702cbed3bee1ae17c78feb85d00b GIT binary patch literal 192 zcmV;x06+gnNk%w1VGsZi0J8u9nVFf2iHY^~_4)bv@bK{4+uQ&D|FN{U?d|Qf&F0D5 z?Wd=w{QUgs>FMX^=l}ozA^8LW000jFEC2ui01yBW000DS@X1N*1UPGamH(iU1QH+` z43ii};vPZqm~L$+una7G@AI)4YnU1cj)Wk=I*&Aa=g_Vl48 zmH)wj0Spv>vM@3*@G|Itcpx(vSX4HgyeYC&>*nrB_bxSQsBGn6*)YRRaLr}Q6>6LJ P$Rx*~-FRR+2ZJ>L#Kbnb literal 0 HcmV?d00001 diff --git a/media/img/icon_clock.gif b/media/img/icon_clock.gif new file mode 100644 index 0000000000000000000000000000000000000000..ff2d57e0a3b6373b7bd9540e688b1b4c71081cb7 GIT binary patch literal 390 zcmV;10eSvMNk%w1VGsZi0M$DH{QUg>{{H#-`S$kq$lLA4+3fD_?(*{T{{H>?`uXqg z@BaV(?CkCH^Yi-p`u6wt#Mtch_4dHk>iGEh^7Hca^z*{j>crRU`1twz{QT_e?DqEc z$J*@b>gvMQ>+|&V$lC14+wAM>>;3)w@9*%!*X#51^1;{Z`}_OH+U@-O`^ehu#MkWU z>FEFe{^{xI#n|ld@$l~N@5kBgv9!0z+wHW?=G)ubr>Cd?|NohpnY8A@0000000000 z00000A^8LW0027xEC2ui01yBW000J~z@2cXD;jmfB(YW_ga{xGQmJF&uGa!=Dy-IU zx$q)@gRrJva4tXt05Uks30VcZ5F=VbfDzy%IyZGW2r3RV4+8@cI5vSg1UL%-4ihvL z4F?pBk1IFOZ1vml&CJGE4FE})gH$(*xI2#8t kA}zwiLpm2FSXaY=R2~vG+}zkoL`Ox%;6gX&=t@BVI|kg>kN^Mx literal 0 HcmV?d00001 diff --git a/media/img/icon_deletelink.gif b/media/img/icon_deletelink.gif new file mode 100644 index 0000000000000000000000000000000000000000..72523e3a3ba1446c8f768c157cea642119a02741 GIT binary patch literal 181 zcmZ?wbhEHbc&kkH2hg{xUB9fxq8%JG(R5 zT3?Eao`!{eDJnj1U~tLY{9|s;X>G0VWo1vp!yowhEs~V{|NlP&4xspxg^__loIwX9 z53-Yi)#yQKi;S#{{sX6 zi;Dh#`0#&e>3>Vh|D2rv=gC*q|>i-WM_<#QV|C1;G zS5*8rF!=rZ_kUyK|3JV%TcG%pg^__lo4aiRnY%vG=3p{kB40{i-Of=+@c@=kM=-;lhR2uU}ugb}c_YKQ=b@!Gj0So;`c@>ec7Z zpFe&2O0>G|#3w~C62$jHd&&!4||@nY7jSp@|JXV0G9y?gi7t5+XBe3+4u zasU4PkdTn*=;-k9@GV=mynOlc$&)9yZryTscRzpr{G&&Y0s{kY-@e`6-rm~Unv;_= zapJ_Do}T37o96WgN=FOWyK|zlnKVG?V<(V^Q=FXkl)zx+J;>C`Rjw@HL+`W7E z(xpqwmMyz;=T2H$T2WEa(W6I~FJFG+#*Mdc-}d(QZripkCMIU>+O?^vsh2Nbo-koT zadGkf{rgw1UY(bhH+%N%fPjE==gyUslw@aTA31WQtgMWIszC843)nmz5DAJC2KN6A z3{A}~t<6mAEF6K!dOBet{LJi3Q>U?Ty6Gw=`74@P2~VEZ!RaF=s>aGHk}BxIJDGhm z3zw*v3(GDRUs-M=4(8p=!mtC)t z{Qe;CdWO$A*9|Y%+MY7&eb8ZiT*u**W%Q-ckPE)2Kc2ks>D=GHfB*mguX9v|fnuQe zlZBCiL4!dDWD>|v3~a>?QwltEq`Vg#b6sS}rMY-Y374ga=%SToS2yx8-qut!l`uMV z$;oAxfZ4Lf%!gb2JX@A%D%sf|4d!%82vX+|Q&(pSPSxNH=I`i?l5i4En$Q)c=ETRA iBoi&_!mXI0DbM99IWL+)+K*2TXdN?;-wroN25SJ!1ANy2 literal 0 HcmV?d00001 diff --git a/media/img/nav-bg-grabber.gif b/media/img/nav-bg-grabber.gif new file mode 100644 index 0000000000000000000000000000000000000000..0a784fa769212348b3cb42f43f2d32c54e6fff6a GIT binary patch literal 116 zcmZ?wbhEHb6l9QRSj56`{P^*AZ{OazbLap6{|x^_7+^s0CkrD30}F!=NC2dkf!Wey z*B$FdhvzH`(_Y#2a57-S&KT*C(G{DQl+NNW9y=`fHnu-v==- Ot=>b+CQo8uum%9*_Ae;_ literal 0 HcmV?d00001 diff --git a/media/img/nav-bg-grabber2.gif b/media/img/nav-bg-grabber2.gif new file mode 100644 index 0000000000000000000000000000000000000000..5b5c5b6e0ef83c1e564e33d9e8e1c75532436d51 GIT binary patch literal 268 zcmV+n0rUPxNk%w1VG#fy0J8u9|NsB?_V(%N>Ehzz`uh6){r%?V=Ire3`1ttn@bK>K z?ep{V$H&Lq+}!T&?*9J%A^8LV00000EC2ui01*Hm000EJ5Xea@RTA6U80cFlTADV3 z;HX*;Py)sC#Bw`#4@l3gG{=P?F!&P|Tt|hFKrjXg9VmlIty-^G0>VY$QV|F%BH96) z17>hw&2GEdu0Z_l?gZ@XMOzdFX11`%71J4G} S($NDQ)eO?v+S}aH5db?j;ed$% literal 0 HcmV?d00001 diff --git a/media/img/nav-bg-reverse.gif b/media/img/nav-bg-reverse.gif new file mode 100644 index 0000000000000000000000000000000000000000..f11029f90fc965141b8815a78ac2651759099475 GIT binary patch literal 186 zcmV;r07d^tNk%w1VG#fy0J8u9|NsB^`1t<*{`U6v@$vEd`}^(f?dRv`;^N}{{r&3d z>hA9D(@t*9{u_A=gpfpKY#xG_U+rVXV3oq`}hC||i=Q&8(m$()z5YF*CjUEw001<4;4tjrTwH+&%FA_x~E6rskH`CdQ7= zuI>)uzWxal`(>Zw+Pr1!Chi?O LckSMx$Y2cs9wnNk literal 0 HcmV?d00001 diff --git a/media/img/selector-add.gif b/media/img/selector-add.gif new file mode 100644 index 0000000000000000000000000000000000000000..50132d1c439494a0a19e1d280385f03d3ac5599b GIT binary patch literal 606 zcmZ?wbhEHb6krfwcoxafw(@M}n)ChZFW!3c{`tGF)3#h)y!U$bf@7^KPS-6uzUAco zS0BDVc=>6^`De|`PR`nSyg_g{XjI&`ak@yUG` zo;EK(J#+ijhQ%lP*I%ezbo}9~&(pSE*?IQS;=MN)@4Gd3=e3%J$D5X(nz`fp(*3u$ zoqaNI*R}d3CpVpX{Q29jre&vU7apIr~bzW=sp-|cz3uWvc? zWa{QC$8Wq`dhpJqjhE{epV)Z(?&i~vr*FGDch`+I#~w`He7Swq*`){W^sT@6^~dl3 z|Nk@49Vq@}VPs&4WY7WG42ly5_T3GUO_4kje3Fi`Y|PEgg2Ei`p1iykJ|h0&z5Zgl z0rM9G$k+=tamfX*T&cAxSkXVyMZhv_>sB}KZDAbD#%4hW4zfg89~5H~^<`z%2RJ`V9$77#OFv^CvqjY0A7XSuxNk>&%VE4w{br3Jf1VK49#UQa3Uc3OT{Z NtIjEA%EiK94FJ;24lMux literal 0 HcmV?d00001 diff --git a/media/img/selector-addall.gif b/media/img/selector-addall.gif new file mode 100644 index 0000000000000000000000000000000000000000..d6e7c639bb2ec270122861f054289845281fae26 GIT binary patch literal 358 zcmZ?wbhEHb6krfwxN64GwdVYqV-FVYy|wM^)3z0-CvU#|?Z@x7m1n1IyE0+p#RUf* z*DpEQwCq&t%5&3q-kG-LYR}pWx1PLjUwNi;)tTmHr>AYX(!J*V^leu=SD$TPd3wsG zD~tDD-+uc3vi-Mqo_}`i`pffoUcPz%`N)+gC$B$Wu={53y7Nb`JiYSZ&EgJ2jU%oBgck}JXFNZEY-hSr6{b%p@TzI-@&-ELR-)%g8_xtzn|NsAIzzr0CvM@3* zm@(*plz{xiz}D;}e*)+h-yWNC)(RZyTq=rvah$l z-QC^j?C`?E!rI!}-rnBp>+8?Y&$F|$v%JQ(wzkK|$N2d8?d|R4>Fx3H@xZ{qud%ZB z_V&`!(&Fap*x1<3&CRj8!??J(+uPg8$;r;n&b76*)z#I=$jG<1x5UK6zrVlr`1}9= z{{R30A^8LW002G!EC2ui01yBW000K7K%dYz*=R~SmZ2~lJ~9pwN1*_@60%NHMxlAX zUK2qgWbklk^e2tm$$Y6>%tp5<1aBx~ID^{#HdGh3{RjW2`-1y|llXdIX?cBNZ+_`frSFT*Tbm`{Jn=f9xc=ztz_wV0- z|Ni~?^XIp2-MVq(#`*K-_wCzv>C&Zd-@aYHe*MaoE4y~>`t<43?%lh$ZQJ(v@#E#o zmmfcV{KtY3(LiF)@D4T0VKnCT(SA zX1)$*HBn6#jwS_7P0<=>4NmpN;)-mGISX90xU|;Ev8_pU4PxOI7UpJ&^3YJ@;Za-V LdE}_8BZD;nhnJNG literal 0 HcmV?d00001 diff --git a/media/img/selector-search.gif b/media/img/selector-search.gif new file mode 100644 index 0000000000000000000000000000000000000000..6d5f4c74923af2daba13baa484364380fb1614b9 GIT binary patch literal 552 zcmZ?wbhEHb6krfwc*ekR;r}fg8=Jp>|9X0Qe){yu!NI}X+uO&-$I8koH8s`3!otqZ z?(W^YSy@?TW@e{PpT2zg^6J&ABO)T)-Q5!s60Tjl=Ire3>gqaW%9PsL+PQP*Ha9mX zCnrZoN9W|^#K*^f{rYv@ym@clym|8E$=&V_@LPJBVtE(?uxDXW;RaaLxbLLEYd;7Mww%N01*VNRUKY#wgg9n+J znUg0^j*E-y=;*j{51X2rQc_ZG-@bkS{(VPBM~0yT6o0ZXf?TTuB0zD%z~0)x z(A3=0+M*~cF2*k1)@;Hotjo#FYS$;lCc@9cB5K1e*(T4%&$OJ0N1L&YotI^~f{vr% zn$~qnssdI5qW0Tb4Ak_r)E!)0jSnm~~hECZvY5o%BVqvfb0K*)eZU6uP literal 0 HcmV?d00001 diff --git a/media/img/selector_stacked-add.gif b/media/img/selector_stacked-add.gif new file mode 100644 index 0000000000000000000000000000000000000000..74261696522de5819780082d9d92d75f8ffdb4fc GIT binary patch literal 612 zcmZ?wbhEHb6krfwcoxdgw({()C+`>Uz23RzeCvwSk6wMQUT~~#(eW)O@4x%}qhZO( z=4B^W9lAAn)1{a1zimDJ=;PO)eQVFX`tbe1%TKd*UVs1P$KQYdUVr@FvFhyR6ZdwU ze>P#`rA;RvPThQ^Vacg^yRJ>!dS%hR+gr{&*>?76|N09vw_ojAb8ha=YxRpy&e(CS zX5q0dryguM`QY`3Zw-r2%-nIkdHLz4Wv6Nu9$&Km_M1=N`!`%%e(?6hjhE^cpICbE zPW_UT?JLi0J9WQr-Gy6EKkPjFXz{*VlQv#%T6(H>;qm&#Ct6mV*>vi0?V{s*E<9;p zb#~+NyGsw;*?ju(++8>N)?b{q|9^%71&Tje7#SEs z8FWCd0L2Ld`@x3LrchxXZVfp-CdTGwF-aChB`GOoO9?O0UN2rZpZN=XRJAypI8=gG zu3D|&6>7p|?7dlrpI>J4W)?;pTi^Y@;vpg82Yh*%1Red)_zN8tI_odX#vXkAI^SWw z8`quLnIE#U3LF+-wUd@+HWGAYV9+`IIYj*f0~?2-=O67a@_!~B5V-KDV{)@!9S?KU zg-$*<4i1Nz9ITzZT>%EXL7SAjj`z#?N@%FQnAjwxsS!|7=*eL;*Vos_$H(O9?cUzr!^6YN%ge8^vckf`>gwvV zyvDP$v)I_!vAV;~&d%H0+sMes)z#I>$;r33x4*x?xVX5rwY9{=#P#_5|Ns9000000 z00000A^8LW002AyEC2ui01yBW000KAK%S5naXdmc6(KMjYAO&AVzD@V4lqm;hLU-| z-jabLRNQE28e){D>0mrlZWF7McDqHrjtjIdGl3s?cnEyf&#j1HCpm1R^ds$Tu?y v2{Xwz1xyMMI@Q+KSVJ%eHQnCb7h_HpIV%Yq94R_BSxrJk53meNO+f%VqdU!B literal 0 HcmV?d00001 diff --git a/media/img/tool-left.gif b/media/img/tool-left.gif new file mode 100644 index 0000000000000000000000000000000000000000..011490ff3a0100bea63eca7d8a3f821edecf6d3f GIT binary patch literal 197 zcmV;$06PCiNk%w1VF>^d0K@+9+1 z>Fn(6>gwvFqods1+`_`bsi~>N#Kh<4=efDLot>Sks;aTEvEJU^(b3W4lL@fC0syEMTS%hy>Zm!0PcpEpJwG;hh<#5^Y_P4;QTzJF~^?;ZNVo;-~tj z3GxIURaQ?9NK-h~-O_%Ehr|6W>p_W03|&Y3moVBW-4OX{v_eKqd6L;=PDTc60DL-S AivR!s literal 0 HcmV?d00001 diff --git a/media/img/tool-right.gif b/media/img/tool-right.gif new file mode 100644 index 0000000000000000000000000000000000000000..cdc140cc590a56bf45ceef6eaeebf47e4a699ac3 GIT binary patch literal 198 zcmV;%06G6hNk%w1VF>^d0K@+9+1 z>Fn(6>gwvFqods1+`_`bsi~>N#Kh<4=efDLot>Sks;aTEvEJU^(b3W4R literal 0 HcmV?d00001 diff --git a/media/img/tool-right_over.gif b/media/img/tool-right_over.gif new file mode 100644 index 0000000000000000000000000000000000000000..4db977e838dd97ae4f59524a764cf8298f19ccc5 GIT binary patch literal 200 zcmZ?wbhEHblL@fC0syEMTS%hy>Zm!0M`SJhE@w+}Rz8zHMDu50@FVv!<=}o0a$2j_;|E wNJ^Lce8rW`28j}!f$kDtvUrX>)$-C{u;f$x#4um1{ZvBtsg!MMAsh_W0PS95AOHXW literal 0 HcmV?d00001 diff --git a/media/img/tooltag-add.gif b/media/img/tooltag-add.gif new file mode 100644 index 0000000000000000000000000000000000000000..8b53d49ae58dbc324ca7fb318198b187fc124c09 GIT binary patch literal 932 zcmZ?wbhEHb6lM@)_|Cxa`}glZfBv+zw0!^m{n4XG%aU|5d-nPB=MNq{xOeZ~wr$(``}?0g zdp3Xm{Fg6Zwzjt3y?giHzkgr9e*ORde?vn9!zdUHfx#C7ia%Mvj?w{lD0p`BHNuZH8`gv5jGtilW#8Ul-s@(Rm3u`n_%YH1afFWM53xbWyi0reSoZU`=F zW>B;|HRonfOG771<|UO1;}pj!{KgMbG6N3=Of=;-YN#}Nd4NeFEUKo%!I@!YFuRjN h0z*m|qaatng9}?1vhrtKUbNTY0V7A3A`=sXH2_xRgyR4J literal 0 HcmV?d00001 diff --git a/media/img/tooltag-add_over.gif b/media/img/tooltag-add_over.gif new file mode 100644 index 0000000000000000000000000000000000000000..bfc52f10de75998687154585752513a27a02e5c4 GIT binary patch literal 336 zcmZ?wbhEHb6lM@)xXQp_AKmol&!20zAN~IQ+b5;fJ+bBa>km(!zx7XVkIL_<>s=I* z-Fg4<%i9m06*kQ}fA#LqpFhjm=B8Ioc1vhpx_)m~&D4mz?loHv1!s0R#56sA{$|&q zv$L0NTfOzr<~=7olUmZNro(_t( z{<*|8FIl(u()IiQ|Npm*YGNP-DE?#tE7t*$AU`p%OuD z64&(xJYQ3LjTSFY75~+{EbMWTq?Tj+^`lM+ch;D9HZb0eJO28D|1uloD@pFe*-apJ^Hn>L+2d-m?#yFEQU|Ni~^ z`t|Go|Nk2r8W_k0ia%MvT6I7q$WIJxH4gmQ9x7=Hf&p1aV>r7mD6wA%agA(z(Y9-o zn{Z!7=F3()sh$@ap>8_^S=AZ45`|}1urBhDn)0zi%$1R$zCpXHxz#1VpeR78J1{*n zKx$GzLbz~Ucw``(R#|u;i#+q?x}l#o5$^*7-1rs_)vpOO{(vYlW{PgEasf C+m{mn literal 0 HcmV?d00001 diff --git a/media/img/tooltag-arrowright_over.gif b/media/img/tooltag-arrowright_over.gif new file mode 100644 index 0000000000000000000000000000000000000000..7163189604a638ee170f093cd042075a7da48c7a GIT binary patch literal 354 zcmZ?wbhEHb6lM@)xXQp_AKmol&!20zAN~IQ+b5;fJ+bBa>km(!zx7XVkIL_<>s=I* z-Fg4<%i9m06*kQ}fA#LqpFhjm=B8Ioc1vhpx_)m~&D4mz?loHv1!s0R#56sA{$|&q zv$L0NTfOzr<~=7olUmZNro(_t( z{<*|8FIl(u()IiQ|Npm*YGNP-DE?#tE7t*$AU`p%)jRO!c&Mb=iC%tqw1%_mf>OuD z64%5AjkaH#++@37WWH>5lj_LG3QgM?$)(Pyl_<=6_Sxb99hOrSl|Hhr49pEp`qi!N zF8KvT0m8k3>6rnFQvwpgW$MEt13C4|!UI|47?&<{5fc~Cj$Ol`%&8*1!G}pzckjNv NA{t6st9%_9tO2syk|zKF literal 0 HcmV?d00001 diff --git a/media/js/SelectBox.js b/media/js/SelectBox.js new file mode 100644 index 0000000000..48ec0a5e4b --- /dev/null +++ b/media/js/SelectBox.js @@ -0,0 +1,110 @@ +var SelectBox = { + cache: new Object(), + init: function(id) { + var box = document.getElementById(id); + var node; + SelectBox.cache[id] = new Array(); + var cache = SelectBox.cache[id]; + for (var i = 0; (node = box.options[i]); i++) { + cache.push({ value: node.value, text: node.text, displayed: 1 }); + } + }, + redisplay: function(id) { + // Repopulate HTML select box from cache + var box = document.getElementById(id); + box.options.length = 0; // clear all options + for (var i = 0, j = SelectBox.cache[id].length; i < j; i++) { + var node = SelectBox.cache[id][i]; + if (node.displayed) { + box.options[box.options.length] = new Option(node.text, node.value, false, false); + } + } + }, + filter: function(id, text) { + // Redisplay the HTML select box, displaying only the choices containing ALL + // the words in text. (It's an AND search.) + var tokens = text.toLowerCase().split(/\s+/); + var node, token; + for (var i = 0; (node = SelectBox.cache[id][i]); i++) { + node.displayed = 1; + for (var j = 0; (token = tokens[j]); j++) { + if (node.text.toLowerCase().indexOf(token) == -1) { + node.displayed = 0; + } + } + } + SelectBox.redisplay(id); + }, + delete_from_cache: function(id, value) { + var node, delete_index = null; + for (var i = 0; (node = SelectBox.cache[id][i]); i++) { + if (node.value == value) { + delete_index = i; + break; + } + } + var j = SelectBox.cache[id].length - 1; + for (var i = delete_index; i < j; i++) { + SelectBox.cache[id][i] = SelectBox.cache[id][i+1]; + } + SelectBox.cache[id].length--; + }, + add_to_cache: function(id, option) { + SelectBox.cache[id].push({ value: option.value, text: option.text, displayed: 1 }); +// SelectBox.sort(id) // Commented out for performance. Can this be deleted? + }, + cache_contains: function(id, value) { + // Check if an item is contained in the cache + var node; + for (var i = 0; (node = SelectBox.cache[id][i]); i++) { + if (node.value == value) { + return true; + } + } + return false; + }, + move: function(from, to) { + var from_box = document.getElementById(from); + var to_box = document.getElementById(to); + var option; + for (var i = 0; (option = from_box.options[i]); i++) { + if (option.selected && SelectBox.cache_contains(from, option.value)) { + SelectBox.add_to_cache(to, { value: option.value, text: option.text, displayed: 1 }); + SelectBox.delete_from_cache(from, option.value); + } + } + SelectBox.redisplay(from); + SelectBox.redisplay(to); + }, + move_all: function(from, to) { + var from_box = document.getElementById(from); + var to_box = document.getElementById(to); + var option; + for (var i = 0; (option = from_box.options[i]); i++) { + SelectBox.add_to_cache(to, { value: option.value, text: option.text, displayed: 1 }); + SelectBox.delete_from_cache(from, option.value); + } + SelectBox.redisplay(from); + SelectBox.redisplay(to); + }, + sort: function(id) { + SelectBox.cache[id].sort( function(a, b) { + a = a.text.toLowerCase(); + b = b.text.toLowerCase(); + try { + if (a > b) return 1; + if (a < b) return -1; + } + catch (e) { + // silently fail on IE 'unknown' exception + } + return 0; + } ); + }, + select_all: function(id) { + var box = document.getElementById(id); + for (var i = 0; i < box.options.length; i++) { + box.options[i].selected = 'selected'; + } + } +} diff --git a/media/js/SelectFilter.js b/media/js/SelectFilter.js new file mode 100644 index 0000000000..0501920608 --- /dev/null +++ b/media/js/SelectFilter.js @@ -0,0 +1,81 @@ +/* +SelectFilter - Turns a multiple-select box into a filter interface. + +Requires SelectBox.js and addevent.js. +*/ + +function findForm(node) { + // returns the node of the form containing the given node + if (node.tagName.toLowerCase() != 'form') { + return findForm(node.parentNode); + } + return node; +} + +var SelectFilter = { + init: function(field_id) { + var from_box = document.getElementById(field_id); + from_box.id += '_from'; // change its ID + // Create the INPUT input box + var input_box = document.createElement('input'); + input_box.id = field_id + '_input'; + input_box.setAttribute('type', 'text'); + from_box.parentNode.insertBefore(input_box, from_box); + from_box.parentNode.insertBefore(document.createElement('br'), input_box.nextSibling); + // Create the TO box + var to_box = document.createElement('select'); + to_box.id = field_id + '_to'; + to_box.setAttribute('multiple', 'multiple'); + to_box.setAttribute('size', from_box.size); + from_box.parentNode.insertBefore(to_box, from_box.nextSibling); + to_box.setAttribute('name', from_box.getAttribute('name')); + from_box.setAttribute('name', from_box.getAttribute('name') + '_old'); + // Give the filters a CSS hook + from_box.setAttribute('class', 'filtered'); + to_box.setAttribute('class', 'filtered'); + // Set up the JavaScript event handlers for the select box filter interface + addEvent(input_box, 'keyup', function(e) { SelectFilter.filter_key_up(e, field_id); }); + addEvent(input_box, 'keydown', function(e) { SelectFilter.filter_key_down(e, field_id); }); + addEvent(from_box, 'dblclick', function() { SelectBox.move(field_id + '_from', field_id + '_to'); }); + addEvent(from_box, 'focus', function() { input_box.focus(); }); + addEvent(to_box, 'dblclick', function() { SelectBox.move(field_id + '_to', field_id + '_from'); }); + addEvent(findForm(from_box), 'submit', function() { SelectBox.select_all(field_id + '_to'); }); + SelectBox.init(field_id + '_from'); + SelectBox.init(field_id + '_to'); + // Move selected from_box options to to_box + SelectBox.move(field_id + '_from', field_id + '_to'); + }, + filter_key_up: function(event, field_id) { + from = document.getElementById(field_id + '_from'); + // don't submit form if user pressed Enter + if ((event.which && event.which == 13) || (event.keyCode && event.keyCode == 13)) { + from.selectedIndex = 0; + SelectBox.move(field_id + '_from', field_id + '_to'); + from.selectedIndex = 0; + return false; + } + var temp = from.selectedIndex; + SelectBox.filter(field_id + '_from', document.getElementById(field_id + '_input').value); + from.selectedIndex = temp; + return true; + }, + filter_key_down: function(event, field_id) { + from = document.getElementById(field_id + '_from'); + // right arrow -- move across + if ((event.which && event.which == 39) || (event.keyCode && event.keyCode == 39)) { + var old_index = from.selectedIndex; + SelectBox.move(field_id + '_from', field_id + '_to'); + from.selectedIndex = (old_index == from.length) ? from.length - 1 : old_index; + return false; + } + // down arrow -- wrap around + if ((event.which && event.which == 40) || (event.keyCode && event.keyCode == 40)) { + from.selectedIndex = (from.length == from.selectedIndex + 1) ? 0 : from.selectedIndex + 1; + } + // up arrow -- wrap around + if ((event.which && event.which == 38) || (event.keyCode && event.keyCode == 38)) { + from.selectedIndex = (from.selectedIndex == 0) ? from.length - 1 : from.selectedIndex - 1; + } + return true; + } +} diff --git a/media/js/SelectFilter2.js b/media/js/SelectFilter2.js new file mode 100644 index 0000000000..2607a62667 --- /dev/null +++ b/media/js/SelectFilter2.js @@ -0,0 +1,129 @@ +/* +SelectFilter2 - Turns a multiple-select box into a filter interface. + +Different than SelectFilter because this is coupled to the admin framework. + +Requires SelectBox.js and addevent.js. +*/ + +// quickElement(tagType, parentReference, textInChildNode, [, attribute, attributeValue ...]); +function quickElement() { + var obj = document.createElement(arguments[0]); + if (arguments[2] != '' && arguments[2] != null) { + var textNode = document.createTextNode(arguments[2]); + obj.appendChild(textNode); + } + var len = arguments.length; + for (var i = 3; i < len; i += 2) { + obj.setAttribute(arguments[i], arguments[i+1]); + } + arguments[1].appendChild(obj); + return obj; +} + +function findForm(node) { + // returns the node of the form containing the given node + if (node.tagName.toLowerCase() != 'form') { + return findForm(node.parentNode); + } + return node; +} + +var SelectFilter = { + init: function(field_id, field_name, is_stacked) { + var from_box = document.getElementById(field_id); + from_box.id += '_from'; // change its ID + from_box.className = 'filtered'; + + // Remove

, because it just gets in the way. + var ps = from_box.parentNode.getElementsByTagName('p'); + for (var i=0; i or

+ var selector_div = quickElement('div', from_box.parentNode); + selector_div.className = is_stacked ? 'selector stacked' : 'selector'; + + //
+ var selector_available = quickElement('div', selector_div, ''); + selector_available.className = 'selector-available'; + quickElement('h2', selector_available, 'Available ' + field_name); + var filter_p = quickElement('p', selector_available, ''); + filter_p.className = 'selector-filter'; + quickElement('img', filter_p, '', 'src', 'http://media.ljworld.com/img/admin/selector-search.gif'); + filter_p.appendChild(document.createTextNode(' ')); + var filter_input = quickElement('input', filter_p, '', 'type', 'text'); + filter_input.id = field_id + '_input'; + selector_available.appendChild(from_box); + var choose_all = quickElement('a', selector_available, 'Choose all', 'href', 'javascript: (function(){ SelectBox.move_all("' + field_id + '_from", "' + field_id + '_to"); })()'); + choose_all.className = 'selector-chooseall'; + + //
    + var selector_chooser = quickElement('ul', selector_div, ''); + selector_chooser.className = 'selector-chooser'; + var add_link = quickElement('a', quickElement('li', selector_chooser, ''), 'Add', 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_from","' + field_id + '_to");})()'); + add_link.className = 'selector-add'; + var remove_link = quickElement('a', quickElement('li', selector_chooser, ''), 'Remove', 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_to","' + field_id + '_from");})()'); + remove_link.className = 'selector-remove'; + + //
    + var selector_chosen = quickElement('div', selector_div, ''); + selector_chosen.className = 'selector-chosen'; + quickElement('h2', selector_chosen, 'Chosen ' + field_name); + var selector_filter = quickElement('p', selector_chosen, 'Select your choice(s) and click '); + selector_filter.className = 'selector-filter'; + quickElement('img', selector_filter, '', 'src', 'http://media.ljworld.com/img/admin/selector-add.gif', 'alt', 'Add'); + var to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', 'multiple', 'size', from_box.size, 'name', from_box.getAttribute('name')); + to_box.className = 'filtered'; + var clear_all = quickElement('a', selector_chosen, 'Clear all', 'href', 'javascript: (function() { SelectBox.move_all("' + field_id + '_to", "' + field_id + '_from");})()'); + clear_all.className = 'selector-clearall'; + + from_box.setAttribute('name', from_box.getAttribute('name') + '_old'); + + // Set up the JavaScript event handlers for the select box filter interface + addEvent(filter_input, 'keyup', function(e) { SelectFilter.filter_key_up(e, field_id); }); + addEvent(filter_input, 'keydown', function(e) { SelectFilter.filter_key_down(e, field_id); }); + addEvent(from_box, 'dblclick', function() { SelectBox.move(field_id + '_from', field_id + '_to'); }); + addEvent(from_box, 'focus', function() { filter_input.focus(); }); + addEvent(to_box, 'dblclick', function() { SelectBox.move(field_id + '_to', field_id + '_from'); }); + addEvent(findForm(from_box), 'submit', function() { SelectBox.select_all(field_id + '_to'); }); + SelectBox.init(field_id + '_from'); + SelectBox.init(field_id + '_to'); + // Move selected from_box options to to_box + SelectBox.move(field_id + '_from', field_id + '_to'); + }, + filter_key_up: function(event, field_id) { + from = document.getElementById(field_id + '_from'); + // don't submit form if user pressed Enter + if ((event.which && event.which == 13) || (event.keyCode && event.keyCode == 13)) { + from.selectedIndex = 0; + SelectBox.move(field_id + '_from', field_id + '_to'); + from.selectedIndex = 0; + return false; + } + var temp = from.selectedIndex; + SelectBox.filter(field_id + '_from', document.getElementById(field_id + '_input').value); + from.selectedIndex = temp; + return true; + }, + filter_key_down: function(event, field_id) { + from = document.getElementById(field_id + '_from'); + // right arrow -- move across + if ((event.which && event.which == 39) || (event.keyCode && event.keyCode == 39)) { + var old_index = from.selectedIndex; + SelectBox.move(field_id + '_from', field_id + '_to'); + from.selectedIndex = (old_index == from.length) ? from.length - 1 : old_index; + return false; + } + // down arrow -- wrap around + if ((event.which && event.which == 40) || (event.keyCode && event.keyCode == 40)) { + from.selectedIndex = (from.length == from.selectedIndex + 1) ? 0 : from.selectedIndex + 1; + } + // up arrow -- wrap around + if ((event.which && event.which == 38) || (event.keyCode && event.keyCode == 38)) { + from.selectedIndex = (from.selectedIndex == 0) ? from.length - 1 : from.selectedIndex - 1; + } + return true; + } +} diff --git a/media/js/admin/CollapsedFieldsets.js b/media/js/admin/CollapsedFieldsets.js new file mode 100644 index 0000000000..bb6eaa79f3 --- /dev/null +++ b/media/js/admin/CollapsedFieldsets.js @@ -0,0 +1,82 @@ +// Finds all fieldsets with class="collapse", collapses them, and gives each +// one a "Show foo" link that uncollapses it. + +function findForm(node) { + // returns the node of the form containing the given node + if (node.tagName.toLowerCase() != 'form') { + return findForm(node.parentNode); + } + return node; +} + +var CollapsedFieldsets = { + collapse_re: /\bcollapse\b/, // Class of fieldsets that should be dealt with. + collapsed_re: /\bcollapsed\b/, // Class that fieldsets get when they're hidden. + collapsed_class: 'collapsed', + init: function() { + var fieldsets = document.getElementsByTagName('fieldset'); + var collapsed_seen = false; + for (var i=0; i + // Show section priorities… + //
    + var div = document.createElement('div'); + + // Give it a hook so we can remove it later. + div.id = 'fieldsetcollapser' + i; + + div.className = 'form-row collapse-toggle'; // CSS hook + var collapse_link = document.createElement('a'); + collapse_link.setAttribute('href', 'javascript:CollapsedFieldsets.display(' + i + ');'); + collapse_link.appendChild(document.createTextNode('Show ' + verbose_name)); + div.appendChild(collapse_link); + fs.appendChild(div); + } + } + if (collapsed_seen) { + // Expand all collapsed fieldsets when form is submitted. + addEvent(findForm(document.getElementsByTagName('fieldset')[0]), 'submit', function() { CollapsedFieldsets.uncollapse_all(); }); + } + }, + fieldset_has_errors: function(fs) { + // Returns true if any fields in the fieldset have validation errors. + var divs = fs.getElementsByTagName('div'); + for (var i=0; i +// + +var DateTimeShortcuts = { + calendars: [], + calendarInputs: [], + clockInputs: [], + calendarDivName1: 'calendarbox', // name of calendar
    that gets toggled + calendarDivName2: 'calendarin', // name of
    that contains calendar + clockDivName: 'clockbox', // name of clock
    that gets toggled + + init: function() { + var inputs = document.getElementsByTagName('input'); + for (var i=0; i + //

    Choose a time

    + // + //

    Cancel

    + //
    + + var clock_box = document.createElement('div'); + clock_box.style.display = 'none'; + clock_box.style.position = 'absolute'; + clock_box.style.left = findPosX(clock_link) + 17 + 'px'; + clock_box.style.top = findPosY(clock_link) - 30 + 'px'; + clock_box.className = 'clockbox module'; + clock_box.setAttribute('id', DateTimeShortcuts.clockDivName + num); + document.body.appendChild(clock_box); + addEvent(clock_box, 'click', DateTimeShortcuts.cancelEventPropagation); + + quickElement('h2', clock_box, 'Choose a time'); + time_list = quickElement('ul', clock_box, '', 'class', 'timelist'); + quickElement("a", quickElement("li", time_list, ""), "Now", "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date().getHourMinute());") + quickElement("a", quickElement("li", time_list, ""), "Midnight", "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", '00:00');") + quickElement("a", quickElement("li", time_list, ""), "6 a.m.", "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", '06:00');") + quickElement("a", quickElement("li", time_list, ""), "Noon", "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", '12:00');") + + cancel_p = quickElement('p', clock_box, '', 'class', 'calendar-cancel'); + quickElement('a', cancel_p, 'Cancel', 'href', 'javascript:DateTimeShortcuts.dismissCalendar(' + num + ');'); + }, + + openClock: function(num) { + document.getElementById(DateTimeShortcuts.clockDivName + num).style.display = 'block'; + addEvent(window, 'click', function() { DateTimeShortcuts.dismissClock(num); return true; }); + }, + + dismissClock: function(num) { + document.getElementById(DateTimeShortcuts.clockDivName + num).style.display = 'none'; + window.onclick = null; + }, + + handleClockQuicklink: function(num, val) { + DateTimeShortcuts.clockInputs[num].value = val; + DateTimeShortcuts.dismissClock(num); + }, + + // Add calendar widget to a given field. + addCalendar: function(inp) { + var num = DateTimeShortcuts.calendars.length; + + DateTimeShortcuts.calendarInputs[num] = inp; + + // Shortcut links (calendar icon and "Today" link) + var shortcuts_span = document.createElement('span'); + inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling); + var today_link = document.createElement('a'); + today_link.setAttribute('href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', 0);'); + today_link.appendChild(document.createTextNode('Today')); + var cal_link = document.createElement('a'); + cal_link.setAttribute('href', 'javascript:DateTimeShortcuts.openCalendar(' + num + ');'); + quickElement('img', cal_link, '', 'src', 'http://media.ljworld.com/img/admin/icon_calendar.gif', 'alt', 'Calendar'); + shortcuts_span.appendChild(document.createTextNode('\240')); + shortcuts_span.appendChild(today_link); + shortcuts_span.appendChild(document.createTextNode('\240|\240')); + shortcuts_span.appendChild(cal_link); + + // Create calendarbox div. + // + // Markup looks like: + // + //
    + //

    + // + // February 2003 + //

    + //
    + // + //
    + //
    + // Yesterday | Today | Tomorrow + //
    + //

    Cancel

    + //
    + var cal_box = document.createElement('div'); + cal_box.style.display = 'none'; + cal_box.style.position = 'absolute'; + cal_box.style.left = findPosX(cal_link) + 17 + 'px'; + cal_box.style.top = findPosY(cal_link) - 75 + 'px'; + cal_box.className = 'calendarbox module'; + cal_box.setAttribute('id', DateTimeShortcuts.calendarDivName1 + num); + document.body.appendChild(cal_box); + addEvent(cal_box, 'click', DateTimeShortcuts.cancelEventPropagation); + + // next-prev links + var cal_nav = quickElement('div', cal_box, ''); + quickElement('a', cal_nav, '<', 'class', 'calendarnav-previous', 'href', 'javascript:DateTimeShortcuts.drawPrev('+num+');'); + quickElement('a', cal_nav, '>', 'class', 'calendarnav-next', 'href', 'javascript:DateTimeShortcuts.drawNext('+num+');'); + cal_box.appendChild(cal_nav); + + // main box + var cal_main = quickElement('div', cal_box, '', 'id', DateTimeShortcuts.calendarDivName2 + num); + cal_main.className = 'calendar'; + DateTimeShortcuts.calendars[num] = new Calendar(DateTimeShortcuts.calendarDivName2 + num, DateTimeShortcuts.handleCalendarCallback(num)); + DateTimeShortcuts.calendars[num].drawCurrent(); + + // calendar shortcuts + var shortcuts = quickElement('div', cal_box, '', 'class', 'calendar-shortcuts'); + quickElement('a', shortcuts, 'Yesterday', 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', -1);'); + shortcuts.appendChild(document.createTextNode('\240|\240')); + quickElement('a', shortcuts, 'Today', 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', 0);'); + shortcuts.appendChild(document.createTextNode('\240|\240')); + quickElement('a', shortcuts, 'Tomorrow', 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', +1);'); + + // cancel bar + var cancel_p = quickElement('p', cal_box, '', 'class', 'calendar-cancel'); + quickElement('a', cancel_p, 'Cancel', 'href', 'javascript:DateTimeShortcuts.dismissCalendar(' + num + ');'); + }, + + openCalendar: function(num) { + document.getElementById(DateTimeShortcuts.calendarDivName1+num).style.display = 'block'; + addEvent(window, 'click', function() { DateTimeShortcuts.dismissCalendar(num); return true; }); + }, + + dismissCalendar: function(num) { + document.getElementById(DateTimeShortcuts.calendarDivName1+num).style.display = 'none'; + window.onclick = null; + }, + + drawPrev: function(num) { + DateTimeShortcuts.calendars[num].drawPreviousMonth(); + }, + + drawNext: function(num) { + DateTimeShortcuts.calendars[num].drawNextMonth(); + }, + + handleCalendarCallback: function(num) { + return "function(y, m, d) { DateTimeShortcuts.calendarInputs["+num+"].value = y+'-'+m+'-'+d; document.getElementById(DateTimeShortcuts.calendarDivName1+"+num+").style.display='none';}"; + }, + + handleCalendarQuickLink: function(num, offset) { + var d = new Date(); + d.setDate(d.getDate() + offset) + DateTimeShortcuts.calendarInputs[num].value = d.getISODate(); + DateTimeShortcuts.dismissCalendar(num); + }, + + cancelEventPropagation: function(e) { + if (!e) var e = window.event; + e.cancelBubble = true; + if (e.stripPropagation) e.stopPropagation(); + } + +} + +addEvent(window, 'load', DateTimeShortcuts.init); diff --git a/media/js/admin/RelatedObjectLookups.js b/media/js/admin/RelatedObjectLookups.js new file mode 100644 index 0000000000..55bd59a850 --- /dev/null +++ b/media/js/admin/RelatedObjectLookups.js @@ -0,0 +1,33 @@ +// Handles related-objects functionality: lookup link for raw_id_admin=True +// and Add Another links. + +function showRelatedObjectLookupPopup(triggeringLink) { + var name = triggeringLink.id.replace(/^lookup_/, ''); + var win = window.open(triggeringLink.href + '?pop=1', name, 'height=500,width=740,resizable=yes,scrollbars=yes'); + win.focus(); + return false; +} + +function dismissRelatedLookupPopup(win, chosenId) { + document.getElementById(win.name).value = chosenId; + win.close(); +} + +function showAddAnotherPopup(triggeringLink) { + var name = triggeringLink.id.replace(/^add_/, ''); + var win = window.open(triggeringLink.href + '?_popup=1', name, 'height=500,width=800,resizable=yes,scrollbars=yes'); + win.focus(); + return false; +} + +function dismissAddAnotherPopup(win, newId, newRepr) { + var elem = document.getElementById(win.name); + if (elem.nodeName == 'SELECT') { + var o = new Option(newRepr, newId); + elem.appendChild(o); + elem.selectedIndex = elem.length - 1; + } else if (elem.nodeName == 'INPUT') { + elem.value = newId; + } + win.close(); +} \ No newline at end of file diff --git a/media/js/admin/add_calendars.js b/media/js/admin/add_calendars.js new file mode 100644 index 0000000000..b0e8247f8d --- /dev/null +++ b/media/js/admin/add_calendars.js @@ -0,0 +1,158 @@ +// Finds all and inserts a calendar after them + +// quickElement(tagType, parentReference, textInChildNode, [, attribute, attributeValue ...]); +function quickElement() { + var obj = document.createElement(arguments[0]); + if (arguments[2] != '' && arguments[2] != null) { + var textNode = document.createTextNode(arguments[2]); + obj.appendChild(textNode); + } + for (var i = 3; i < arguments.length; i += 2) { + obj.setAttribute(arguments[i], arguments[i+1]); + } + arguments[1].appendChild(obj); + return obj; +} + +// findPosX / findPosY: see http://www.quirksmode.org/js/findpos.html +function findPosX(obj) +{ + var curleft = 0; + if (obj.offsetParent) + { + while (obj.offsetParent) + { + curleft += obj.offsetLeft + obj = obj.offsetParent; + } + } + else if (obj.x) + curleft += obj.x; + return curleft; +} + +function findPosY(obj) +{ + var curtop = 0; + if (obj.offsetParent) + { + while (obj.offsetParent) + { + curtop += obj.offsetTop + obj = obj.offsetParent; + } + } + else if (obj.y) + curtop += obj.y; + return curtop; +} + +var AddCal = { + cals: [], + inps: [], + divname1: 'calendarbox', // name of
    that gets toggled + divname2: 'calendarin', // name of
    that contains calendar + init: function() { + var inputs = document.getElementsByTagName('input'); + for (var i=0; i < inputs.length; i++) { + var inp = inputs[i]; + if (inp.getAttribute('type') == 'text' && inp.className.match(/vDateField/)) { + var num = AddCal.cals.length; + + AddCal.inps[num] = inp; + + // Calendar + var cal_link = document.createElement('a'); + cal_link.setAttribute('href', 'javascript:AddCal.toggle(' + num + ');'); + quickElement('img', cal_link, '', 'src', 'http://media.ljworld.com/img/admin/icon_calendar.gif', 'alt', 'Calendar'); + inp.parentNode.insertBefore(cal_link, inp.nextSibling); + + // Markup looks like: + // + //
    + //

    + // + // February 2003 + //

    + //
    + // + //
    + //
    + // Yesterday | Today | Tomorrow + //
    + //

    Cancel

    + //
    + var cal_box = document.createElement('div'); + cal_box.style.display = 'none'; + cal_box.style.position = 'absolute'; + cal_box.style.left = findPosX(cal_link) + 17 + 'px'; + cal_box.style.top = findPosY(cal_link) - 75 + 'px'; + cal_box.className = 'calendarbox module'; + cal_box.setAttribute('id', AddCal.divname1 + num); + + // next-prev links + var cal_nav = quickElement('div', cal_box, ''); + quickElement('a', cal_nav, '<', 'class', 'calendarnav-previous', 'href', 'javascript:AddCal.drawPrev('+num+');'); + quickElement('a', cal_nav, '>', 'class', 'calendarnav-next', 'href', 'javascript:AddCal.drawNext('+num+');'); + cal_box.appendChild(cal_nav); + + // main box + var cal_main = quickElement('div', cal_box, '', 'id', AddCal.divname2 + num); + cal_main.className = 'calendar'; + document.body.appendChild(cal_box); + AddCal.cals[num] = new Calendar(AddCal.divname2 + num, AddCal.handleCallback(num)); + AddCal.cals[num].drawCurrent(); + + // calendar shortcuts + var shortcuts = quickElement('div', cal_box, '', 'class', 'calendar-shortcuts'); + quickElement('a', shortcuts, 'Yesterday', 'href', 'javascript:AddCal.handleQuickLink(' + num + ', -1);'); + shortcuts.appendChild(document.createTextNode('\240|\240')); + quickElement('a', shortcuts, 'Today', 'href', 'javascript:AddCal.handleQuickLink(' + num + ', 0);'); + shortcuts.appendChild(document.createTextNode('\240|\240')); + quickElement('a', shortcuts, 'Tomorrow', 'href', 'javascript:AddCal.handleQuickLink(' + num + ', +1);'); + + // cancel bar + var cancel_p = quickElement('p', cal_box, '', 'class', 'calendar-cancel'); + quickElement('a', cancel_p, 'Cancel', 'href', 'javascript:AddCal.toggle(' + num + ');'); + + + } + } + }, + toggle: function(num) { + var box = document.getElementById(AddCal.divname1+num); + box.style.display = (box.style.display == 'none') ? 'block' : 'none'; + /* + if (box.style.display = 'block') { + var x = 0; + var y = 0; + if (!e) var e = window.event; + if (e.pageX || e.pageY) { + x = e.pageX; + y = e.pageY; + } else if (e.clientX || e.clientY) { + x = e.clientX + document.body.scrollLeft; + y = e.clientY + document.body.scrollTop; + } + box.style.left = x; + box.style.top = y; + } + */ + }, + drawPrev: function(num) { + AddCal.cals[num].drawPreviousMonth(); + }, + drawNext: function(num) { + AddCal.cals[num].drawNextMonth(); + }, + handleCallback: function(num) { + return "function(y, m, d) { AddCal.inps["+num+"].value = y+'-'+m+'-'+d; document.getElementById(AddCal.divname1+"+num+").style.display='none';}"; + }, + handleQuickLink: function(num, offset) { + var d = new Date(); + d.setDate(d.getDate() + offset) + AddCal.inps[num].value = d.getISODate(); + AddCal.toggle(num); + } +} +addEvent(window, 'load', AddCal.init); diff --git a/media/js/admin/ordering.js b/media/js/admin/ordering.js new file mode 100644 index 0000000000..fb0f5b007e --- /dev/null +++ b/media/js/admin/ordering.js @@ -0,0 +1,137 @@ +addEvent(window, 'load', reorder_init); + +var lis; +var top = 90; +var left = 545; +var height = 30; + +function reorder_init() { + lis = document.getElementsBySelector('ul#orderthese li'); + var input = document.getElementsBySelector('input[name=order_]')[0]; + setOrder(input.value.split(',')); + input.disabled = true; + draw(); + // Now initialise the dragging behaviour + var limit = (lis.length - 1) * height; + for (var i = 0; i < lis.length; i++) { + var li = lis[i]; + var img = document.getElementById('handle'+li.id); + li.style.zIndex = 1; + Drag.init(img, li, left + 10, left + 10, top + 10, top + 10 + limit); + li.onDragStart = startDrag; + li.onDragEnd = endDrag; + img.style.cursor = 'move'; + } +} + +function submitOrderForm() { + var inputOrder = document.getElementsBySelector('input[name=order_]')[0]; + inputOrder.value = getOrder(); + inputOrder.disabled=false; +} + +function startDrag() { + this.style.zIndex = '10'; + this.className = 'dragging'; +} + +function endDrag(x, y) { + this.style.zIndex = '1'; + this.className = ''; + // Work out how far along it has been dropped, using x co-ordinate + var oldIndex = this.index; + var newIndex = Math.round((y - 10 - top) / height); + // 'Snap' to the correct position + this.style.top = (10 + top + newIndex * height) + 'px'; + this.index = newIndex; + moveItem(oldIndex, newIndex); +} + +function moveItem(oldIndex, newIndex) { + // Swaps two items, adjusts the index and left co-ord for all others + if (oldIndex == newIndex) { + return; // Nothing to swap; + } + var direction, lo, hi; + if (newIndex > oldIndex) { + lo = oldIndex; + hi = newIndex; + direction = -1; + } else { + direction = 1; + hi = oldIndex; + lo = newIndex; + } + var lis2 = new Array(); // We will build the new order in this array + for (var i = 0; i < lis.length; i++) { + if (i < lo || i > hi) { + // Position of items not between the indexes is unaffected + lis2[i] = lis[i]; + continue; + } else if (i == newIndex) { + lis2[i] = lis[oldIndex]; + continue; + } else { + // Item is between the two indexes - move it along 1 + lis2[i] = lis[i - direction]; + } + } + // Re-index everything + reIndex(lis2); + lis = lis2; + draw(); +// document.getElementById('hiddenOrder').value = getOrder(); + document.getElementsBySelector('input[name=order_]')[0].value = getOrder(); +} + +function reIndex(lis) { + for (var i = 0; i < lis.length; i++) { + lis[i].index = i; + } +} + +function draw() { + for (var i = 0; i < lis.length; i++) { + var li = lis[i]; + li.index = i; + li.style.position = 'absolute'; + li.style.left = (10 + left) + 'px'; + li.style.top = (10 + top + (i * height)) + 'px'; + } +} + +function getOrder() { + var order = new Array(lis.length); + for (var i = 0; i < lis.length; i++) { + order[i] = lis[i].id.substring(1, 100); + } + return order.join(','); +} + +function setOrder(id_list) { + /* Set the current order to match the lsit of IDs */ + var temp_lis = new Array(); + for (var i = 0; i < id_list.length; i++) { + var id = 'p' + id_list[i]; + temp_lis[temp_lis.length] = document.getElementById(id); + } + reIndex(temp_lis); + lis = temp_lis; + draw(); +} + +function addEvent(elm, evType, fn, useCapture) +// addEvent and removeEvent +// cross-browser event handling for IE5+, NS6 and Mozilla +// By Scott Andrew +{ + if (elm.addEventListener){ + elm.addEventListener(evType, fn, useCapture); + return true; + } else if (elm.attachEvent){ + var r = elm.attachEvent("on"+evType, fn); + return r; + } else { + elm['on'+evType] = fn; + } +} diff --git a/media/js/calendar.js b/media/js/calendar.js new file mode 100644 index 0000000000..ad1f0a9734 --- /dev/null +++ b/media/js/calendar.js @@ -0,0 +1,139 @@ +/* +calendar.js - Calendar functions by Adrian Holovaty +*/ + +function removeChildren(a) { // "a" is reference to an object + while (a.hasChildNodes()) a.removeChild(a.lastChild); +} + +// quickElement(tagType, parentReference, textInChildNode, [, attribute, attributeValue ...]); +function quickElement() { + var obj = document.createElement(arguments[0]); + if (arguments[2] != '' && arguments[2] != null) { + var textNode = document.createTextNode(arguments[2]); + obj.appendChild(textNode); + } + var len = arguments.length; + for (var i = 3; i < len; i += 2) { + obj.setAttribute(arguments[i], arguments[i+1]); + } + arguments[1].appendChild(obj); + return obj; +} + +// CalendarNamespace -- Provides a collection of HTML calendar-related helper functions +var CalendarNamespace = { + monthsOfYear: 'January February March April May June July August September October November December'.split(' '), + daysOfWeek: 'S M T W T F S'.split(' '), + isLeapYear: function(year) { + return (((year % 4)==0) && ((year % 100)!=0) || ((year % 400)==0)); + }, + getDaysInMonth: function(month,year) { + var days; + if (month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12) { + days = 31; + } + else if (month==4 || month==6 || month==9 || month==11) { + days = 30; + } + else if (month==2 && CalendarNamespace.isLeapYear(year)) { + days = 29; + } + else { + days = 28; + } + return days; + }, + draw: function(month, year, div_id, callback) { // month = 1-12, year = 1-9999 + month = parseInt(month); + year = parseInt(year); + var calDiv = document.getElementById(div_id); + removeChildren(calDiv); + var calTable = document.createElement('table'); + quickElement('caption', calTable, CalendarNamespace.monthsOfYear[month-1] + ' ' + year); + var tableBody = quickElement('tbody', calTable); + + // Draw days-of-week header + var tableRow = quickElement('tr', tableBody); + for (var i = 0; i < 7; i++) { + quickElement('th', tableRow, CalendarNamespace.daysOfWeek[i]); + } + + var startingPos = new Date(year, month-1, 1).getDay(); + var days = CalendarNamespace.getDaysInMonth(month, year); + + // Draw blanks before first of month + tableRow = quickElement('tr', tableBody); + for (var i = 0; i < startingPos; i++) { + quickElement('td', tableRow, ' ', 'bgcolor','#f3f3f3'); + } + + // Draw days of month + var currentDay = 1; + for (var i = startingPos; currentDay <= days; i++) { + if (i%7 == 0 && currentDay != 1) { + tableRow = quickElement('tr', tableBody); + } + var cell = quickElement('td', tableRow, ''); + quickElement('a', cell, currentDay, 'href', 'javascript:void(' + callback + '('+year+','+month+','+currentDay+'));'); + currentDay++; + } + + // Draw blanks after end of month (optional, but makes for valid code) + while (tableRow.childNodes.length < 7) { + quickElement('td', tableRow, ' ', 'bgcolor','#f3f3f3'); + } + + calDiv.appendChild(calTable); + } +} + +// Calendar -- A calendar instance +function Calendar(div_id, callback) { + // div_id (string) is the ID of the element in which the calendar will + // be displayed + // callback (string) is the name of a JavaScript function that will be + // called with the parameters (year, month, day) when a day in the + // calendar is clicked + this.div_id = div_id; + this.callback = callback; + this.today = new Date(); + this.currentMonth = this.today.getMonth() + 1; + this.currentYear = this.today.getFullYear(); + this.drawCurrent = function() { + CalendarNamespace.draw(this.currentMonth, this.currentYear, this.div_id, this.callback); + } + this.drawDate = function(month, year) { + this.currentMonth = month; + this.currentYear = year; + this.drawCurrent(); + } + this.drawPreviousMonth = function() { + if (this.currentMonth == 1) { + this.currentMonth = 12; + this.currentYear--; + } + else { + this.currentMonth--; + } + this.drawCurrent(); + } + this.drawNextMonth = function() { + if (this.currentMonth == 12) { + this.currentMonth = 1; + this.currentYear++; + } + else { + this.currentMonth++; + } + this.drawCurrent(); + } + this.drawPreviousYear = function() { + this.currentYear--; + this.drawCurrent(); + } + this.drawNextYear = function() { + this.currentYear++; + this.drawCurrent(); + } +} diff --git a/media/js/core.js b/media/js/core.js new file mode 100644 index 0000000000..188e477939 --- /dev/null +++ b/media/js/core.js @@ -0,0 +1,138 @@ +// Core javascript helper functions + +// Cross-browser event handlers. +function addEvent(obj, evType, fn) { + if (obj.addEventListener) { + obj.addEventListener(evType, fn, false); + return true; + } else if (obj.attachEvent) { + var r = obj.attachEvent("on" + evType, fn); + return r; + } else { + return false; + } +} + +function removeEvent(obj, evType, fn) { + if (obj.removeEventListener) { + obj.removeEventListener(evType, fn, false); + return true; + } else if (obj.detachEvent) { + obj.detachEvent("on" + evType, fn); + } else { + return false; + } +} + +// quickElement(tagType, parentReference, textInChildNode, [, attribute, attributeValue ...]); +function quickElement() { + var obj = document.createElement(arguments[0]); + if (arguments[2] != '' && arguments[2] != null) { + var textNode = document.createTextNode(arguments[2]); + obj.appendChild(textNode); + } + var len = arguments.length; + for (var i = 3; i < len; i += 2) { + obj.setAttribute(arguments[i], arguments[i+1]); + } + arguments[1].appendChild(obj); + return obj; +} + +// ---------------------------------------------------------------------------- +// Cross-browser xmlhttp object +// from http://jibbering.com/2002/4/httprequest.html +// ---------------------------------------------------------------------------- +var xmlhttp; +/*@cc_on @*/ +/*@if (@_jscript_version >= 5) + try { + xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); + } catch (e) { + try { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } catch (E) { + xmlhttp = false; + } + } +@else + xmlhttp = false; +@end @*/ +if (!xmlhttp && typeof XMLHttpRequest != 'undefined') { + xmlhttp = new XMLHttpRequest(); +} + +// ---------------------------------------------------------------------------- +// Find-position functions by PPK +// See http://www.xs4all.nl/~ppk/js/index.html?/~ppk/js/findpos.html +// ---------------------------------------------------------------------------- +function findPosX(obj) { + var curleft = 0; + if (obj.offsetParent) { + while (obj.offsetParent) { + curleft += obj.offsetLeft + obj = obj.offsetParent; + } + } else if (obj.x) { + curleft += obj.x; + } + return curleft; +} + +function findPosY(obj) { + var curtop = 0; + if (obj.offsetParent) { + while (obj.offsetParent) { + curtop += obj.offsetTop + obj = obj.offsetParent; + } + } else if (obj.y) { + curtop += obj.y; + } + return curtop; +} + +//----------------------------------------------------------------------------- +// Date object extensions +// ---------------------------------------------------------------------------- +Date.prototype.getCorrectYear = function() { + // Date.getYear() is unreliable -- + // see http://www.quirksmode.org/js/introdate.html#year + var y = this.getYear() % 100; + return (y < 38) ? y + 2000 : y + 1900; +} + +Date.prototype.getTwoDigitMonth = function() { + return (this.getMonth() < 9) ? '0' + (this.getMonth()+1) : (this.getMonth()+1); +} + +Date.prototype.getTwoDigitDate = function() { + return (this.getDate() < 10) ? '0' + this.getDate() : this.getDate(); +} + +Date.prototype.getTwoDigitHour = function() { + return (this.getHours() < 10) ? '0' + this.getHours() : this.getHours(); +} + +Date.prototype.getTwoDigitMinute = function() { + return (this.getMinutes() < 10) ? '0' + this.getMinutes() : this.getMinutes(); +} + +Date.prototype.getISODate = function() { + return this.getCorrectYear() + '-' + this.getTwoDigitMonth() + '-' + this.getTwoDigitDate(); +} + +Date.prototype.getHourMinute = function() { + return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute(); +} + +// ---------------------------------------------------------------------------- +// String object extensions +// ---------------------------------------------------------------------------- +String.prototype.pad_left = function(pad_length, pad_string) { + new_string = this; + for (var i = 0; new_string.length < pad_length; i++) { + new_string = pad_string + new_string; + } + return new_string; +} \ No newline at end of file diff --git a/media/js/dateparse.js b/media/js/dateparse.js new file mode 100644 index 0000000000..cec36e41e0 --- /dev/null +++ b/media/js/dateparse.js @@ -0,0 +1,227 @@ +/* 'Magic' date parsing, by Simon Willison (6th October 2003) + http://simon.incutio.com/archive/2003/10/06/betterDateInput + Adapted for 6newslawrence.com, 28th January 2004 +*/ + +/* Finds the index of the first occurence of item in the array, or -1 if not found */ +Array.prototype.indexOf = function(item) { + for (var i = 0; i < this.length; i++) { + if (this[i] == item) { + return i; + } + } + return -1; +}; +/* Returns an array of items judged 'true' by the passed in test function */ +Array.prototype.filter = function(test) { + var matches = []; + for (var i = 0; i < this.length; i++) { + if (test(this[i])) { + matches[matches.length] = this[i]; + } + } + return matches; +}; + +var monthNames = "January February March April May June July August September October November December".split(" "); +var weekdayNames = "Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "); + +/* Takes a string, returns the index of the month matching that string, throws + an error if 0 or more than 1 matches +*/ +function parseMonth(month) { + var matches = monthNames.filter(function(item) { + return new RegExp("^" + month, "i").test(item); + }); + if (matches.length == 0) { + throw new Error("Invalid month string"); + } + if (matches.length > 1) { + throw new Error("Ambiguous month"); + } + return monthNames.indexOf(matches[0]); +} +/* Same as parseMonth but for days of the week */ +function parseWeekday(weekday) { + var matches = weekdayNames.filter(function(item) { + return new RegExp("^" + weekday, "i").test(item); + }); + if (matches.length == 0) { + throw new Error("Invalid day string"); + } + if (matches.length > 1) { + throw new Error("Ambiguous weekday"); + } + return weekdayNames.indexOf(matches[0]); +} + +/* Array of objects, each has 're', a regular expression and 'handler', a + function for creating a date from something that matches the regular + expression. Handlers may throw errors if string is unparseable. +*/ +var dateParsePatterns = [ + // Today + { re: /^tod/i, + handler: function() { + return new Date(); + } + }, + // Tomorrow + { re: /^tom/i, + handler: function() { + var d = new Date(); + d.setDate(d.getDate() + 1); + return d; + } + }, + // Yesterday + { re: /^yes/i, + handler: function() { + var d = new Date(); + d.setDate(d.getDate() - 1); + return d; + } + }, + // 4th + { re: /^(\d{1,2})(st|nd|rd|th)?$/i, + handler: function(bits) { + var d = new Date(); + d.setDate(parseInt(bits[1], 10)); + return d; + } + }, + // 4th Jan + { re: /^(\d{1,2})(?:st|nd|rd|th)? (\w+)$/i, + handler: function(bits) { + var d = new Date(); + d.setDate(parseInt(bits[1], 10)); + d.setMonth(parseMonth(bits[2])); + return d; + } + }, + // 4th Jan 2003 + { re: /^(\d{1,2})(?:st|nd|rd|th)? (\w+),? (\d{4})$/i, + handler: function(bits) { + var d = new Date(); + d.setDate(parseInt(bits[1], 10)); + d.setMonth(parseMonth(bits[2])); + d.setYear(bits[3]); + return d; + } + }, + // Jan 4th + { re: /^(\w+) (\d{1,2})(?:st|nd|rd|th)?$/i, + handler: function(bits) { + var d = new Date(); + d.setDate(parseInt(bits[2], 10)); + d.setMonth(parseMonth(bits[1])); + return d; + } + }, + // Jan 4th 2003 + { re: /^(\w+) (\d{1,2})(?:st|nd|rd|th)?,? (\d{4})$/i, + handler: function(bits) { + var d = new Date(); + d.setDate(parseInt(bits[2], 10)); + d.setMonth(parseMonth(bits[1])); + d.setYear(bits[3]); + return d; + } + }, + // next Tuesday - this is suspect due to weird meaning of "next" + { re: /^next (\w+)$/i, + handler: function(bits) { + var d = new Date(); + var day = d.getDay(); + var newDay = parseWeekday(bits[1]); + var addDays = newDay - day; + if (newDay <= day) { + addDays += 7; + } + d.setDate(d.getDate() + addDays); + return d; + } + }, + // last Tuesday + { re: /^last (\w+)$/i, + handler: function(bits) { + throw new Error("Not yet implemented"); + } + }, + // mm/dd/yyyy (American style) + { re: /(\d{1,2})\/(\d{1,2})\/(\d{4})/, + handler: function(bits) { + var d = new Date(); + d.setYear(bits[3]); + d.setDate(parseInt(bits[2], 10)); + d.setMonth(parseInt(bits[1], 10) - 1); // Because months indexed from 0 + return d; + } + }, + // yyyy-mm-dd (ISO style) + { re: /(\d{4})-(\d{1,2})-(\d{1,2})/, + handler: function(bits) { + var d = new Date(); + d.setYear(parseInt(bits[1])); + d.setDate(parseInt(bits[3], 10)); + d.setMonth(parseInt(bits[2], 10) - 1); + return d; + } + }, +]; + +function parseDateString(s) { + for (var i = 0; i < dateParsePatterns.length; i++) { + var re = dateParsePatterns[i].re; + var handler = dateParsePatterns[i].handler; + var bits = re.exec(s); + if (bits) { + return handler(bits); + } + } + throw new Error("Invalid date string"); +} + +function fmt00(x) { + // fmt00: Tags leading zero onto numbers 0 - 9. + // Particularly useful for displaying results from Date methods. + // + if (Math.abs(parseInt(x)) < 10){ + x = "0"+ Math.abs(x); + } + return x; +} + +function parseDateStringISO(s) { + try { + var d = parseDateString(s); + return d.getFullYear() + '-' + (fmt00(d.getMonth() + 1)) + '-' + fmt00(d.getDate()) + } + catch (e) { return s; } +} +function magicDate(input) { + var messagespan = input.id + 'Msg'; + try { + var d = parseDateString(input.value); + input.value = d.getFullYear() + '-' + (fmt00(d.getMonth() + 1)) + '-' + + fmt00(d.getDate()); + input.className = ''; + // Human readable date + if (document.getElementById(messagespan)) { + document.getElementById(messagespan).firstChild.nodeValue = d.toDateString(); + document.getElementById(messagespan).className = 'normal'; + } + } + catch (e) { + input.className = 'error'; + var message = e.message; + // Fix for IE6 bug + if (message.indexOf('is null or not an object') > -1) { + message = 'Invalid date string'; + } + if (document.getElementById(messagespan)) { + document.getElementById(messagespan).firstChild.nodeValue = message; + document.getElementById(messagespan).className = 'error'; + } + } +} diff --git a/media/js/getElementsBySelector.js b/media/js/getElementsBySelector.js new file mode 100644 index 0000000000..ae6d387a91 --- /dev/null +++ b/media/js/getElementsBySelector.js @@ -0,0 +1,167 @@ +/* document.getElementsBySelector(selector) + - returns an array of element objects from the current document + matching the CSS selector. Selectors can contain element names, + class names and ids and can be nested. For example: + + elements = document.getElementsBySelect('div#main p a.external') + + Will return an array of all 'a' elements with 'external' in their + class attribute that are contained inside 'p' elements that are + contained inside the 'div' element which has id="main" + + New in version 0.4: Support for CSS2 and CSS3 attribute selectors: + See http://www.w3.org/TR/css3-selectors/#attribute-selectors + + Version 0.4 - Simon Willison, March 25th 2003 + -- Works in Phoenix 0.5, Mozilla 1.3, Opera 7, Internet Explorer 6, Internet Explorer 5 on Windows + -- Opera 7 fails +*/ + +function getAllChildren(e) { + // Returns all children of element. Workaround required for IE5/Windows. Ugh. + return e.all ? e.all : e.getElementsByTagName('*'); +} + +document.getElementsBySelector = function(selector) { + // Attempt to fail gracefully in lesser browsers + if (!document.getElementsByTagName) { + return new Array(); + } + // Split selector in to tokens + var tokens = selector.split(' '); + var currentContext = new Array(document); + for (var i = 0; i < tokens.length; i++) { + token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');; + if (token.indexOf('#') > -1) { + // Token is an ID selector + var bits = token.split('#'); + var tagName = bits[0]; + var id = bits[1]; + var element = document.getElementById(id); + if (tagName && element.nodeName.toLowerCase() != tagName) { + // tag with that ID not found, return false + return new Array(); + } + // Set currentContext to contain just this element + currentContext = new Array(element); + continue; // Skip to next token + } + if (token.indexOf('.') > -1) { + // Token contains a class selector + var bits = token.split('.'); + var tagName = bits[0]; + var className = bits[1]; + if (!tagName) { + tagName = '*'; + } + // Get elements matching tag, filter them for class selector + var found = new Array; + var foundCount = 0; + for (var h = 0; h < currentContext.length; h++) { + var elements; + if (tagName == '*') { + elements = getAllChildren(currentContext[h]); + } else { + try { + elements = currentContext[h].getElementsByTagName(tagName); + } + catch(e) { + elements = []; + } + } + for (var j = 0; j < elements.length; j++) { + found[foundCount++] = elements[j]; + } + } + currentContext = new Array; + var currentContextIndex = 0; + for (var k = 0; k < found.length; k++) { + if (found[k].className && found[k].className.match(new RegExp('\\b'+className+'\\b'))) { + currentContext[currentContextIndex++] = found[k]; + } + } + continue; // Skip to next token + } + // Code to deal with attribute selectors + if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) { + var tagName = RegExp.$1; + var attrName = RegExp.$2; + var attrOperator = RegExp.$3; + var attrValue = RegExp.$4; + if (!tagName) { + tagName = '*'; + } + // Grab all of the tagName elements within current context + var found = new Array; + var foundCount = 0; + for (var h = 0; h < currentContext.length; h++) { + var elements; + if (tagName == '*') { + elements = getAllChildren(currentContext[h]); + } else { + elements = currentContext[h].getElementsByTagName(tagName); + } + for (var j = 0; j < elements.length; j++) { + found[foundCount++] = elements[j]; + } + } + currentContext = new Array; + var currentContextIndex = 0; + var checkFunction; // This function will be used to filter the elements + switch (attrOperator) { + case '=': // Equality + checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue); }; + break; + case '~': // Match one of space seperated words + checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('\\b'+attrValue+'\\b'))); }; + break; + case '|': // Match start with value followed by optional hyphen + checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))); }; + break; + case '^': // Match starts with value + checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0); }; + break; + case '$': // Match ends with value - fails with "Warning" in Opera 7 + checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length); }; + break; + case '*': // Match ends with value + checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1); }; + break; + default : + // Just test for existence of attribute + checkFunction = function(e) { return e.getAttribute(attrName); }; + } + currentContext = new Array; + var currentContextIndex = 0; + for (var k = 0; k < found.length; k++) { + if (checkFunction(found[k])) { + currentContext[currentContextIndex++] = found[k]; + } + } + // alert('Attribute Selector: '+tagName+' '+attrName+' '+attrOperator+' '+attrValue); + continue; // Skip to next token + } + // If we get here, token is JUST an element (not a class or ID selector) + tagName = token; + var found = new Array; + var foundCount = 0; + for (var h = 0; h < currentContext.length; h++) { + var elements = currentContext[h].getElementsByTagName(tagName); + for (var j = 0; j < elements.length; j++) { + found[foundCount++] = elements[j]; + } + } + currentContext = found; + } + return currentContext; +} + +/* That revolting regular expression explained +/^(\w+)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/ + \---/ \---/\-------------/ \-------/ + | | | | + | | | The value + | | ~,|,^,$,* or = + | Attribute + Tag +*/ diff --git a/media/js/timeparse.js b/media/js/timeparse.js new file mode 100644 index 0000000000..882f41d56e --- /dev/null +++ b/media/js/timeparse.js @@ -0,0 +1,94 @@ +var timeParsePatterns = [ + // 9 + { re: /^\d{1,2}$/i, + handler: function(bits) { + if (bits[0].length == 1) { + return '0' + bits[0] + ':00'; + } else { + return bits[0] + ':00'; + } + } + }, + // 13:00 + { re: /^\d{2}[:.]\d{2}$/i, + handler: function(bits) { + return bits[0].replace('.', ':'); + } + }, + // 9:00 + { re: /^\d[:.]\d{2}$/i, + handler: function(bits) { + return '0' + bits[0].replace('.', ':'); + } + }, + // 3 am / 3 a.m. / 3am + { re: /^(\d+)\s*([ap])(?:.?m.?)?$/i, + handler: function(bits) { + var hour = parseInt(bits[1]); + if (hour == 12) { + hour = 0; + } + if (bits[2].toLowerCase() == 'p') { + if (hour == 12) { + hour = 0; + } + return (hour + 12) + ':00'; + } else { + if (hour < 10) { + return '0' + hour + ':00'; + } else { + return hour + ':00'; + } + } + } + }, + // 3.30 am / 3:15 a.m. / 3.00am + { re: /^(\d+)[.:](\d{2})\s*([ap]).?m.?$/i, + handler: function(bits) { + var hour = parseInt(bits[1]); + var mins = parseInt(bits[2]); + if (mins < 10) { + mins = '0' + mins; + } + if (hour == 12) { + hour = 0; + } + if (bits[3].toLowerCase() == 'p') { + if (hour == 12) { + hour = 0; + } + return (hour + 12) + ':' + mins; + } else { + if (hour < 10) { + return '0' + hour + ':' + mins; + } else { + return hour + ':' + mins; + } + } + } + }, + // noon + { re: /^no/i, + handler: function(bits) { + return '12:00'; + } + }, + // midnight + { re: /^mid/i, + handler: function(bits) { + return '00:00'; + } + } +]; + +function parseTimeString(s) { + for (var i = 0; i < timeParsePatterns.length; i++) { + var re = timeParsePatterns[i].re; + var handler = timeParsePatterns[i].handler; + var bits = re.exec(s); + if (bits) { + return handler(bits); + } + } + return s; +} diff --git a/media/js/urlify.js b/media/js/urlify.js new file mode 100644 index 0000000000..412130ad6f --- /dev/null +++ b/media/js/urlify.js @@ -0,0 +1,16 @@ +function URLify(s, num_chars) { + // changes, e.g., "Petty theft" to "petty_theft" + + // remove all these words from the string before urlifying + removelist = ["a", "an", "as", "at", "before", "but", "by", "for", "from", + "is", "in", "into", "like", "of", "off", "on", "onto", "per", + "since", "than", "the", "this", "that", "to", "up", "via", + "with"]; + r = new RegExp('\\b(' + removelist.join('|') + ')\\b', 'gi'); + s = s.replace(r, ''); + s = s.replace(/[^\w\s]/g, ''); // remove unneeded chars + s = s.replace(/^\s+|\s+$/g, ''); // trim leading/trailing spaces + s = s.replace(/\s+/g, '_'); // convert spaces to underscores + s = s.toLowerCase(); // convert to lowercase + return s.substring(0, num_chars);// trim to first num_chars chars +} \ No newline at end of file