[ Index ]

PHP Cross Reference of Mambo 4.6.5

[ Variables ]     [ Functions ]     [ Classes ]     [ Constants ]     [ Statistics ]

title

Body

[close]

/mambots/editors/mostlyce/jscripts/tiny_mce/plugins/safari/ -> editor_plugin_src.js (source)

   1  /**

   2   * $Id: editor_plugin_src.js 264 2007-04-26 20:53:09Z spocke $

   3   *

   4   * @author Moxiecode

   5   * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.

   6   */
   7  
   8  (function() {
   9      var Event = tinymce.dom.Event, grep = tinymce.grep, each = tinymce.each, inArray = tinymce.inArray, isOldWebKit = tinymce.isOldWebKit;
  10  
  11      tinymce.create('tinymce.plugins.Safari', {
  12          init : function(ed) {
  13              var t = this, dom;
  14  
  15              // Ignore on non webkit

  16              if (!tinymce.isWebKit)
  17                  return;
  18  
  19              t.editor = ed;
  20              t.webKitFontSizes = ['x-small', 'small', 'medium', 'large', 'x-large', 'xx-large', '-webkit-xxx-large'];
  21              t.namedFontSizes = ['xx-small', 'x-small','small','medium','large','x-large', 'xx-large'];
  22  
  23              // Safari will crash if the build in createlink command is used

  24  /*            ed.addCommand('CreateLink', function(u, v) {

  25                  ed.execCommand("mceInsertContent", false, '<a href="' + dom.encode(v) + '">' + ed.selection.getContent() + '</a>');

  26              });*/
  27  
  28              // Workaround for FormatBlock bug, http://bugs.webkit.org/show_bug.cgi?id=16004

  29              ed.addCommand('FormatBlock', function(u, v) {
  30                  var dom = ed.dom, e = dom.getParent(ed.selection.getNode(), dom.isBlock);
  31  
  32                  if (e)
  33                      dom.replace(dom.create(v), e, 1);
  34                  else
  35                      ed.getDoc().execCommand("FormatBlock", false, v);
  36              });
  37  
  38              // Workaround for InsertHTML bug, http://bugs.webkit.org/show_bug.cgi?id=16382

  39              ed.addCommand('mceInsertContent', function(u, v) {
  40                  ed.getDoc().execCommand("InsertText", false, 'mce_marker');
  41                  ed.getBody().innerHTML = ed.getBody().innerHTML.replace(/mce_marker/g, v + '<span id="_mce_tmp">XX</span>');
  42                  ed.selection.select(ed.dom.get('_mce_tmp'));
  43                  ed.getDoc().execCommand("Delete", false, ' ');
  44              });
  45  
  46              // Workaround for missing shift+enter support, http://bugs.webkit.org/show_bug.cgi?id=16973

  47              ed.onKeyPress.add(function(ed, e) {
  48                  if (e.keyCode == 13 && e.shiftKey) {
  49                      t._insertBR(ed);
  50                      Event.cancel(e);
  51                  }
  52              });
  53  
  54              // Safari returns incorrect values

  55              ed.addQueryValueHandler('FontSize', function(u, v) {
  56                  var e, v;
  57  
  58                  // Check for the real font size at the start of selection

  59                  if ((e = ed.dom.getParent(ed.selection.getStart(), 'span')) && (v = e.style.fontSize))
  60                      return tinymce.inArray(t.namedFontSizes, v) + 1;
  61  
  62                  // Check for the real font size at the end of selection

  63                  if ((e = ed.dom.getParent(ed.selection.getEnd(), 'span')) && (v = e.style.fontSize))
  64                      return tinymce.inArray(t.namedFontSizes, v) + 1;
  65  
  66                  // Return default value it's better than nothing right!

  67                  return ed.getDoc().queryCommandValue('FontSize');
  68              });
  69  
  70              // Safari returns incorrect values

  71              ed.addQueryValueHandler('FontName', function(u, v) {
  72                  var e, v;
  73  
  74                  // Check for the real font name at the start of selection

  75                  if ((e = ed.dom.getParent(ed.selection.getStart(), 'span')) && (v = e.style.fontFamily))
  76                      return v.replace(/, /g, ',');
  77  
  78                  // Check for the real font name at the end of selection

  79                  if ((e = ed.dom.getParent(ed.selection.getEnd(), 'span')) && (v = e.style.fontFamily))
  80                      return v.replace(/, /g, ',');
  81  
  82                  // Return default value it's better than nothing right!

  83                  return ed.getDoc().queryCommandValue('FontName');
  84              });
  85  
  86              // Workaround for bug, http://bugs.webkit.org/show_bug.cgi?id=12250

  87              ed.onClick.add(function(ed, e) {
  88                  e = e.target;
  89  
  90                  if (e.nodeName == 'IMG') {
  91                      t.selElm = e;
  92                      ed.selection.select(e);
  93                  } else
  94                      t.selElm = null;
  95              });
  96  
  97              ed.onBeforeExecCommand.add(function(ed, c, b) {
  98                  var r = t.bookmarkRng;
  99  
 100                  // Restore selection

 101                  if (r) {
 102                      ed.selection.setRng(r);
 103                      t.bookmarkRng = null;
 104                      //console.debug('restore', r.startContainer, r.startOffset, r.endContainer, r.endOffset);

 105                  }
 106              });
 107  
 108              ed.onInit.add(function() {
 109                  t._fixWebKitSpans();
 110  
 111                  ed.windowManager.onOpen.add(function() {
 112                      var r = ed.selection.getRng();
 113  
 114                      // Store selection if valid

 115                      if (r.startContainer != ed.getDoc()) {
 116                          t.bookmarkRng = r.cloneRange();
 117                          //console.debug('store', r.startContainer, r.startOffset, r.endContainer, r.endOffset);

 118                      }
 119                  });
 120  
 121                  ed.windowManager.onClose.add(function() {
 122                      t.bookmarkRng = null;
 123                  });
 124  
 125                  if (isOldWebKit)
 126                      t._patchSafari2x(ed);
 127              });
 128  
 129              ed.onSetContent.add(function() {
 130                  dom = ed.dom;
 131  
 132                  // Convert strong,b,em,u,strike to spans

 133                  each(['strong','b','em','u','strike','sub','sup','a'], function(v) {
 134                      each(grep(dom.select(v)).reverse(), function(n) {
 135                          var nn = n.nodeName.toLowerCase(), st;
 136  
 137                          // Convert anchors into images

 138                          if (nn == 'a') {
 139                              if (n.name)
 140                                  dom.replace(dom.create('img', {mce_name : 'a', name : n.name, 'class' : 'mceItemAnchor'}), n);
 141  
 142                              return;
 143                          }
 144  
 145                          switch (nn) {
 146                              case 'b':
 147                              case 'strong':
 148                                  if (nn == 'b')
 149                                      nn = 'strong';
 150  
 151                                  st = 'font-weight: bold;';
 152                                  break;
 153  
 154                              case 'em':
 155                                  st = 'font-style: italic;';
 156                                  break;
 157  
 158                              case 'u':
 159                                  st = 'text-decoration: underline;';
 160                                  break;
 161  
 162                              case 'sub':
 163                                  st = 'vertical-align: sub;';
 164                                  break;
 165  
 166                              case 'sup':
 167                                  st = 'vertical-align: super;';
 168                                  break;
 169  
 170                              case 'strike':
 171                                  st = 'text-decoration: line-through;';
 172                                  break;
 173                          }
 174  
 175                          dom.replace(dom.create('span', {mce_name : nn, style : st, 'class' : 'Apple-style-span'}), n, 1);
 176                      });
 177                  });
 178              });
 179  
 180              ed.onPreProcess.add(function(ed, o) {
 181                  dom = ed.dom;
 182  
 183                  each(grep(o.node.getElementsByTagName('span')).reverse(), function(n) {
 184                      var v, bg;
 185  
 186                      if (o.get) {
 187                          if (dom.hasClass(n, 'Apple-style-span')) {
 188                              bg = n.style.backgroundColor;
 189  
 190                              switch (dom.getAttrib(n, 'mce_name')) {
 191                                  case 'font':
 192                                      if (!ed.settings.convert_fonts_to_spans)
 193                                          dom.setAttrib(n, 'style', '');
 194                                      break;
 195  
 196                                  case 'strong':
 197                                  case 'em':
 198                                  case 'sub':
 199                                  case 'sup':
 200                                      dom.setAttrib(n, 'style', '');
 201                                      break;
 202  
 203                                  case 'strike':
 204                                  case 'u':
 205                                      if (!ed.settings.inline_styles)
 206                                          dom.setAttrib(n, 'style', '');
 207                                      else
 208                                          dom.setAttrib(n, 'mce_name', '');
 209  
 210                                      break;
 211  
 212                                  default:
 213                                      if (!ed.settings.inline_styles)
 214                                          dom.setAttrib(n, 'style', '');
 215                              }
 216  
 217  
 218                              if (bg)
 219                                  n.style.backgroundColor = bg;
 220                          }
 221                      }
 222  
 223                      if (dom.hasClass(n, 'mceItemRemoved'))
 224                          dom.remove(n, 1);
 225                  });
 226              });
 227  
 228              ed.onPostProcess.add(function(ed, o) {
 229                  // Safari adds BR at end of all block elements

 230                  o.content = o.content.replace(/<br \/><\/(h[1-6]|div|p|address|pre)>/g, '</$1>');
 231  
 232                  // Safari adds id="undefined" to HR elements

 233                  o.content = o.content.replace(/ id=\"undefined\"/g, '');
 234              });
 235          },
 236  
 237          _fixWebKitSpans : function() {
 238              var t = this, ed = t.editor;
 239  
 240              if (!isOldWebKit) {
 241                  // Use mutator events on new WebKit

 242                  Event.add(ed.getDoc(), 'DOMNodeInserted', function(e) {
 243                      e = e.target;
 244  
 245                      if (e && e.nodeType == 1)
 246                          t._fixAppleSpan(e);
 247                  });
 248              } else {
 249                  // Do post command processing in old WebKit since the browser crashes on Mutator events :(

 250                  ed.onExecCommand.add(function() {
 251                      each(ed.dom.select('span'), function(n) {
 252                          t._fixAppleSpan(n);
 253                      });
 254  
 255                      ed.nodeChanged();
 256                  });
 257              }
 258          },
 259  
 260          _fixAppleSpan : function(e) {
 261              var ed = this.editor, dom = ed.dom, fz = this.webKitFontSizes, fzn = this.namedFontSizes, s = ed.settings, st, p;
 262  
 263              if (dom.getAttrib(e, 'mce_fixed'))
 264                  return;
 265  
 266              // Handle Apple style spans

 267              if (e.nodeName == 'SPAN' && e.className == 'Apple-style-span') {
 268                  st = e.style;
 269  
 270                  if (!s.convert_fonts_to_spans) {
 271                      if (st.fontSize) {
 272                          dom.setAttrib(e, 'mce_name', 'font');
 273                          dom.setAttrib(e, 'size', inArray(fz, st.fontSize) + 1);
 274                      }
 275  
 276                      if (st.fontFamily) {
 277                          dom.setAttrib(e, 'mce_name', 'font');
 278                          dom.setAttrib(e, 'face', st.fontFamily);
 279                      }
 280  
 281                      if (st.color) {
 282                          dom.setAttrib(e, 'mce_name', 'font');
 283                          dom.setAttrib(e, 'color', dom.toHex(st.color));
 284                      }
 285  
 286                      if (st.backgroundColor) {
 287                          dom.setAttrib(e, 'mce_name', 'font');
 288                          dom.setStyle(e, 'background-color', st.backgroundColor);
 289                      }
 290                  } else {
 291                      if (st.fontSize)
 292                          dom.setStyle(e, 'fontSize', fzn[inArray(fz, st.fontSize)]);
 293                  }
 294  
 295                  if (st.fontWeight == 'bold')
 296                      dom.setAttrib(e, 'mce_name', 'strong');
 297  
 298                  if (st.fontStyle == 'italic')
 299                      dom.setAttrib(e, 'mce_name', 'em');
 300  
 301                  if (st.textDecoration == 'underline')
 302                      dom.setAttrib(e, 'mce_name', 'u');
 303  
 304                  if (st.textDecoration == 'line-through')
 305                      dom.setAttrib(e, 'mce_name', 'strike');
 306  
 307                  if (st.verticalAlign == 'super')
 308                      dom.setAttrib(e, 'mce_name', 'sup');
 309  
 310                  if (st.verticalAlign == 'sub')
 311                      dom.setAttrib(e, 'mce_name', 'sub');
 312  
 313                  dom.setAttrib(e, 'mce_fixed', '1');
 314              }
 315          },
 316  
 317          _patchSafari2x : function(ed) {
 318              var t = this, setContent, getNode, dom = ed.dom, lr;
 319  
 320              // Inline dialogs

 321              if (ed.windowManager.onBeforeOpen) {
 322                  ed.windowManager.onBeforeOpen.add(function() {
 323                      r = ed.selection.getRng();
 324                  });
 325              }
 326  
 327              // Fake select on 2.x

 328              ed.selection.select = function(n) {
 329                  this.getSel().setBaseAndExtent(n, 0, n, 1);
 330              };
 331  
 332              getNode = ed.selection.getNode;
 333              ed.selection.getNode = function() {
 334                  return t.selElm || getNode.call(this);
 335              };
 336  
 337              // Fake range on Safari 2.x

 338              ed.selection.getRng = function() {
 339                  var t = this, s = t.getSel(), d = ed.getDoc(), r, rb, ra, di;
 340  
 341                  // Fake range on Safari 2.x

 342                  if (s.anchorNode) {
 343                      r = d.createRange();
 344  
 345                      try {
 346                          // Setup before range

 347                          rb = d.createRange();
 348                          rb.setStart(s.anchorNode, s.anchorOffset);
 349                          rb.collapse(1);
 350  
 351                          // Setup after range

 352                          ra = d.createRange();
 353                          ra.setStart(s.focusNode, s.focusOffset);
 354                          ra.collapse(1);
 355  
 356                          // Setup start/end points by comparing locations

 357                          di = rb.compareBoundaryPoints(rb.START_TO_END, ra) < 0;
 358                          r.setStart(di ? s.anchorNode : s.focusNode, di ? s.anchorOffset : s.focusOffset);
 359                          r.setEnd(di ? s.focusNode : s.anchorNode, di ? s.focusOffset : s.anchorOffset);
 360  
 361                          lr = r;
 362                      } catch (ex) {
 363                          // Sometimes fails, at least we tried to do it by the book. I hope Safari 2.x will go disappear soooon!!!

 364                      }
 365                  }
 366  
 367                  return r || lr;
 368              };
 369  
 370              // Fix setContent so it works

 371              setContent = ed.selection.setContent;
 372              ed.selection.setContent = function(h, s) {
 373                  var r = this.getRng(), b;
 374  
 375                  try {
 376                      setContent.call(this, h, s);
 377                  } catch (ex) {
 378                      // Workaround for Safari 2.x

 379                      b = dom.create('body');
 380                      b.innerHTML = h;
 381  
 382                      each(b.childNodes, function(n) {
 383                          r.insertNode(n.cloneNode(true));
 384                      });
 385                  }
 386              };
 387          },
 388  
 389          _insertBR : function(ed) {
 390              var dom = ed.dom, s = ed.selection, r = s.getRng(), br;
 391  
 392              // Insert BR element

 393              r.insertNode(br = dom.create('br'));
 394  
 395              // Place caret after BR

 396              r.setStartAfter(br);
 397              r.setEndAfter(br);
 398              s.setRng(r);
 399  
 400              // Could not place caret after BR then insert an nbsp entity and move the caret

 401              if (s.getSel().focusNode == br.previousSibling) {
 402                  s.select(dom.insertAfter(dom.doc.createTextNode('\u00a0'), br));
 403                  s.collapse(1);
 404              }
 405  
 406              // Scroll to new position, scrollIntoView can't be used due to bug: http://bugs.webkit.org/show_bug.cgi?id=16117

 407              ed.getWin().scrollTo(0, dom.getPos(s.getRng().startContainer).y);
 408          }
 409      });
 410  
 411      // Register plugin

 412      tinymce.PluginManager.add('safari', tinymce.plugins.Safari);
 413  })();
 414