Guest User

CKEditor Chrome SPAN Bugfix

a guest
Jun 26th, 2013
420
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Nur für Webkit Browser
  2. if ( CKEDITOR.env.webkit ) {
  3.  
  4.     console.log('>>> Using Webkit Span Bugfix');
  5.  
  6.     var getParentsToClosestBlockElement = function(node) {
  7.  
  8.         var parentsToBlockElement = new Array();
  9.  
  10.         if ( node instanceof CKEDITOR.dom.element || node instanceof CKEDITOR.dom.text ) {
  11.  
  12.             // Alle Elternknoten des Knotens holen (inkl. des Knotens selbst)
  13.             var parents = node.getParents(true);
  14.  
  15.             // Wenn Elternknoten vorhanden
  16.             if ( parents != null ) {
  17.  
  18.                 // Elternelementse durchschleifen
  19.                 for ( var i = 0; i < parents.length; i++ ) {
  20.  
  21.                     parentsToBlockElement[i] = parents[i];
  22.  
  23.                     // Wenn Elternelement ein Blockelement, dann das vorherige
  24.                     // Elternelement wegspeichern und abbrechen
  25.                     if ( i >= 1 && parents[i] instanceof CKEDITOR.dom.element
  26.                         && parents[i].getComputedStyle('display') == 'block' ) {
  27.  
  28.                         break;
  29.  
  30.                     }
  31.  
  32.                 }
  33.  
  34.             }
  35.  
  36.         }
  37.  
  38.         return parentsToBlockElement;
  39.  
  40.     }
  41.  
  42.     var getNextNodeSiblingsOfSelection = function() {
  43.  
  44.         // Rückgabearray
  45.         var siblings = new Array();
  46.  
  47.         // Selektion holen
  48.         var selection = editor.getSelection();
  49.  
  50.         var nextNode = null;
  51.  
  52.         // Wenn Selektion vorhanden
  53.         if ( selection != null ) {
  54.  
  55.             // Ranges der Selektion holen
  56.             var ranges = selection.getRanges();
  57.  
  58.             // Wenn Ranges vorhanden
  59.             if ( ranges.length ) {
  60.  
  61.                 var nextNode = ranges[0].getNextNode();
  62.  
  63.                 // Wenn Knoten vorhanden
  64.                 if ( nextNode != null ) {
  65.  
  66.                     var nextNodeParents = getParentsToClosestBlockElement(nextNode);
  67.  
  68.                     // Wenn Element vorhanden
  69.                     if ( nextNodeParents[nextNodeParents.length - 2] != undefined ) {
  70.  
  71.                         var element = nextNodeParents[nextNodeParents.length - 2];
  72.  
  73.                         // Das Element und alle seine nachfolgenden Elemente (in der gleichen Ebene)
  74.                         // wegspeichern
  75.                         do {
  76.  
  77.                             siblings.push(element);
  78.                             element = element.getNext();
  79.  
  80.                         } while ( element != null );
  81.  
  82.                     }
  83.  
  84.                 }
  85.  
  86.             }
  87.  
  88.         }
  89.  
  90.         var redoSelection = function() {
  91.  
  92.             if ( selection != null && ranges != null && ranges.length ) {
  93.  
  94.                 selection.selectRanges(ranges);
  95.  
  96.             }
  97.  
  98.         }
  99.  
  100.         return {
  101.             'siblings':         siblings,
  102.             'redoSelection':    redoSelection,
  103.             'nextNode':         nextNode
  104.         };
  105.  
  106.     }
  107.  
  108.     // Wenn Editor im Editierungsmodus ist (WYSIWYG Modus)
  109.     editor.on('contentDom', function() {
  110.  
  111.         // Wenn KeyDown Event getriggert wurde
  112.         editor.document.on('keydown', function(event) {
  113.  
  114.             var nextNodeSiblingsOnKeyDown = getNextNodeSiblingsOfSelection();
  115.  
  116.             // Einmalig beim keyDown Event das KeyUp Event binden
  117.             // => Wird dann aufgerufen, nachdem Chrome die SPANs gesetzt hat! ;)
  118.             editor.document.once('keyup', function(event) {
  119.  
  120.                 var nextNodeSiblingsOnKeyUp = getNextNodeSiblingsOfSelection();
  121.  
  122.                 var blockElementsMerged = false;
  123.  
  124.                 if ( nextNodeSiblingsOnKeyDown.nextNode != null
  125.                     && nextNodeSiblingsOnKeyUp.nextNode != null ) {
  126.  
  127.                     var nextNodeOnKeyDownParents = getParentsToClosestBlockElement(nextNodeSiblingsOnKeyDown.nextNode);
  128.                     var nextNodeOnKeyUpParents = getParentsToClosestBlockElement(nextNodeSiblingsOnKeyUp.nextNode);
  129.  
  130.                     if ( nextNodeOnKeyDownParents[nextNodeOnKeyDownParents.length - 1].getAddress().join('|')
  131.                         != nextNodeOnKeyUpParents[nextNodeOnKeyUpParents.length - 1].getAddress().join('|') ) {
  132.  
  133.                         blockElementsMerged = true;
  134.  
  135.                     }
  136.  
  137.                 }
  138.  
  139.                 if ( blockElementsMerged ) {
  140.  
  141.                     console.log('>>> Detected merge of block elements');
  142.  
  143.                     for ( var i = 0; i < nextNodeSiblingsOnKeyDown.siblings.length; i++ ) {
  144.  
  145.                         if ( nextNodeSiblingsOnKeyUp.siblings[i] == undefined ) break;
  146.  
  147.                         nodeBeforeKey   = nextNodeSiblingsOnKeyDown.siblings[i];
  148.                         nodeAfterKey    = nextNodeSiblingsOnKeyUp.siblings[i];
  149.  
  150.                         // Textknoten wurde in einen Span umgewandelt
  151.                         if ( nodeBeforeKey instanceof CKEDITOR.dom.text
  152.                             && nodeAfterKey instanceof CKEDITOR.dom.element
  153.                             && nodeAfterKey.getName() == 'span' ) {
  154.  
  155.                             console.log('>>> Remove Webkit Span', nodeAfterKey.getOuterHtml());
  156.  
  157.                             nodeAfterKey.remove(true);
  158.  
  159.                         // In einem Span Element wurde das Style-Attribut geändert
  160.                         } else if ( nodeBeforeKey instanceof CKEDITOR.dom.element
  161.                             && nodeBeforeKey.getName() == 'span'
  162.                             && nodeAfterKey instanceof CKEDITOR.dom.element
  163.                             && nodeAfterKey.getName() == 'span'
  164.                             && nodeAfterKey.getAttribute('style') != nodeBeforeKey.getAttribute('style') ) {
  165.  
  166.                             console.log('>>> Update Webkit Span Style Attribute', nodeAfterKey.getOuterHtml(), 'to', nodeBeforeKey.getAttribute('style'));
  167.  
  168.                             nodeAfterKey.setAttribute('style', nodeBeforeKey.getAttribute('style'));
  169.  
  170.                         }
  171.  
  172.                         // Bugfix => Selektion wiederherstellen
  173.                         nextNodeSiblingsOnKeyUp.redoSelection();
  174.  
  175.                     }
  176.  
  177.                 }
  178.  
  179.             });
  180.  
  181.         });
  182.  
  183.     });
  184.  
  185. }
Advertisement
Add Comment
Please, Sign In to add comment