[ Index ]
 

Code source de Serendipity 1.2

Accédez au Source d'autres logiciels libres

title

Body

[fermer]

/htmlarea/plugins/ContextMenu/ -> context-menu.js (source)

   1  // Context Menu Plugin for HTMLArea-3.0
   2  // Sponsored by www.americanbible.org
   3  // Implementation by Mihai Bazon, http://dynarch.com/mishoo/
   4  //
   5  // (c) dynarch.com 2003.
   6  // Distributed under the same terms as HTMLArea itself.
   7  // This notice MUST stay intact for use (see license.txt).
   8  //
   9  // $Id: context-menu.js,v 1.2 2005/01/11 15:00:55 garvinhicking Exp $
  10  
  11  HTMLArea.loadStyle("menu.css", "ContextMenu");
  12  
  13  function ContextMenu(editor) {
  14      this.editor = editor;
  15  };
  16  
  17  ContextMenu._pluginInfo = {
  18      name          : "ContextMenu",
  19      version       : "1.0",
  20      developer     : "Mihai Bazon",
  21      developer_url : "http://dynarch.com/mishoo/",
  22      c_owner       : "dynarch.com",
  23      sponsor       : "American Bible Society",
  24      sponsor_url   : "http://www.americanbible.org",
  25      license       : "htmlArea"
  26  };
  27  
  28  ContextMenu.prototype.onGenerate = function() {
  29      var self = this;
  30      var doc = this.editordoc = this.editor._iframe.contentWindow.document;
  31      HTMLArea._addEvents(doc, ["contextmenu"],
  32                  function (event) {
  33                      return self.popupMenu(HTMLArea.is_ie ? self.editor._iframe.contentWindow.event : event);
  34                  });
  35      this.currentMenu = null;
  36  };
  37  
  38  ContextMenu.prototype.getContextMenu = function(target) {
  39      var self = this;
  40      var editor = this.editor;
  41      var config = editor.config;
  42      var menu = [];
  43      var tbo = this.editor.plugins.TableOperations;
  44      if (tbo) tbo = tbo.instance;
  45      var i18n = ContextMenu.I18N;
  46  
  47      var selection = editor.hasSelectedText();
  48      if (selection)
  49          menu.push([ i18n["Cut"], function() { editor.execCommand("cut"); }, null, config.btnList["cut"][1] ],
  50                [ i18n["Copy"], function() { editor.execCommand("copy"); }, null, config.btnList["copy"][1] ]);
  51      menu.push([ i18n["Paste"], function() { editor.execCommand("paste"); }, null, config.btnList["paste"][1] ]);
  52  
  53      var currentTarget = target;
  54      var elmenus = [];
  55  
  56      var link = null;
  57      var table = null;
  58      var tr = null;
  59      var td = null;
  60      var img = null;
  61  
  62  	function tableOperation(opcode) {
  63          tbo.buttonPress(editor, opcode);
  64      };
  65  
  66  	function insertPara(after) {
  67          var el = currentTarget;
  68          var par = el.parentNode;
  69          var p = editor._doc.createElement("p");
  70          p.appendChild(editor._doc.createElement("br"));
  71          par.insertBefore(p, after ? el.nextSibling : el);
  72          var sel = editor._getSelection();
  73          var range = editor._createRange(sel);
  74          if (!HTMLArea.is_ie) {
  75              sel.removeAllRanges();
  76              range.selectNodeContents(p);
  77              range.collapse(true);
  78              sel.addRange(range);
  79          } else {
  80              range.moveToElementText(p);
  81              range.collapse(true);
  82              range.select();
  83          }
  84      };
  85  
  86      for (; target; target = target.parentNode) {
  87          var tag = target.tagName;
  88          if (!tag)
  89              continue;
  90          tag = tag.toLowerCase();
  91          switch (tag) {
  92              case "img":
  93              img = target;
  94              elmenus.push(null,
  95                       [ i18n["Image Properties"],
  96                         function() {
  97                             editor._insertImage(img);
  98                         },
  99                         i18n["Show the image properties dialog"],
 100                         config.btnList["insertimage"][1] ]
 101                  );
 102              break;
 103              case "a":
 104              link = target;
 105              elmenus.push(null,
 106                       [ i18n["Modify Link"],
 107                         function() { editor.execCommand("createlink", true); },
 108                         i18n["Current URL is"] + ': ' + link.href,
 109                         config.btnList["createlink"][1] ],
 110  
 111                       [ i18n["Check Link"],
 112                         function() { window.open(link.href); },
 113                         i18n["Opens this link in a new window"] ],
 114  
 115                       [ i18n["Remove Link"],
 116                         function() {
 117                             if (confirm(i18n["Please confirm that you want to unlink this element."] + "\n" +
 118                                 i18n["Link points to:"] + " " + link.href)) {
 119                                 while (link.firstChild)
 120                                     link.parentNode.insertBefore(link.firstChild, link);
 121                                 link.parentNode.removeChild(link);
 122                             }
 123                         },
 124                         i18n["Unlink the current element"] ]
 125                  );
 126              break;
 127              case "td":
 128              td = target;
 129              if (!tbo) break;
 130              elmenus.push(null,
 131                       [ i18n["Cell Properties"],
 132                         function() { tableOperation("TO-cell-prop"); },
 133                         i18n["Show the Table Cell Properties dialog"],
 134                         config.btnList["TO-cell-prop"][1] ]
 135                  );
 136              break;
 137              case "tr":
 138              tr = target;
 139              if (!tbo) break;
 140              elmenus.push(null,
 141                       [ i18n["Row Properties"],
 142                         function() { tableOperation("TO-row-prop"); },
 143                         i18n["Show the Table Row Properties dialog"],
 144                         config.btnList["TO-row-prop"][1] ],
 145  
 146                       [ i18n["Insert Row Before"],
 147                         function() { tableOperation("TO-row-insert-above"); },
 148                         i18n["Insert a new row before the current one"],
 149                         config.btnList["TO-row-insert-above"][1] ],
 150  
 151                       [ i18n["Insert Row After"],
 152                         function() { tableOperation("TO-row-insert-under"); },
 153                         i18n["Insert a new row after the current one"],
 154                         config.btnList["TO-row-insert-under"][1] ],
 155  
 156                       [ i18n["Delete Row"],
 157                         function() { tableOperation("TO-row-delete"); },
 158                         i18n["Delete the current row"],
 159                         config.btnList["TO-row-delete"][1] ]
 160                  );
 161              break;
 162              case "table":
 163              table = target;
 164              if (!tbo) break;
 165              elmenus.push(null,
 166                       [ i18n["Table Properties"],
 167                         function() { tableOperation("TO-table-prop"); },
 168                         i18n["Show the Table Properties dialog"],
 169                         config.btnList["TO-table-prop"][1] ],
 170  
 171                       [ i18n["Insert Column Before"],
 172                         function() { tableOperation("TO-col-insert-before"); },
 173                         i18n["Insert a new column before the current one"],
 174                         config.btnList["TO-col-insert-before"][1] ],
 175  
 176                       [ i18n["Insert Column After"],
 177                         function() { tableOperation("TO-col-insert-after"); },
 178                         i18n["Insert a new column after the current one"],
 179                         config.btnList["TO-col-insert-after"][1] ],
 180  
 181                       [ i18n["Delete Column"],
 182                         function() { tableOperation("TO-col-delete"); },
 183                         i18n["Delete the current column"],
 184                         config.btnList["TO-col-delete"][1] ]
 185                  );
 186              break;
 187              case "body":
 188              elmenus.push(null,
 189                       [ i18n["Justify Left"],
 190                         function() { editor.execCommand("justifyleft"); }, null,
 191                         config.btnList["justifyleft"][1] ],
 192                       [ i18n["Justify Center"],
 193                         function() { editor.execCommand("justifycenter"); }, null,
 194                         config.btnList["justifycenter"][1] ],
 195                       [ i18n["Justify Right"],
 196                         function() { editor.execCommand("justifyright"); }, null,
 197                         config.btnList["justifyright"][1] ],
 198                       [ i18n["Justify Full"],
 199                         function() { editor.execCommand("justifyfull"); }, null,
 200                         config.btnList["justifyfull"][1] ]
 201                  );
 202              break;
 203          }
 204      }
 205  
 206      if (selection && !link)
 207          menu.push(null, [ i18n["Make link"],
 208                    function() { editor.execCommand("createlink", true); },
 209                    i18n["Create a link"],
 210                    config.btnList["createlink"][1] ]);
 211  
 212      for (var i = 0; i < elmenus.length; ++i)
 213          menu.push(elmenus[i]);
 214  
 215      if (!/html|body/i.test(currentTarget.tagName))
 216          menu.push(null,
 217                [ i18n["Remove the"] + " &lt;" + currentTarget.tagName + "&gt; " + i18n["Element"],
 218                  function() {
 219                      if (confirm(i18n["Please confirm that you want to remove this element:"] + " " +
 220                          currentTarget.tagName)) {
 221                          var el = currentTarget;
 222                          var p = el.parentNode;
 223                          p.removeChild(el);
 224                          if (HTMLArea.is_gecko) {
 225                              if (p.tagName.toLowerCase() == "td" && !p.hasChildNodes())
 226                                  p.appendChild(editor._doc.createElement("br"));
 227                              editor.forceRedraw();
 228                              editor.focusEditor();
 229                              editor.updateToolbar();
 230                              if (table) {
 231                                  var save_collapse = table.style.borderCollapse;
 232                                  table.style.borderCollapse = "collapse";
 233                                  table.style.borderCollapse = "separate";
 234                                  table.style.borderCollapse = save_collapse;
 235                              }
 236                          }
 237                      }
 238                  },
 239                  i18n["Remove this node from the document"] ],
 240                [ i18n["Insert paragraph before"],
 241                  function() { insertPara(false); },
 242                  i18n["Insert a paragraph before the current node"] ],
 243                [ i18n["Insert paragraph after"],
 244                  function() { insertPara(true); },
 245                  i18n["Insert a paragraph after the current node"] ]
 246                );
 247      return menu;
 248  };
 249  
 250  ContextMenu.prototype.popupMenu = function(ev) {
 251      var self = this;
 252      var i18n = ContextMenu.I18N;
 253      if (this.currentMenu)
 254          this.currentMenu.parentNode.removeChild(this.currentMenu);
 255  	function getPos(el) {
 256          var r = { x: el.offsetLeft, y: el.offsetTop };
 257          if (el.offsetParent) {
 258              var tmp = getPos(el.offsetParent);
 259              r.x += tmp.x;
 260              r.y += tmp.y;
 261          }
 262          return r;
 263      };
 264  	function documentClick(ev) {
 265          ev || (ev = window.event);
 266          if (!self.currentMenu) {
 267              alert(i18n["How did you get here? (Please report!)"]);
 268              return false;
 269          }
 270          var el = HTMLArea.is_ie ? ev.srcElement : ev.target;
 271          for (; el != null && el != self.currentMenu; el = el.parentNode);
 272          if (el == null)
 273              self.closeMenu();
 274          //HTMLArea._stopEvent(ev);
 275          //return false;
 276      };
 277      var keys = [];
 278  	function keyPress(ev) {
 279          ev || (ev = window.event);
 280          HTMLArea._stopEvent(ev);
 281          if (ev.keyCode == 27) {
 282              self.closeMenu();
 283              return false;
 284          }
 285          var key = String.fromCharCode(HTMLArea.is_ie ? ev.keyCode : ev.charCode).toLowerCase();
 286          for (var i = keys.length; --i >= 0;) {
 287              var k = keys[i];
 288              if (k[0].toLowerCase() == key)
 289                  k[1].__msh.activate();
 290          }
 291      };
 292      self.closeMenu = function() {
 293          self.currentMenu.parentNode.removeChild(self.currentMenu);
 294          self.currentMenu = null;
 295          HTMLArea._removeEvent(document, "mousedown", documentClick);
 296          HTMLArea._removeEvent(self.editordoc, "mousedown", documentClick);
 297          if (keys.length > 0)
 298              HTMLArea._removeEvent(self.editordoc, "keypress", keyPress);
 299          if (HTMLArea.is_ie)
 300              self.iePopup.hide();
 301      };
 302      var target = HTMLArea.is_ie ? ev.srcElement : ev.target;
 303      var ifpos = getPos(self.editor._iframe);
 304      var x = ev.clientX + ifpos.x;
 305      var y = ev.clientY + ifpos.y;
 306  
 307      var div;
 308      var doc;
 309      if (!HTMLArea.is_ie) {
 310          doc = document;
 311      } else {
 312          // IE stinks
 313          var popup = this.iePopup = window.createPopup();
 314          doc = popup.document;
 315          doc.open();
 316          doc.write("<html><head><style type='text/css'>@import url(" + _editor_url + "plugins/ContextMenu/menu.css); html, body { padding: 0px; margin: 0px; overflow: hidden; border: 0px; }</style></head><body unselectable='yes'></body></html>");
 317          doc.close();
 318      }
 319      div = doc.createElement("div");
 320      if (HTMLArea.is_ie)
 321          div.unselectable = "on";
 322      div.oncontextmenu = function() { return false; };
 323      div.className = "htmlarea-context-menu";
 324      if (!HTMLArea.is_ie)
 325          div.style.left = div.style.top = "0px";
 326      doc.body.appendChild(div);
 327  
 328      var table = doc.createElement("table");
 329      div.appendChild(table);
 330      table.cellSpacing = 0;
 331      table.cellPadding = 0;
 332      var parent = doc.createElement("tbody");
 333      table.appendChild(parent);
 334  
 335      var options = this.getContextMenu(target);
 336      for (var i = 0; i < options.length; ++i) {
 337          var option = options[i];
 338          var item = doc.createElement("tr");
 339          parent.appendChild(item);
 340          if (HTMLArea.is_ie)
 341              item.unselectable = "on";
 342          else item.onmousedown = function(ev) {
 343              HTMLArea._stopEvent(ev);
 344              return false;
 345          };
 346          if (!option) {
 347              item.className = "separator";
 348              var td = doc.createElement("td");
 349              td.className = "icon";
 350              var IE_IS_A_FUCKING_SHIT = '>';
 351              if (HTMLArea.is_ie) {
 352                  td.unselectable = "on";
 353                  IE_IS_A_FUCKING_SHIT = " unselectable='on' style='height=1px'>&nbsp;";
 354              }
 355              td.innerHTML = "<div" + IE_IS_A_FUCKING_SHIT + "</div>";
 356              var td1 = td.cloneNode(true);
 357              td1.className = "label";
 358              item.appendChild(td);
 359              item.appendChild(td1);
 360          } else {
 361              var label = option[0];
 362              item.className = "item";
 363              item.__msh = {
 364                  item: item,
 365                  label: label,
 366                  action: option[1],
 367                  tooltip: option[2] || null,
 368                  icon: option[3] || null,
 369                  activate: function() {
 370                      self.closeMenu();
 371                      self.editor.focusEditor();
 372                      this.action();
 373                  }
 374              };
 375              label = label.replace(/_([a-zA-Z0-9])/, "<u>$1</u>");
 376              if (label != option[0])
 377                  keys.push([ RegExp.$1, item ]);
 378              label = label.replace(/__/, "_");
 379              var td1 = doc.createElement("td");
 380              if (HTMLArea.is_ie)
 381                  td1.unselectable = "on";
 382              item.appendChild(td1);
 383              td1.className = "icon";
 384              if (item.__msh.icon)
 385                  td1.innerHTML = "<img align='middle' src='" + item.__msh.icon + "' />";
 386              var td2 = doc.createElement("td");
 387              if (HTMLArea.is_ie)
 388                  td2.unselectable = "on";
 389              item.appendChild(td2);
 390              td2.className = "label";
 391              td2.innerHTML = label;
 392              item.onmouseover = function() {
 393                  this.className += " hover";
 394                  self.editor._statusBarTree.innerHTML = this.__msh.tooltip || '&nbsp;';
 395              };
 396              item.onmouseout = function() { this.className = "item"; };
 397              item.oncontextmenu = function(ev) {
 398                  this.__msh.activate();
 399                  if (!HTMLArea.is_ie)
 400                      HTMLArea._stopEvent(ev);
 401                  return false;
 402              };
 403              item.onmouseup = function(ev) {
 404                  var timeStamp = (new Date()).getTime();
 405                  if (timeStamp - self.timeStamp > 500)
 406                      this.__msh.activate();
 407                  if (!HTMLArea.is_ie)
 408                      HTMLArea._stopEvent(ev);
 409                  return false;
 410              };
 411              //if (typeof option[2] == "string")
 412              //item.title = option[2];
 413          }
 414      }
 415  
 416      if (!HTMLArea.is_ie) {
 417          var dx = x + div.offsetWidth - window.innerWidth + 4;
 418          var dy = y + div.offsetHeight - window.innerHeight + 4;
 419          if (dx > 0) x -= dx;
 420          if (dy > 0) y -= dy;
 421          div.style.left = x + "px";
 422          div.style.top = y + "px";
 423      } else {
 424          // determine the size (did I mention that IE stinks?)
 425          var foobar = document.createElement("div");
 426          foobar.className = "htmlarea-context-menu";
 427          foobar.innerHTML = div.innerHTML;
 428          document.body.appendChild(foobar);
 429          var w = foobar.offsetWidth;
 430          var h = foobar.offsetHeight;
 431          document.body.removeChild(foobar);
 432          this.iePopup.show(ev.screenX, ev.screenY, w, h);
 433      }
 434  
 435      this.currentMenu = div;
 436      this.timeStamp = (new Date()).getTime();
 437  
 438      HTMLArea._addEvent(document, "mousedown", documentClick);
 439      HTMLArea._addEvent(this.editordoc, "mousedown", documentClick);
 440      if (keys.length > 0)
 441          HTMLArea._addEvent(this.editordoc, "keypress", keyPress);
 442  
 443      HTMLArea._stopEvent(ev);
 444      return false;
 445  };


Généré le : Sat Nov 24 09:00:37 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics