[ Index ]
 

Code source de Plume CMS 1.2.2

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/manager/tools/visualedit/js/ -> jsToolBar.js (source)

   1  function jsToolBar(textarea) {
   2      if (!document.createElement) { return; }
   3      
   4      if (!textarea) { return; }
   5      
   6      if ((typeof(document["selection"]) == "undefined")
   7      && (typeof(textarea["setSelectionRange"]) == "undefined")) {
   8          return;
   9      }
  10      
  11      this.textarea = textarea;
  12      
  13      this.editor = document.createElement('div');
  14      this.editor.className = 'jstEditor';
  15      
  16      this.textarea.parentNode.insertBefore(this.editor,this.textarea);
  17      this.editor.appendChild(this.textarea);
  18      
  19      this.toolbar = document.createElement("div");
  20      this.toolbar.className = 'jstElements';
  21      this.editor.parentNode.insertBefore(this.toolbar,this.editor);
  22      
  23      // Dragable resizing (only for gecko)
  24      if (this.editor.addEventListener)
  25      {
  26          this.handle = document.createElement('div');
  27          this.handle.className = 'jstHandle';
  28          var dragStart = this.resizeDragStart;
  29          var This = this;
  30          this.handle.addEventListener('mousedown',function(event) { dragStart.call(This,event); },false);
  31          
  32          this.editor.parentNode.insertBefore(this.handle,this.editor.nextSibling);
  33      }
  34      
  35      this.context = null;
  36      this.toolNodes = {}; // lorsque la toolbar est dessinée , cet objet est garni 
  37                      // de raccourcis vers les éléments DOM correspondants aux outils.
  38  }
  39  
  40  function jsButton(title, fn, scope, className) {
  41      this.title = title || null;
  42      this.fn = fn || function(){};
  43      this.scope = scope || null;
  44      this.className = className || null;
  45  }
  46  jsButton.prototype.draw = function() {
  47      if (!this.scope) return null;
  48      
  49      var button = document.createElement('button');
  50      button.setAttribute('type','button');
  51      if (this.className) button.className = this.className;
  52      button.title = this.title;
  53      var span = document.createElement('span');
  54      span.appendChild(document.createTextNode(this.title));
  55      button.appendChild(span);
  56      
  57      if (this.icon != undefined) {
  58          button.style.backgroundImage = 'url('+this.icon+')';
  59      }
  60      if (typeof(this.fn) == 'function') {
  61          var This = this;
  62          button.onclick = function() { try { This.fn.apply(This.scope, arguments) } catch (e) {} return false; };
  63      }
  64      return button;
  65  }
  66  
  67  function jsSpace(id) {
  68      this.id = id || null;
  69      this.width = null;
  70  }
  71  jsSpace.prototype.draw = function() {
  72      var span = document.createElement('span');
  73      if (this.id) span.id = this.id;
  74      span.appendChild(document.createTextNode(String.fromCharCode(160)));
  75      span.className = 'jstSpacer';
  76      if (this.width) span.style.marginRight = this.width+'px';
  77      
  78      return span;
  79  } 
  80  
  81  function jsCombo(title, options, scope, className) {
  82      this.title = title || null;
  83      this.options = options || null;
  84      this.scope = scope || null;
  85      this.className = className || null;
  86  }
  87  jsCombo.prototype.draw = function() {
  88      if (!this.scope || !this.options) return null;
  89  
  90      var select = document.createElement('select');
  91      if (this.className) select.className = className;
  92      select.title = this.title;
  93      
  94      for (var o in this.options) {
  95      // aOption == {label: aLabel, fn: aFunction}
  96          var opt = this.options[o];
  97          var option = document.createElement('option');
  98          option.value = o;
  99          option.appendChild(document.createTextNode(opt.label));
 100          select.appendChild(option);
 101      }
 102  
 103      var This = this;
 104      select.onchange = function() {
 105      // pour l'instant on associe une fonction par option.
 106      // l'autre solution est d'attacher une fonction globable auxquelle on passe
 107      // un argument dépendant de l'option sélectionnée ( ce serait peut être plus
 108      // léger en lignes de code...mais pas sûr..)
 109          var option = This.options[this.value];
 110          if (typeof option.fn != 'function') return false;
 111          try { 
 112              option.fn.apply(This.scope);
 113              //option.fn.apply(This.scope, arguments);
 114          } catch (e) { alert(e); }
 115  
 116          return false;
 117      }
 118  
 119      return select;
 120  }
 121  
 122  
 123  jsToolBar.prototype = {
 124      base_url: '',
 125      mode: 'xhtml',
 126      elements: {},
 127      
 128      getMode: function() {
 129          return this.mode;
 130      },
 131      
 132      setMode: function(mode) {
 133          this.mode = mode || 'xhtml';
 134      },
 135      
 136      switchMode: function(mode) {
 137          mode = mode || 'xhtml';
 138          this.draw(mode);
 139      },
 140      
 141      button: function(toolName) {
 142          var tool = this.elements[toolName];
 143          if (typeof tool.fn[this.mode] != 'function') return null;
 144          var b = new jsButton(tool.title, tool.fn[this.mode], this, 'jstb_'+toolName);
 145          if (tool.icon != undefined) b.icon = tool.icon;
 146          return b;
 147      },
 148      space: function(toolName) {
 149          var tool = new jsSpace(toolName)
 150          if (this.elements[toolName].width !== undefined)
 151              tool.width = this.elements[toolName].width;
 152          return tool;
 153      },
 154      combo: function(toolName) {
 155          var tool = this.elements[toolName];
 156          var options = {};
 157          var length = 0;
 158          for (var o in tool.options) {
 159              var opt = tool.options[o];
 160              if (typeof opt.fn[this.mode] != 'function') continue;
 161              options[o] = {label: opt.label, fn: opt.fn[this.mode]};
 162              length++;
 163          }
 164          if (length == 0) return null;
 165  
 166          return new jsCombo(tool.title, options, this);
 167      },
 168      draw: function(mode) {
 169          this.setMode(mode);
 170          
 171          // Empty toolbar
 172          while (this.toolbar.hasChildNodes()) {
 173              this.toolbar.removeChild(this.toolbar.firstChild)
 174          }
 175          this.toolNodes = {}; // vide les raccourcis DOM/**/
 176          
 177          // Draw toolbar elements
 178          var b, tool, newTool;
 179          
 180          for (var i in this.elements) {
 181              b = this.elements[i];
 182  
 183              var disabled =
 184              b.type == undefined || b.type == ''
 185              || (b.disabled != undefined && b.disabled)
 186              || (b.context != undefined && b.context != null && b.context != this.context);
 187              
 188              if (!disabled && typeof this[b.type] == 'function') {
 189                  tool = this[b.type](i);
 190                  if (tool) newTool = tool.draw();
 191                  if (newTool) {
 192                      this.toolNodes[i] = newTool; //mémorise l'accès DOM pour usage éventuel ultérieur
 193                      this.toolbar.appendChild(newTool);
 194                  }
 195              }
 196          }
 197      },
 198      
 199      singleTag: function(stag,etag) {
 200          stag = stag || null;
 201          etag = etag || stag;
 202          
 203          if (!stag || !etag) { return; }
 204          
 205          this.encloseSelection(stag,etag);
 206      },
 207      
 208      encloseSelection: function(prefix, suffix, fn) {
 209          this.textarea.focus();
 210          
 211          prefix = prefix || '';
 212          suffix = suffix || '';
 213          
 214          var start, end, sel, scrollPos, subst, res;
 215          
 216          if (typeof(document["selection"]) != "undefined") {
 217              sel = document.selection.createRange().text;
 218          } else if (typeof(this.textarea["setSelectionRange"]) != "undefined") {
 219              start = this.textarea.selectionStart;
 220              end = this.textarea.selectionEnd;
 221              scrollPos = this.textarea.scrollTop;
 222              sel = this.textarea.value.substring(start, end);
 223          }
 224          
 225          if (sel.match(/ $/)) { // exclude ending space char, if any
 226              sel = sel.substring(0, sel.length - 1);
 227              suffix = suffix + " ";
 228          }
 229          
 230          if (typeof(fn) == 'function') {
 231              res = (sel) ? fn.call(this,sel) : fn('');
 232          } else {
 233              res = (sel) ? sel : '';
 234          }
 235          
 236          subst = prefix + res + suffix;
 237          
 238          if (typeof(document["selection"]) != "undefined") {
 239              var range = document.selection.createRange().text = subst;
 240              this.textarea.caretPos -= suffix.length;
 241          } else if (typeof(this.textarea["setSelectionRange"]) != "undefined") {
 242              this.textarea.value = this.textarea.value.substring(0, start) + subst +
 243              this.textarea.value.substring(end);
 244              if (sel) {
 245                  this.textarea.setSelectionRange(start + subst.length, start + subst.length);
 246              } else {
 247                  this.textarea.setSelectionRange(start + prefix.length, start + prefix.length);
 248              }
 249              this.textarea.scrollTop = scrollPos;
 250          }
 251      },
 252      
 253      stripBaseURL: function(url) {
 254          if (this.base_url != '') {
 255              var pos = url.indexOf(this.base_url);
 256              if (pos == 0) {
 257                  url = url.substr(this.base_url.length);
 258              }
 259          }
 260          
 261          return url;
 262      }
 263  };
 264  
 265  /** Resizer
 266  -------------------------------------------------------- */
 267  jsToolBar.prototype.resizeSetStartH = function() {
 268      this.dragStartH = this.textarea.offsetHeight + 0;
 269  };
 270  jsToolBar.prototype.resizeDragStart = function(event) {
 271      var This = this;
 272      this.dragStartY = event.clientY;
 273      this.resizeSetStartH();
 274      document.addEventListener('mousemove', this.dragMoveHdlr=function(event){This.resizeDragMove(event);}, false);
 275      document.addEventListener('mouseup', this.dragStopHdlr=function(event){This.resizeDragStop(event);}, false);
 276  };
 277  
 278  jsToolBar.prototype.resizeDragMove = function(event) {
 279      this.textarea.style.height = (this.dragStartH+event.clientY-this.dragStartY)+'px';
 280  };
 281  
 282  jsToolBar.prototype.resizeDragStop = function(event) {
 283      document.removeEventListener('mousemove', this.dragMoveHdlr, false);
 284      document.removeEventListener('mouseup', this.dragStopHdlr, false);
 285  };
 286  
 287  // Elements definition ------------------------------------
 288  // block format (paragraph, headers)
 289  jsToolBar.prototype.elements.blocks = {
 290      type: 'combo',
 291      title: 'block format',
 292      options: {
 293          none: { label: '-- none --', fn: {} }, // only for wysiwyg mode
 294          nonebis: {label: '- block format -', fn: {} }, // only for xhtml mode
 295          p: { label: 'Paragraph', fn: {} },
 296          h1: { label: 'Header 1', fn: {} },
 297          h2: { label: 'Header 2', fn: {} },
 298          h3: { label: 'Header 3', fn: {} },
 299          h4: { label: 'Header 4', fn: {} },
 300          h5: { label: 'Header 5', fn: {} },
 301          h6: { label: 'Header 6', fn: {} }
 302      }
 303  }
 304  jsToolBar.prototype.elements.blocks.options.nonebis.fn.xhtml = function() {
 305      this.textarea.focus();
 306  };
 307  jsToolBar.prototype.elements.blocks.options.p.fn.xhtml = function() {
 308      this.singleTag('<p>','</p>');
 309  };
 310  jsToolBar.prototype.elements.blocks.options.h1.fn.xhtml = function() {
 311      this.singleTag('<h1>','</h1>');
 312  };
 313  jsToolBar.prototype.elements.blocks.options.h2.fn.xhtml = function() {
 314      this.singleTag('<h2>','</h2>');
 315  };
 316  jsToolBar.prototype.elements.blocks.options.h3.fn.xhtml = function() {
 317      this.singleTag('<h3>','</h3>');
 318  };
 319  jsToolBar.prototype.elements.blocks.options.h4.fn.xhtml = function() {
 320      this.singleTag('<h4>','</h4>');
 321  };
 322  jsToolBar.prototype.elements.blocks.options.h5.fn.xhtml = function() {
 323      this.singleTag('<h5>','</h5>');
 324  };
 325  jsToolBar.prototype.elements.blocks.options.h1.fn.xhtml = function() {
 326      this.singleTag('<h6>','</h6>');
 327  };
 328  
 329  jsToolBar.prototype.elements.blocks.options.nonebis.fn.wiki = function() {
 330      this.textarea.focus();
 331  };
 332  jsToolBar.prototype.elements.blocks.options.h2.fn.wiki = function() {
 333      this.encloseSelection('!!!');
 334  };
 335  jsToolBar.prototype.elements.blocks.options.h3.fn.wiki = function() {
 336      this.encloseSelection('!!');
 337  };
 338  jsToolBar.prototype.elements.blocks.options.h4.fn.wiki = function() {
 339      this.encloseSelection('!');
 340  };
 341  /* jsToolBar.prototype.elements.blocks.options.h5.fn.wiki = function() {
 342      this.encloseSelection('!');
 343  }; */
 344  
 345  // spacer
 346  jsToolBar.prototype.elements.space0 = {type: 'space'}
 347  
 348  // strong
 349  jsToolBar.prototype.elements.strong = {
 350      type: 'button',
 351      title: 'Strong emphasis',
 352      fn: {
 353          wiki: function() { this.singleTag('__') },
 354          xhtml: function() { this.singleTag('<strong>','</strong>') }
 355      }
 356  }
 357  
 358  // em
 359  jsToolBar.prototype.elements.em = {
 360      type: 'button',
 361      title: 'Emphasis',
 362      fn: {
 363          wiki: function() { this.singleTag("''") },
 364          xhtml: function() { this.singleTag('<em>','</em>') }
 365      }
 366  }
 367  
 368  // ins
 369  jsToolBar.prototype.elements.ins = {
 370      type: 'button',
 371      title: 'Inserted',
 372      fn: {
 373          // wiki: function() { this.singleTag('++') },
 374          xhtml: function() { this.singleTag('<ins>','</ins>') }
 375      }
 376  }
 377  
 378  // del
 379  jsToolBar.prototype.elements.del = {
 380      type: 'button',
 381      title: 'Deleted',
 382      fn: {
 383          // wiki: function() { this.singleTag('--') },
 384          xhtml: function() { this.singleTag('<del>','</del>') }
 385      }
 386  }
 387  
 388  // quote
 389  jsToolBar.prototype.elements.quote = {
 390      type: 'button',
 391      title: 'Inline quote',
 392      fn: {
 393          wiki: function() { this.singleTag('{{','}}') },
 394          xhtml: function() { this.singleTag('<q>','</q>') }
 395      }
 396  }
 397  
 398  // code
 399  jsToolBar.prototype.elements.code = {
 400      type: 'button',
 401      title: 'Code',
 402      fn: {
 403          wiki: function() { this.singleTag('@@') },
 404          xhtml: function() { this.singleTag('<code>','</code>')}
 405      }
 406  }
 407  
 408  // spacer
 409  jsToolBar.prototype.elements.space1 = {type: 'space'}
 410  
 411  // br
 412  jsToolBar.prototype.elements.br = {
 413      type: 'button',
 414      title: 'Line break',
 415      fn: {
 416          wiki: function() { this.encloseSelection("%%%\n",'') },
 417          xhtml: function() { this.encloseSelection("<br />\n",'')}
 418      }
 419  }
 420  
 421  // spacer
 422  jsToolBar.prototype.elements.space2 = {type: 'space'}
 423  
 424  // blockquote
 425  jsToolBar.prototype.elements.blockquote = {
 426      type: 'button',
 427      title: 'Blockquote',
 428      fn: {
 429          xhtml: function() { this.singleTag('<blockquote>','</blockquote>') },
 430          wiki: function() {
 431              this.encloseSelection("\n",'',
 432              function(str) {
 433                  str = str.replace(/\r/g,'');
 434                  return '> '+str.replace(/\n/g,"\n> ");
 435              });
 436          }
 437      }
 438  }
 439  
 440  // pre
 441  jsToolBar.prototype.elements.pre = {
 442      type: 'button',
 443      title: 'Preformated text',
 444      fn: {
 445          wiki: function() {
 446              this.encloseSelection("\n",'',
 447              function(str) {
 448                  str = str.replace(/\r/g,'');
 449                  return ' '+str.replace(/\n/g,"\n ");
 450              });
 451          }, //wiki: function() { this.singleTag("///\n","\n///") },
 452          xhtml: function() { this.singleTag('<pre>','</pre>') }
 453      }
 454  }
 455  
 456  // ul
 457  jsToolBar.prototype.elements.ul = {
 458      type: 'button',
 459      title: 'Unordered list',
 460      fn: {
 461          wiki: function() {
 462              this.encloseSelection('','',function(str) {
 463                  str = str.replace(/\r/g,'');
 464                  return '* '+str.replace(/\n/g,"\n* ");
 465              });
 466          },
 467          xhtml: function() {
 468              this.encloseSelection('','',function(str) {
 469                  str = str.replace(/\r/g,'');
 470                  str = str.replace(/\n/g,"</li>\n <li>");
 471                  return "<ul>\n <li>"+str+"</li>\n</ul>";
 472              });
 473          }
 474      }
 475  }
 476  
 477  // ol
 478  jsToolBar.prototype.elements.ol = {
 479      type: 'button',
 480      title: 'Ordered list',
 481      fn: {
 482          wiki: function() {
 483              this.encloseSelection('','',function(str) {
 484                  str = str.replace(/\r/g,'');
 485                  return '# '+str.replace(/\n/g,"\n# ");
 486              });
 487          },
 488          xhtml: function() {
 489              this.encloseSelection('','',function(str) {
 490                  str = str.replace(/\r/g,'');
 491                  str = str.replace(/\n/g,"</li>\n <li>");
 492                  return "<ol>\n <li>"+str+"</li>\n</ol>";
 493              });
 494          }
 495      }
 496  }
 497  
 498  // spacer
 499  jsToolBar.prototype.elements.space3 = {type: 'space'}
 500  
 501  // link
 502  jsToolBar.prototype.elements.link = {
 503      type: 'button',
 504      title: 'Link',
 505      fn: {},
 506      href_prompt: 'Please give page URL:',
 507      hreflang_prompt: 'Language of this page:',
 508      default_hreflang: '',
 509      prompt: function(href,hreflang) {
 510          href = href || '';
 511          hreflang = hreflang || this.elements.link.default_hreflang;
 512          
 513          href = window.prompt(this.elements.link.href_prompt,href);
 514          if (!href) { return false; }
 515          
 516          hreflang = window.prompt(this.elements.link.hreflang_prompt,
 517          hreflang);
 518          
 519          return { href: this.stripBaseURL(href), hreflang: hreflang };
 520      }
 521  }
 522  
 523  jsToolBar.prototype.elements.link.fn.xhtml = function() {
 524      var link = this.elements.link.prompt.call(this);
 525      if (link) {
 526          var stag = '<a href="'+link.href+'"';
 527          if (link.hreflang) { stag = stag+' hreflang="'+link.hreflang+'"'; }
 528          if (link.title) { stag = stag+' title="'+link.title+'"'; }
 529          stag = stag+'>';
 530          var etag = '</a>';
 531          
 532          this.encloseSelection(stag,etag);
 533      }
 534  };
 535  jsToolBar.prototype.elements.link.fn.wiki = function() {
 536      var link = this.elements.link.prompt.call(this);
 537      if (link) {
 538          var stag = '[';
 539          var etag = '|'+link.href;
 540          if (link.hreflang) { etag = etag+'|'+link.hreflang; }
 541          etag = etag+']';
 542          
 543          this.encloseSelection(stag,etag);
 544      }
 545  };
 546  
 547  // img
 548  jsToolBar.prototype.elements.img = {
 549          type: 'button',
 550          title: 'External image',
 551          src_prompt: 'Please give image URL:',
 552          fn: {},
 553          prompt: function(src) {
 554              src = src || '';
 555              return this.stripBaseURL(window.prompt(this.elements.img.src_prompt,src));
 556          }
 557  };
 558  jsToolBar.prototype.elements.img.fn.xhtml = function() {
 559      var src = this.elements.img.prompt.call(this);
 560      if (src) {
 561          this.encloseSelection('','',function(str) {
 562              if (str) {
 563                  return '<img src="'+src+'" alt="'+str+'" />';
 564              } else {
 565                  return '<img src="'+src+'" alt="" />';
 566              }
 567          });
 568      }
 569  };
 570  jsToolBar.prototype.elements.img.fn.wiki = function() {
 571      var src = this.elements.img.prompt.call(this);
 572      if (src) {
 573          this.encloseSelection('','',function(str) {
 574              if (str) {
 575                  return '(('+src+'|'+str+'))';
 576              } else {
 577                  return '(('+src+'))';
 578              }
 579          });
 580      }
 581  };


Généré le : Mon Nov 26 11:57:01 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics