[ Index ] |
PHP Cross Reference of MyBB |
[Summary view] [Print] [Text view]
1 var messageEditor = Class.create(); 2 3 messageEditor.prototype = { 4 openTags: new Array(), 5 toolbarHeight: 0, 6 currentTheme: '', 7 themePath: '', 8 openDropDownMenu: null, 9 10 setTheme: function(theme) 11 { 12 if(this.currentTheme != '' || $('editorTheme')) { 13 $('editorTheme').remove(); 14 } 15 16 var stylesheet = document.createElement('link'); 17 stylesheet.setAttribute('rel', 'stylesheet'); 18 stylesheet.setAttribute('type', 'text/css'); 19 stylesheet.setAttribute('href', this.baseURL + 'editor_themes/'+theme+'/stylesheet.css'); 20 document.getElementsByTagName('head')[0].appendChild(stylesheet); 21 this.currentTheme = theme; 22 this.themePath = this.baseURL + 'editor_themes/'+theme; 23 }, 24 25 initialize: function(textarea, options) 26 { 27 // Sorry Konqueror, but due to a browser bug out of control with textarea values 28 // you do not get to use the fancy editor. 29 30 if(MyBB.browser == "konqueror" || (typeof(mybb_editor_disabled) != "undefined" && mybb_editor_disabled == true)) 31 { 32 return false; 33 } 34 35 // Establish the base path to this javascript file 36 $$('script').each(function(script) { 37 if(script.src && script.src.indexOf('editor.js') != -1) { 38 this.baseURL = script.src.replace(/editor\.js(.*?)$/, ''); 39 } 40 }, this); 41 42 this.options = options; 43 44 if(this.options) 45 { 46 if(!this.options.lang) 47 { 48 return false; 49 } 50 51 if(!this.options.rtl) 52 { 53 this.options.rtl = 0; 54 } 55 } 56 57 if(this.options && this.options.theme) 58 { 59 this.setTheme(this.options.theme); 60 } 61 else 62 { 63 this.setTheme('default'); 64 } 65 66 // Defines an array of fonts to be shown in the font drop down. 67 this.fonts = new Object(); 68 this.fonts["Arial"] = "Arial"; 69 this.fonts["Courier"] = "Courier"; 70 this.fonts["Impact"] = "Impact"; 71 this.fonts["Tahoma"] = "Tahoma"; 72 this.fonts["Times New Roman"] = "Times New Roman"; 73 this.fonts["Trebuchet MS"] = "Trebuchet MS"; 74 this.fonts["Verdana"] = "Verdana"; 75 76 // An array of font sizes to be shown. 77 this.sizes = new Object(); 78 this.sizes["xx-small"] = this.options.lang.size_xx_small; 79 this.sizes["x-small"] = this.options.lang.size_x_small; 80 this.sizes["small"] = this.options.lang.size_small; 81 this.sizes["medium"] = this.options.lang.size_medium; 82 this.sizes["large"] = this.options.lang.size_large; 83 this.sizes["x-large"] = this.options.lang.size_x_large; 84 this.sizes["xx-large"] = this.options.lang.size_xx_large; 85 86 // An array of colours to be shown. 87 this.colors = new Object(); 88 this.colors[1] = "#800000"; 89 this.colors[2] = "#8B4513"; 90 this.colors[3] = "#006400"; 91 this.colors[4] = "#2F4F4F"; 92 this.colors[5] = "#000080"; 93 this.colors[6] = "#4B0082"; 94 this.colors[7] = "#800080"; 95 this.colors[8] = "#000000"; 96 this.colors[9] = "#FF0000"; 97 this.colors[10] = "#DAA520"; 98 this.colors[11] = "#6B8E23"; 99 this.colors[12] = "#708090"; 100 this.colors[13] = "#0000CD"; 101 this.colors[14] = "#483D8B"; 102 this.colors[15] = "#C71585"; 103 this.colors[16] = "#696969"; 104 this.colors[17] = "#FF4500"; 105 this.colors[18] = "#FFA500"; 106 this.colors[19] = "#808000"; 107 this.colors[20] = "#4682B4"; 108 this.colors[21] = "#1E90FF"; 109 this.colors[22] = "#9400D3"; 110 this.colors[23] = "#FF1493"; 111 this.colors[24] = "#A9A9A9"; 112 this.colors[25] = "#FF6347"; 113 this.colors[26] = "#FFD700"; 114 this.colors[27] = "#32CD32"; 115 this.colors[28] = "#87CEEB"; 116 this.colors[29] = "#00BFFF"; 117 this.colors[30] = "#9370DB"; 118 this.colors[31] = "#FF69B4"; 119 this.colors[32] = "#DCDCDC"; 120 this.colors[33] = "#FFDAB9"; 121 this.colors[34] = "#FFFFE0"; 122 this.colors[35] = "#98FB98"; 123 this.colors[36] = "#E0FFFF"; 124 this.colors[37] = "#87CEFA"; 125 this.colors[38] = "#E6E6FA"; 126 this.colors[39] = "#DDA0DD"; 127 this.colors[40] = "#FFFFFF"; 128 129 // An array of video services to be shown (youtube, vimeo, etc) 130 this.videos = new Object(); 131 this.videos["dailymotion"] = this.options.lang.video_dailymotion; 132 this.videos["metacafe"] = this.options.lang.video_metacafe; 133 this.videos["myspacetv"] = this.options.lang.video_myspacetv; 134 this.videos["vimeo"] = this.options.lang.video_vimeo; 135 this.videos["yahoo"] = this.options.lang.video_yahoo; 136 this.videos["youtube"] = this.options.lang.video_youtube; 137 138 // Here we get the ID of the textarea we're replacing and store it. 139 this.textarea = textarea; 140 141 // Only swap it over once the page has loaded (add event) 142 if(MyBB.page_loaded == 1) 143 { 144 this.showEditor(); 145 } 146 else 147 { 148 Event.observe(document, "dom:loaded", this.showEditor.bindAsEventListener(this)); 149 } 150 }, 151 152 showEditor: function() 153 { 154 // Assign the old textarea to a variable for later use. 155 oldTextarea = $(this.textarea); 156 157 // Now this.textarea becomes the new textarea ID 158 this.textarea += "_new"; 159 160 // Begin the creation of our new editor. 161 162 this.editor = document.createElement("div"); 163 this.editor.style.position = "relative"; 164 this.editor.style.display = "none"; 165 this.editor.className = "messageEditor"; 166 167 // Append the new editor 168 oldTextarea.parentNode.insertBefore(this.editor, oldTextarea); 169 170 // Determine the overall height and width - messy, but works 171 w = oldTextarea.getDimensions().width+"px"; 172 if(!w || parseInt(w) < 400) 173 { 174 w = "400px"; 175 } 176 if(this.options && this.options.height) 177 { 178 h = this.options.height; 179 } 180 else if(oldTextarea.offsetHeight) 181 { 182 h = oldTextarea.offsetHeight+"px"; 183 } 184 else if(oldTextarea.clientHeight) 185 { 186 h = oldTextarea.clientHeight+"px"; 187 } 188 else if(oldTextarea.style.height) 189 { 190 h = oldTextarea.style.height; 191 } 192 else 193 { 194 h = "400px"; 195 } 196 this.editor.style.width = w; 197 this.editor.style.height = h; 198 199 this.createToolbarContainer('top'); 200 201 this.createToolbar('closetags', { 202 container: 'top', 203 alignment: 'right', 204 items: [ 205 {type: 'button', name: 'close_tags', insert: 'zzzz', sprite: 'close_tags', width: 80, style: {visibility: 'hidden'}} 206 ] 207 }); 208 this.createToolbar('topformatting', { 209 container: 'top', 210 items: [ 211 {type: 'dropdown', name: 'font', insert: 'font', title: this.options.lang.font, options: this.fonts}, 212 {type: 'dropdown', name: 'size', insert: 'size', title: this.options.lang.size, options: this.sizes}, 213 {type: 'button', name: 'color', insert: 'color', dropdown: true, color_select: true, image: 'color.gif', draw_option: this.drawColorOption, options: this.colors} 214 ] 215 }); 216 217 this.createToolbarContainer('bottom'); 218 219 this.createToolbar('insertables', { 220 container: 'bottom', 221 alignment: 'right', 222 items: [ 223 {type: 'button', name: 'list_num', sprite: 'list_num', insert: 'list', extra: 1, title: this.options.lang.title_numlist}, 224 {type: 'button', name: 'list_bullet', sprite: 'list_bullet', insert: 'list', title: this.options.lang.title_bulletlist}, 225 {type: 'separator'}, 226 {type: 'button', name: 'img', sprite: 'image', insert: 'image', extra: 1, title: this.options.lang.title_image}, 227 {type: 'button', name: 'url', sprite: 'link', insert: 'url', title: this.options.lang.title_hyperlink}, 228 {type: 'button', name: 'email', sprite: 'email', insert: 'email', extra: 1, title: this.options.lang.title_email}, 229 {type: 'separator'}, 230 {type: 'button', name: 'quote', sprite: 'quote', insert: 'quote', title: this.options.lang.title_quote}, 231 {type: 'button', name: 'code', sprite: 'code', insert: 'code', title: this.options.lang.title_code}, 232 {type: 'button', name: 'php', sprite: 'php', insert: 'php', title: this.options.lang.title_php}, 233 {type: 'button', name: 'video', insert: 'video', image: 'television.gif', dropdown: true, title: this.options.lang.title_video, options: this.videos} 234 ] 235 }); 236 this.createToolbar('formatting', { 237 container: 'bottom', 238 items: [ 239 {type: 'button', name: 'b', sprite: 'bold', insert: 'b', title: this.options.lang.title_bold}, 240 {type: 'button', name: 'i', sprite: 'italic', insert: 'i', title: this.options.lang.title_italic}, 241 {type: 'button', name: 'u', sprite: 'underline', insert: 'u', title: this.options.lang.title_underline}, 242 {type: 'separator'}, 243 {type: 'button', name: 'align_left', sprite: 'align_left', insert: 'align', extra: 'left', title: this.options.lang.title_left}, 244 {type: 'button', name: 'align_center', sprite: 'align_center', insert: 'align', extra: 'center', title: this.options.lang.title_center}, 245 {type: 'button', name: 'align_right', sprite: 'align_right', insert: 'align', extra: 'right', title: this.options.lang.title_right}, 246 {type: 'button', name: 'align_justify', sprite: 'align_justify', insert: 'align', extra: 'justify', title: this.options.lang.title_justify} 247 ] 248 }); 249 250 // Create our new text area 251 areaContainer = document.createElement("div"); 252 areaContainer.style.clear = "both"; 253 254 // Set the width/height of the area 255 subtract = 20; 256 subtract2 = 8; 257 areaContainer.style.height = parseInt(Element.getDimensions(this.editor).height)-this.toolbarHeight-subtract+"px"; 258 areaContainer.style.width = parseInt(Element.getDimensions(this.editor).width)-subtract2+"px"; 259 260 // Create text area 261 textInput = document.createElement("textarea"); 262 textInput.setAttribute("cols", oldTextarea.getAttribute("cols")); 263 textInput.setAttribute("rows", oldTextarea.getAttribute("rows")); 264 textInput.id = this.textarea; 265 textInput.name = oldTextarea.name+"_new"; 266 textInput.style.height = parseInt(areaContainer.style.height)+"px"; 267 textInput.style.width = parseInt(areaContainer.style.width)+"px"; 268 269 if(oldTextarea.value != '') 270 { 271 textInput.value = oldTextarea.value; 272 } 273 274 if(oldTextarea.tabIndex) 275 { 276 textInput.tabIndex = oldTextarea.tabIndex; 277 } 278 279 areaContainer.appendChild(textInput); 280 this.editor.appendChild(areaContainer); 281 282 if(oldTextarea.form) 283 { 284 Event.observe(oldTextarea.form, "submit", this.closeTags.bindAsEventListener(this)); 285 Event.observe(oldTextarea.form, "submit", this.updateOldArea.bindAsEventListener(this)); 286 } 287 288 // Hide the old editor 289 oldTextarea.style.visibility = "hidden"; 290 oldTextarea.style.position = "absolute"; 291 oldTextarea.style.top = "-1000px"; 292 oldTextarea.id += "_old"; 293 this.oldTextarea = oldTextarea; 294 295 this.editor.style.display = ""; 296 Event.observe(textInput, "keyup", this.updateOldArea.bindAsEventListener(this)); 297 298 if(MyBB.browser == 'ie') { 299 Event.observe($(this.textarea), 'focus', function() { 300 this.trackingCaret = true; 301 }.bindAsEventListener(this)); 302 Event.observe($(this.textarea), 'blur', function() { 303 this.trackingCaret = false; 304 }.bindAsEventListener(this)); 305 Event.observe($(this.textarea), 'mousedown', function() { 306 this.trackingCaret = true; 307 this.storeCaret(); 308 }.bindAsEventListener(this)); 309 } 310 311 Event.observe(textInput, "blur", this.updateOldArea.bindAsEventListener(this)); 312 }, 313 314 drawColorOption: function(option) 315 { 316 var item = document.createElement('li'); 317 item.extra = option.value; 318 item.className = 'editor_dropdown_color_item'; 319 item.innerHTML = '<a style="background-color: '+option.value+'"></a>'; 320 return item; 321 }, 322 323 createToolbarContainer: function(name) 324 { 325 if($('editor_toolbar_container_'+name)) return; 326 327 var container = document.createElement("div"); 328 container.id = 'editor_toolbar_container_'+name; 329 container.className = 'toolbar_container'; 330 331 this.editor.appendChild(container); 332 333 this.toolbarHeight += 28; 334 335 return container; 336 }, 337 338 createToolbar: function(name, options) 339 { 340 if(typeof(options.container) == 'undefined') 341 { 342 options.container = this.createToolbarContainer('auto_'+name); 343 } 344 else { 345 options.container = $('editor_toolbar_container_'+options.container); 346 if(!options.container) return; 347 } 348 349 if($('editor_toolbar_'+name)) return; 350 351 var toolbar = document.createElement('div'); 352 toolbar.id = 'editor_toolbar_'+name; 353 toolbar.className = 'toolbar'; 354 355 var clear = document.createElement('br'); 356 clear.style.clear = 'both'; 357 toolbar.appendChild(clear); 358 359 if(options.alignment && options.alignment == 'right') { 360 toolbar.className += ' float_right'; 361 } 362 options.container.appendChild(toolbar); 363 if(typeof(options.items) == 'object') { 364 for(var i = 0; i < options.items.length; ++i) { 365 this.addToolbarItem(toolbar, options.items[i]); 366 } 367 } 368 // add closing item 369 if(toolbar.lastChild.previousSibling) 370 toolbar.lastChild.previousSibling.className += ' toolbar_button_group_last'; 371 }, 372 373 setElementState: function(element, state) { 374 element.addClassName('toolbar_'+state); 375 376 if(element.hasClassName('toolbar_button_group_first')) { 377 if(state == 'clicked') { 378 append = 'toolbar_clicked'; 379 } 380 else if(state == 'hover') { 381 append = 'toolbar_hover'; 382 } 383 append += '_button_group_first'; 384 element.addClassName(append); 385 } 386 387 if(element.hasClassName('toolbar_button_group_last')) { 388 if(state == 'clicked') { 389 append = 'toolbar_clicked'; 390 } 391 else if(state == 'hover') { 392 append = 'toolbar_hover'; 393 } 394 append += '_button_group_last'; 395 element.addClassName(append); 396 } 397 }, 398 399 removeElementState: function(element, state) 400 { 401 element.removeClassName('toolbar_'+state); 402 403 if(element.hasClassName('toolbar_button_group_first')) { 404 if(state == 'clicked') { 405 append = 'toolbar_clicked'; 406 } 407 else if(state == 'hover') { 408 append = 'toolbar_hover'; 409 } 410 append += '_button_group_first'; 411 element.removeClassName(append); 412 } 413 414 if(element.hasClassName('toolbar_button_group_last')) { 415 if(state == 'clicked') { 416 append = 'toolbar_clicked'; 417 } 418 else if(state == 'hover') { 419 append = 'toolbar_hover'; 420 } 421 append += '_button_group_last'; 422 element.removeClassName(append); 423 } 424 }, 425 426 dropDownMenuItemClick: function(e) 427 { 428 this.restartEditorSelection(); 429 element = Event.element(e); 430 431 if(!element) 432 return; 433 434 if(!element.extra) 435 element = element.up('li'); 436 437 var mnu = element.up('ul'); 438 var dropdown = this.getElementToolbarItem(mnu); 439 var label = dropdown.down('.editor_dropdown_label'); 440 441 if(!dropdown.insertText || (dropdown.insertText != "video" && mnu.activeItem && mnu.activeItem == element)) 442 return; 443 444 mnu.lastItemValue = element.extra; 445 446 if(this.getSelectedText($(this.textarea))) 447 { 448 this.setDropDownMenuActiveItem(dropdown, 0); 449 } 450 else 451 { 452 if(label) 453 { 454 label.innerHTML = element.innerHTML; 455 label.style.overflow = 'hidden'; 456 } 457 var sel_color = dropdown.down('.editor_button_color_selected') 458 if(sel_color) 459 { 460 sel_color.style.backgroundColor = element.extra; 461 var use_default = dropdown.down('.editor_dropdown_color_item_default'); 462 if(use_default) use_default.style.display = ''; 463 } 464 mnu.activeItem = element; 465 element.addClassName('editor_dropdown_menu_item_active'); 466 } 467 468 this.insertMyCode(dropdown.insertText, element.extra); 469 this.hideOpenDropDownMenu(); 470 Event.stop(e); 471 }, 472 473 setDropDownMenuActiveItem: function(element, index) 474 { 475 if(element == null) 476 { 477 return; 478 } 479 var mnu = element.down('ul'); 480 var label = element.down('.editor_dropdown_label'); 481 482 if(mnu.activeItem) 483 { 484 mnu.activeItem.removeClassName('editor_dropdown_menu_item_active'); 485 mnu.activeItem = null; 486 } 487 488 if(index > 0) 489 { 490 var item = mnu.childNodes[index]; 491 if(!item) return; 492 mnu.activeItem = item; 493 if(label) 494 { 495 label.innerHTML = item.innerHTML; 496 } 497 498 var sel_color = element.down('.editor_dropdown_color_selected') 499 if(sel_color) 500 { 501 sel_color.style.backgroundColor = item.style.backgroundColor; 502 mnu.lastItemValue = item.insertExtra; 503 var use_default = element.down('.editor_dropdown_color_item_default'); 504 if(use_default) use_default.style.display = ''; 505 } 506 item.addClassName('editor_dropdown_menu_item_active'); 507 } 508 else 509 { 510 if(label) 511 { 512 label.innerHTML = mnu.childNodes[0].innerHTML; 513 } 514 515 var sel_color = element.down('.editor_button_color_selected') 516 if(sel_color) 517 { 518 //sel_color.style.backgroundColor = ''; 519 var use_default = element.down('.editor_dropdown_color_item_default'); 520 if(use_default) use_default.style.display = 'none'; 521 } 522 this.removeElementState(element, 'clicked'); 523 } 524 }, 525 526 createDropDownMenu: function(options) 527 { 528 var dropdown = document.createElement('div'); 529 dropdown.elementType = options.type; 530 if(options.image || options.sprite) 531 dropdown.className = 'toolbar_dropdown_image'; 532 else 533 dropdown.className = 'toolbar_dropdown'; 534 535 dropdown.className += ' editor_dropdown toolbar_dropdown_'+options.name; 536 dropdown.id = 'editor_item_'+options.name; 537 538 Event.observe(dropdown, 'mouseover', function() 539 { 540 this.storeCaret(); 541 dropdown.addClassName('toolbar_dropdown_over'); 542 }.bindAsEventListener(this)); 543 Event.observe(dropdown, 'mouseout', function() 544 { 545 this.storeCaret(); 546 dropdown.removeClassName('toolbar_dropdown_over'); 547 }.bindAsEventListener(this)); 548 dropdown.insertText = options.insert; 549 550 // create the dropdown label container 551 var label = document.createElement('div'); 552 label.className = 'editor_dropdown_label'; 553 if(options.title) 554 { 555 label.innerHTML = options.title; 556 } 557 else 558 { 559 label.innerHTML = ' '; 560 } 561 dropdown.appendChild(label) 562 563 // create the arrow 564 var arrow = document.createElement('div'); 565 arrow.className = 'editor_dropdown_arrow'; 566 dropdown.appendChild(arrow); 567 568 // create the menu item container 569 var mnu = this.buildDropDownMenu(options); 570 571 Event.observe(dropdown, 'click', this.toggleDropDownMenu.bindAsEventListener(this)); 572 dropdown.appendChild(mnu); 573 return dropdown; 574 }, 575 576 buildDropDownMenu: function(options) 577 { 578 var mnu = document.createElement('ul'); 579 mnu.className = 'editor_dropdown_menu'; 580 mnu.style.display = 'none'; 581 582 // create the first item 583 if(options.title) 584 { 585 var item = document.createElement('li'); 586 item.className = 'editor_dropdown_menu_title'; 587 item.innerHTML = options.title; 588 mnu.appendChild(item); 589 Event.observe(item, 'click', function() 590 { 591 if(mnu.activeItem) 592 { 593 this.restartEditorSelection(); 594 this.insertMyCode(dropdown.insertText, '-'); 595 } 596 this.setDropDownMenuActiveItem(dropdown, 0); 597 }.bindAsEventListener(this)); 598 } 599 600 $H(options.options).each(function(option) 601 { 602 if(options.draw_option) 603 { 604 item = options.draw_option(option) 605 } 606 else 607 { 608 var item = document.createElement('li'); 609 item.innerHTML = option.value; 610 611 var content = document.createElement('span'); 612 item.appendChild(content); 613 item.extra = option.key; 614 } 615 Event.observe(item, 'click', this.dropDownMenuItemClick.bindAsEventListener(this)); 616 Event.observe(item, 'mouseover', function() 617 { 618 item.addClassName('editor_dropdown_menu_item_over'); 619 }); 620 Event.observe(item, 'mouseout', function() 621 { 622 item.removeClassName('editor_dropdown_menu_item_over'); 623 }); 624 mnu.appendChild(item); 625 }, this); 626 return mnu; 627 }, 628 629 toggleDropDownMenu: function(e) 630 { 631 element = Event.element(e); 632 if(!element) 633 return; 634 if(!element.elementType) 635 element = this.getElementToolbarItem(element); 636 637 var mnu = $(element).down('ul'); 638 639 // This menu is already open, close it 640 if(mnu.style.display != 'none') 641 { 642 mnu.style.display = 'none'; 643 element.removeClassName('editor_dropdown_menu_open'); 644 this.removeElementState(element, 'clicked'); 645 this.openDropDownMenu = null; 646 Event.stopObserving(document, 'click', this.hideOpenDropDownMenu.bindAsEventListener(this)); 647 } 648 // Opening this menu 649 else 650 { 651 // If a menu is already open, close it first 652 this.showDropDownMenu(mnu); 653 } 654 this.removeElementState(element, 'clicked'); 655 Event.stop(e); 656 }, 657 658 showDropDownMenu: function(mnu) 659 { 660 this.hideOpenDropDownMenu(); 661 mnu.style.display = ''; 662 element = this.getElementToolbarItem(mnu); 663 element.addClassName('editor_dropdown_menu_open'); 664 this.setElementState(element, 'clicked'); 665 this.openDropDownMenu = mnu; 666 Event.observe(document, 'click', this.hideOpenDropDownMenu.bindAsEventListener(this)); 667 }, 668 669 hideOpenDropDownMenu: function() 670 { 671 if(!this.openDropDownMenu) return; 672 this.openDropDownMenu.style.display = 'none'; 673 this.getElementToolbarItem(this.openDropDownMenu).removeClassName('editor_dropdown_menu_open'); 674 var dropDown = this.getElementToolbarItem(this.openDropDownMenu); 675 this.removeElementState(this.openDropDownMenu.parentNode, 'clicked'); 676 this.removeElementState(element, 'clicked'); 677 this.openDropDownMenu = null; 678 Event.stopObserving(document, 'click', this.hideOpenDropDownMenu.bindAsEventListener(this)); 679 }, 680 681 getElementToolbarItem: function(elem) 682 { 683 var parent = elem; 684 do { 685 if(parent.insertText) return parent; 686 parent = parent.parentNode; 687 } while($(parent)); 688 689 return false; 690 }, 691 692 storeCaret: function() 693 { 694 if(MyBB.browser != 'ie' || !this.trackingCaret) 695 { 696 return; 697 } 698 699 // Internet explorer errors if you try and select an element... so just handle that by try catch 700 try { 701 var range = document.selection.createRange(); 702 var range_all = document.body.createTextRange(); 703 range_all.moveToElementText($(this.textarea)); 704 for(var sel_start = 0; range_all.compareEndPoints('StartToStart', range) < 0; sel_start++) 705 range_all.moveStart('character', 1); 706 707 var range_all = document.body.createTextRange(); 708 range_all.moveToElementText($(this.textarea)); 709 for(var sel_end = 0; range_all.compareEndPoints('StartToEnd', range) < 0; sel_end++) 710 range_all.moveStart('character', 1); 711 712 this.lastCaretS = sel_start; 713 this.lastCaretE = sel_end; 714 } catch(e) { } 715 }, 716 717 restartEditorSelection: function() 718 { 719 if(MyBB.browser != 'ie') 720 { 721 return; 722 } 723 724 var range = $(this.textarea).createTextRange(); 725 range.collapse(true); 726 range.moveStart('character', this.lastCaretS); 727 range.moveEnd('character', this.lastCaretE - this.lastCaretS); 728 range.select(); 729 }, 730 731 addToolbarItem: function(toolbar, options) 732 { 733 if(typeof(toolbar) == 'string') 734 { 735 toolbar = $('editor_toolbar_'+toolbar); 736 } 737 738 if(!$(toolbar)) return; 739 740 // Does this item already exist? 741 if($('editor_item_'+options.name)) return; 742 743 insert_first_class = false; 744 745 // Is this the first item? childnodes = 1 (closing br) or lastchild.previousSibling = sep 746 if(toolbar.childNodes.length == 1 || (toolbar.lastChild.previousSibling && toolbar.lastChild.previousSibling.className.indexOf('toolbar_sep') > -1 || (toolbar.lastChild.previousSibling.className.indexOf('editor_dropdown') > -1 && options.type != 'dropdown'))) 747 { 748 insert_first_class = true; 749 } 750 751 if(options.type == "dropdown") 752 { 753 var dropdown = this.createDropDownMenu(options); 754 if(dropdown) 755 toolbar.insertBefore(dropdown, toolbar.lastChild); 756 757 if(insert_first_class == true) 758 dropdown.className += ' toolbar_dropdown_group_first'; 759 } 760 else if(options.type == 'button') 761 { 762 var button = this.createToolbarButton(options) 763 toolbar.insertBefore(button, toolbar.lastChild); 764 765 if(insert_first_class == true) 766 button.className += ' toolbar_button_group_first'; 767 } 768 else if(options.type == 'separator') 769 { 770 if(toolbar.lastChild.previousSibling && !$(toolbar.lastChild.previousSibling).hasClassName('toolbar_dropdown')) 771 { 772 toolbar.lastChild.previousSibling.className += ' toolbar_button_group_last'; 773 } 774 var separator = document.createElement("span"); 775 separator.elementType = options.type; 776 separator.className = "toolbar_sep"; 777 toolbar.insertBefore(separator, toolbar.lastChild); 778 } 779 }, 780 781 createToolbarButton: function(options) 782 { 783 var button = document.createElement('span'); 784 button.elementType = options.type; 785 button.id = 'editor_item_'+options.name; 786 if(typeof(options.title) != 'undefined') 787 { 788 button.title = options.title; 789 } 790 button.className = 'toolbar_button toolbar_normal toolbar_button_'+options.name; 791 792 if(typeof(options.style) == 'object') 793 { 794 $H(options.style).each(function(item) { 795 eval('button.style.'+item.key+' = "'+item.value+'";'); 796 }); 797 } 798 button.insertText = options.insert; 799 button.insertExtra = ''; 800 if(typeof(options.extra) != 'undefined') 801 button.insertExtra = options.extra; 802 803 if(typeof(options.sprite) != 'undefined') 804 { 805 var img = document.createElement('span'); 806 img.className = 'toolbar_sprite toolbar_sprite_'+options.sprite; 807 } 808 else 809 { 810 var img = document.createElement('img'); 811 img.src = this.themePath + "/images/" + options.image; 812 } 813 button.appendChild(img); 814 815 if(options.dropdown) 816 { 817 if(options.color_select == true) 818 { 819 var sel = document.createElement('em'); 820 sel.className = 'editor_button_color_selected'; 821 button.appendChild(sel); 822 } 823 // create the arrow 824 var arrow = document.createElement('u'); 825 arrow.className = 'toolbar_button_arrow'; 826 button.appendChild(arrow); 827 button.className += ' toolbar_button_with_arrow'; 828 } 829 830 var end = document.createElement('strong'); 831 button.appendChild(end); 832 833 // Create the actual drop down menu 834 if(options.dropdown) 835 { 836 // create the menu item container 837 var mnu = this.buildDropDownMenu(options); 838 839 Event.observe(arrow, 'click', this.toggleDropDownMenu.bindAsEventListener(this)); 840 Event.observe(button, 'click', this.toggleDropDownMenu.bindAsEventListener(this)); 841 Event.observe(arrow, 'mouseover', function(e) 842 { 843 elem = Event.element(e); 844 if(!elem) return; 845 elem.parentNode.addClassName('toolbar_button_over_arrow'); 846 }); 847 Event.observe(arrow, 'mouseout', function(e) 848 { 849 elem = Event.element(e); 850 if(!elem) return; 851 elem.parentNode.removeClassName('toolbar_button_over_arrow'); 852 }); 853 button.appendChild(mnu); 854 button.dropdown = true; 855 button.menu = mnu; 856 } 857 858 // Does this button have enabled/disabled states? 859 if(options.disabled_img || options.disabled_sprite) 860 { 861 button.disable = function() 862 { 863 if(button.disabled == true) return; 864 865 if(options.disabled_sprite) 866 { 867 img.removeClassName('toolbar_sprite_'+options.sprite); 868 img.addClassName('toolbar_sprite_disabled_'+options.disabled_sprite); 869 } 870 else 871 img.src = this.themePath + '/images/' + options.disabled_img; 872 873 button.disabled = true; 874 }; 875 876 button.enable = function() 877 { 878 if(!button.disabled) return; 879 880 if(options.disabled_sprite) 881 { 882 img.removeClassName('toolbar_sprite_disabled_'+options.disabled_sprite); 883 img.addClassName('toolbar_sprite_'+options.sprite); 884 } 885 else 886 img.src = this.themePath + '/images/' + options.image; 887 888 button.enabled = true; 889 }; 890 891 if(options.disabled && options.disabled == true) 892 { 893 button.disable(); 894 button.disabled = true; 895 } 896 else 897 button.disabled = false; 898 } 899 900 Event.observe(button, "mouseover", this.toolbarItemHover.bindAsEventListener(this)); 901 Event.observe(button, "mouseout", this.toolbarItemOut.bindAsEventListener(this)); 902 903 if(!options.dropdown) 904 { 905 // Dropdown event listener is above... 906 Event.observe(button, "click", this.toolbarItemClick.bindAsEventListener(this)); 907 } 908 return button; 909 }, 910 911 updateOldArea: function(e) 912 { 913 this.oldTextarea.value = $(this.textarea).value; 914 }, 915 916 toolbarItemOut: function(e) 917 { 918 this.storeCaret(); 919 element = Event.element(e); 920 921 if(!element) 922 return false; 923 924 if(!element.elementType) 925 element = this.getElementToolbarItem(element); 926 927 if(element.disabled) 928 return; 929 930 if(typeof(element.insertText) != 'undefined') 931 { 932 if(element.insertExtra) 933 { 934 insertCode = element.insertText+"_"+element.insertExtra; 935 } 936 else 937 { 938 insertCode = element.insertText; 939 } 940 941 if(this.openTags.indexOf(insertCode) != -1 || element.className.indexOf('editor_dropdown_menu_open') > -1) 942 { 943 this.setElementState(element, 'clicked'); 944 } 945 } 946 this.removeElementState(element, 'hover'); 947 }, 948 949 toolbarItemHover: function(e) 950 { 951 this.storeCaret(); 952 element = Event.element(e); 953 if(!element) 954 return false; 955 956 if(!element.elementType) 957 element = this.getElementToolbarItem(element); 958 959 if(element.disabled) 960 return; 961 962 if(!element.className || element.className.indexOf('toolbar_clicked') == -1) 963 this.setElementState(element, 'hover'); 964 }, 965 966 toolbarItemClick: function(e) 967 { 968 element = Event.element(e); 969 970 if(!element) 971 return false; 972 973 if(!element.elementType) 974 element = this.getElementToolbarItem(element); 975 976 if(element.disabled) 977 return; 978 979 if(element.dropdown && element.menu) 980 { 981 if(typeof(element.menu.activeItem) != "undefined") 982 { 983 Event.stop(e); 984 if(!element.menu.lastItemValue) 985 { 986 this.showDropDownMenu(element.menu); 987 } 988 else 989 { 990 this.insertMyCode(element.insertText, element.menu.lastItemValue); 991 } 992 993 return; 994 } 995 } 996 997 if(element.id == "editor_item_close_tags") 998 { 999 this.closeTags(); 1000 } 1001 else 1002 { 1003 if(typeof(element.insertExtra) != 'undefined') 1004 this.insertMyCode(element.insertText, element.insertExtra); 1005 else 1006 this.insertMyCode(element.insertText); 1007 } 1008 }, 1009 1010 insertList: function(type) 1011 { 1012 list = ""; 1013 1014 do 1015 { 1016 listItem = prompt(this.options.lang.enter_list_item, ""); 1017 1018 if(listItem != "" && listItem != null) 1019 { 1020 list = list+"[*]"+listItem+"\n"; 1021 } 1022 } 1023 while(listItem != "" && listItem != null); 1024 1025 if(list == "") 1026 { 1027 return false; 1028 } 1029 1030 if(type) 1031 { 1032 list = "[list="+type+"]\n"+list; 1033 } 1034 else 1035 { 1036 list = "[list]\n"+list; 1037 } 1038 1039 list = list+"[/list]\n"; 1040 this.performInsert(list, "", true, false); 1041 }, 1042 1043 insertURL: function() 1044 { 1045 selectedText = this.getSelectedText($(this.textarea)); 1046 url = prompt(this.options.lang.enter_url, "http://"); 1047 1048 if(url) 1049 { 1050 if(!selectedText) 1051 { 1052 title = prompt(this.options.lang.enter_url_title, ""); 1053 } 1054 else 1055 { 1056 title = selectedText; 1057 } 1058 1059 if(title) 1060 { 1061 this.performInsert("[url="+url+"]"+title+"[/url]", "", true, false); 1062 } 1063 else 1064 { 1065 this.performInsert("[url]"+url+"[/url]", "", true, false); 1066 } 1067 } 1068 }, 1069 1070 insertEmail: function() 1071 { 1072 selectedText = this.getSelectedText($(this.textarea)); 1073 email = prompt(this.options.lang.enter_email, ""); 1074 1075 if(email) 1076 { 1077 if(!selectedText) 1078 { 1079 title = prompt(this.options.lang.enter_email_title, ""); 1080 } 1081 else 1082 { 1083 title = selectedText; 1084 } 1085 1086 if(title) 1087 { 1088 this.performInsert("[email="+email+"]"+title+"[/email]", "", true, false); 1089 } 1090 else 1091 { 1092 this.performInsert("[email]"+email+"[/email]", "", true, false); 1093 } 1094 } 1095 }, 1096 1097 insertIMG: function() 1098 { 1099 image = prompt(this.options.lang.enter_image, "http://"); 1100 1101 if(image) 1102 { 1103 this.performInsert("[img]"+image+"[/img]", "", true); 1104 } 1105 }, 1106 1107 insertVideo: function(type) 1108 { 1109 selectedText = this.getSelectedText($(this.textarea)); 1110 1111 if(!selectedText) 1112 { 1113 url = prompt(this.options.lang.enter_video_url, "http://"); 1114 } 1115 else 1116 { 1117 url = selectedText; 1118 } 1119 1120 if(url) 1121 { 1122 this.performInsert("[video="+type+"]"+url+"[/video]", "", true, false); 1123 } 1124 this.setDropDownMenuActiveItem($('editor_item_video'), 0); 1125 }, 1126 1127 insertMyCode: function(code, extra) 1128 { 1129 this.restartEditorSelection(); 1130 1131 switch(code) 1132 { 1133 case "list": 1134 this.insertList(extra); 1135 break; 1136 case "url": 1137 this.insertURL(); 1138 break; 1139 case "image": 1140 this.insertIMG(); 1141 break; 1142 case "email": 1143 this.insertEmail(); 1144 break; 1145 case "video": 1146 this.insertVideo(extra); 1147 break; 1148 default: 1149 var already_open = false; 1150 var no_insert = false; 1151 if(extra) 1152 { 1153 var full_tag = code+"_"+extra; 1154 } 1155 else 1156 { 1157 var full_tag = code; 1158 } 1159 1160 var newTags = new Array(); 1161 this.openTags.each(function(tag) 1162 { 1163 exploded_tag = tag.split("_"); 1164 if(exploded_tag[0] == code) 1165 { 1166 already_open = true; 1167 this.performInsert("[/"+exploded_tag[0]+"]", "", false); 1168 var elem = $('editor_item_'+exploded_tag[0]); 1169 1170 if(elem) 1171 { 1172 this.removeElementState(elem, 'clicked'); 1173 } 1174 1175 if(elem && (elem.elementType == "dropdown" || elem.dropdown || elem.menu)) 1176 { 1177 this.setDropDownMenuActiveItem(elem, 0); 1178 } 1179 1180 if(tag == full_tag) 1181 { 1182 no_insert = true; 1183 } 1184 } 1185 else 1186 { 1187 newTags[newTags.length] = tag; 1188 } 1189 }.bind(this)); 1190 1191 this.openTags = newTags; 1192 var do_insert = false; 1193 1194 if(extra != "" && extra != "-" && no_insert == false) 1195 { 1196 start_tag = "["+code+"="+extra+"]"; 1197 end_tag = "[/"+code+"]"; 1198 do_insert = true; 1199 } 1200 else if(!extra && already_open == false) 1201 { 1202 start_tag = "["+code+"]"; 1203 end_tag = "[/"+code+"]"; 1204 do_insert = true; 1205 } 1206 1207 if(do_insert == true) 1208 { 1209 if(!this.performInsert(start_tag, end_tag, true)) 1210 { 1211 this.openTags.push(full_tag); 1212 $('editor_item_close_tags').style.visibility = ''; 1213 } 1214 else if($('editor_item_'+full_tag)) 1215 { 1216 this.removeElementState($('editor_item_'+full_tag), 'clicked'); 1217 } 1218 else if($('editor_item_'+code)) 1219 { 1220 elem = $('editor_item_'+code); 1221 if(elem.type == "dropdown" || elem.dropdown || elem.menu) 1222 this.setDropDownMenuActiveItem($('editor_item_'+start_tag), 0); 1223 } 1224 } 1225 } 1226 1227 if(this.openTags.length == 0) 1228 { 1229 $('editor_item_close_tags').style.visibility = 'hidden'; 1230 } 1231 }, 1232 1233 getSelectedText: function(element) 1234 { 1235 element.focus(); 1236 if(document.selection) 1237 { 1238 var selection = document.selection; 1239 var range = selection.createRange(); 1240 1241 if((selection.type == "Text" || selection.type == "None") && range != null) 1242 { 1243 return range.text; 1244 } 1245 } 1246 else if(element.selectionEnd) 1247 { 1248 var select_start = element.selectionStart; 1249 var select_end = element.selectionEnd; 1250 if(select_end <= 0) 1251 { 1252 select_end = element.textLength; 1253 } 1254 var start = element.value.substring(0, select_start); 1255 var middle = element.value.substring(select_start, select_end); 1256 return middle; 1257 } 1258 }, 1259 1260 performInsert: function(open_tag, close_tag, is_single, ignore_selection) 1261 { 1262 var is_closed = true; 1263 1264 if(!ignore_selection) 1265 { 1266 var ignore_selection = false; 1267 } 1268 1269 if(!close_tag) 1270 { 1271 var close_tag = ""; 1272 } 1273 var textarea = $(this.textarea); 1274 textarea.focus(); 1275 1276 if(document.selection) 1277 { 1278 var selection = document.selection; 1279 var range = selection.createRange(); 1280 1281 if(ignore_selection != false) 1282 { 1283 selection.collapse; 1284 } 1285 1286 if((selection.type == "Text" || selection.type == "None") && range != null && ignore_selection != true) 1287 { 1288 if(close_tag != "" && range.text.length > 0) 1289 { 1290 var keep_selected = true; 1291 range.text = open_tag+range.text+close_tag; 1292 } 1293 else 1294 { 1295 var keep_selected = false; 1296 1297 if(is_single) 1298 { 1299 is_closed = false; 1300 } 1301 range.text = open_tag; 1302 } 1303 range.select(); 1304 } 1305 else 1306 { 1307 textarea.value += open_tag; 1308 } 1309 } 1310 else if(typeof(textarea.selectionEnd) != 'undefined') 1311 { 1312 var select_start = textarea.selectionStart; 1313 var select_end = textarea.selectionEnd; 1314 var scroll_top = textarea.scrollTop; 1315 1316 var start = textarea.value.substring(0, select_start); 1317 var middle = textarea.value.substring(select_start, select_end); 1318 var end = textarea.value.substring(select_end, textarea.textLength); 1319 1320 if(select_end - select_start > 0 && ignore_selection != true && close_tag != "") 1321 { 1322 var keep_selected = true; 1323 middle = open_tag+middle+close_tag; 1324 } 1325 else 1326 { 1327 var keep_selected = false; 1328 if(is_single) 1329 { 1330 is_closed = false; 1331 } 1332 middle = open_tag; 1333 } 1334 1335 textarea.value = start+middle+end; 1336 1337 if(keep_selected == true && ignore_selection != true) 1338 { 1339 textarea.selectionStart = select_start; 1340 textarea.selectionEnd = select_start + middle.length; 1341 } 1342 else if(ignore_selection != true) 1343 { 1344 textarea.selectionStart = select_start + middle.length; 1345 textarea.selectionEnd = textarea.selectionStart; 1346 } 1347 textarea.scrollTop = scroll_top; 1348 } 1349 else 1350 { 1351 textarea.value += open_tag; 1352 1353 if(is_single) 1354 { 1355 is_closed = false; 1356 } 1357 } 1358 this.updateOldArea(); 1359 textarea.focus(); 1360 this.trackingCaret = true; 1361 this.storeCaret(); 1362 this.trackingCaret = false; 1363 return is_closed; 1364 }, 1365 1366 closeTags: function() 1367 { 1368 if(this.openTags[0]) 1369 { 1370 while(this.openTags[0]) 1371 { 1372 tag = this.openTags.pop(); 1373 exploded_tag = tag.split("_"); 1374 this.performInsert("[/"+exploded_tag[0]+"]", "", false); 1375 1376 if($('editor_item_'+exploded_tag[0])) 1377 { 1378 tag = $('editor_item_'+exploded_tag[0]); 1379 } 1380 else 1381 { 1382 tag = $('editor_item_'+tag); 1383 } 1384 if(tag) 1385 { 1386 if(tag.elementType == "dropdown" || tag.dropdown || tag.menu) 1387 { 1388 this.setDropDownMenuActiveItem(tag, 0); 1389 } 1390 else 1391 { 1392 this.removeElementState(tag, 'clicked'); 1393 } 1394 } 1395 } 1396 } 1397 $(this.textarea).focus(); 1398 $('editor_item_close_tags').style.visibility = 'hidden'; 1399 this.openTags = new Array(); 1400 }, 1401 1402 bindSmilieInserter: function(id) 1403 { 1404 if(!$(id)) 1405 { 1406 return false; 1407 } 1408 1409 var smilies = $(id).select('.smilie'); 1410 1411 if(smilies.length > 0) 1412 { 1413 smilies.each(function(smilie) 1414 { 1415 smilie.onclick = this.insertSmilie.bindAsEventListener(this); 1416 smilie.style.cursor = "pointer"; 1417 }.bind(this)); 1418 } 1419 }, 1420 1421 openGetMoreSmilies: function(editor) 1422 { 1423 MyBB.popupWindow('misc.php?action=smilies&popup=true&editor='+editor, 'sminsert', 240, 280); 1424 }, 1425 1426 insertSmilie: function(e) 1427 { 1428 element = Event.element(e); 1429 1430 if(!element || !element.alt) 1431 { 1432 return false; 1433 } 1434 this.performInsert(element.alt, "", true, false); 1435 }, 1436 1437 insertAttachment: function(aid) 1438 { 1439 this.performInsert("[attachment="+aid+"]", "", true, false); 1440 } 1441 };
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Oct 8 19:19:50 2013 | Cross-referenced by PHPXref 0.7.1 |