diff options
Diffstat (limited to 'public')
| -rw-r--r-- | public/javascripts/admin_interface.js | 7 | ||||
| -rw-r--r-- | public/javascripts/admin_search.js | 62 | ||||
| -rwxr-xr-x | public/javascripts/jquery.hotkeys.js | 244 | ||||
| -rw-r--r-- | public/stylesheets/admin.css | 64 |
4 files changed, 337 insertions, 40 deletions
diff --git a/public/javascripts/admin_interface.js b/public/javascripts/admin_interface.js index 5fe91a2..f890afb 100644 --- a/public/javascripts/admin_interface.js +++ b/public/javascripts/admin_interface.js | |||
| @@ -1,5 +1,10 @@ | |||
| 1 | $(document).ready(function () { | 1 | $(document).ready(function () { |
| 2 | admin_search.initialize(); | 2 | $("#search_widget").hide(); |
| 3 | |||
| 4 | $(document).bind("keydown", 'Alt+f', function(){ | ||
| 5 | admin_search.display_toggle(); | ||
| 6 | return false; | ||
| 7 | }); | ||
| 3 | 8 | ||
| 4 | $("#metadata").attr("style", "display: none;"); | 9 | $("#metadata").attr("style", "display: none;"); |
| 5 | 10 | ||
diff --git a/public/javascripts/admin_search.js b/public/javascripts/admin_search.js index d645cca..ba52bb5 100644 --- a/public/javascripts/admin_search.js +++ b/public/javascripts/admin_search.js | |||
| @@ -1,28 +1,40 @@ | |||
| 1 | admin_search = { | 1 | admin_search = { |
| 2 | 2 | ||
| 3 | initialize : function() { | 3 | display_toggle : function() { |
| 4 | $("#search_term").bind("keyup", function() { | 4 | if ($('#search_widget').css("display") != "none") { |
| 5 | if ($(this).attr("value")) { | 5 | $('#search_widget').fadeOut(); |
| 6 | $.ajax({ | ||
| 7 | type: "GET", | ||
| 8 | url: "/admin/search", | ||
| 9 | data: "search_term=" + $(this).attr("value"), | ||
| 10 | dataType: "json", | ||
| 11 | success : function(results) { | ||
| 12 | admin_search.show_results(results); | ||
| 13 | } | ||
| 14 | }); | ||
| 15 | } | ||
| 16 | else { | ||
| 17 | $('#results').empty(); | ||
| 18 | } | ||
| 19 | }); | ||
| 20 | }, | ||
| 21 | |||
| 22 | show_results : function(results) { | ||
| 23 | $('#results').empty(); | ||
| 24 | for (result in results) { | ||
| 25 | $('#results').append("<p>" + results[result].title + "</p>"); | ||
| 26 | } | 6 | } |
| 27 | } | 7 | else { |
| 28 | } \ No newline at end of file | 8 | $('#search_widget').fadeIn(); |
| 9 | $('#search_term').attr("value", ""); | ||
| 10 | $('#search_term').focus(); | ||
| 11 | } | ||
| 12 | |||
| 13 | $("#search_term").bind("keyup", function() { | ||
| 14 | if ($(this).attr("value")) { | ||
| 15 | $.ajax({ | ||
| 16 | type: "GET", | ||
| 17 | url: "/admin/search", | ||
| 18 | data: "search_term=" + $(this).attr("value"), | ||
| 19 | dataType: "json", | ||
| 20 | success : function(results) { | ||
| 21 | admin_search.show_results(results); | ||
| 22 | } | ||
| 23 | }); | ||
| 24 | } | ||
| 25 | else { | ||
| 26 | $('#search_results').slideUp(); | ||
| 27 | $('#search_results').empty(); | ||
| 28 | } | ||
| 29 | }); | ||
| 30 | }, | ||
| 31 | |||
| 32 | show_results : function(results) { | ||
| 33 | $('#search_results').empty(); | ||
| 34 | for (result in results) { | ||
| 35 | $('#search_results').append("<p><a href='"+ results[result].edit_path + "'>" + results[result].title + "</a></p>"); | ||
| 36 | } | ||
| 37 | $('#search_results').slideDown(); | ||
| 38 | } | ||
| 39 | |||
| 40 | } \ No newline at end of file | ||
diff --git a/public/javascripts/jquery.hotkeys.js b/public/javascripts/jquery.hotkeys.js new file mode 100755 index 0000000..9a8f2de --- /dev/null +++ b/public/javascripts/jquery.hotkeys.js | |||
| @@ -0,0 +1,244 @@ | |||
| 1 | /* | ||
| 2 | (c) Copyrights 2007 - 2008 | ||
| 3 | |||
| 4 | Original idea by by Binny V A, http://www.openjs.com/scripts/events/keyboard_shortcuts/ | ||
| 5 | |||
| 6 | jQuery Plugin by Tzury Bar Yochay | ||
| 7 | tzury.by@gmail.com | ||
| 8 | http://evalinux.wordpress.com | ||
| 9 | http://facebook.com/profile.php?id=513676303 | ||
| 10 | |||
| 11 | Project's sites: | ||
| 12 | http://code.google.com/p/js-hotkeys/ | ||
| 13 | http://github.com/tzuryby/hotkeys/tree/master | ||
| 14 | |||
| 15 | License: same as jQuery license. | ||
| 16 | |||
| 17 | USAGE: | ||
| 18 | // simple usage | ||
| 19 | $(document).bind('keydown', 'Ctrl+c', function(){ alert('copy anyone?');}); | ||
| 20 | |||
| 21 | // special options such as disableInIput | ||
| 22 | $(document).bind('keydown', {combi:'Ctrl+x', disableInInput: true} , function() {}); | ||
| 23 | |||
| 24 | Note: | ||
| 25 | This plugin wraps the following jQuery methods: $.fn.find, $.fn.bind and $.fn.unbind | ||
| 26 | */ | ||
| 27 | |||
| 28 | (function (jQuery){ | ||
| 29 | // keep reference to the original $.fn.bind, $.fn.unbind and $.fn.find | ||
| 30 | jQuery.fn.__bind__ = jQuery.fn.bind; | ||
| 31 | jQuery.fn.__unbind__ = jQuery.fn.unbind; | ||
| 32 | jQuery.fn.__find__ = jQuery.fn.find; | ||
| 33 | |||
| 34 | var hotkeys = { | ||
| 35 | version: '0.7.9', | ||
| 36 | override: /keypress|keydown|keyup/g, | ||
| 37 | triggersMap: {}, | ||
| 38 | |||
| 39 | specialKeys: { 27: 'esc', 9: 'tab', 32:'space', 13: 'return', 8:'backspace', 145: 'scroll', | ||
| 40 | 20: 'capslock', 144: 'numlock', 19:'pause', 45:'insert', 36:'home', 46:'del', | ||
| 41 | 35:'end', 33: 'pageup', 34:'pagedown', 37:'left', 38:'up', 39:'right',40:'down', | ||
| 42 | 109: '-', | ||
| 43 | 112:'f1',113:'f2', 114:'f3', 115:'f4', 116:'f5', 117:'f6', 118:'f7', 119:'f8', | ||
| 44 | 120:'f9', 121:'f10', 122:'f11', 123:'f12', 191: '/'}, | ||
| 45 | |||
| 46 | shiftNums: { "`":"~", "1":"!", "2":"@", "3":"#", "4":"$", "5":"%", "6":"^", "7":"&", | ||
| 47 | "8":"*", "9":"(", "0":")", "-":"_", "=":"+", ";":":", "'":"\"", ",":"<", | ||
| 48 | ".":">", "/":"?", "\\":"|" }, | ||
| 49 | |||
| 50 | newTrigger: function (type, combi, callback) { | ||
| 51 | // i.e. {'keyup': {'ctrl': {cb: callback, disableInInput: false}}} | ||
| 52 | var result = {}; | ||
| 53 | result[type] = {}; | ||
| 54 | result[type][combi] = {cb: callback, disableInInput: false}; | ||
| 55 | return result; | ||
| 56 | } | ||
| 57 | }; | ||
| 58 | // add firefox num pad char codes | ||
| 59 | //if (jQuery.browser.mozilla){ | ||
| 60 | // add num pad char codes | ||
| 61 | hotkeys.specialKeys = jQuery.extend(hotkeys.specialKeys, { 96: '0', 97:'1', 98: '2', 99: | ||
| 62 | '3', 100: '4', 101: '5', 102: '6', 103: '7', 104: '8', 105: '9', 106: '*', | ||
| 63 | 107: '+', 109: '-', 110: '.', 111 : '/' | ||
| 64 | }); | ||
| 65 | //} | ||
| 66 | |||
| 67 | // a wrapper around of $.fn.find | ||
| 68 | // see more at: http://groups.google.com/group/jquery-en/browse_thread/thread/18f9825e8d22f18d | ||
| 69 | jQuery.fn.find = function( selector ) { | ||
| 70 | this.query = selector; | ||
| 71 | return jQuery.fn.__find__.apply(this, arguments); | ||
| 72 | }; | ||
| 73 | |||
| 74 | jQuery.fn.unbind = function (type, combi, fn){ | ||
| 75 | if (jQuery.isFunction(combi)){ | ||
| 76 | fn = combi; | ||
| 77 | combi = null; | ||
| 78 | } | ||
| 79 | if (combi && typeof combi === 'string'){ | ||
| 80 | var selectorId = ((this.prevObject && this.prevObject.query) || (this[0].id && this[0].id) || this[0]).toString(); | ||
| 81 | var hkTypes = type.split(' '); | ||
| 82 | for (var x=0; x<hkTypes.length; x++){ | ||
| 83 | delete hotkeys.triggersMap[selectorId][hkTypes[x]][combi]; | ||
| 84 | } | ||
| 85 | } | ||
| 86 | // call jQuery original unbind | ||
| 87 | return this.__unbind__(type, fn); | ||
| 88 | }; | ||
| 89 | |||
| 90 | jQuery.fn.bind = function(type, data, fn){ | ||
| 91 | // grab keyup,keydown,keypress | ||
| 92 | var handle = type.match(hotkeys.override); | ||
| 93 | |||
| 94 | if (jQuery.isFunction(data) || !handle){ | ||
| 95 | // call jQuery.bind only | ||
| 96 | return this.__bind__(type, data, fn); | ||
| 97 | } | ||
| 98 | else{ | ||
| 99 | // split the job | ||
| 100 | var result = null, | ||
| 101 | // pass the rest to the original $.fn.bind | ||
| 102 | pass2jq = jQuery.trim(type.replace(hotkeys.override, '')); | ||
| 103 | |||
| 104 | // see if there are other types, pass them to the original $.fn.bind | ||
| 105 | if (pass2jq){ | ||
| 106 | result = this.__bind__(pass2jq, data, fn); | ||
| 107 | } | ||
| 108 | |||
| 109 | if (typeof data === "string"){ | ||
| 110 | data = {'combi': data}; | ||
| 111 | } | ||
| 112 | if(data.combi){ | ||
| 113 | for (var x=0; x < handle.length; x++){ | ||
| 114 | var eventType = handle[x]; | ||
| 115 | var combi = data.combi.toLowerCase(), | ||
| 116 | trigger = hotkeys.newTrigger(eventType, combi, fn), | ||
| 117 | selectorId = ((this.prevObject && this.prevObject.query) || (this[0].id && this[0].id) || this[0]).toString(); | ||
| 118 | |||
| 119 | //trigger[eventType][combi].propagate = data.propagate; | ||
| 120 | trigger[eventType][combi].disableInInput = data.disableInInput; | ||
| 121 | |||
| 122 | // first time selector is bounded | ||
| 123 | if (!hotkeys.triggersMap[selectorId]) { | ||
| 124 | hotkeys.triggersMap[selectorId] = trigger; | ||
| 125 | } | ||
| 126 | // first time selector is bounded with this type | ||
| 127 | else if (!hotkeys.triggersMap[selectorId][eventType]) { | ||
| 128 | hotkeys.triggersMap[selectorId][eventType] = trigger[eventType]; | ||
| 129 | } | ||
| 130 | // make trigger point as array so more than one handler can be bound | ||
| 131 | var mapPoint = hotkeys.triggersMap[selectorId][eventType][combi]; | ||
| 132 | if (!mapPoint){ | ||
| 133 | hotkeys.triggersMap[selectorId][eventType][combi] = [trigger[eventType][combi]]; | ||
| 134 | } | ||
| 135 | else if (mapPoint.constructor !== Array){ | ||
| 136 | hotkeys.triggersMap[selectorId][eventType][combi] = [mapPoint]; | ||
| 137 | } | ||
| 138 | else { | ||
| 139 | hotkeys.triggersMap[selectorId][eventType][combi][mapPoint.length] = trigger[eventType][combi]; | ||
| 140 | } | ||
| 141 | |||
| 142 | // add attribute and call $.event.add per matched element | ||
| 143 | this.each(function(){ | ||
| 144 | // jQuery wrapper for the current element | ||
| 145 | var jqElem = jQuery(this); | ||
| 146 | |||
| 147 | // element already associated with another collection | ||
| 148 | if (jqElem.attr('hkId') && jqElem.attr('hkId') !== selectorId){ | ||
| 149 | selectorId = jqElem.attr('hkId') + ";" + selectorId; | ||
| 150 | } | ||
| 151 | jqElem.attr('hkId', selectorId); | ||
| 152 | }); | ||
| 153 | result = this.__bind__(handle.join(' '), data, hotkeys.handler) | ||
| 154 | } | ||
| 155 | } | ||
| 156 | return result; | ||
| 157 | } | ||
| 158 | }; | ||
| 159 | // work-around for opera and safari where (sometimes) the target is the element which was last | ||
| 160 | // clicked with the mouse and not the document event it would make sense to get the document | ||
| 161 | hotkeys.findElement = function (elem){ | ||
| 162 | if (!jQuery(elem).attr('hkId')){ | ||
| 163 | if (jQuery.browser.opera || jQuery.browser.safari){ | ||
| 164 | while (!jQuery(elem).attr('hkId') && elem.parentNode){ | ||
| 165 | elem = elem.parentNode; | ||
| 166 | } | ||
| 167 | } | ||
| 168 | } | ||
| 169 | return elem; | ||
| 170 | }; | ||
| 171 | // the event handler | ||
| 172 | hotkeys.handler = function(event) { | ||
| 173 | var target = hotkeys.findElement(event.currentTarget), | ||
| 174 | jTarget = jQuery(target), | ||
| 175 | ids = jTarget.attr('hkId'); | ||
| 176 | |||
| 177 | if(ids){ | ||
| 178 | ids = ids.split(';'); | ||
| 179 | var code = event.which, | ||
| 180 | type = event.type, | ||
| 181 | special = hotkeys.specialKeys[code], | ||
| 182 | // prevent f5 overlapping with 't' (or f4 with 's', etc.) | ||
| 183 | character = !special && String.fromCharCode(code).toLowerCase(), | ||
| 184 | shift = event.shiftKey, | ||
| 185 | ctrl = event.ctrlKey, | ||
| 186 | // patch for jquery 1.2.5 && 1.2.6 see more at: | ||
| 187 | // http://groups.google.com/group/jquery-en/browse_thread/thread/83e10b3bb1f1c32b | ||
| 188 | alt = event.altKey || event.originalEvent.altKey, | ||
| 189 | mapPoint = null; | ||
| 190 | |||
| 191 | for (var x=0; x < ids.length; x++){ | ||
| 192 | if (hotkeys.triggersMap[ids[x]][type]){ | ||
| 193 | mapPoint = hotkeys.triggersMap[ids[x]][type]; | ||
| 194 | break; | ||
| 195 | } | ||
| 196 | } | ||
| 197 | |||
| 198 | //find by: id.type.combi.options | ||
| 199 | if (mapPoint){ | ||
| 200 | var trigger; | ||
| 201 | // event type is associated with the hkId | ||
| 202 | if(!shift && !ctrl && !alt) { // No Modifiers | ||
| 203 | trigger = mapPoint[special] || (character && mapPoint[character]); | ||
| 204 | } | ||
| 205 | else{ | ||
| 206 | // check combinations (alt|ctrl|shift+anything) | ||
| 207 | var modif = ''; | ||
| 208 | if(alt) modif +='alt+'; | ||
| 209 | if(ctrl) modif+= 'ctrl+'; | ||
| 210 | if(shift) modif += 'shift+'; | ||
| 211 | // modifiers + special keys or modifiers + character or modifiers + shift character or just shift character | ||
| 212 | trigger = mapPoint[modif+special]; | ||
| 213 | if (!trigger){ | ||
| 214 | if (character){ | ||
| 215 | trigger = mapPoint[modif+character] | ||
| 216 | || mapPoint[modif+hotkeys.shiftNums[character]] | ||
| 217 | // '$' can be triggered as 'Shift+4' or 'Shift+$' or just '$' | ||
| 218 | || (modif === 'shift+' && mapPoint[hotkeys.shiftNums[character]]); | ||
| 219 | } | ||
| 220 | } | ||
| 221 | } | ||
| 222 | if (trigger){ | ||
| 223 | var result = false; | ||
| 224 | for (var x=0; x < trigger.length; x++){ | ||
| 225 | if(trigger[x].disableInInput){ | ||
| 226 | // double check event.currentTarget and event.target | ||
| 227 | var elem = jQuery(event.target); | ||
| 228 | if (jTarget.is("input") || jTarget.is("textarea") || jTarget.is("select") | ||
| 229 | || elem.is("input") || elem.is("textarea") || elem.is("select")) { | ||
| 230 | return true; | ||
| 231 | } | ||
| 232 | } | ||
| 233 | // call the registered callback function | ||
| 234 | result = result || trigger[x].cb.apply(this, [event]); | ||
| 235 | } | ||
| 236 | return result; | ||
| 237 | } | ||
| 238 | } | ||
| 239 | } | ||
| 240 | }; | ||
| 241 | // place it under window so it can be extended and overridden by others | ||
| 242 | window.hotkeys = hotkeys; | ||
| 243 | return jQuery; | ||
| 244 | })(jQuery); | ||
diff --git a/public/stylesheets/admin.css b/public/stylesheets/admin.css index e077918..faebbea 100644 --- a/public/stylesheets/admin.css +++ b/public/stylesheets/admin.css | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | body { | 3 | body { |
| 4 | font-family: Helvetica, Arial, sans-serif; | 4 | font-family: Helvetica, Arial, sans-serif; |
| 5 | font-size: 12px; | 5 | font-size: 12px; |
| 6 | margin: 0px; | ||
| 6 | } | 7 | } |
| 7 | 8 | ||
| 8 | a { | 9 | a { |
| @@ -64,33 +65,38 @@ div.pagination span.current, div.pagination a:hover { | |||
| 64 | text-align: right; | 65 | text-align: right; |
| 65 | } | 66 | } |
| 66 | 67 | ||
| 67 | #navigation, #subnavigation { | 68 | #navigation { |
| 68 | margin-left: 0px; | 69 | position: relative; |
| 70 | margin-top: 10px; | ||
| 71 | } | ||
| 72 | |||
| 73 | #navigation div { | ||
| 69 | float: left; | 74 | float: left; |
| 70 | } | 75 | } |
| 71 | 76 | ||
| 77 | |||
| 72 | #navigation a:hover { | 78 | #navigation a:hover { |
| 73 | color: #ffffff; | 79 | color: #ffffff; |
| 74 | background-color: #000000; | 80 | background-color: #000000; |
| 75 | } | 81 | } |
| 76 | 82 | ||
| 77 | #navigation a, #subnavigation a { | 83 | #main_navigation a, #sub_navigation a { |
| 78 | letter-spacing: 1px; | 84 | letter-spacing: 1px; |
| 79 | padding-left: 5px; | 85 | padding-left: 5px; |
| 80 | padding-right: 5px; | 86 | padding-right: 5px; |
| 81 | text-transform: lowercase; | 87 | text-transform: lowercase; |
| 82 | } | 88 | } |
| 83 | 89 | ||
| 84 | #subnavigation a { | 90 | #sub_navigation a { |
| 85 | color: #969696; | 91 | color: #969696; |
| 86 | } | 92 | } |
| 87 | 93 | ||
| 88 | #subnavigation a:hover { | 94 | #sub_navigation a:hover { |
| 89 | color: #ffffff; | 95 | color: #ffffff; |
| 90 | background-color: #ff9600; | 96 | background-color: #ff9600; |
| 91 | } | 97 | } |
| 92 | 98 | ||
| 93 | #subnavigation a.selected { | 99 | #sub_navigation a.selected { |
| 94 | color: #ffffff; | 100 | color: #ffffff; |
| 95 | background-color: #ff9600; | 101 | background-color: #ff9600; |
| 96 | } | 102 | } |
| @@ -100,9 +106,6 @@ div.pagination span.current, div.pagination a:hover { | |||
| 100 | background-color: #000000; | 106 | background-color: #000000; |
| 101 | } | 107 | } |
| 102 | 108 | ||
| 103 | #admin_search { | ||
| 104 | } | ||
| 105 | |||
| 106 | /* Nodes */ | 109 | /* Nodes */ |
| 107 | 110 | ||
| 108 | table#node_table { | 111 | table#node_table { |
| @@ -211,12 +214,10 @@ input[type=text]#page_title { | |||
| 211 | } | 214 | } |
| 212 | 215 | ||
| 213 | input[type=text]#tag_list { | 216 | input[type=text]#tag_list { |
| 214 | width: 690px; | ||
| 215 | padding: 5px; | 217 | padding: 5px; |
| 216 | } | 218 | } |
| 217 | 219 | ||
| 218 | input[type=text]#node_slug { | 220 | input[type=text]#node_slug { |
| 219 | width: 690px; | ||
| 220 | padding: 5px; | 221 | padding: 5px; |
| 221 | } | 222 | } |
| 222 | 223 | ||
| @@ -235,14 +236,14 @@ input[type=radio] { | |||
| 235 | } | 236 | } |
| 236 | 237 | ||
| 237 | textarea#page_abstract { | 238 | textarea#page_abstract { |
| 238 | height: 150px; | ||
| 239 | width: 690px; | 239 | width: 690px; |
| 240 | height: 150px; | ||
| 240 | padding: 5px; | 241 | padding: 5px; |
| 241 | } | 242 | } |
| 242 | 243 | ||
| 243 | #page_editor textarea#page_body { | 244 | #page_editor textarea#page_body { |
| 244 | height: 600px; | ||
| 245 | width: 700px; | 245 | width: 700px; |
| 246 | height: 600px; | ||
| 246 | } | 247 | } |
| 247 | 248 | ||
| 248 | #page_editor #metadata, #page_editor #content { | 249 | #page_editor #metadata, #page_editor #content { |
| @@ -303,4 +304,39 @@ div#draft_list table tr:hover { | |||
| 303 | table tr.header { | 304 | table tr.header { |
| 304 | height: 20px; | 305 | height: 20px; |
| 305 | text-align: left; | 306 | text-align: left; |
| 306 | } \ No newline at end of file | 307 | } |
| 308 | |||
| 309 | #search_widget { | ||
| 310 | position: absolute; | ||
| 311 | top: 20px; | ||
| 312 | left: 400px; | ||
| 313 | width: 300px; | ||
| 314 | border: 1px solid #000000; | ||
| 315 | -webkit-box-shadow: 3px 3px 5px #b1b1b1; | ||
| 316 | -moz-box-shadow: 10px 10px 5px #888, 10px 10px 30px rgba(0,0,0,0.4); | ||
| 317 | background-color: #ffffff; | ||
| 318 | padding: 3px; | ||
| 319 | text-align: center; | ||
| 320 | } | ||
| 321 | |||
| 322 | #search_widget span { | ||
| 323 | font-size: 18px; | ||
| 324 | } | ||
| 325 | |||
| 326 | #search_widget input { | ||
| 327 | width: 210px; | ||
| 328 | font-size: 18px; | ||
| 329 | } | ||
| 330 | |||
| 331 | #search_widget #search_results { | ||
| 332 | padding: 4px; | ||
| 333 | text-align: left; | ||
| 334 | } | ||
| 335 | |||
| 336 | table#content th.description { | ||
| 337 | width: 100px; | ||
| 338 | } | ||
| 339 | |||
| 340 | table#content th.content { | ||
| 341 | width: 690px; | ||
| 342 | } | ||
