[ Index ]

PHP Cross Reference of Unnamed Project

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 = 12;
 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.itemType = 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.itemType)
 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(element, 'clicked');
 676          this.openDropDownMenu = null;
 677          Event.stopObserving(document, 'click', this.hideOpenDropDownMenu.bindAsEventListener(this));
 678      },
 679  
 680      getElementToolbarItem: function(elem)
 681      {
 682          var parent = elem;
 683          do {
 684              if(parent.insertText) return parent;
 685              parent = parent.parentNode;
 686          } while($(parent));
 687  
 688          return false;
 689      },
 690  
 691      storeCaret: function()
 692      {
 693          if(MyBB.browser != 'ie' || !this.trackingCaret)
 694          {
 695              return;
 696          }
 697          
 698          // Internet explorer errors if you try and select an element... so just handle that by try catch
 699          try {
 700              var range = document.selection.createRange();
 701              var range_all = document.body.createTextRange();
 702              range_all.moveToElementText($(this.textarea));
 703              for(var sel_start = 0; range_all.compareEndPoints('StartToStart', range) < 0; sel_start++)
 704                  range_all.moveStart('character', 1);
 705  
 706              var range_all = document.body.createTextRange();
 707              range_all.moveToElementText($(this.textarea));
 708              for(var sel_end = 0; range_all.compareEndPoints('StartToEnd', range) < 0; sel_end++)
 709                  range_all.moveStart('character', 1);
 710  
 711              this.lastCaretS = sel_start;
 712              this.lastCaretE = sel_end;
 713          } catch(e) { }
 714      },
 715  
 716      restartEditorSelection: function()
 717      {
 718          if(MyBB.browser != 'ie')
 719          {
 720              return;
 721          }
 722  
 723          var range = $(this.textarea).createTextRange();
 724          range.collapse(true);
 725          range.moveStart('character', this.lastCaretS);
 726          range.moveEnd('character', this.lastCaretE - this.lastCaretS);
 727          range.select();
 728      },
 729  
 730      addToolbarItem: function(toolbar, options)
 731      {
 732          if(typeof(toolbar) == 'string')
 733          {
 734              toolbar = $('editor_toolbar_'+toolbar);
 735          }
 736  
 737          if(!$(toolbar)) return;
 738  
 739          // Does this item already exist?
 740          if($('editor_item_'+options.name)) return;
 741  
 742          insert_first_class = false;
 743  
 744          // Is this the first item? childnodes = 1 (closing br) or lastchild.previousSibling = sep
 745          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')))
 746          {
 747              insert_first_class = true;
 748          }
 749  
 750          if(options.type == "dropdown")
 751          {
 752              var dropdown = this.createDropDownMenu(options);
 753              if(dropdown)
 754                  toolbar.insertBefore(dropdown, toolbar.lastChild);
 755  
 756              if(insert_first_class == true)
 757                  dropdown.className += ' toolbar_dropdown_group_first';
 758          }
 759          else if(options.type == 'button')
 760          {
 761              var button = this.createToolbarButton(options)
 762              toolbar.insertBefore(button, toolbar.lastChild);
 763  
 764              if(insert_first_class == true)
 765                  button.className += ' toolbar_button_group_first';
 766          }
 767          else if(options.type == 'separator')
 768          {
 769              if(toolbar.lastChild.previousSibling && !$(toolbar.lastChild.previousSibling).hasClassName('toolbar_dropdown'))
 770              {
 771                  toolbar.lastChild.previousSibling.className += ' toolbar_button_group_last';
 772              }
 773              var separator = document.createElement("span");
 774              separator.itemType = options.type;
 775              separator.className = "toolbar_sep";
 776              toolbar.insertBefore(separator, toolbar.lastChild);
 777          }
 778      },
 779  
 780      createToolbarButton: function(options)
 781      {
 782          var button = document.createElement('span');
 783          button.itemType = options.type;
 784          button.id = 'editor_item_'+options.name;
 785          if(typeof(options.title) != 'undefined')
 786          {
 787              button.title = options.title;
 788          }
 789          button.className = 'toolbar_button toolbar_normal toolbar_button_'+options.name;
 790  
 791          if(typeof(options.style) == 'object')
 792          {
 793              $H(options.style).each(function(item) {
 794                  eval('button.style.'+item.key+' = "'+item.value+'";');
 795              });
 796          }
 797          button.insertText = options.insert;
 798          button.insertExtra = '';
 799          if(typeof(options.extra) != 'undefined')
 800              button.insertExtra = options.extra;
 801          
 802          if(typeof(options.sprite) != 'undefined')
 803          {
 804              var img = document.createElement('span');
 805              img.className = 'toolbar_sprite toolbar_sprite_'+options.sprite;
 806          }
 807          else
 808          {
 809              var img = document.createElement('img');
 810              img.src = this.themePath + "/images/" + options.image;
 811          }
 812          button.appendChild(img);
 813  
 814          if(options.dropdown)
 815          {
 816              if(options.color_select == true)
 817              {
 818                  var sel = document.createElement('em');
 819                  sel.className = 'editor_button_color_selected';
 820                  button.appendChild(sel);
 821              }
 822              // create the arrow
 823              var arrow = document.createElement('u');
 824              arrow.className = 'toolbar_button_arrow';
 825              button.appendChild(arrow);
 826              button.className += ' toolbar_button_with_arrow';
 827          }
 828  
 829          var end = document.createElement('strong');
 830          button.appendChild(end);
 831  
 832          // Create the actual drop down menu
 833          if(options.dropdown)
 834          {
 835              // create the menu item container
 836              var mnu = this.buildDropDownMenu(options);
 837  
 838              Event.observe(arrow, 'click', this.toggleDropDownMenu.bindAsEventListener(this));
 839              Event.observe(button, 'click', this.toggleDropDownMenu.bindAsEventListener(this));
 840              Event.observe(arrow, 'mouseover', function(e)
 841              {
 842                  elem = Event.element(e);
 843                  if(!elem) return;
 844                  elem.parentNode.addClassName('toolbar_button_over_arrow');
 845              });
 846              Event.observe(arrow, 'mouseout', function(e)
 847              {
 848                  elem = Event.element(e);
 849                  if(!elem) return;
 850                  elem.parentNode.removeClassName('toolbar_button_over_arrow');
 851              });
 852              button.appendChild(mnu);
 853              button.dropdown = true;
 854              button.menu = mnu;
 855          }
 856  
 857          // Does this button have enabled/disabled states?
 858          if(options.disabled_img || options.disabled_sprite)
 859          {
 860              button.disable = function()
 861              {
 862                  if(button.disabled == true) return;
 863  
 864                  if(options.disabled_sprite)
 865                  {
 866                      img.removeClassName('toolbar_sprite_'+options.sprite);
 867                      img.addClassName('toolbar_sprite_disabled_'+options.disabled_sprite);
 868                  }
 869                  else
 870                      img.src = this.themePath + '/images/' + options.disabled_img;
 871  
 872                  button.disabled = true;
 873              };
 874  
 875              button.enable = function()
 876              {
 877                  if(!button.disabled) return;
 878  
 879                  if(options.disabled_sprite)
 880                  {
 881                      img.removeClassName('toolbar_sprite_disabled_'+options.disabled_sprite);
 882                      img.addClassName('toolbar_sprite_'+options.sprite);
 883                  }
 884                  else
 885                      img.src = this.themePath + '/images/' + options.image;
 886  
 887                  button.enabled = true;
 888              };
 889  
 890              if(options.disabled && options.disabled == true)
 891              {
 892                  button.disable();
 893                  button.disabled = true;
 894              }
 895              else
 896                  button.disabled = false;
 897          }
 898  
 899          Event.observe(button, "mouseover", this.toolbarItemHover.bindAsEventListener(this));
 900          Event.observe(button, "mouseout", this.toolbarItemOut.bindAsEventListener(this));
 901  
 902          if(!options.dropdown)
 903          {
 904              // Dropdown event listener is above...
 905              Event.observe(button, "click", this.toolbarItemClick.bindAsEventListener(this));
 906          }
 907          return button;
 908      },
 909  
 910      updateOldArea: function(e)
 911      {
 912          this.oldTextarea.value = $(this.textarea).value;
 913      },
 914  
 915      toolbarItemOut: function(e)
 916      {
 917          this.storeCaret();
 918          element = Event.element(e);
 919  
 920          if(!element)
 921              return false;
 922  
 923          if(!element.itemType)
 924              element =     this.getElementToolbarItem(element);
 925  
 926          if(element.disabled)
 927              return;
 928  
 929          if(typeof(element.insertText) != 'undefined')
 930          {
 931              if(element.insertExtra)
 932              {
 933                  insertCode = element.insertText+"_"+element.insertExtra;
 934              }
 935              else
 936              {
 937                  insertCode = element.insertText;
 938              }
 939  
 940              if(this.openTags.indexOf(insertCode) != -1 || element.className.indexOf('editor_dropdown_menu_open') > -1)
 941              {
 942                  this.setElementState(element, 'clicked');
 943              }
 944          }
 945          this.removeElementState(element, 'hover');
 946      },
 947  
 948      toolbarItemHover: function(e)
 949      {
 950          this.storeCaret();
 951          element = Event.element(e);
 952          if(!element)
 953              return false;
 954  
 955          if(!element.itemType)
 956              element = this.getElementToolbarItem(element);
 957  
 958          if(element.disabled)
 959              return;
 960  
 961          if(!element.className || element.className.indexOf('toolbar_clicked') == -1)
 962              this.setElementState(element, 'hover');
 963      },
 964  
 965      toolbarItemClick: function(e)
 966      {
 967          element = Event.element(e);
 968  
 969          if(!element)
 970              return false;
 971  
 972          if(!element.itemType)
 973              element = this.getElementToolbarItem(element);
 974  
 975          if(element.disabled)
 976              return;
 977  
 978          if(element.dropdown && element.menu)
 979          {
 980              if(typeof(element.menu.activeItem) != "undefined")
 981              {
 982                  Event.stop(e);
 983                  if(!element.menu.lastItemValue)
 984                  {
 985                      this.showDropDownMenu(element.menu);
 986                  }
 987                  else
 988                  {
 989                      this.insertMyCode(element.insertText, element.menu.lastItemValue);
 990                  }
 991  
 992                  return;
 993              }
 994          }
 995  
 996          if(element.id == "editor_item_close_tags")
 997          {
 998              this.closeTags();
 999          }
1000          else
1001          {
1002              if(typeof(element.insertExtra) != 'undefined')
1003                  this.insertMyCode(element.insertText, element.insertExtra);
1004              else
1005                  this.insertMyCode(element.insertText);
1006          }
1007      },
1008  
1009      insertList: function(type)
1010      {
1011          list = "";
1012  
1013          do
1014          {
1015              listItem = prompt(this.options.lang.enter_list_item, "");
1016  
1017              if(listItem != "" && listItem != null)
1018              {
1019                  list = list+"[*]"+listItem+"\n";
1020              }
1021          }
1022          while(listItem != "" && listItem != null);
1023  
1024          if(list == "")
1025          {
1026              return false;
1027          }
1028  
1029          if(type)
1030          {
1031              list = "[list="+type+"]\n"+list;
1032          }
1033          else
1034          {
1035              list = "[list]\n"+list;
1036          }
1037  
1038          list = list+"[/list]\n";
1039          this.performInsert(list, "", true, false);
1040      },
1041  
1042      insertURL: function()
1043      {
1044          selectedText = this.getSelectedText($(this.textarea));
1045          url = prompt(this.options.lang.enter_url, "http://");
1046  
1047          if(url)
1048          {
1049              if(!selectedText)
1050              {
1051                  title = prompt(this.options.lang.enter_url_title, "");
1052              }
1053              else
1054              {
1055                  title = selectedText;
1056              }
1057  
1058              if(title)
1059              {
1060                  this.performInsert("[url="+url+"]"+title+"[/url]", "", true, false);
1061              }
1062              else
1063              {
1064                  this.performInsert("[url]"+url+"[/url]", "", true, false);
1065              }
1066          }
1067      },
1068  
1069      insertEmail: function()
1070      {
1071          selectedText = this.getSelectedText($(this.textarea));
1072          email = prompt(this.options.lang.enter_email, "");
1073  
1074          if(email)
1075          {
1076              if(!selectedText)
1077              {
1078                  title = prompt(this.options.lang.enter_email_title, "");
1079              }
1080              else
1081              {
1082                  title = selectedText;
1083              }
1084  
1085              if(title)
1086              {
1087                  this.performInsert("[email="+email+"]"+title+"[/email]", "", true, false);
1088              }
1089              else
1090              {
1091                  this.performInsert("[email]"+email+"[/email]", "", true, false);
1092              }
1093          }
1094      },
1095  
1096      insertIMG: function()
1097      {
1098          image = prompt(this.options.lang.enter_image, "http://");
1099  
1100          if(image)
1101          {
1102              this.performInsert("[img]"+image+"[/img]", "", true);
1103          }
1104      },
1105      
1106      insertVideo: function(type)
1107      {
1108          selectedText = this.getSelectedText($(this.textarea));
1109  
1110          if(!selectedText)
1111          {
1112              url = prompt(this.options.lang.enter_video_url, "http://");
1113          }
1114          else
1115          {
1116              url = selectedText;
1117          }
1118  
1119          if(url)
1120          {
1121              this.performInsert("[video="+type+"]"+url+"[/video]", "", true, false);
1122          }
1123          this.setDropDownMenuActiveItem($('editor_item_video'), 0);
1124      },
1125  
1126      insertMyCode: function(code, extra)
1127      {
1128          this.restartEditorSelection();
1129  
1130          switch(code)
1131          {
1132              case "list":
1133                  this.insertList(extra);
1134                  break;
1135              case "url":
1136                  this.insertURL();
1137                  break;
1138              case "image":
1139                  this.insertIMG();
1140                  break;
1141              case "email":
1142                  this.insertEmail();
1143                  break;
1144              case "video":
1145                  this.insertVideo(extra);
1146                  break;
1147              default:
1148                  var already_open = false;
1149                  var no_insert = false;
1150                  if(extra)
1151                  {
1152                      var full_tag = code+"_"+extra;
1153                  }
1154                  else
1155                  {
1156                      var full_tag = code;
1157                  }
1158  
1159                  var newTags = new Array();
1160                  this.openTags.each(function(tag)
1161                  {
1162                      exploded_tag = tag.split("_");
1163                      if(exploded_tag[0] == code)
1164                      {
1165                          already_open = true;
1166                          this.performInsert("[/"+exploded_tag[0]+"]", "", false);
1167                          var elem = $('editor_item_'+exploded_tag[0]);
1168  
1169                          if(elem)
1170                          {
1171                              this.removeElementState(elem, 'clicked');
1172                          }
1173  
1174                          if(elem && (elem.itemType == "dropdown" || elem.dropdown || elem.menu))
1175                          {
1176                              this.setDropDownMenuActiveItem(elem, 0);
1177                          }
1178  
1179                          if(tag == full_tag)
1180                          {
1181                              no_insert = true;
1182                          }
1183                      }
1184                      else
1185                      {
1186                          newTags[newTags.length] = tag;
1187                      }
1188                  }.bind(this));
1189  
1190                  this.openTags = newTags;
1191                  var do_insert = false;
1192  
1193                  if(extra != "" && extra != "-" && no_insert == false)
1194                  {
1195                      start_tag = "["+code+"="+extra+"]";
1196                      end_tag = "[/"+code+"]";
1197                      do_insert = true;
1198                  }
1199                  else if(!extra && already_open == false)
1200                  {
1201                      start_tag = "["+code+"]";
1202                      end_tag = "[/"+code+"]";
1203                      do_insert = true;
1204                  }
1205  
1206                  if(do_insert == true)
1207                  {
1208                      if(!this.performInsert(start_tag, end_tag, true))
1209                      {
1210                          this.openTags.push(full_tag);
1211                          $('editor_item_close_tags').style.visibility = '';
1212                      }
1213                      else if($('editor_item_'+full_tag))
1214                      {
1215                          this.removeElementState($('editor_item_'+full_tag), 'clicked');
1216                      }
1217                      else if($('editor_item_'+code))
1218                      {
1219                          elem = $('editor_item_'+code);
1220                          if(elem.type == "dropdown" || elem.dropdown || elem.menu)
1221                              this.setDropDownMenuActiveItem($('editor_item_'+start_tag), 0);
1222                      }
1223                  }
1224          }
1225  
1226          if(this.openTags.length == 0)
1227          {
1228              $('editor_item_close_tags').style.visibility = 'hidden';
1229          }
1230      },
1231  
1232      getSelectedText: function(element)
1233      {
1234          element.focus();
1235          if(document.selection)
1236          {
1237              var selection = document.selection;
1238              var range = selection.createRange();
1239  
1240              if((selection.type == "Text" || selection.type == "None") && range != null)
1241              {
1242                  return range.text;
1243              }
1244          }
1245          else if(element.selectionEnd)
1246          {
1247              var select_start = element.selectionStart;
1248              var select_end = element.selectionEnd;
1249              if(select_end <= 0)
1250              {
1251                  select_end = element.textLength;
1252              }
1253              var start = element.value.substring(0, select_start);
1254              var middle = element.value.substring(select_start, select_end);
1255              return middle;
1256          }
1257      },
1258  
1259      performInsert: function(open_tag, close_tag, is_single, ignore_selection)
1260      {
1261          var is_closed = true;
1262  
1263          if(!ignore_selection)
1264          {
1265              var ignore_selection = false;
1266          }
1267  
1268          if(!close_tag)
1269          {
1270              var close_tag = "";
1271          }
1272          var textarea = $(this.textarea);
1273          textarea.focus();
1274  
1275          if(document.selection)
1276          {
1277              var selection = document.selection;
1278              var range = selection.createRange();
1279  
1280              if(ignore_selection != false)
1281              {
1282                  selection.collapse;
1283              }
1284  
1285              if((selection.type == "Text" || selection.type == "None") && range != null && ignore_selection != true)
1286              {
1287                  if(close_tag != "" && range.text.length > 0)
1288                  {
1289                      var keep_selected = true;
1290                      range.text = open_tag+range.text+close_tag;
1291                  }
1292                  else
1293                  {
1294                      var keep_selected = false;
1295  
1296                      if(is_single)
1297                      {
1298                          is_closed = false;
1299                      }
1300                      range.text = open_tag;
1301                  }
1302                  range.select();
1303              }
1304              else
1305              {
1306                  textarea.value += open_tag;
1307              }
1308          }
1309          else if(typeof(textarea.selectionEnd) != 'undefined')
1310          {
1311              var select_start = textarea.selectionStart;
1312              var select_end = textarea.selectionEnd;
1313              var scroll_top = textarea.scrollTop;
1314  
1315              var start = textarea.value.substring(0, select_start);
1316              var middle = textarea.value.substring(select_start, select_end);
1317              var end = textarea.value.substring(select_end, textarea.textLength);
1318  
1319              if(select_end - select_start > 0 && ignore_selection != true && close_tag != "")
1320              {
1321                  var keep_selected = true;
1322                  middle = open_tag+middle+close_tag;
1323              }
1324              else
1325              {
1326                  var keep_selected = false;
1327                  if(is_single)
1328                  {
1329                      is_closed = false;
1330                  }
1331                  middle = open_tag;
1332              }
1333  
1334              textarea.value = start+middle+end;
1335  
1336              if(keep_selected == true && ignore_selection != true)
1337              {
1338                  textarea.selectionStart = select_start;
1339                  textarea.selectionEnd = select_start + middle.length;
1340              }
1341              else if(ignore_selection != true)
1342              {
1343                  textarea.selectionStart = select_start + middle.length;
1344                  textarea.selectionEnd = textarea.selectionStart;
1345              }
1346              textarea.scrollTop = scroll_top;
1347          }
1348          else
1349          {
1350              textarea.value += open_tag;
1351  
1352              if(is_single)
1353              {
1354                  is_closed = false;
1355              }
1356          }
1357          this.updateOldArea();
1358          textarea.focus();
1359          this.trackingCaret = true;
1360          this.storeCaret();
1361          this.trackingCaret = false;        
1362          return is_closed;
1363      },
1364  
1365      closeTags: function()
1366      {
1367          if(this.openTags[0])
1368          {
1369              while(this.openTags[0])
1370              {
1371                  tag = this.openTags.pop();
1372                  exploded_tag = tag.split("_");
1373                  this.performInsert("[/"+exploded_tag[0]+"]", "", false);
1374  
1375                  if($('editor_item_'+exploded_tag[0]))
1376                  {
1377                      tag = $('editor_item_'+exploded_tag[0]);
1378                  }
1379                  else
1380                  {
1381                      tag = $('editor_item_'+tag);
1382                  }
1383                  if(tag)
1384                  {
1385                      if(tag.itemType == "dropdown" || tag.dropdown || tag.menu)
1386                      {
1387                          this.setDropDownMenuActiveItem(tag, 0);
1388                      }
1389                      else
1390                      {
1391                          this.removeElementState(tag, 'clicked');
1392                      }
1393                  }
1394              }
1395          }
1396          $(this.textarea).focus();
1397          $('editor_item_close_tags').style.visibility = 'hidden';
1398          this.openTags = new Array();
1399      },
1400  
1401      bindSmilieInserter: function(id)
1402      {
1403          if(!$(id))
1404          {
1405              return false;
1406          }
1407  
1408          var smilies = $(id).select('.smilie');
1409  
1410          if(smilies.length > 0)
1411          {
1412              smilies.each(function(smilie)
1413              {
1414                  smilie.onclick = this.insertSmilie.bindAsEventListener(this);
1415                  smilie.style.cursor = "pointer";
1416              }.bind(this));
1417          }
1418      },
1419  
1420      openGetMoreSmilies: function(editor)
1421      {
1422          MyBB.popupWindow('misc.php?action=smilies&popup=true&editor='+editor, 'sminsert', 240, 280);
1423      },
1424  
1425      insertSmilie: function(e)
1426      {
1427          element = Event.element(e);
1428  
1429          if(!element || !element.alt)
1430          {
1431              return false;
1432          }
1433          this.performInsert(element.alt, "", true, false);
1434      },
1435  
1436      insertAttachment: function(aid)
1437      {
1438          this.performInsert("[attachment="+aid+"]", "", true, false);
1439      }
1440  };


Generated: Sun Jan 1 10:49:49 2012 Cross-referenced by PHPXref 0.7.1