annotate static/js/markitup/jquery.markitup.js @ 467:b910cc1460c8

Add the ability to conditionally add model instances to the search index on update. This is not perfect, as some instances should be deleted from the index if they are updated such that they should not be in the index anymore. Will think about and address that later.
author Brian Neal <bgneal@gmail.com>
date Sun, 24 Jul 2011 18:12:20 +0000
parents c78c6e007e61
children d280b27fed17
rev   line source
bgneal@312 1 // ----------------------------------------------------------------------------
bgneal@312 2 // markItUp! Universal MarkUp Engine, JQuery plugin
bgneal@466 3 // v 1.1.11
bgneal@312 4 // Dual licensed under the MIT and GPL licenses.
bgneal@312 5 // ----------------------------------------------------------------------------
bgneal@466 6 // Copyright (C) 2007-2011 Jay Salvat
bgneal@312 7 // http://markitup.jaysalvat.com/
bgneal@312 8 // ----------------------------------------------------------------------------
bgneal@312 9 // Permission is hereby granted, free of charge, to any person obtaining a copy
bgneal@312 10 // of this software and associated documentation files (the "Software"), to deal
bgneal@312 11 // in the Software without restriction, including without limitation the rights
bgneal@312 12 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
bgneal@312 13 // copies of the Software, and to permit persons to whom the Software is
bgneal@312 14 // furnished to do so, subject to the following conditions:
bgneal@312 15 //
bgneal@312 16 // The above copyright notice and this permission notice shall be included in
bgneal@312 17 // all copies or substantial portions of the Software.
bgneal@312 18 //
bgneal@312 19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
bgneal@312 20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
bgneal@312 21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
bgneal@312 22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
bgneal@312 23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
bgneal@312 24 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
bgneal@312 25 // THE SOFTWARE.
bgneal@312 26 // ----------------------------------------------------------------------------
bgneal@312 27 (function($) {
bgneal@312 28 $.fn.markItUp = function(settings, extraSettings) {
bgneal@312 29 var options, ctrlKey, shiftKey, altKey;
bgneal@312 30 ctrlKey = shiftKey = altKey = false;
bgneal@312 31
bgneal@312 32 options = { id: '',
bgneal@312 33 nameSpace: '',
bgneal@312 34 root: '',
bgneal@312 35 previewInWindow: '', // 'width=800, height=600, resizable=yes, scrollbars=yes'
bgneal@312 36 previewAutoRefresh: true,
bgneal@312 37 previewPosition: 'after',
bgneal@312 38 previewTemplatePath: '~/templates/preview.html',
bgneal@466 39 previewParser: false,
bgneal@312 40 previewParserPath: '',
bgneal@312 41 previewParserVar: 'data',
bgneal@312 42 resizeHandle: true,
bgneal@312 43 beforeInsert: '',
bgneal@312 44 afterInsert: '',
bgneal@312 45 onEnter: {},
bgneal@312 46 onShiftEnter: {},
bgneal@312 47 onCtrlEnter: {},
bgneal@312 48 onTab: {},
bgneal@312 49 markupSet: [ { /* set */ } ]
bgneal@312 50 };
bgneal@312 51 $.extend(options, settings, extraSettings);
bgneal@312 52
bgneal@312 53 // compute markItUp! path
bgneal@312 54 if (!options.root) {
bgneal@312 55 $('script').each(function(a, tag) {
bgneal@312 56 miuScript = $(tag).get(0).src.match(/(.*)jquery\.markitup(\.pack)?\.js$/);
bgneal@312 57 if (miuScript !== null) {
bgneal@312 58 options.root = miuScript[1];
bgneal@312 59 }
bgneal@312 60 });
bgneal@312 61 }
bgneal@312 62
bgneal@312 63 return this.each(function() {
bgneal@312 64 var $$, textarea, levels, scrollPosition, caretPosition, caretOffset,
bgneal@312 65 clicked, hash, header, footer, previewWindow, template, iFrame, abort;
bgneal@312 66 $$ = $(this);
bgneal@312 67 textarea = this;
bgneal@312 68 levels = [];
bgneal@312 69 abort = false;
bgneal@312 70 scrollPosition = caretPosition = 0;
bgneal@312 71 caretOffset = -1;
bgneal@312 72
bgneal@312 73 options.previewParserPath = localize(options.previewParserPath);
bgneal@312 74 options.previewTemplatePath = localize(options.previewTemplatePath);
bgneal@312 75
bgneal@312 76 // apply the computed path to ~/
bgneal@312 77 function localize(data, inText) {
bgneal@312 78 if (inText) {
bgneal@312 79 return data.replace(/("|')~\//g, "$1"+options.root);
bgneal@312 80 }
bgneal@312 81 return data.replace(/^~\//, options.root);
bgneal@312 82 }
bgneal@312 83
bgneal@312 84 // init and build editor
bgneal@312 85 function init() {
bgneal@312 86 id = ''; nameSpace = '';
bgneal@312 87 if (options.id) {
bgneal@312 88 id = 'id="'+options.id+'"';
bgneal@312 89 } else if ($$.attr("id")) {
bgneal@312 90 id = 'id="markItUp'+($$.attr("id").substr(0, 1).toUpperCase())+($$.attr("id").substr(1))+'"';
bgneal@312 91
bgneal@312 92 }
bgneal@312 93 if (options.nameSpace) {
bgneal@312 94 nameSpace = 'class="'+options.nameSpace+'"';
bgneal@312 95 }
bgneal@312 96 $$.wrap('<div '+nameSpace+'></div>');
bgneal@312 97 $$.wrap('<div '+id+' class="markItUp"></div>');
bgneal@312 98 $$.wrap('<div class="markItUpContainer"></div>');
bgneal@312 99 $$.addClass("markItUpEditor");
bgneal@312 100
bgneal@312 101 // add the header before the textarea
bgneal@312 102 header = $('<div class="markItUpHeader"></div>').insertBefore($$);
bgneal@312 103 $(dropMenus(options.markupSet)).appendTo(header);
bgneal@312 104
bgneal@312 105 // add the footer after the textarea
bgneal@312 106 footer = $('<div class="markItUpFooter"></div>').insertAfter($$);
bgneal@312 107
bgneal@312 108 // add the resize handle after textarea
bgneal@312 109 if (options.resizeHandle === true && $.browser.safari !== true) {
bgneal@312 110 resizeHandle = $('<div class="markItUpResizeHandle"></div>')
bgneal@312 111 .insertAfter($$)
bgneal@312 112 .bind("mousedown", function(e) {
bgneal@312 113 var h = $$.height(), y = e.clientY, mouseMove, mouseUp;
bgneal@312 114 mouseMove = function(e) {
bgneal@312 115 $$.css("height", Math.max(20, e.clientY+h-y)+"px");
bgneal@312 116 return false;
bgneal@312 117 };
bgneal@312 118 mouseUp = function(e) {
bgneal@312 119 $("html").unbind("mousemove", mouseMove).unbind("mouseup", mouseUp);
bgneal@312 120 return false;
bgneal@312 121 };
bgneal@312 122 $("html").bind("mousemove", mouseMove).bind("mouseup", mouseUp);
bgneal@312 123 });
bgneal@312 124 footer.append(resizeHandle);
bgneal@312 125 }
bgneal@312 126
bgneal@312 127 // listen key events
bgneal@312 128 $$.keydown(keyPressed).keyup(keyPressed);
bgneal@312 129
bgneal@312 130 // bind an event to catch external calls
bgneal@312 131 $$.bind("insertion", function(e, settings) {
bgneal@312 132 if (settings.target !== false) {
bgneal@312 133 get();
bgneal@312 134 }
bgneal@312 135 if (textarea === $.markItUp.focused) {
bgneal@312 136 markup(settings);
bgneal@312 137 }
bgneal@312 138 });
bgneal@312 139
bgneal@312 140 // remember the last focus
bgneal@312 141 $$.focus(function() {
bgneal@312 142 $.markItUp.focused = this;
bgneal@312 143 });
bgneal@312 144 }
bgneal@312 145
bgneal@312 146 // recursively build header with dropMenus from markupset
bgneal@312 147 function dropMenus(markupSet) {
bgneal@312 148 var ul = $('<ul></ul>'), i = 0;
bgneal@312 149 $('li:hover > ul', ul).css('display', 'block');
bgneal@312 150 $.each(markupSet, function() {
bgneal@312 151 var button = this, t = '', title, li, j;
bgneal@312 152 title = (button.key) ? (button.name||'')+' [Ctrl+'+button.key+']' : (button.name||'');
bgneal@312 153 key = (button.key) ? 'accesskey="'+button.key+'"' : '';
bgneal@312 154 if (button.separator) {
bgneal@312 155 li = $('<li class="markItUpSeparator">'+(button.separator||'')+'</li>').appendTo(ul);
bgneal@312 156 } else {
bgneal@312 157 i++;
bgneal@312 158 for (j = levels.length -1; j >= 0; j--) {
bgneal@312 159 t += levels[j]+"-";
bgneal@312 160 }
bgneal@312 161 li = $('<li class="markItUpButton markItUpButton'+t+(i)+' '+(button.className||'')+'"><a href="" '+key+' title="'+title+'">'+(button.name||'')+'</a></li>')
bgneal@312 162 .bind("contextmenu", function() { // prevent contextmenu on mac and allow ctrl+click
bgneal@312 163 return false;
bgneal@312 164 }).click(function() {
bgneal@312 165 return false;
bgneal@466 166 }).bind("focusin", function(){
bgneal@312 167 $$.focus();
bgneal@466 168 }).mouseup(function() {
bgneal@312 169 if (button.call) {
bgneal@312 170 eval(button.call)();
bgneal@312 171 }
bgneal@312 172 setTimeout(function() { markup(button) },1);
bgneal@312 173 return false;
bgneal@312 174 }).hover(function() {
bgneal@312 175 $('> ul', this).show();
bgneal@312 176 $(document).one('click', function() { // close dropmenu if click outside
bgneal@312 177 $('ul ul', header).hide();
bgneal@312 178 }
bgneal@312 179 );
bgneal@312 180 }, function() {
bgneal@312 181 $('> ul', this).hide();
bgneal@312 182 }
bgneal@312 183 ).appendTo(ul);
bgneal@312 184 if (button.dropMenu) {
bgneal@312 185 levels.push(i);
bgneal@312 186 $(li).addClass('markItUpDropMenu').append(dropMenus(button.dropMenu));
bgneal@312 187 }
bgneal@312 188 }
bgneal@312 189 });
bgneal@312 190 levels.pop();
bgneal@312 191 return ul;
bgneal@312 192 }
bgneal@312 193
bgneal@312 194 // markItUp! markups
bgneal@312 195 function magicMarkups(string) {
bgneal@312 196 if (string) {
bgneal@312 197 string = string.toString();
bgneal@312 198 string = string.replace(/\(\!\(([\s\S]*?)\)\!\)/g,
bgneal@312 199 function(x, a) {
bgneal@312 200 var b = a.split('|!|');
bgneal@312 201 if (altKey === true) {
bgneal@312 202 return (b[1] !== undefined) ? b[1] : b[0];
bgneal@312 203 } else {
bgneal@312 204 return (b[1] === undefined) ? "" : b[0];
bgneal@312 205 }
bgneal@312 206 }
bgneal@312 207 );
bgneal@312 208 // [![prompt]!], [![prompt:!:value]!]
bgneal@312 209 string = string.replace(/\[\!\[([\s\S]*?)\]\!\]/g,
bgneal@312 210 function(x, a) {
bgneal@312 211 var b = a.split(':!:');
bgneal@312 212 if (abort === true) {
bgneal@312 213 return false;
bgneal@312 214 }
bgneal@312 215 value = prompt(b[0], (b[1]) ? b[1] : '');
bgneal@312 216 if (value === null) {
bgneal@312 217 abort = true;
bgneal@312 218 }
bgneal@312 219 return value;
bgneal@312 220 }
bgneal@312 221 );
bgneal@312 222 return string;
bgneal@312 223 }
bgneal@312 224 return "";
bgneal@312 225 }
bgneal@312 226
bgneal@312 227 // prepare action
bgneal@312 228 function prepare(action) {
bgneal@312 229 if ($.isFunction(action)) {
bgneal@312 230 action = action(hash);
bgneal@312 231 }
bgneal@312 232 return magicMarkups(action);
bgneal@312 233 }
bgneal@312 234
bgneal@312 235 // build block to insert
bgneal@312 236 function build(string) {
bgneal@466 237 var openWith = prepare(clicked.openWith);
bgneal@466 238 var placeHolder = prepare(clicked.placeHolder);
bgneal@466 239 var replaceWith = prepare(clicked.replaceWith);
bgneal@466 240 var closeWith = prepare(clicked.closeWith);
bgneal@466 241 var openBlockWith = prepare(clicked.openBlockWith);
bgneal@466 242 var closeBlockWith = prepare(clicked.closeBlockWith);
bgneal@466 243 var multiline = clicked.multiline;
bgneal@466 244
bgneal@312 245 if (replaceWith !== "") {
bgneal@312 246 block = openWith + replaceWith + closeWith;
bgneal@312 247 } else if (selection === '' && placeHolder !== '') {
bgneal@312 248 block = openWith + placeHolder + closeWith;
bgneal@312 249 } else {
bgneal@466 250 string = string || selection;
bgneal@466 251
bgneal@466 252 var lines = selection.split(/\r?\n/), blocks = [];
bgneal@466 253 for (var l=0; l < lines.length; l++) {
bgneal@466 254 line = lines[l];
bgneal@466 255 if ($.trim(line) == '') {
bgneal@466 256 continue;
bgneal@466 257 }
bgneal@466 258 if (line.match(/ +$/)) {
bgneal@466 259 blocks.push(openWith + line.replace(/ $/, '') + closeWith + ' ');
bgneal@466 260 } else {
bgneal@466 261 blocks.push(openWith + line + closeWith);
bgneal@466 262 }
bgneal@466 263 }
bgneal@466 264
bgneal@466 265 block = blocks.join("\n");
bgneal@312 266 }
bgneal@466 267
bgneal@466 268 block = openBlockWith + block + closeBlockWith;
bgneal@466 269
bgneal@312 270 return { block:block,
bgneal@312 271 openWith:openWith,
bgneal@312 272 replaceWith:replaceWith,
bgneal@312 273 placeHolder:placeHolder,
bgneal@312 274 closeWith:closeWith
bgneal@312 275 };
bgneal@312 276 }
bgneal@312 277
bgneal@312 278 // define markup to insert
bgneal@312 279 function markup(button) {
bgneal@312 280 var len, j, n, i;
bgneal@312 281 hash = clicked = button;
bgneal@312 282 get();
bgneal@312 283 $.extend(hash, { line:"",
bgneal@312 284 root:options.root,
bgneal@312 285 textarea:textarea,
bgneal@312 286 selection:(selection||''),
bgneal@312 287 caretPosition:caretPosition,
bgneal@312 288 ctrlKey:ctrlKey,
bgneal@312 289 shiftKey:shiftKey,
bgneal@312 290 altKey:altKey
bgneal@312 291 }
bgneal@312 292 );
bgneal@312 293 // callbacks before insertion
bgneal@312 294 prepare(options.beforeInsert);
bgneal@312 295 prepare(clicked.beforeInsert);
bgneal@466 296 if ((ctrlKey === true && shiftKey === true) || button.multiline === true) {
bgneal@312 297 prepare(clicked.beforeMultiInsert);
bgneal@312 298 }
bgneal@312 299 $.extend(hash, { line:1 });
bgneal@466 300
bgneal@466 301 if ((ctrlKey === true && shiftKey === true)) {
bgneal@312 302 lines = selection.split(/\r?\n/);
bgneal@312 303 for (j = 0, n = lines.length, i = 0; i < n; i++) {
bgneal@312 304 if ($.trim(lines[i]) !== '') {
bgneal@312 305 $.extend(hash, { line:++j, selection:lines[i] } );
bgneal@312 306 lines[i] = build(lines[i]).block;
bgneal@312 307 } else {
bgneal@312 308 lines[i] = "";
bgneal@312 309 }
bgneal@312 310 }
bgneal@312 311 string = { block:lines.join('\n')};
bgneal@312 312 start = caretPosition;
bgneal@312 313 len = string.block.length + (($.browser.opera) ? n-1 : 0);
bgneal@312 314 } else if (ctrlKey === true) {
bgneal@312 315 string = build(selection);
bgneal@312 316 start = caretPosition + string.openWith.length;
bgneal@312 317 len = string.block.length - string.openWith.length - string.closeWith.length;
bgneal@466 318 len = len - (string.block.match(/ $/) ? 1 : 0);
bgneal@312 319 len -= fixIeBug(string.block);
bgneal@312 320 } else if (shiftKey === true) {
bgneal@312 321 string = build(selection);
bgneal@312 322 start = caretPosition;
bgneal@312 323 len = string.block.length;
bgneal@312 324 len -= fixIeBug(string.block);
bgneal@312 325 } else {
bgneal@312 326 string = build(selection);
bgneal@312 327 start = caretPosition + string.block.length ;
bgneal@312 328 len = 0;
bgneal@312 329 start -= fixIeBug(string.block);
bgneal@312 330 }
bgneal@312 331 if ((selection === '' && string.replaceWith === '')) {
bgneal@312 332 caretOffset += fixOperaBug(string.block);
bgneal@312 333
bgneal@312 334 start = caretPosition + string.openWith.length;
bgneal@312 335 len = string.block.length - string.openWith.length - string.closeWith.length;
bgneal@312 336
bgneal@312 337 caretOffset = $$.val().substring(caretPosition, $$.val().length).length;
bgneal@312 338 caretOffset -= fixOperaBug($$.val().substring(0, caretPosition));
bgneal@312 339 }
bgneal@312 340 $.extend(hash, { caretPosition:caretPosition, scrollPosition:scrollPosition } );
bgneal@312 341
bgneal@312 342 if (string.block !== selection && abort === false) {
bgneal@312 343 insert(string.block);
bgneal@312 344 set(start, len);
bgneal@312 345 } else {
bgneal@312 346 caretOffset = -1;
bgneal@312 347 }
bgneal@312 348 get();
bgneal@312 349
bgneal@312 350 $.extend(hash, { line:'', selection:selection });
bgneal@312 351
bgneal@312 352 // callbacks after insertion
bgneal@466 353 if ((ctrlKey === true && shiftKey === true) || button.multiline === true) {
bgneal@312 354 prepare(clicked.afterMultiInsert);
bgneal@312 355 }
bgneal@312 356 prepare(clicked.afterInsert);
bgneal@312 357 prepare(options.afterInsert);
bgneal@312 358
bgneal@312 359 // refresh preview if opened
bgneal@312 360 if (previewWindow && options.previewAutoRefresh) {
bgneal@312 361 refreshPreview();
bgneal@312 362 }
bgneal@312 363
bgneal@312 364 // reinit keyevent
bgneal@312 365 shiftKey = altKey = ctrlKey = abort = false;
bgneal@312 366 }
bgneal@312 367
bgneal@312 368 // Substract linefeed in Opera
bgneal@312 369 function fixOperaBug(string) {
bgneal@312 370 if ($.browser.opera) {
bgneal@312 371 return string.length - string.replace(/\n*/g, '').length;
bgneal@312 372 }
bgneal@312 373 return 0;
bgneal@312 374 }
bgneal@312 375 // Substract linefeed in IE
bgneal@312 376 function fixIeBug(string) {
bgneal@312 377 if ($.browser.msie) {
bgneal@312 378 return string.length - string.replace(/\r*/g, '').length;
bgneal@312 379 }
bgneal@312 380 return 0;
bgneal@312 381 }
bgneal@312 382
bgneal@312 383 // add markup
bgneal@312 384 function insert(block) {
bgneal@312 385 if (document.selection) {
bgneal@312 386 var newSelection = document.selection.createRange();
bgneal@312 387 newSelection.text = block;
bgneal@312 388 } else {
bgneal@312 389 textarea.value = textarea.value.substring(0, caretPosition) + block + textarea.value.substring(caretPosition + selection.length, textarea.value.length);
bgneal@312 390 }
bgneal@312 391 }
bgneal@312 392
bgneal@312 393 // set a selection
bgneal@312 394 function set(start, len) {
bgneal@312 395 if (textarea.createTextRange){
bgneal@312 396 // quick fix to make it work on Opera 9.5
bgneal@312 397 if ($.browser.opera && $.browser.version >= 9.5 && len == 0) {
bgneal@312 398 return false;
bgneal@312 399 }
bgneal@312 400 range = textarea.createTextRange();
bgneal@312 401 range.collapse(true);
bgneal@312 402 range.moveStart('character', start);
bgneal@312 403 range.moveEnd('character', len);
bgneal@312 404 range.select();
bgneal@312 405 } else if (textarea.setSelectionRange ){
bgneal@312 406 textarea.setSelectionRange(start, start + len);
bgneal@312 407 }
bgneal@312 408 textarea.scrollTop = scrollPosition;
bgneal@312 409 textarea.focus();
bgneal@312 410 }
bgneal@312 411
bgneal@312 412 // get the selection
bgneal@312 413 function get() {
bgneal@312 414 textarea.focus();
bgneal@312 415
bgneal@312 416 scrollPosition = textarea.scrollTop;
bgneal@312 417 if (document.selection) {
bgneal@312 418 selection = document.selection.createRange().text;
bgneal@312 419 if ($.browser.msie) { // ie
bgneal@312 420 var range = document.selection.createRange(), rangeCopy = range.duplicate();
bgneal@312 421 rangeCopy.moveToElementText(textarea);
bgneal@312 422 caretPosition = -1;
bgneal@312 423 while(rangeCopy.inRange(range)) {
bgneal@312 424 rangeCopy.moveStart('character');
bgneal@312 425 caretPosition ++;
bgneal@312 426 }
bgneal@312 427 } else { // opera
bgneal@312 428 caretPosition = textarea.selectionStart;
bgneal@312 429 }
bgneal@312 430 } else { // gecko & webkit
bgneal@312 431 caretPosition = textarea.selectionStart;
bgneal@466 432
bgneal@312 433 selection = textarea.value.substring(caretPosition, textarea.selectionEnd);
bgneal@312 434 }
bgneal@312 435 return selection;
bgneal@312 436 }
bgneal@312 437
bgneal@312 438 // open preview window
bgneal@312 439 function preview() {
bgneal@312 440 if (!previewWindow || previewWindow.closed) {
bgneal@312 441 if (options.previewInWindow) {
bgneal@312 442 previewWindow = window.open('', 'preview', options.previewInWindow);
bgneal@312 443 $(window).unload(function() {
bgneal@312 444 previewWindow.close();
bgneal@312 445 });
bgneal@312 446 } else {
bgneal@312 447 iFrame = $('<iframe class="markItUpPreviewFrame"></iframe>');
bgneal@312 448 if (options.previewPosition == 'after') {
bgneal@312 449 iFrame.insertAfter(footer);
bgneal@312 450 } else {
bgneal@312 451 iFrame.insertBefore(header);
bgneal@312 452 }
bgneal@312 453 previewWindow = iFrame[iFrame.length - 1].contentWindow || frame[iFrame.length - 1];
bgneal@312 454 }
bgneal@312 455 } else if (altKey === true) {
bgneal@312 456 if (iFrame) {
bgneal@312 457 iFrame.remove();
bgneal@312 458 } else {
bgneal@312 459 previewWindow.close();
bgneal@312 460 }
bgneal@312 461 previewWindow = iFrame = false;
bgneal@312 462 }
bgneal@312 463 if (!options.previewAutoRefresh) {
bgneal@312 464 refreshPreview();
bgneal@312 465 }
bgneal@312 466 if (options.previewInWindow) {
bgneal@312 467 previewWindow.focus();
bgneal@312 468 }
bgneal@312 469 }
bgneal@312 470
bgneal@312 471 // refresh Preview window
bgneal@312 472 function refreshPreview() {
bgneal@312 473 renderPreview();
bgneal@312 474 }
bgneal@312 475
bgneal@312 476 function renderPreview() {
bgneal@312 477 var phtml;
bgneal@466 478 if (options.previewParser && typeof options.previewParser === 'function') {
bgneal@466 479 var data = options.previewParser( $$.val() );
bgneal@466 480 writeInPreview( localize(data, 1) );
bgneal@466 481 } else if (options.previewParserPath !== '') {
bgneal@466 482 $.ajax({
bgneal@312 483 type: 'POST',
bgneal@466 484 dataType: 'text',
bgneal@466 485 global: false,
bgneal@312 486 url: options.previewParserPath,
bgneal@312 487 data: options.previewParserVar+'='+encodeURIComponent($$.val()),
bgneal@312 488 success: function(data) {
bgneal@312 489 writeInPreview( localize(data, 1) );
bgneal@312 490 }
bgneal@466 491 });
bgneal@312 492 } else {
bgneal@312 493 if (!template) {
bgneal@466 494 $.ajax({
bgneal@312 495 url: options.previewTemplatePath,
bgneal@466 496 dataType: 'text',
bgneal@466 497 global: false,
bgneal@312 498 success: function(data) {
bgneal@312 499 writeInPreview( localize(data, 1).replace(/<!-- content -->/g, $$.val()) );
bgneal@312 500 }
bgneal@466 501 });
bgneal@312 502 }
bgneal@312 503 }
bgneal@312 504 return false;
bgneal@312 505 }
bgneal@312 506
bgneal@312 507 function writeInPreview(data) {
bgneal@312 508 if (previewWindow.document) {
bgneal@312 509 try {
bgneal@312 510 sp = previewWindow.document.documentElement.scrollTop
bgneal@312 511 } catch(e) {
bgneal@312 512 sp = 0;
bgneal@312 513 }
bgneal@312 514 previewWindow.document.open();
bgneal@312 515 previewWindow.document.write(data);
bgneal@312 516 previewWindow.document.close();
bgneal@312 517 previewWindow.document.documentElement.scrollTop = sp;
bgneal@312 518 }
bgneal@312 519 }
bgneal@312 520
bgneal@312 521 // set keys pressed
bgneal@312 522 function keyPressed(e) {
bgneal@312 523 shiftKey = e.shiftKey;
bgneal@312 524 altKey = e.altKey;
bgneal@466 525 ctrlKey = (!(e.altKey && e.ctrlKey)) ? (e.ctrlKey || e.metaKey) : false;
bgneal@312 526
bgneal@312 527 if (e.type === 'keydown') {
bgneal@312 528 if (ctrlKey === true) {
bgneal@466 529 li = $('a[accesskey="'+String.fromCharCode(e.keyCode)+'"]', header).parent('li');
bgneal@312 530 if (li.length !== 0) {
bgneal@312 531 ctrlKey = false;
bgneal@312 532 setTimeout(function() {
bgneal@466 533 li.triggerHandler('mouseup');
bgneal@312 534 },1);
bgneal@312 535 return false;
bgneal@312 536 }
bgneal@312 537 }
bgneal@312 538 if (e.keyCode === 13 || e.keyCode === 10) { // Enter key
bgneal@312 539 if (ctrlKey === true) { // Enter + Ctrl
bgneal@312 540 ctrlKey = false;
bgneal@312 541 markup(options.onCtrlEnter);
bgneal@312 542 return options.onCtrlEnter.keepDefault;
bgneal@312 543 } else if (shiftKey === true) { // Enter + Shift
bgneal@312 544 shiftKey = false;
bgneal@312 545 markup(options.onShiftEnter);
bgneal@312 546 return options.onShiftEnter.keepDefault;
bgneal@312 547 } else { // only Enter
bgneal@312 548 markup(options.onEnter);
bgneal@312 549 return options.onEnter.keepDefault;
bgneal@312 550 }
bgneal@312 551 }
bgneal@312 552 if (e.keyCode === 9) { // Tab key
bgneal@312 553 if (shiftKey == true || ctrlKey == true || altKey == true) {
bgneal@312 554 return false;
bgneal@312 555 }
bgneal@312 556 if (caretOffset !== -1) {
bgneal@312 557 get();
bgneal@312 558 caretOffset = $$.val().length - caretOffset;
bgneal@312 559 set(caretOffset, 0);
bgneal@312 560 caretOffset = -1;
bgneal@312 561 return false;
bgneal@312 562 } else {
bgneal@312 563 markup(options.onTab);
bgneal@312 564 return options.onTab.keepDefault;
bgneal@312 565 }
bgneal@312 566 }
bgneal@312 567 }
bgneal@312 568 }
bgneal@312 569
bgneal@312 570 init();
bgneal@312 571 });
bgneal@312 572 };
bgneal@312 573
bgneal@312 574 $.fn.markItUpRemove = function() {
bgneal@312 575 return this.each(function() {
bgneal@312 576 var $$ = $(this).unbind().removeClass('markItUpEditor');
bgneal@312 577 $$.parent('div').parent('div.markItUp').parent('div').replaceWith($$);
bgneal@312 578 }
bgneal@312 579 );
bgneal@312 580 };
bgneal@312 581
bgneal@312 582 $.markItUp = function(settings) {
bgneal@312 583 var options = { target:false };
bgneal@312 584 $.extend(options, settings);
bgneal@312 585 if (options.target) {
bgneal@312 586 return $(options.target).each(function() {
bgneal@312 587 $(this).focus();
bgneal@312 588 $(this).trigger('insertion', [options]);
bgneal@312 589 });
bgneal@312 590 } else {
bgneal@312 591 $('textarea').trigger('insertion', [options]);
bgneal@312 592 }
bgneal@312 593 };
bgneal@312 594 })(jQuery);