2012-01-18 2 views
7

Ho problemi nello sviluppo di plugin CKEditor che inseriscono contenuti non modificabili nel flusso del testo. Ho cercato di utilizzare le funzioni della gamma, ma con scarso successo in quanto la documentazione è meno che stellare. Quindi, dato un testo, diciamo gli inserti del plugin "[[roba non modificabile]]" e poi su di visualizzazione WYSIWYG avvolge che in un arco di modo che possa essere designato in un colore:CKEditor posizione del cursore dopo l'inserimento dell'elemento non modificabile

<p>This is some text[[uneditable stuff here]]</p>

Al primo inserimento roba immutabile, vogliamo che l'utente possa continuare a digitare o premere Invio per una nuova riga. Il seguente codice (che sono arrivato qui: How to set cursor position to end of text in CKEditor?) funziona in Firefox, ma (naturalmente) non in IE9, 8 o 7:

var s = editor.getSelection(); 
editor.insertElement(e); // element 'e'= a span created earlier 
var p = e.getParent(); 
s.selectElement(p); 
var selected_ranges = s.getRanges(); 
selected_ranges[0].collapse(false); // false = to the end of the selected node 
s.selectRanges(selected_ranges); // putting the current selection there 

Quindi quello che voglio che accada è che il cursore passa alla posizione "^" :

<p>This is some text<span>[[uneditable stuff here]]</span>^</p>

Se il nuovo elemento non è alla fine della linea, dopo la creazione di esso, il cursore dovrebbe andare a qui:

<p>This is some text<span>[[uneditable stuff here]]</span>^ with more text after the new element</p>

In FF, posso ottenere il cursore alla fine della linea anche se non in posizione dopo il nuovo elemento. In IE, il cursore è ancora all'interno del nuovo SPAN, che vedo quando digito ed è ancora nel colore css dello span, e quando si passa alla visualizzazione SOURCE, il testo è scomparso (perché è un'estensione non modificabile).

So che esiste un metodo range.setStartAfter, ma non sono stato in grado di farlo funzionare anche in FF/Chrome.

Qualcuno ha una buona padronanza sull'utilizzo dei metodi di intervallo e selezione in CKEditor? Lo so I no!

Iniziare a pensare che usare semplicemente editor.insertElement sia sbagliato, e dovrei conoscere le funzioni di FakeElement (insertBogus?), Che non capisco ancora. I plug-in per immagini come link e immagini non sembrano avere questo problema.

+0

Sto provando a risolvere questo problema adesso. Hai avuto qualche successo da quando hai postato? – coyotesqrl

risposta

6

Ho dovuto fare alcune cose subdole per risolvere questo problema, ma è stato risolto: dopo aver creato l'elemento non modificabile (una span con contenuto modificabile modificabile: falso) ho dovuto creare uno span "fittizio" con testo composto da uno spazio. Quindi, inserisco l'intervallo reale, quindi il manichino. Ma solo quando si crea un nuovo oggetto.

Quindi questo va nella sezione "se non si tratta di modificare un elemento selezionato". Qui, 'a' è l'istanza dell'editor, 'e' è l'elemento non modificabile desiderato, 'f' è l'estensione fittizia.

var e=new CKEDITOR.dom.element('span',a.document); 
e.setAttributes({// stuff to create our element}); 
var f=new CKEDITOR.dom.element('span',a.document); 
f.setAttributes({ 
    'class':'dummyF' 
}); 
f.setText(' '); // that's just one space 

// after section dealing with editing a selected item, in "else": 
var sel = a.getSelection(); // current cursor position 
a.insertElement(e); // the real new element 
if(CKEDITOR.env.ie || CKEDITOR.env.webkit){ // IE & Chrome like this way 
    f.insertAfter(e); 
    sel.selectElement(f); 
} 
else { //FF likes this way (to ensure cursor stays in the right place) 
    f.insertAfter(e); 
    var rangeObjForSelection = new CKEDITOR.dom.range(a.document); 
    rangeObjForSelection.selectNodeContents(f); 
    a.getSelection().selectRanges([ rangeObjForSelection ]); 
} 

Devo ammettere che non capisco del tutto il mio codice. Ci sono arrivato per ore di prove ed errori. Oh, e ho dovuto aggiungere una regola HtmlFilter per sbarazzarsi di sinistra-over 'f' elementi:

e.addRules({ 
    // e is the htmlFilter: applied to editor data before/upon output 
    elements:{ 
    span:function(s){ // 's' is any spans found in the editor 
     if(s.attributes&&s.attributes['data-cke-myelement']) { 
      //stuff to do with my element 
     } 
     else if(s.attributes['class']=='dummyF') { //CKEDITOR.env.ie&& 
      // for dummy spans to deal with "can't type or hit enter after new element" problem 
      realtext = new String(s.children[0]['value']); 
      realtext.replace(/^&nbsp;/,''); 
      s.children[0]['value'] = realtext; 
      delete s.name; 
     } 
    } 
    } 
}); 

Devo anche aggiungere che non mi ricordo il motivo per cui ho dovuto sostituire entità "nbsp" prima cancellando l'intervallo. Ma funziona. E non so perché per eliminarti usi "s.name" invece di solo "s".

La speranza che aiuta qualcuno.

2

Ho affrontato lo stesso problema e sono stato in grado di avere il cursore prima e dopo il mio contenuto non modificabile (elemento SVG) avvolgendo il mio elemento SVG in <span>&#8203; + element + &#8203;</span>

const eHtml = '<span>&#8203; ' + svgHtml + '&#8203;</span>'; // Wrap element in a span with sorrounding &#8203; 
const wrpEl = CKEDITOR.dom.element.createFromHtml(eHtml); 
editor.insertElement(wrpEl); 
wrpEl.remove(true); // Remove wrapping span leaving children. 

Questo ha funzionato bene per me, ora sono in grado prendi il cursore all'inizio e termina alla fine sull'elemento SVG.