[ Index ]

PHP Cross Reference of MyBB

title

Body

[close]

/jscripts/ -> editor.js (source)

   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 = '&nbsp;';
 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  };


Generated: Tue Oct 8 19:19:50 2013 Cross-referenced by PHPXref 0.7.1