| @@ -0,0 +1,293 @@ | ||
| /* CHANGELISTS */ | ||
|
|
||
| #changelist { | ||
| position: relative; | ||
| width: 100%; | ||
| } | ||
|
|
||
| #changelist table { | ||
| width: 100%; | ||
| } | ||
|
|
||
| .change-list .hiddenfields { display:none; } | ||
|
|
||
| .change-list .filtered table { | ||
| border-right: 1px solid #ddd; | ||
| } | ||
|
|
||
| .change-list .filtered { | ||
| min-height: 400px; | ||
| } | ||
|
|
||
| .change-list .filtered { | ||
| background: white url(../img/changelist-bg.gif) top right repeat-y !important; | ||
| } | ||
|
|
||
| .change-list .filtered .results, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull { | ||
| margin-right: 160px !important; | ||
| width: auto !important; | ||
| } | ||
|
|
||
| .change-list .filtered table tbody th { | ||
| padding-right: 1em; | ||
| } | ||
|
|
||
| #changelist-form .results { | ||
| overflow-x: auto; | ||
| } | ||
|
|
||
| #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/nav-bg.gif) 0 180% repeat-x; | ||
| overflow: hidden; | ||
| } | ||
|
|
||
| .change-list .filtered .paginator { | ||
| border-right: 1px solid #ddd; | ||
| } | ||
|
|
||
| /* CHANGELIST TABLES */ | ||
|
|
||
| #changelist table thead th { | ||
| padding: 0; | ||
| white-space: nowrap; | ||
| vertical-align: middle; | ||
| } | ||
|
|
||
| #changelist table thead th.action-checkbox-column { | ||
| width: 1.5em; | ||
| text-align: center; | ||
| } | ||
|
|
||
| #changelist table tbody td, #changelist table tbody th { | ||
| border-left: 1px solid #ddd; | ||
| } | ||
|
|
||
| #changelist table tbody td:first-child, #changelist table tbody th:first-child { | ||
| border-left: 0; | ||
| border-right: 1px solid #ddd; | ||
| } | ||
|
|
||
| #changelist table tbody td.action-checkbox { | ||
| text-align:center; | ||
| } | ||
|
|
||
| #changelist table tfoot { | ||
| color: #666; | ||
| } | ||
|
|
||
| /* TOOLBAR */ | ||
|
|
||
| #changelist #toolbar { | ||
| padding: 3px; | ||
| border-bottom: 1px solid #ddd; | ||
| background: #e1e1e1 url(../img/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; | ||
| } | ||
|
|
||
| #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/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 { | ||
| padding: 3px 6px; | ||
| font-weight: bold; | ||
| list-style-type: none; | ||
| display: inline-block; | ||
| } | ||
|
|
||
| .change-list ul.toplinks .date-back a { | ||
| color: #999; | ||
| } | ||
|
|
||
| .change-list ul.toplinks .date-back a:hover { | ||
| color: #036; | ||
| } | ||
|
|
||
| /* 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; | ||
| } | ||
|
|
||
| /* ACTIONS */ | ||
|
|
||
| .filtered .actions { | ||
| margin-right: 160px !important; | ||
| border-right: 1px solid #ddd; | ||
| } | ||
|
|
||
| #changelist table input { | ||
| margin: 0; | ||
| } | ||
|
|
||
| #changelist table tbody tr.selected { | ||
| background-color: #FFFFCC; | ||
| } | ||
|
|
||
| #changelist .actions { | ||
| color: #999; | ||
| padding: 3px; | ||
| border-top: 1px solid #fff; | ||
| border-bottom: 1px solid #ddd; | ||
| background: white url(../img/nav-bg-reverse.gif) 0 -10px repeat-x; | ||
| } | ||
|
|
||
| #changelist .actions.selected { | ||
| background: #fffccf; | ||
| border-top: 1px solid #fffee8; | ||
| border-bottom: 1px solid #edecd6; | ||
| } | ||
|
|
||
| #changelist .actions span.all, | ||
| #changelist .actions span.action-counter, | ||
| #changelist .actions span.clear, | ||
| #changelist .actions span.question { | ||
| font-size: 11px; | ||
| margin: 0 0.5em; | ||
| display: none; | ||
| } | ||
|
|
||
| #changelist .actions:last-child { | ||
| border-bottom: none; | ||
| } | ||
|
|
||
| #changelist .actions select { | ||
| border: 1px solid #aaa; | ||
| margin-left: 0.5em; | ||
| padding: 1px 2px; | ||
| } | ||
|
|
||
| #changelist .actions label { | ||
| font-size: 11px; | ||
| margin-left: 0.5em; | ||
| } | ||
|
|
||
| #changelist #action-toggle { | ||
| display: none; | ||
| } | ||
|
|
||
| #changelist .actions .button { | ||
| font-size: 11px; | ||
| padding: 1px 2px; | ||
| } |
| @@ -0,0 +1,30 @@ | ||
| /* DASHBOARD */ | ||
|
|
||
| .dashboard .module table th { | ||
| width: 100%; | ||
| } | ||
|
|
||
| .dashboard .module table td { | ||
| white-space: nowrap; | ||
| } | ||
|
|
||
| .dashboard .module table td a { | ||
| display: block; | ||
| padding-right: .6em; | ||
| } | ||
|
|
||
| /* RECENT ACTIONS MODULE */ | ||
|
|
||
| .module ul.actionlist { | ||
| margin-left: 0; | ||
| } | ||
|
|
||
| ul.actionlist li { | ||
| list-style-type: none; | ||
| } | ||
|
|
||
| ul.actionlist li { | ||
| overflow: hidden; | ||
| text-overflow: ellipsis; | ||
| -o-text-overflow: ellipsis; | ||
| } |
| @@ -0,0 +1,376 @@ | ||
| @import url('widgets.css'); | ||
|
|
||
| /* FORM ROWS */ | ||
|
|
||
| .form-row { | ||
| overflow: hidden; | ||
| padding: 8px 12px; | ||
| font-size: 11px; | ||
| border-bottom: 1px solid #eee; | ||
| } | ||
|
|
||
| .form-row img, .form-row input { | ||
| vertical-align: middle; | ||
| } | ||
|
|
||
| form .form-row p { | ||
| padding-left: 0; | ||
| font-size: 11px; | ||
| } | ||
|
|
||
| .hidden { | ||
| display: none; | ||
| } | ||
|
|
||
| /* FORM LABELS */ | ||
|
|
||
| form h4 { | ||
| margin: 0 !important; | ||
| padding: 0 !important; | ||
| border: none !important; | ||
| } | ||
|
|
||
| label { | ||
| font-weight: normal !important; | ||
| color: #666; | ||
| font-size: 12px; | ||
| } | ||
|
|
||
| .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: 3px 10px 0 0; | ||
| float: left; | ||
| width: 8em; | ||
| word-wrap: break-word; | ||
| } | ||
|
|
||
| .aligned ul label { | ||
| display: inline; | ||
| float: none; | ||
| width: auto; | ||
| } | ||
|
|
||
| .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; | ||
| padding-left: 4px; | ||
| } | ||
|
|
||
| .colM .aligned .vLargeTextField, .colM .aligned .vXMLLargeTextField { | ||
| width: 610px; | ||
| } | ||
|
|
||
| .checkbox-row p.help { | ||
| margin-left: 0; | ||
| padding-left: 0 !important; | ||
| } | ||
|
|
||
| fieldset .field-box { | ||
| float: left; | ||
| margin-right: 20px; | ||
| } | ||
|
|
||
| /* 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 { | ||
| display: block !important; | ||
| } | ||
|
|
||
| fieldset.collapsed h2 { | ||
| background-image: url(../img/nav-bg.gif); | ||
| background-position: bottom left; | ||
| color: #999; | ||
| } | ||
|
|
||
| fieldset.collapsed .collapse-toggle { | ||
| background: transparent; | ||
| display: inline !important; | ||
| } | ||
|
|
||
| /* MONOSPACE TEXTAREAS */ | ||
|
|
||
| fieldset.monospace textarea { | ||
| font-family: "Bitstream Vera Sans Mono",Monaco,"Courier New",Courier,monospace; | ||
| } | ||
|
|
||
| /* SUBMIT ROW */ | ||
|
|
||
| .submit-row { | ||
| padding: 5px 7px; | ||
| text-align: right; | ||
| background: white url(../img/nav-bg.gif) 0 100% repeat-x; | ||
| border: 1px solid #ccc; | ||
| margin: 5px 0; | ||
| overflow: hidden; | ||
| } | ||
|
|
||
| body.popup .submit-row { | ||
| overflow: auto; | ||
| } | ||
|
|
||
| .submit-row input { | ||
| margin: 0 0 0 5px; | ||
| } | ||
|
|
||
| .submit-row p { | ||
| margin: 0.3em; | ||
| } | ||
|
|
||
| .submit-row p.deletelink-box { | ||
| float: left; | ||
| } | ||
|
|
||
| .submit-row .deletelink { | ||
| background: url(../img/icon_deletelink.gif) 0 50% no-repeat; | ||
| padding-left: 14px; | ||
| } | ||
|
|
||
| /* CUSTOM FORM FIELDS */ | ||
|
|
||
| .vSelectMultipleField { | ||
| vertical-align: top !important; | ||
| } | ||
|
|
||
| .vCheckboxField { | ||
| border: none; | ||
| } | ||
|
|
||
| .vDateField, .vTimeField { | ||
| margin-right: 2px; | ||
| } | ||
|
|
||
| .vDateField { | ||
| min-width: 6.85em; | ||
| } | ||
|
|
||
| .vTimeField { | ||
| min-width: 4.7em; | ||
| } | ||
|
|
||
| .vURLField { | ||
| width: 30em; | ||
| } | ||
|
|
||
| .vLargeTextField, .vXMLLargeTextField { | ||
| width: 48em; | ||
| } | ||
|
|
||
| .flatpages-flatpage #id_content { | ||
| height: 40.2em; | ||
| } | ||
|
|
||
| .module table .vPositiveSmallIntegerField { | ||
| width: 2.2em; | ||
| } | ||
|
|
||
| .vTextField { | ||
| width: 20em; | ||
| } | ||
|
|
||
| .vIntegerField { | ||
| width: 5em; | ||
| } | ||
|
|
||
| .vBigIntegerField { | ||
| width: 10em; | ||
| } | ||
|
|
||
| .vForeignKeyRawIdAdminField { | ||
| width: 5em; | ||
| } | ||
|
|
||
| /* INLINES */ | ||
|
|
||
| .inline-group { | ||
| padding: 0; | ||
| border: 1px solid #ccc; | ||
| margin: 10px 0; | ||
| } | ||
|
|
||
| .inline-group .aligned label { | ||
| width: 8em; | ||
| } | ||
|
|
||
| .inline-related { | ||
| position: relative; | ||
| } | ||
|
|
||
| .inline-related h3 { | ||
| margin: 0; | ||
| color: #666; | ||
| padding: 3px 5px; | ||
| font-size: 11px; | ||
| background: #e1e1e1 url(../img/nav-bg.gif) top left repeat-x; | ||
| border-bottom: 1px solid #ddd; | ||
| } | ||
|
|
||
| .inline-related h3 span.delete { | ||
| float: right; | ||
| } | ||
|
|
||
| .inline-related h3 span.delete label { | ||
| margin-left: 2px; | ||
| font-size: 11px; | ||
| } | ||
|
|
||
| .inline-related fieldset { | ||
| margin: 0; | ||
| background: #fff; | ||
| border: none; | ||
| width: 100%; | ||
| } | ||
|
|
||
| .inline-related fieldset.module h3 { | ||
| margin: 0; | ||
| padding: 2px 5px 3px 5px; | ||
| font-size: 11px; | ||
| text-align: left; | ||
| font-weight: bold; | ||
| background: #bcd; | ||
| color: #fff; | ||
| } | ||
|
|
||
| .inline-group .tabular fieldset.module { | ||
| border: none; | ||
| border-bottom: 1px solid #ddd; | ||
| } | ||
|
|
||
| .inline-related.tabular fieldset.module table { | ||
| width: 100%; | ||
| } | ||
|
|
||
| .last-related fieldset { | ||
| border: none; | ||
| } | ||
|
|
||
| .inline-group .tabular tr.has_original td { | ||
| padding-top: 2em; | ||
| } | ||
|
|
||
| .inline-group .tabular tr td.original { | ||
| padding: 2px 0 0 0; | ||
| width: 0; | ||
| _position: relative; | ||
| } | ||
|
|
||
| .inline-group .tabular th.original { | ||
| width: 0px; | ||
| padding: 0; | ||
| } | ||
|
|
||
| .inline-group .tabular td.original p { | ||
| position: absolute; | ||
| left: 0; | ||
| height: 1.1em; | ||
| padding: 2px 7px; | ||
| overflow: hidden; | ||
| font-size: 9px; | ||
| font-weight: bold; | ||
| color: #666; | ||
| _width: 700px; | ||
| } | ||
|
|
||
| .inline-group ul.tools { | ||
| padding: 0; | ||
| margin: 0; | ||
| list-style: none; | ||
| } | ||
|
|
||
| .inline-group ul.tools li { | ||
| display: inline; | ||
| padding: 0 5px; | ||
| } | ||
|
|
||
| .inline-group div.add-row, | ||
| .inline-group .tabular tr.add-row td { | ||
| color: #666; | ||
| padding: 3px 5px; | ||
| border-bottom: 1px solid #ddd; | ||
| background: #e1e1e1 url(../img/nav-bg.gif) top left repeat-x; | ||
| } | ||
|
|
||
| .inline-group .tabular tr.add-row td { | ||
| padding: 4px 5px 3px; | ||
| border-bottom: none; | ||
| } | ||
|
|
||
| .inline-group ul.tools a.add, | ||
| .inline-group div.add-row a, | ||
| .inline-group .tabular tr.add-row td a { | ||
| background: url(../img/icon_addlink.gif) 0 50% no-repeat; | ||
| padding-left: 14px; | ||
| font-size: 11px; | ||
| outline: 0; /* Remove dotted border around link */ | ||
| } | ||
|
|
||
| .empty-form { | ||
| display: none; | ||
| } |
| @@ -0,0 +1,63 @@ | ||
| /* IE 6 & 7 */ | ||
|
|
||
| /* Proper fixed width for dashboard in IE6 */ | ||
|
|
||
| .dashboard #content { | ||
| *width: 768px; | ||
| } | ||
|
|
||
| .dashboard #content-main { | ||
| *width: 535px; | ||
| } | ||
|
|
||
| /* IE 6 ONLY */ | ||
|
|
||
| /* Keep header from flowing off the page */ | ||
|
|
||
| #container { | ||
| _position: static; | ||
| } | ||
|
|
||
| /* Put the right sidebars back on the page */ | ||
|
|
||
| .colMS #content-related { | ||
| _margin-right: 0; | ||
| _margin-left: 10px; | ||
| _position: static; | ||
| } | ||
|
|
||
| /* Put the left sidebars back on the page */ | ||
|
|
||
| .colSM #content-related { | ||
| _margin-right: 10px; | ||
| _margin-left: -115px; | ||
| _position: static; | ||
| } | ||
|
|
||
| .form-row { | ||
| _height: 1%; | ||
| } | ||
|
|
||
| /* Fix right margin for changelist filters in IE6 */ | ||
|
|
||
| #changelist-filter ul { | ||
| _margin-right: -10px; | ||
| } | ||
|
|
||
| /* IE ignores min-height, but treats height as if it were min-height */ | ||
|
|
||
| .change-list .filtered { | ||
| _height: 400px; | ||
| } | ||
|
|
||
| /* IE doesn't know alpha transparency in PNGs */ | ||
|
|
||
| .inline-deletelink { | ||
| background: transparent url(../img/inline-delete-8bit.png) no-repeat; | ||
| } | ||
|
|
||
| /* IE7 doesn't support inline-block */ | ||
| .change-list ul.toplinks li { | ||
| zoom: 1; | ||
| *display: inline; | ||
| } |
| @@ -0,0 +1,60 @@ | ||
| /* LOGIN FORM */ | ||
|
|
||
| body.login { | ||
| background: #eee; | ||
| } | ||
|
|
||
| .login #container { | ||
| background: white; | ||
| border: 1px solid #ccc; | ||
| width: 28em; | ||
| min-width: 300px; | ||
| margin-left: auto; | ||
| margin-right: auto; | ||
| margin-top: 100px; | ||
| } | ||
|
|
||
| .login #content-main { | ||
| width: 100%; | ||
| } | ||
|
|
||
| .login form { | ||
| margin-top: 1em; | ||
| } | ||
|
|
||
| .login .form-row { | ||
| padding: 4px 0; | ||
| float: left; | ||
| width: 100%; | ||
| } | ||
|
|
||
| .login .form-row label { | ||
| padding-right: 0.5em; | ||
| line-height: 2em; | ||
| font-size: 1em; | ||
| clear: both; | ||
| color: #333; | ||
| } | ||
|
|
||
| .login .form-row #id_username, .login .form-row #id_password { | ||
| clear: both; | ||
| padding: 6px; | ||
| width: 100%; | ||
| -webkit-box-sizing: border-box; | ||
| -moz-box-sizing: border-box; | ||
| box-sizing: border-box; | ||
| } | ||
|
|
||
| .login span.help { | ||
| font-size: 10px; | ||
| display: block; | ||
| } | ||
|
|
||
| .login .submit-row { | ||
| clear: both; | ||
| padding: 1em 0 0 9.4em; | ||
| } | ||
|
|
||
| .login .password-reset-link { | ||
| text-align: center; | ||
| } |
| @@ -0,0 +1,250 @@ | ||
| body { | ||
| direction: rtl; | ||
| } | ||
|
|
||
| /* LOGIN */ | ||
|
|
||
| .login .form-row { | ||
| float: right; | ||
| } | ||
|
|
||
| .login .form-row label { | ||
| float: right; | ||
| padding-left: 0.5em; | ||
| padding-right: 0; | ||
| text-align: left; | ||
| } | ||
|
|
||
| .login .submit-row { | ||
| clear: both; | ||
| padding: 1em 9.4em 0 0; | ||
| } | ||
|
|
||
| /* GLOBAL */ | ||
|
|
||
| th { | ||
| text-align: right; | ||
| } | ||
|
|
||
| .module h2, .module caption { | ||
| text-align: right; | ||
| } | ||
|
|
||
| .addlink, .changelink { | ||
| padding-left: 0px; | ||
| padding-right: 12px; | ||
| background-position: 100% 0.2em; | ||
| } | ||
|
|
||
| .deletelink { | ||
| padding-left: 0px; | ||
| padding-right: 12px; | ||
| background-position: 100% 0.25em; | ||
| } | ||
|
|
||
| .object-tools { | ||
| float: left; | ||
| } | ||
|
|
||
| thead th:first-child, | ||
| tfoot td:first-child { | ||
| border-left: 1px solid #ddd !important; | ||
| } | ||
|
|
||
| /* LAYOUT */ | ||
|
|
||
| #user-tools { | ||
| right: auto; | ||
| left: 0; | ||
| text-align: left; | ||
| } | ||
|
|
||
| div.breadcrumbs { | ||
| text-align: right; | ||
| } | ||
|
|
||
| #content-main { | ||
| float: right; | ||
| } | ||
|
|
||
| #content-related { | ||
| float: left; | ||
| margin-left: -19em; | ||
| margin-right: auto; | ||
| } | ||
|
|
||
| .colMS { | ||
| margin-left: 20em !important; | ||
| margin-right: 10px !important; | ||
| } | ||
|
|
||
| /* SORTABLE TABLES */ | ||
|
|
||
| table thead th.sorted .sortoptions { | ||
| float: left; | ||
| } | ||
|
|
||
| thead th.sorted .text { | ||
| padding-right: 0; | ||
| padding-left: 42px; | ||
| } | ||
|
|
||
| /* dashboard styles */ | ||
|
|
||
| .dashboard .module table td a { | ||
| padding-left: .6em; | ||
| padding-right: 12px; | ||
| } | ||
|
|
||
| /* changelists styles */ | ||
|
|
||
| .change-list .filtered { | ||
| background: white url(../img/changelist-bg_rtl.gif) top left repeat-y !important; | ||
| } | ||
|
|
||
| .change-list .filtered table { | ||
| border-left: 1px solid #ddd; | ||
| border-right: 0px none; | ||
| } | ||
|
|
||
| #changelist-filter { | ||
| right: auto; | ||
| left: 0; | ||
| border-left: 0px none; | ||
| border-right: 1px solid #ddd; | ||
| } | ||
|
|
||
| .change-list .filtered .results, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull { | ||
| margin-right: 0px !important; | ||
| margin-left: 160px !important; | ||
| } | ||
|
|
||
| #changelist-filter li.selected { | ||
| border-left: 0px none; | ||
| padding-left: 0px; | ||
| margin-left: 0; | ||
| border-right: 5px solid #ccc; | ||
| padding-right: 5px; | ||
| margin-right: -10px; | ||
| } | ||
|
|
||
| .filtered .actions { | ||
| border-left:1px solid #DDDDDD; | ||
| margin-left:160px !important; | ||
| border-right: 0 none; | ||
| margin-right:0 !important; | ||
| } | ||
|
|
||
| #changelist table tbody td:first-child, #changelist table tbody th:first-child { | ||
| border-right: 0; | ||
| border-left: 1px solid #ddd; | ||
| } | ||
|
|
||
| /* FORMS */ | ||
|
|
||
| .aligned label { | ||
| padding: 0 0 3px 1em; | ||
| float: right; | ||
| } | ||
|
|
||
| .submit-row { | ||
| text-align: left | ||
| } | ||
|
|
||
| .submit-row p.deletelink-box { | ||
| float: right; | ||
| } | ||
|
|
||
| .submit-row .deletelink { | ||
| background: url(../img/icon_deletelink.gif) 0 50% no-repeat; | ||
| padding-right: 14px; | ||
| } | ||
|
|
||
| .vDateField, .vTimeField { | ||
| margin-left: 2px; | ||
| } | ||
|
|
||
| form ul.inline li { | ||
| float: right; | ||
| padding-right: 0; | ||
| padding-left: 7px; | ||
| } | ||
|
|
||
| input[type=submit].default, .submit-row input.default { | ||
| float: left; | ||
| } | ||
|
|
||
| fieldset .field-box { | ||
| float: right; | ||
| margin-left: 20px; | ||
| margin-right: 0; | ||
| } | ||
|
|
||
| .errorlist li { | ||
| background-position: 100% .3em; | ||
| padding: 4px 25px 4px 5px; | ||
| } | ||
|
|
||
| .errornote { | ||
| background-position: 100% .3em; | ||
| padding: 4px 25px 4px 5px; | ||
| } | ||
|
|
||
| /* WIDGETS */ | ||
|
|
||
| .calendarnav-previous { | ||
| top: 0; | ||
| left: auto; | ||
| right: 0; | ||
| } | ||
|
|
||
| .calendarnav-next { | ||
| top: 0; | ||
| right: auto; | ||
| left: 0; | ||
| } | ||
|
|
||
| .calendar caption, .calendarbox h2 { | ||
| text-align: center; | ||
| } | ||
|
|
||
| .selector { | ||
| float: right; | ||
| } | ||
|
|
||
| .selector .selector-filter { | ||
| text-align: right; | ||
| } | ||
|
|
||
| .inline-deletelink { | ||
| float: left; | ||
| } | ||
|
|
||
| /* MISC */ | ||
|
|
||
| .inline-related h2, .inline-group h2 { | ||
| text-align: right | ||
| } | ||
|
|
||
| .inline-related h3 span.delete { | ||
| padding-right: 20px; | ||
| padding-left: inherit; | ||
| left: 10px; | ||
| right: inherit; | ||
| float:left; | ||
| } | ||
|
|
||
| .inline-related h3 span.delete label { | ||
| margin-left: inherit; | ||
| margin-right: 2px; | ||
| } | ||
|
|
||
| /* IE7 specific bug fixes */ | ||
|
|
||
| div.colM { | ||
| position: relative; | ||
| } | ||
|
|
||
| .submit-row input { | ||
| float: left; | ||
| } |
| @@ -0,0 +1,20 @@ | ||
| Copyright (c) 2010 John Resig, http://jquery.com/ | ||
|
|
||
| Permission is hereby granted, free of charge, to any person obtaining | ||
| a copy of this software and associated documentation files (the | ||
| "Software"), to deal in the Software without restriction, including | ||
| without limitation the rights to use, copy, modify, merge, publish, | ||
| distribute, sublicense, and/or sell copies of the Software, and to | ||
| permit persons to whom the Software is furnished to do so, subject to | ||
| the following conditions: | ||
|
|
||
| The above copyright notice and this permission notice shall be | ||
| included in all copies or substantial portions of the Software. | ||
|
|
||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| @@ -0,0 +1,114 @@ | ||
| 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) { | ||
| var new_option = new Option(node.text, node.value, false, false); | ||
| // Shows a tooltip when hovering over the option | ||
| new_option.setAttribute("title", node.text); | ||
| box.options[box.options.length] = new_option; | ||
| } | ||
| } | ||
| }, | ||
| 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}); | ||
| }, | ||
| 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++) { | ||
| if (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); | ||
| }, | ||
| 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'; | ||
| } | ||
| } | ||
| } |
| @@ -0,0 +1,161 @@ | ||
| /* | ||
| SelectFilter2 - Turns a multiple-select box into a filter interface. | ||
| Requires core.js, SelectBox.js and addevent.js. | ||
| */ | ||
| (function($) { | ||
| function findForm(node) { | ||
| // returns the node of the form containing the given node | ||
| if (node.tagName.toLowerCase() != 'form') { | ||
| return findForm(node.parentNode); | ||
| } | ||
| return node; | ||
| } | ||
|
|
||
| window.SelectFilter = { | ||
| init: function(field_id, field_name, is_stacked, admin_static_prefix) { | ||
| if (field_id.match(/__prefix__/)){ | ||
| // Don't intialize on empty forms. | ||
| return; | ||
| } | ||
| var from_box = document.getElementById(field_id); | ||
| from_box.id += '_from'; // change its ID | ||
| from_box.className = 'filtered'; | ||
|
|
||
| var ps = from_box.parentNode.getElementsByTagName('p'); | ||
| for (var i=0; i<ps.length; i++) { | ||
| if (ps[i].className.indexOf("info") != -1) { | ||
| // Remove <p class="info">, because it just gets in the way. | ||
| from_box.parentNode.removeChild(ps[i]); | ||
| } else if (ps[i].className.indexOf("help") != -1) { | ||
| // Move help text up to the top so it isn't below the select | ||
| // boxes or wrapped off on the side to the right of the add | ||
| // button: | ||
| from_box.parentNode.insertBefore(ps[i], from_box.parentNode.firstChild); | ||
| } | ||
| } | ||
|
|
||
| // <div class="selector"> or <div class="selector stacked"> | ||
| var selector_div = quickElement('div', from_box.parentNode); | ||
| selector_div.className = is_stacked ? 'selector stacked' : 'selector'; | ||
|
|
||
| // <div class="selector-available"> | ||
| var selector_available = quickElement('div', selector_div); | ||
| selector_available.className = 'selector-available'; | ||
| var title_available = quickElement('h2', selector_available, interpolate(gettext('Available %s') + ' ', [field_name])); | ||
| quickElement('img', title_available, '', 'src', admin_static_prefix + 'img/icon-unknown.gif', 'width', '10', 'height', '10', 'class', 'help help-tooltip', 'title', interpolate(gettext('This is the list of available %s. You may choose some by selecting them in the box below and then clicking the "Choose" arrow between the two boxes.'), [field_name])); | ||
|
|
||
| var filter_p = quickElement('p', selector_available, '', 'id', field_id + '_filter'); | ||
| filter_p.className = 'selector-filter'; | ||
|
|
||
| var search_filter_label = quickElement('label', filter_p, '', 'for', field_id + "_input"); | ||
|
|
||
| var search_selector_img = quickElement('img', search_filter_label, '', 'src', admin_static_prefix + 'img/selector-search.gif', 'class', 'help-tooltip', 'alt', '', 'title', interpolate(gettext("Type into this box to filter down the list of available %s."), [field_name])); | ||
|
|
||
| filter_p.appendChild(document.createTextNode(' ')); | ||
|
|
||
| var filter_input = quickElement('input', filter_p, '', 'type', 'text', 'placeholder', gettext("Filter")); | ||
| filter_input.id = field_id + '_input'; | ||
|
|
||
| selector_available.appendChild(from_box); | ||
| var choose_all = quickElement('a', selector_available, gettext('Choose all'), 'title', interpolate(gettext('Click to choose all %s at once.'), [field_name]), 'href', 'javascript: (function(){ SelectBox.move_all("' + field_id + '_from", "' + field_id + '_to"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_add_all_link'); | ||
| choose_all.className = 'selector-chooseall'; | ||
|
|
||
| // <ul class="selector-chooser"> | ||
| var selector_chooser = quickElement('ul', selector_div); | ||
| selector_chooser.className = 'selector-chooser'; | ||
| var add_link = quickElement('a', quickElement('li', selector_chooser), gettext('Choose'), 'title', gettext('Choose'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_from","' + field_id + '_to"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_add_link'); | ||
| add_link.className = 'selector-add'; | ||
| var remove_link = quickElement('a', quickElement('li', selector_chooser), gettext('Remove'), 'title', gettext('Remove'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_to","' + field_id + '_from"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_remove_link'); | ||
| remove_link.className = 'selector-remove'; | ||
|
|
||
| // <div class="selector-chosen"> | ||
| var selector_chosen = quickElement('div', selector_div); | ||
| selector_chosen.className = 'selector-chosen'; | ||
| var title_chosen = quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s') + ' ', [field_name])); | ||
| quickElement('img', title_chosen, '', 'src', admin_static_prefix + 'img/icon-unknown.gif', 'width', '10', 'height', '10', 'class', 'help help-tooltip', 'title', interpolate(gettext('This is the list of chosen %s. You may remove some by selecting them in the box below and then clicking the "Remove" arrow between the two boxes.'), [field_name])); | ||
|
|
||
| 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, gettext('Remove all'), 'title', interpolate(gettext('Click to remove all chosen %s at once.'), [field_name]), 'href', 'javascript: (function() { SelectBox.move_all("' + field_id + '_to", "' + field_id + '_from"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_remove_all_link'); | ||
| 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, 'change', function(e) { SelectFilter.refresh_icons(field_id) }); | ||
| addEvent(to_box, 'change', function(e) { SelectFilter.refresh_icons(field_id) }); | ||
| addEvent(from_box, 'dblclick', function() { SelectBox.move(field_id + '_from', field_id + '_to'); SelectFilter.refresh_icons(field_id); }); | ||
| addEvent(to_box, 'dblclick', function() { SelectBox.move(field_id + '_to', field_id + '_from'); SelectFilter.refresh_icons(field_id); }); | ||
| 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'); | ||
|
|
||
| if (!is_stacked) { | ||
| // In horizontal mode, give the same height to the two boxes. | ||
| var j_from_box = $(from_box); | ||
| var j_to_box = $(to_box); | ||
| var resize_filters = function() { j_to_box.height($(filter_p).outerHeight() + j_from_box.outerHeight()); } | ||
| if (j_from_box.outerHeight() > 0) { | ||
| resize_filters(); // This fieldset is already open. Resize now. | ||
| } else { | ||
| // This fieldset is probably collapsed. Wait for its 'show' event. | ||
| j_to_box.closest('fieldset').one('show.fieldset', resize_filters); | ||
| } | ||
| } | ||
|
|
||
| // Initial icon refresh | ||
| SelectFilter.refresh_icons(field_id); | ||
| }, | ||
| refresh_icons: function(field_id) { | ||
| var from = $('#' + field_id + '_from'); | ||
| var to = $('#' + field_id + '_to'); | ||
| var is_from_selected = from.find('option:selected').length > 0; | ||
| var is_to_selected = to.find('option:selected').length > 0; | ||
| // Active if at least one item is selected | ||
| $('#' + field_id + '_add_link').toggleClass('active', is_from_selected); | ||
| $('#' + field_id + '_remove_link').toggleClass('active', is_to_selected); | ||
| // Active if the corresponding box isn't empty | ||
| $('#' + field_id + '_add_all_link').toggleClass('active', from.find('option').length > 0); | ||
| $('#' + field_id + '_remove_all_link').toggleClass('active', to.find('option').length > 0); | ||
| }, | ||
| filter_key_up: function(event, field_id) { | ||
| var 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) { | ||
| var 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; | ||
| } | ||
| } | ||
|
|
||
| })(django.jQuery); |
| @@ -0,0 +1,144 @@ | ||
| (function($) { | ||
| var lastChecked; | ||
|
|
||
| $.fn.actions = function(opts) { | ||
| var options = $.extend({}, $.fn.actions.defaults, opts); | ||
| var actionCheckboxes = $(this); | ||
| var list_editable_changed = false; | ||
| var checker = function(checked) { | ||
| if (checked) { | ||
| showQuestion(); | ||
| } else { | ||
| reset(); | ||
| } | ||
| $(actionCheckboxes).prop("checked", checked) | ||
| .parent().parent().toggleClass(options.selectedClass, checked); | ||
| }, | ||
| updateCounter = function() { | ||
| var sel = $(actionCheckboxes).filter(":checked").length; | ||
| // _actions_icnt is defined in the generated HTML | ||
| // and contains the total amount of objects in the queryset | ||
| $(options.counterContainer).html(interpolate( | ||
| ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), { | ||
| sel: sel, | ||
| cnt: _actions_icnt | ||
| }, true)); | ||
| $(options.allToggle).prop("checked", function() { | ||
| var value; | ||
| if (sel == actionCheckboxes.length) { | ||
| value = true; | ||
| showQuestion(); | ||
| } else { | ||
| value = false; | ||
| clearAcross(); | ||
| } | ||
| return value; | ||
| }); | ||
| }, | ||
| showQuestion = function() { | ||
| $(options.acrossClears).hide(); | ||
| $(options.acrossQuestions).show(); | ||
| $(options.allContainer).hide(); | ||
| }, | ||
| showClear = function() { | ||
| $(options.acrossClears).show(); | ||
| $(options.acrossQuestions).hide(); | ||
| $(options.actionContainer).toggleClass(options.selectedClass); | ||
| $(options.allContainer).show(); | ||
| $(options.counterContainer).hide(); | ||
| }, | ||
| reset = function() { | ||
| $(options.acrossClears).hide(); | ||
| $(options.acrossQuestions).hide(); | ||
| $(options.allContainer).hide(); | ||
| $(options.counterContainer).show(); | ||
| }, | ||
| clearAcross = function() { | ||
| reset(); | ||
| $(options.acrossInput).val(0); | ||
| $(options.actionContainer).removeClass(options.selectedClass); | ||
| }; | ||
| // Show counter by default | ||
| $(options.counterContainer).show(); | ||
| // Check state of checkboxes and reinit state if needed | ||
| $(this).filter(":checked").each(function(i) { | ||
| $(this).parent().parent().toggleClass(options.selectedClass); | ||
| updateCounter(); | ||
| if ($(options.acrossInput).val() == 1) { | ||
| showClear(); | ||
| } | ||
| }); | ||
| $(options.allToggle).show().click(function() { | ||
| checker($(this).prop("checked")); | ||
| updateCounter(); | ||
| }); | ||
| $("a", options.acrossQuestions).click(function(event) { | ||
| event.preventDefault(); | ||
| $(options.acrossInput).val(1); | ||
| showClear(); | ||
| }); | ||
| $("a", options.acrossClears).click(function(event) { | ||
| event.preventDefault(); | ||
| $(options.allToggle).prop("checked", false); | ||
| clearAcross(); | ||
| checker(0); | ||
| updateCounter(); | ||
| }); | ||
| lastChecked = null; | ||
| $(actionCheckboxes).click(function(event) { | ||
| if (!event) { event = window.event; } | ||
| var target = event.target ? event.target : event.srcElement; | ||
| if (lastChecked && $.data(lastChecked) != $.data(target) && event.shiftKey === true) { | ||
| var inrange = false; | ||
| $(lastChecked).prop("checked", target.checked) | ||
| .parent().parent().toggleClass(options.selectedClass, target.checked); | ||
| $(actionCheckboxes).each(function() { | ||
| if ($.data(this) == $.data(lastChecked) || $.data(this) == $.data(target)) { | ||
| inrange = (inrange) ? false : true; | ||
| } | ||
| if (inrange) { | ||
| $(this).prop("checked", target.checked) | ||
| .parent().parent().toggleClass(options.selectedClass, target.checked); | ||
| } | ||
| }); | ||
| } | ||
| $(target).parent().parent().toggleClass(options.selectedClass, target.checked); | ||
| lastChecked = target; | ||
| updateCounter(); | ||
| }); | ||
| $('form#changelist-form table#result_list tr').find('td:gt(0) :input').change(function() { | ||
| list_editable_changed = true; | ||
| }); | ||
| $('form#changelist-form button[name="index"]').click(function(event) { | ||
| if (list_editable_changed) { | ||
| return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost.")); | ||
| } | ||
| }); | ||
| $('form#changelist-form input[name="_save"]').click(function(event) { | ||
| var action_changed = false; | ||
| $('select option:selected', options.actionContainer).each(function() { | ||
| if ($(this).val()) { | ||
| action_changed = true; | ||
| } | ||
| }); | ||
| if (action_changed) { | ||
| if (list_editable_changed) { | ||
| return confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")); | ||
| } else { | ||
| return confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button.")); | ||
| } | ||
| } | ||
| }); | ||
| }; | ||
| /* Setup plugin defaults */ | ||
| $.fn.actions.defaults = { | ||
| actionContainer: "div.actions", | ||
| counterContainer: "span.action-counter", | ||
| allContainer: "div.actions span.all", | ||
| acrossInput: "div.actions input.select-across", | ||
| acrossQuestions: "div.actions span.question", | ||
| acrossClears: "div.actions span.clear", | ||
| allToggle: "#action-toggle", | ||
| selectedClass: "selected" | ||
| }; | ||
| })(django.jQuery); |
| @@ -0,0 +1,97 @@ | ||
| // Handles related-objects functionality: lookup link for raw_id_fields | ||
| // and Add Another links. | ||
|
|
||
| function html_unescape(text) { | ||
| // Unescape a string that was escaped using django.utils.html.escape. | ||
| text = text.replace(/</g, '<'); | ||
| text = text.replace(/>/g, '>'); | ||
| text = text.replace(/"/g, '"'); | ||
| text = text.replace(/'/g, "'"); | ||
| text = text.replace(/&/g, '&'); | ||
| return text; | ||
| } | ||
|
|
||
| // IE doesn't accept periods or dashes in the window name, but the element IDs | ||
| // we use to generate popup window names may contain them, therefore we map them | ||
| // to allowed characters in a reversible way so that we can locate the correct | ||
| // element when the popup window is dismissed. | ||
| function id_to_windowname(text) { | ||
| text = text.replace(/\./g, '__dot__'); | ||
| text = text.replace(/\-/g, '__dash__'); | ||
| return text; | ||
| } | ||
|
|
||
| function windowname_to_id(text) { | ||
| text = text.replace(/__dot__/g, '.'); | ||
| text = text.replace(/__dash__/g, '-'); | ||
| return text; | ||
| } | ||
|
|
||
| function showRelatedObjectLookupPopup(triggeringLink) { | ||
| var name = triggeringLink.id.replace(/^lookup_/, ''); | ||
| name = id_to_windowname(name); | ||
| var href; | ||
| if (triggeringLink.href.search(/\?/) >= 0) { | ||
| href = triggeringLink.href + '&_popup=1'; | ||
| } else { | ||
| href = triggeringLink.href + '?_popup=1'; | ||
| } | ||
| var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes'); | ||
| win.focus(); | ||
| return false; | ||
| } | ||
|
|
||
| function dismissRelatedLookupPopup(win, chosenId) { | ||
| var name = windowname_to_id(win.name); | ||
| var elem = document.getElementById(name); | ||
| if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) { | ||
| elem.value += ',' + chosenId; | ||
| } else { | ||
| document.getElementById(name).value = chosenId; | ||
| } | ||
| win.close(); | ||
| } | ||
|
|
||
| function showAddAnotherPopup(triggeringLink) { | ||
| var name = triggeringLink.id.replace(/^add_/, ''); | ||
| name = id_to_windowname(name); | ||
| var href = triggeringLink.href; | ||
| if (href.indexOf('?') == -1) { | ||
| href += '?_popup=1'; | ||
| } else { | ||
| href += '&_popup=1'; | ||
| } | ||
| var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes'); | ||
| win.focus(); | ||
| return false; | ||
| } | ||
|
|
||
| function dismissAddAnotherPopup(win, newId, newRepr) { | ||
| // newId and newRepr are expected to have previously been escaped by | ||
| // django.utils.html.escape. | ||
| newId = html_unescape(newId); | ||
| newRepr = html_unescape(newRepr); | ||
| var name = windowname_to_id(win.name); | ||
| var elem = document.getElementById(name); | ||
| var o; | ||
| if (elem) { | ||
| var elemName = elem.nodeName.toUpperCase(); | ||
| if (elemName == 'SELECT') { | ||
| o = new Option(newRepr, newId); | ||
| elem.options[elem.options.length] = o; | ||
| o.selected = true; | ||
| } else if (elemName == 'INPUT') { | ||
| if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) { | ||
| elem.value += ',' + newId; | ||
| } else { | ||
| elem.value = newId; | ||
| } | ||
| } | ||
| } else { | ||
| var toId = name + "_to"; | ||
| o = new Option(newRepr, newId); | ||
| SelectBox.add_to_cache(toId, o); | ||
| SelectBox.redisplay(toId); | ||
| } | ||
| win.close(); | ||
| } |
| @@ -0,0 +1,169 @@ | ||
| /* | ||
| calendar.js - Calendar functions by Adrian Holovaty | ||
| depends on core.js for utility functions like removeChildren or quickElement | ||
| */ | ||
|
|
||
| // CalendarNamespace -- Provides a collection of HTML calendar-related helper functions | ||
| var CalendarNamespace = { | ||
| monthsOfYear: gettext('January February March April May June July August September October November December').split(' '), | ||
| daysOfWeek: gettext('S M T W T F S').split(' '), | ||
| firstDayOfWeek: parseInt(get_format('FIRST_DAY_OF_WEEK')), | ||
| 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, selected) { // month = 1-12, year = 1-9999 | ||
| var today = new Date(); | ||
| var todayDay = today.getDate(); | ||
| var todayMonth = today.getMonth()+1; | ||
| var todayYear = today.getFullYear(); | ||
| var todayClass = ''; | ||
|
|
||
| // Use UTC functions here because the date field does not contain time | ||
| // and using the UTC function variants prevent the local time offset | ||
| // from altering the date, specifically the day field. For example: | ||
| // | ||
| // ``` | ||
| // var x = new Date('2013-10-02'); | ||
| // var day = x.getDate(); | ||
| // ``` | ||
| // | ||
| // The day variable above will be 1 instead of 2 in, say, US Pacific time | ||
| // zone. | ||
| var isSelectedMonth = false; | ||
| if (typeof selected != 'undefined') { | ||
| isSelectedMonth = (selected.getUTCFullYear() == year && (selected.getUTCMonth()+1) == month); | ||
| } | ||
|
|
||
| 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 + CalendarNamespace.firstDayOfWeek) % 7]); | ||
| } | ||
|
|
||
| var startingPos = new Date(year, month-1, 1 - CalendarNamespace.firstDayOfWeek).getDay(); | ||
| var days = CalendarNamespace.getDaysInMonth(month, year); | ||
|
|
||
| // Draw blanks before first of month | ||
| tableRow = quickElement('tr', tableBody); | ||
| for (var i = 0; i < startingPos; i++) { | ||
| var _cell = quickElement('td', tableRow, ' '); | ||
| _cell.className = "nonday"; | ||
| } | ||
|
|
||
| // Draw days of month | ||
| var currentDay = 1; | ||
| for (var i = startingPos; currentDay <= days; i++) { | ||
| if (i%7 == 0 && currentDay != 1) { | ||
| tableRow = quickElement('tr', tableBody); | ||
| } | ||
| if ((currentDay==todayDay) && (month==todayMonth) && (year==todayYear)) { | ||
| todayClass='today'; | ||
| } else { | ||
| todayClass=''; | ||
| } | ||
|
|
||
| // use UTC function; see above for explanation. | ||
| if (isSelectedMonth && currentDay == selected.getUTCDate()) { | ||
| if (todayClass != '') todayClass += " "; | ||
| todayClass += "selected"; | ||
| } | ||
|
|
||
| var cell = quickElement('td', tableRow, '', 'class', todayClass); | ||
|
|
||
| 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) { | ||
| var _cell = quickElement('td', tableRow, ' '); | ||
| _cell.className = "nonday"; | ||
| } | ||
|
|
||
| calDiv.appendChild(calTable); | ||
| } | ||
| } | ||
|
|
||
| // Calendar -- A calendar instance | ||
| function Calendar(div_id, callback, selected) { | ||
| // 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(); | ||
| if (typeof selected != 'undefined') { | ||
| this.selected = selected; | ||
| } | ||
| } | ||
| Calendar.prototype = { | ||
| drawCurrent: function() { | ||
| CalendarNamespace.draw(this.currentMonth, this.currentYear, this.div_id, this.callback, this.selected); | ||
| }, | ||
| drawDate: function(month, year, selected) { | ||
| this.currentMonth = month; | ||
| this.currentYear = year; | ||
|
|
||
| if(selected) { | ||
| this.selected = selected; | ||
| } | ||
|
|
||
| this.drawCurrent(); | ||
| }, | ||
| drawPreviousMonth: function() { | ||
| if (this.currentMonth == 1) { | ||
| this.currentMonth = 12; | ||
| this.currentYear--; | ||
| } | ||
| else { | ||
| this.currentMonth--; | ||
| } | ||
| this.drawCurrent(); | ||
| }, | ||
| drawNextMonth: function() { | ||
| if (this.currentMonth == 12) { | ||
| this.currentMonth = 1; | ||
| this.currentYear++; | ||
| } | ||
| else { | ||
| this.currentMonth++; | ||
| } | ||
| this.drawCurrent(); | ||
| }, | ||
| drawPreviousYear: function() { | ||
| this.currentYear--; | ||
| this.drawCurrent(); | ||
| }, | ||
| drawNextYear: function() { | ||
| this.currentYear++; | ||
| this.drawCurrent(); | ||
| } | ||
| } |
| @@ -0,0 +1,24 @@ | ||
| (function($) { | ||
| $(document).ready(function() { | ||
| // Add anchor tag for Show/Hide link | ||
| $("fieldset.collapse").each(function(i, elem) { | ||
| // Don't hide if fields in this fieldset have errors | ||
| if ($(elem).find("div.errors").length == 0) { | ||
| $(elem).addClass("collapsed").find("h2").first().append(' (<a id="fieldsetcollapser' + | ||
| i +'" class="collapse-toggle" href="#">' + gettext("Show") + | ||
| '</a>)'); | ||
| } | ||
| }); | ||
| // Add toggle to anchor tag | ||
| $("fieldset.collapse a.collapse-toggle").click(function(ev) { | ||
| if ($(this).closest("fieldset").hasClass("collapsed")) { | ||
| // Show | ||
| $(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset", [$(this).attr("id")]); | ||
| } else { | ||
| // Hide | ||
| $(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset", [$(this).attr("id")]); | ||
| } | ||
| return false; | ||
| }); | ||
| }); | ||
| })(django.jQuery); |
| @@ -0,0 +1,222 @@ | ||
| // Core javascript helper functions | ||
|
|
||
| // basic browser identification & version | ||
| var isOpera = (navigator.userAgent.indexOf("Opera")>=0) && parseFloat(navigator.appVersion); | ||
| var isIE = ((document.all) && (!isOpera)) && parseFloat(navigator.appVersion.split("MSIE ")[1].split(";")[0]); | ||
|
|
||
| // 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); | ||
| return true; | ||
| } else { | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| function cancelEventPropagation(e) { | ||
| if (!e) e = window.event; | ||
| e.cancelBubble = true; | ||
| if (e.stopPropagation) e.stopPropagation(); | ||
| } | ||
|
|
||
| // quickElement(tagType, parentReference [, textInChildNode, attribute, attributeValue ...]); | ||
| function quickElement() { | ||
| var obj = document.createElement(arguments[0]); | ||
| if (arguments[2]) { | ||
| 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; | ||
| } | ||
|
|
||
| // "a" is reference to an object | ||
| function removeChildren(a) { | ||
| while (a.hasChildNodes()) a.removeChild(a.lastChild); | ||
| } | ||
|
|
||
| // ---------------------------------------------------------------------------- | ||
| // 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.quirksmode.org/js/findpos.html | ||
| // ---------------------------------------------------------------------------- | ||
| function findPosX(obj) { | ||
| var curleft = 0; | ||
| if (obj.offsetParent) { | ||
| while (obj.offsetParent) { | ||
| curleft += obj.offsetLeft - ((isOpera) ? 0 : obj.scrollLeft); | ||
| obj = obj.offsetParent; | ||
| } | ||
| // IE offsetParent does not include the top-level | ||
| if (isIE && obj.parentElement){ | ||
| curleft += obj.offsetLeft - obj.scrollLeft; | ||
| } | ||
| } else if (obj.x) { | ||
| curleft += obj.x; | ||
| } | ||
| return curleft; | ||
| } | ||
|
|
||
| function findPosY(obj) { | ||
| var curtop = 0; | ||
| if (obj.offsetParent) { | ||
| while (obj.offsetParent) { | ||
| curtop += obj.offsetTop - ((isOpera) ? 0 : obj.scrollTop); | ||
| obj = obj.offsetParent; | ||
| } | ||
| // IE offsetParent does not include the top-level | ||
| if (isIE && obj.parentElement){ | ||
| curtop += obj.offsetTop - obj.scrollTop; | ||
| } | ||
| } else if (obj.y) { | ||
| curtop += obj.y; | ||
| } | ||
| return curtop; | ||
| } | ||
|
|
||
| //----------------------------------------------------------------------------- | ||
| // Date object extensions | ||
| // ---------------------------------------------------------------------------- | ||
|
|
||
| Date.prototype.getTwelveHours = function() { | ||
| hours = this.getHours(); | ||
| if (hours == 0) { | ||
| return 12; | ||
| } | ||
| else { | ||
| return hours <= 12 ? hours : hours-12 | ||
| } | ||
| } | ||
|
|
||
| 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.getTwoDigitTwelveHour = function() { | ||
| return (this.getTwelveHours() < 10) ? '0' + this.getTwelveHours() : this.getTwelveHours(); | ||
| } | ||
|
|
||
| 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.getTwoDigitSecond = function() { | ||
| return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds(); | ||
| } | ||
|
|
||
| Date.prototype.getHourMinute = function() { | ||
| return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute(); | ||
| } | ||
|
|
||
| Date.prototype.getHourMinuteSecond = function() { | ||
| return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute() + ':' + this.getTwoDigitSecond(); | ||
| } | ||
|
|
||
| Date.prototype.strftime = function(format) { | ||
| var fields = { | ||
| c: this.toString(), | ||
| d: this.getTwoDigitDate(), | ||
| H: this.getTwoDigitHour(), | ||
| I: this.getTwoDigitTwelveHour(), | ||
| m: this.getTwoDigitMonth(), | ||
| M: this.getTwoDigitMinute(), | ||
| p: (this.getHours() >= 12) ? 'PM' : 'AM', | ||
| S: this.getTwoDigitSecond(), | ||
| w: '0' + this.getDay(), | ||
| x: this.toLocaleDateString(), | ||
| X: this.toLocaleTimeString(), | ||
| y: ('' + this.getFullYear()).substr(2, 4), | ||
| Y: '' + this.getFullYear(), | ||
| '%' : '%' | ||
| }; | ||
| var result = '', i = 0; | ||
| while (i < format.length) { | ||
| if (format.charAt(i) === '%') { | ||
| result = result + fields[format.charAt(i + 1)]; | ||
| ++i; | ||
| } | ||
| else { | ||
| result = result + format.charAt(i); | ||
| } | ||
| ++i; | ||
| } | ||
| return result; | ||
| } | ||
|
|
||
| // ---------------------------------------------------------------------------- | ||
| // String object extensions | ||
| // ---------------------------------------------------------------------------- | ||
| String.prototype.pad_left = function(pad_length, pad_string) { | ||
| var new_string = this; | ||
| for (var i = 0; new_string.length < pad_length; i++) { | ||
| new_string = pad_string + new_string; | ||
| } | ||
| return new_string; | ||
| } | ||
|
|
||
| // ---------------------------------------------------------------------------- | ||
| // Get the computed style for and element | ||
| // ---------------------------------------------------------------------------- | ||
| function getStyle(oElm, strCssRule){ | ||
| var strValue = ""; | ||
| if(document.defaultView && document.defaultView.getComputedStyle){ | ||
| strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule); | ||
| } | ||
| else if(oElm.currentStyle){ | ||
| strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){ | ||
| return p1.toUpperCase(); | ||
| }); | ||
| strValue = oElm.currentStyle[strCssRule]; | ||
| } | ||
| return strValue; | ||
| } |
| @@ -0,0 +1,272 @@ | ||
| /** | ||
| * Django admin inlines | ||
| * | ||
| * Based on jQuery Formset 1.1 | ||
| * @author Stanislaus Madueke (stan DOT madueke AT gmail DOT com) | ||
| * @requires jQuery 1.2.6 or later | ||
| * | ||
| * Copyright (c) 2009, Stanislaus Madueke | ||
| * All rights reserved. | ||
| * | ||
| * Spiced up with Code from Zain Memon's GSoC project 2009 | ||
| * and modified for Django by Jannis Leidel, Travis Swicegood and Julien Phalip. | ||
| * | ||
| * Licensed under the New BSD License | ||
| * See: http://www.opensource.org/licenses/bsd-license.php | ||
| */ | ||
| (function($) { | ||
| $.fn.formset = function(opts) { | ||
| var options = $.extend({}, $.fn.formset.defaults, opts); | ||
| var $this = $(this); | ||
| var $parent = $this.parent(); | ||
| var updateElementIndex = function(el, prefix, ndx) { | ||
| var id_regex = new RegExp("(" + prefix + "-(\\d+|__prefix__))"); | ||
| var replacement = prefix + "-" + ndx; | ||
| if ($(el).prop("for")) { | ||
| $(el).prop("for", $(el).prop("for").replace(id_regex, replacement)); | ||
| } | ||
| if (el.id) { | ||
| el.id = el.id.replace(id_regex, replacement); | ||
| } | ||
| if (el.name) { | ||
| el.name = el.name.replace(id_regex, replacement); | ||
| } | ||
| }; | ||
| var totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS").prop("autocomplete", "off"); | ||
| var nextIndex = parseInt(totalForms.val(), 10); | ||
| var maxForms = $("#id_" + options.prefix + "-MAX_NUM_FORMS").prop("autocomplete", "off"); | ||
| // only show the add button if we are allowed to add more items, | ||
| // note that max_num = None translates to a blank string. | ||
| var showAddButton = maxForms.val() === '' || (maxForms.val()-totalForms.val()) > 0; | ||
| $this.each(function(i) { | ||
| $(this).not("." + options.emptyCssClass).addClass(options.formCssClass); | ||
| }); | ||
| if ($this.length && showAddButton) { | ||
| var addButton; | ||
| if ($this.prop("tagName") == "TR") { | ||
| // If forms are laid out as table rows, insert the | ||
| // "add" button in a new table row: | ||
| var numCols = this.eq(-1).children().length; | ||
| $parent.append('<tr class="' + options.addCssClass + '"><td colspan="' + numCols + '"><a href="javascript:void(0)">' + options.addText + "</a></tr>"); | ||
| addButton = $parent.find("tr:last a"); | ||
| } else { | ||
| // Otherwise, insert it immediately after the last form: | ||
| $this.filter(":last").after('<div class="' + options.addCssClass + '"><a href="javascript:void(0)">' + options.addText + "</a></div>"); | ||
| addButton = $this.filter(":last").next().find("a"); | ||
| } | ||
| addButton.click(function(e) { | ||
| e.preventDefault(); | ||
| var totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS"); | ||
| var template = $("#" + options.prefix + "-empty"); | ||
| var row = template.clone(true); | ||
| row.removeClass(options.emptyCssClass) | ||
| .addClass(options.formCssClass) | ||
| .attr("id", options.prefix + "-" + nextIndex); | ||
| if (row.is("tr")) { | ||
| // If the forms are laid out in table rows, insert | ||
| // the remove button into the last table cell: | ||
| row.children(":last").append('<div><a class="' + options.deleteCssClass +'" href="javascript:void(0)">' + options.deleteText + "</a></div>"); | ||
| } else if (row.is("ul") || row.is("ol")) { | ||
| // If they're laid out as an ordered/unordered list, | ||
| // insert an <li> after the last list item: | ||
| row.append('<li><a class="' + options.deleteCssClass +'" href="javascript:void(0)">' + options.deleteText + "</a></li>"); | ||
| } else { | ||
| // Otherwise, just insert the remove button as the | ||
| // last child element of the form's container: | ||
| row.children(":first").append('<span><a class="' + options.deleteCssClass + '" href="javascript:void(0)">' + options.deleteText + "</a></span>"); | ||
| } | ||
| row.find("*").each(function() { | ||
| updateElementIndex(this, options.prefix, totalForms.val()); | ||
| }); | ||
| // Insert the new form when it has been fully edited | ||
| row.insertBefore($(template)); | ||
| // Update number of total forms | ||
| $(totalForms).val(parseInt(totalForms.val(), 10) + 1); | ||
| nextIndex += 1; | ||
| // Hide add button in case we've hit the max, except we want to add infinitely | ||
| if ((maxForms.val() !== '') && (maxForms.val()-totalForms.val()) <= 0) { | ||
| addButton.parent().hide(); | ||
| } | ||
| // The delete button of each row triggers a bunch of other things | ||
| row.find("a." + options.deleteCssClass).click(function(e) { | ||
| e.preventDefault(); | ||
| // Remove the parent form containing this button: | ||
| var row = $(this).parents("." + options.formCssClass); | ||
| row.remove(); | ||
| nextIndex -= 1; | ||
| // If a post-delete callback was provided, call it with the deleted form: | ||
| if (options.removed) { | ||
| options.removed(row); | ||
| } | ||
| // Update the TOTAL_FORMS form count. | ||
| var forms = $("." + options.formCssClass); | ||
| $("#id_" + options.prefix + "-TOTAL_FORMS").val(forms.length); | ||
| // Show add button again once we drop below max | ||
| if ((maxForms.val() === '') || (maxForms.val()-forms.length) > 0) { | ||
| addButton.parent().show(); | ||
| } | ||
| // Also, update names and ids for all remaining form controls | ||
| // so they remain in sequence: | ||
| for (var i=0, formCount=forms.length; i<formCount; i++) | ||
| { | ||
| updateElementIndex($(forms).get(i), options.prefix, i); | ||
| $(forms.get(i)).find("*").each(function() { | ||
| updateElementIndex(this, options.prefix, i); | ||
| }); | ||
| } | ||
| }); | ||
| // If a post-add callback was supplied, call it with the added form: | ||
| if (options.added) { | ||
| options.added(row); | ||
| } | ||
| }); | ||
| } | ||
| return this; | ||
| }; | ||
|
|
||
| /* Setup plugin defaults */ | ||
| $.fn.formset.defaults = { | ||
| prefix: "form", // The form prefix for your django formset | ||
| addText: "add another", // Text for the add link | ||
| deleteText: "remove", // Text for the delete link | ||
| addCssClass: "add-row", // CSS class applied to the add link | ||
| deleteCssClass: "delete-row", // CSS class applied to the delete link | ||
| emptyCssClass: "empty-row", // CSS class applied to the empty row | ||
| formCssClass: "dynamic-form", // CSS class applied to each form in a formset | ||
| added: null, // Function called each time a new form is added | ||
| removed: null // Function called each time a form is deleted | ||
| }; | ||
|
|
||
|
|
||
| // Tabular inlines --------------------------------------------------------- | ||
| $.fn.tabularFormset = function(options) { | ||
| var $rows = $(this); | ||
| var alternatingRows = function(row) { | ||
| $($rows.selector).not(".add-row").removeClass("row1 row2") | ||
| .filter(":even").addClass("row1").end() | ||
| .filter(":odd").addClass("row2"); | ||
| }; | ||
|
|
||
| var reinitDateTimeShortCuts = function() { | ||
| // Reinitialize the calendar and clock widgets by force | ||
| if (typeof DateTimeShortcuts != "undefined") { | ||
| $(".datetimeshortcuts").remove(); | ||
| DateTimeShortcuts.init(); | ||
| } | ||
| }; | ||
|
|
||
| var updateSelectFilter = function() { | ||
| // If any SelectFilter widgets are a part of the new form, | ||
| // instantiate a new SelectFilter instance for it. | ||
| if (typeof SelectFilter != 'undefined'){ | ||
| $('.selectfilter').each(function(index, value){ | ||
| var namearr = value.name.split('-'); | ||
| SelectFilter.init(value.id, namearr[namearr.length-1], false, options.adminStaticPrefix ); | ||
| }); | ||
| $('.selectfilterstacked').each(function(index, value){ | ||
| var namearr = value.name.split('-'); | ||
| SelectFilter.init(value.id, namearr[namearr.length-1], true, options.adminStaticPrefix ); | ||
| }); | ||
| } | ||
| }; | ||
|
|
||
| var initPrepopulatedFields = function(row) { | ||
| row.find('.prepopulated_field').each(function() { | ||
| var field = $(this), | ||
| input = field.find('input, select, textarea'), | ||
| dependency_list = input.data('dependency_list') || [], | ||
| dependencies = []; | ||
| $.each(dependency_list, function(i, field_name) { | ||
| dependencies.push('#' + row.find('.field-' + field_name).find('input, select, textarea').attr('id')); | ||
| }); | ||
| if (dependencies.length) { | ||
| input.prepopulate(dependencies, input.attr('maxlength')); | ||
| } | ||
| }); | ||
| }; | ||
|
|
||
| $rows.formset({ | ||
| prefix: options.prefix, | ||
| addText: options.addText, | ||
| formCssClass: "dynamic-" + options.prefix, | ||
| deleteCssClass: "inline-deletelink", | ||
| deleteText: options.deleteText, | ||
| emptyCssClass: "empty-form", | ||
| removed: alternatingRows, | ||
| added: function(row) { | ||
| initPrepopulatedFields(row); | ||
| reinitDateTimeShortCuts(); | ||
| updateSelectFilter(); | ||
| alternatingRows(row); | ||
| } | ||
| }); | ||
|
|
||
| return $rows; | ||
| }; | ||
|
|
||
| // Stacked inlines --------------------------------------------------------- | ||
| $.fn.stackedFormset = function(options) { | ||
| var $rows = $(this); | ||
| var updateInlineLabel = function(row) { | ||
| $($rows.selector).find(".inline_label").each(function(i) { | ||
| var count = i + 1; | ||
| $(this).html($(this).html().replace(/(#\d+)/g, "#" + count)); | ||
| }); | ||
| }; | ||
|
|
||
| var reinitDateTimeShortCuts = function() { | ||
| // Reinitialize the calendar and clock widgets by force, yuck. | ||
| if (typeof DateTimeShortcuts != "undefined") { | ||
| $(".datetimeshortcuts").remove(); | ||
| DateTimeShortcuts.init(); | ||
| } | ||
| }; | ||
|
|
||
| var updateSelectFilter = function() { | ||
| // If any SelectFilter widgets were added, instantiate a new instance. | ||
| if (typeof SelectFilter != "undefined"){ | ||
| $(".selectfilter").each(function(index, value){ | ||
| var namearr = value.name.split('-'); | ||
| SelectFilter.init(value.id, namearr[namearr.length-1], false, options.adminStaticPrefix); | ||
| }); | ||
| $(".selectfilterstacked").each(function(index, value){ | ||
| var namearr = value.name.split('-'); | ||
| SelectFilter.init(value.id, namearr[namearr.length-1], true, options.adminStaticPrefix); | ||
| }); | ||
| } | ||
| }; | ||
|
|
||
| var initPrepopulatedFields = function(row) { | ||
| row.find('.prepopulated_field').each(function() { | ||
| var field = $(this), | ||
| input = field.find('input, select, textarea'), | ||
| dependency_list = input.data('dependency_list') || [], | ||
| dependencies = []; | ||
| $.each(dependency_list, function(i, field_name) { | ||
| dependencies.push('#' + row.find('.form-row .field-' + field_name).find('input, select, textarea').attr('id')); | ||
| }); | ||
| if (dependencies.length) { | ||
| input.prepopulate(dependencies, input.attr('maxlength')); | ||
| } | ||
| }); | ||
| }; | ||
|
|
||
| $rows.formset({ | ||
| prefix: options.prefix, | ||
| addText: options.addText, | ||
| formCssClass: "dynamic-" + options.prefix, | ||
| deleteCssClass: "inline-deletelink", | ||
| deleteText: options.deleteText, | ||
| emptyCssClass: "empty-form", | ||
| removed: updateInlineLabel, | ||
| added: (function(row) { | ||
| initPrepopulatedFields(row); | ||
| reinitDateTimeShortCuts(); | ||
| updateSelectFilter(); | ||
| updateInlineLabel(row); | ||
| }) | ||
| }); | ||
|
|
||
| return $rows; | ||
| }; | ||
| })(django.jQuery); |
| @@ -0,0 +1,7 @@ | ||
| /* Puts the included jQuery into our own namespace using noConflict and passing | ||
| * it 'true'. This ensures that the included jQuery doesn't pollute the global | ||
| * namespace (i.e. this preserves pre-existing values for both window.$ and | ||
| * window.jQuery). | ||
| */ | ||
| var django = django || {}; | ||
| django.jQuery = jQuery.noConflict(true); |
| @@ -0,0 +1,39 @@ | ||
| (function($) { | ||
| $.fn.prepopulate = function(dependencies, maxLength) { | ||
| /* | ||
| Depends on urlify.js | ||
| Populates a selected field with the values of the dependent fields, | ||
| URLifies and shortens the string. | ||
| dependencies - array of dependent fields ids | ||
| maxLength - maximum length of the URLify'd string | ||
| */ | ||
| return this.each(function() { | ||
| var prepopulatedField = $(this); | ||
|
|
||
| var populate = function () { | ||
| // Bail if the field's value has been changed by the user | ||
| if (prepopulatedField.data('_changed')) { | ||
| return; | ||
| } | ||
|
|
||
| var values = []; | ||
| $.each(dependencies, function(i, field) { | ||
| field = $(field); | ||
| if (field.val().length > 0) { | ||
| values.push(field.val()); | ||
| } | ||
| }); | ||
| prepopulatedField.val(URLify(values.join(' '), maxLength)); | ||
| }; | ||
|
|
||
| prepopulatedField.data('_changed', false); | ||
| prepopulatedField.change(function() { | ||
| prepopulatedField.data('_changed', true); | ||
| }); | ||
|
|
||
| if (!prepopulatedField.val()) { | ||
| $(dependencies.join(',')).keyup(populate).change(populate).focus(populate); | ||
| } | ||
| }); | ||
| }; | ||
| })(django.jQuery); |
| @@ -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; | ||
| } |
| @@ -0,0 +1,147 @@ | ||
| var LATIN_MAP = { | ||
| 'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE', 'Ç': | ||
| 'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I', 'Î': 'I', | ||
| 'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O', 'Õ': 'O', 'Ö': | ||
| 'O', 'Ő': 'O', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U', 'Ü': 'U', 'Ű': 'U', | ||
| 'Ý': 'Y', 'Þ': 'TH', 'Ÿ': 'Y', 'ß': 'ss', 'à':'a', 'á':'a', 'â': 'a', 'ã': | ||
| 'a', 'ä': 'a', 'å': 'a', 'æ': 'ae', 'ç': 'c', 'è': 'e', 'é': 'e', 'ê': 'e', | ||
| 'ë': 'e', 'ì': 'i', 'í': 'i', 'î': 'i', 'ï': 'i', 'ð': 'd', 'ñ': 'n', 'ò': | ||
| 'o', 'ó': 'o', 'ô': 'o', 'õ': 'o', 'ö': 'o', 'ő': 'o', 'ø': 'o', 'ù': 'u', | ||
| 'ú': 'u', 'û': 'u', 'ü': 'u', 'ű': 'u', 'ý': 'y', 'þ': 'th', 'ÿ': 'y' | ||
| }; | ||
| var LATIN_SYMBOLS_MAP = { | ||
| '©':'(c)' | ||
| }; | ||
| var GREEK_MAP = { | ||
| 'α':'a', 'β':'b', 'γ':'g', 'δ':'d', 'ε':'e', 'ζ':'z', 'η':'h', 'θ':'8', | ||
| 'ι':'i', 'κ':'k', 'λ':'l', 'μ':'m', 'ν':'n', 'ξ':'3', 'ο':'o', 'π':'p', | ||
| 'ρ':'r', 'σ':'s', 'τ':'t', 'υ':'y', 'φ':'f', 'χ':'x', 'ψ':'ps', 'ω':'w', | ||
| 'ά':'a', 'έ':'e', 'ί':'i', 'ό':'o', 'ύ':'y', 'ή':'h', 'ώ':'w', 'ς':'s', | ||
| 'ϊ':'i', 'ΰ':'y', 'ϋ':'y', 'ΐ':'i', | ||
| 'Α':'A', 'Β':'B', 'Γ':'G', 'Δ':'D', 'Ε':'E', 'Ζ':'Z', 'Η':'H', 'Θ':'8', | ||
| 'Ι':'I', 'Κ':'K', 'Λ':'L', 'Μ':'M', 'Ν':'N', 'Ξ':'3', 'Ο':'O', 'Π':'P', | ||
| 'Ρ':'R', 'Σ':'S', 'Τ':'T', 'Υ':'Y', 'Φ':'F', 'Χ':'X', 'Ψ':'PS', 'Ω':'W', | ||
| 'Ά':'A', 'Έ':'E', 'Ί':'I', 'Ό':'O', 'Ύ':'Y', 'Ή':'H', 'Ώ':'W', 'Ϊ':'I', | ||
| 'Ϋ':'Y' | ||
| }; | ||
| var TURKISH_MAP = { | ||
| 'ş':'s', 'Ş':'S', 'ı':'i', 'İ':'I', 'ç':'c', 'Ç':'C', 'ü':'u', 'Ü':'U', | ||
| 'ö':'o', 'Ö':'O', 'ğ':'g', 'Ğ':'G' | ||
| }; | ||
| var RUSSIAN_MAP = { | ||
| 'а':'a', 'б':'b', 'в':'v', 'г':'g', 'д':'d', 'е':'e', 'ё':'yo', 'ж':'zh', | ||
| 'з':'z', 'и':'i', 'й':'j', 'к':'k', 'л':'l', 'м':'m', 'н':'n', 'о':'o', | ||
| 'п':'p', 'р':'r', 'с':'s', 'т':'t', 'у':'u', 'ф':'f', 'х':'h', 'ц':'c', | ||
| 'ч':'ch', 'ш':'sh', 'щ':'sh', 'ъ':'', 'ы':'y', 'ь':'', 'э':'e', 'ю':'yu', | ||
| 'я':'ya', | ||
| 'А':'A', 'Б':'B', 'В':'V', 'Г':'G', 'Д':'D', 'Е':'E', 'Ё':'Yo', 'Ж':'Zh', | ||
| 'З':'Z', 'И':'I', 'Й':'J', 'К':'K', 'Л':'L', 'М':'M', 'Н':'N', 'О':'O', | ||
| 'П':'P', 'Р':'R', 'С':'S', 'Т':'T', 'У':'U', 'Ф':'F', 'Х':'H', 'Ц':'C', | ||
| 'Ч':'Ch', 'Ш':'Sh', 'Щ':'Sh', 'Ъ':'', 'Ы':'Y', 'Ь':'', 'Э':'E', 'Ю':'Yu', | ||
| 'Я':'Ya' | ||
| }; | ||
| var UKRAINIAN_MAP = { | ||
| 'Є':'Ye', 'І':'I', 'Ї':'Yi', 'Ґ':'G', 'є':'ye', 'і':'i', 'ї':'yi', 'ґ':'g' | ||
| }; | ||
| var CZECH_MAP = { | ||
| 'č':'c', 'ď':'d', 'ě':'e', 'ň': 'n', 'ř':'r', 'š':'s', 'ť':'t', 'ů':'u', | ||
| 'ž':'z', 'Č':'C', 'Ď':'D', 'Ě':'E', 'Ň': 'N', 'Ř':'R', 'Š':'S', 'Ť':'T', | ||
| 'Ů':'U', 'Ž':'Z' | ||
| }; | ||
| var POLISH_MAP = { | ||
| 'ą':'a', 'ć':'c', 'ę':'e', 'ł':'l', 'ń':'n', 'ó':'o', 'ś':'s', 'ź':'z', | ||
| 'ż':'z', 'Ą':'A', 'Ć':'C', 'Ę':'E', 'Ł':'L', 'Ń':'N', 'Ó':'O', 'Ś':'S', | ||
| 'Ź':'Z', 'Ż':'Z' | ||
| }; | ||
| var LATVIAN_MAP = { | ||
| 'ā':'a', 'č':'c', 'ē':'e', 'ģ':'g', 'ī':'i', 'ķ':'k', 'ļ':'l', 'ņ':'n', | ||
| 'š':'s', 'ū':'u', 'ž':'z', 'Ā':'A', 'Č':'C', 'Ē':'E', 'Ģ':'G', 'Ī':'I', | ||
| 'Ķ':'K', 'Ļ':'L', 'Ņ':'N', 'Š':'S', 'Ū':'U', 'Ž':'Z' | ||
| }; | ||
| var ARABIC_MAP = { | ||
| 'أ':'a', 'ب':'b', 'ت':'t', 'ث': 'th', 'ج':'g', 'ح':'h', 'خ':'kh', 'د':'d', | ||
| 'ذ':'th', 'ر':'r', 'ز':'z', 'س':'s', 'ش':'sh', 'ص':'s', 'ض':'d', 'ط':'t', | ||
| 'ظ':'th', 'ع':'aa', 'غ':'gh', 'ف':'f', 'ق':'k', 'ك':'k', 'ل':'l', 'م':'m', | ||
| 'ن':'n', 'ه':'h', 'و':'o', 'ي':'y' | ||
| }; | ||
| var LITHUANIAN_MAP = { | ||
| 'ą':'a', 'č':'c', 'ę':'e', 'ė':'e', 'į':'i', 'š':'s', 'ų':'u', 'ū':'u', | ||
| 'ž':'z', | ||
| 'Ą':'A', 'Č':'C', 'Ę':'E', 'Ė':'E', 'Į':'I', 'Š':'S', 'Ų':'U', 'Ū':'U', | ||
| 'Ž':'Z' | ||
| }; | ||
| var SERBIAN_MAP = { | ||
| 'ђ':'dj', 'ј':'j', 'љ':'lj', 'њ':'nj', 'ћ':'c', 'џ':'dz', 'đ':'dj', | ||
| 'Ђ':'Dj', 'Ј':'j', 'Љ':'Lj', 'Њ':'Nj', 'Ћ':'C', 'Џ':'Dz', 'Đ':'Dj' | ||
| }; | ||
| var AZERBAIJANI_MAP = { | ||
| 'ç':'c', 'ə':'e', 'ğ':'g', 'ı':'i', 'ö':'o', 'ş':'s', 'ü':'u', | ||
| 'Ç':'C', 'Ə':'E', 'Ğ':'G', 'İ':'I', 'Ö':'O', 'Ş':'S', 'Ü':'U' | ||
| }; | ||
|
|
||
| var ALL_DOWNCODE_MAPS = [ | ||
| LATIN_MAP, | ||
| LATIN_SYMBOLS_MAP, | ||
| GREEK_MAP, | ||
| TURKISH_MAP, | ||
| RUSSIAN_MAP, | ||
| UKRAINIAN_MAP, | ||
| CZECH_MAP, | ||
| POLISH_MAP, | ||
| LATVIAN_MAP, | ||
| ARABIC_MAP, | ||
| LITHUANIAN_MAP, | ||
| SERBIAN_MAP, | ||
| AZERBAIJANI_MAP | ||
| ]; | ||
|
|
||
| var Downcoder = { | ||
| 'Initialize': function() { | ||
| if (Downcoder.map) { // already made | ||
| return; | ||
| } | ||
| Downcoder.map = {}; | ||
| Downcoder.chars = []; | ||
| for (var i=0; i<ALL_DOWNCODE_MAPS.length; i++) { | ||
| var lookup = ALL_DOWNCODE_MAPS[i]; | ||
| for (var c in lookup) { | ||
| if (lookup.hasOwnProperty(c)) { | ||
| Downcoder.map[c] = lookup[c]; | ||
| } | ||
| } | ||
| } | ||
| for (var k in Downcoder.map) { | ||
| if (Downcoder.map.hasOwnProperty(k)) { | ||
| Downcoder.chars.push(k); | ||
| } | ||
| } | ||
| Downcoder.regex = new RegExp(Downcoder.chars.join('|'), 'g'); | ||
| } | ||
| }; | ||
|
|
||
| function downcode(slug) { | ||
| Downcoder.Initialize(); | ||
| return slug.replace(Downcoder.regex, function(m) { | ||
| return Downcoder.map[m]; | ||
| }); | ||
| } | ||
|
|
||
|
|
||
| function URLify(s, num_chars) { | ||
| // changes, e.g., "Petty theft" to "petty_theft" | ||
| // remove all these words from the string before urlifying | ||
| s = downcode(s); | ||
| var 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" | ||
| ]; | ||
| var r = new RegExp('\\b(' + removelist.join('|') + ')\\b', 'gi'); | ||
| s = s.replace(r, ''); | ||
| // if downcode doesn't hit, the char will be stripped here | ||
| 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 hyphens | ||
| s = s.toLowerCase(); // convert to lowercase | ||
| return s.substring(0, num_chars);// trim to first num_chars chars | ||
| } |
| @@ -0,0 +1,48 @@ | ||
| { | ||
| "name": "bootstrap", | ||
| "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.", | ||
| "version": "3.3.2", | ||
| "keywords": [ | ||
| "css", | ||
| "js", | ||
| "less", | ||
| "mobile-first", | ||
| "responsive", | ||
| "front-end", | ||
| "framework", | ||
| "web" | ||
| ], | ||
| "homepage": "http://getbootstrap.com", | ||
| "main": [ | ||
| "less/bootstrap.less", | ||
| "dist/css/bootstrap.css", | ||
| "dist/js/bootstrap.js", | ||
| "dist/fonts/glyphicons-halflings-regular.eot", | ||
| "dist/fonts/glyphicons-halflings-regular.svg", | ||
| "dist/fonts/glyphicons-halflings-regular.ttf", | ||
| "dist/fonts/glyphicons-halflings-regular.woff" | ||
| ], | ||
| "ignore": [ | ||
| "/.*", | ||
| "_config.yml", | ||
| "CNAME", | ||
| "composer.json", | ||
| "CONTRIBUTING.md", | ||
| "docs", | ||
| "js/tests", | ||
| "test-infra" | ||
| ], | ||
| "dependencies": { | ||
| "jquery": ">= 1.9.1" | ||
| }, | ||
| "_release": "3.3.2", | ||
| "_resolution": { | ||
| "type": "version", | ||
| "tag": "v3.3.2", | ||
| "commit": "bcf7dd38b5ab180256e2e4fb5da0369551b3f082" | ||
| }, | ||
| "_source": "git://github.com/twbs/bootstrap.git", | ||
| "_target": "~3.3.2", | ||
| "_originalSource": "bootstrap", | ||
| "_direct": true | ||
| } |