2012-01-18 38 views
7

Tengo problemas para desarrollar complementos CKEditor que inserten contenidos no editables en el flujo de texto. He estado tratando de utilizar las funciones de rango, pero con poco éxito ya que la documentación es menos que estelar. Por lo tanto, dado un poco de texto, digamos que los insertos de plug-in "[[cosas no editable]]" y después de la visualización WYSIWYG envuelve de que en un lapso de modo que puede ser de estilo en un color:Posición del cursor CKEditor después de insertar el elemento no editable

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

Cuando primera inserción lo que no se puede editar, queremos que el usuario pueda continuar escribiendo o pulsando Intro para una nueva línea. El siguiente código (que llegué aquí: How to set cursor position to end of text in CKEditor?) funciona en Firefox, pero (por supuesto) no en 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 

Así que lo que quiero que suceda es que el cursor va en la posición "^" :

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

Si el nuevo elemento no se encuentra al final de la línea, a continuación, después de crearlo, el cursor debe ir a aquí:

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

En FF, puedo colocar el cursor al final de la línea, aunque no en la posición después del nuevo elemento. En IE, el cursor todavía está dentro del nuevo SPAN, que veo cuando escribo y todavía está en el color css del tramo, y cuando cambio a la vista SOURCE, el texto se va (porque es un tramo no editable).

Sé que hay un método range.setStartAfter, pero han sido totalmente incapaces de hacerlo funcionar incluso en FF/Chrome.

¿Alguien tiene un buen manejo sobre el uso de rango y métodos de selección en CKEditor? Sé I ¡no!

Empezar a pensar que usar editor.insertElement es incorrecto, y debo aprender sobre las funciones FakeElement (insertBogus?), Que aún no entiendo. Los complementos de stock para enlaces e imágenes no parecen tener este problema.

+0

Estoy tratando de resolver este problema ahora mismo. ¿Has tenido éxito desde que publicaste? – coyotesqrl

Respuesta

6

Tuve que hacer algunas cosas furtivas para resolver esto, pero se resolvió: Después de crear el elemento no editable (un tramo con atributo content-editable: false) tuve que crear un tramo "ficticio" con texto que consiste en un espacio Entonces, inserto el lapso real, luego el maniquí. Pero solo cuando se crea un nuevo elemento.

Por lo tanto, esto va en la sección "si no se trata de editar un elemento seleccionado". Aquí, 'a' es la instancia del editor, 'e' es el elemento no editable deseado, 'f' es el lapso ficticio.

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 ]); 
} 

Tengo que admitir que no entiendo completamente mi propio código. Llegué allí durante horas de prueba y error. Ah, y he tenido que añadir una regla de htmlFilter para deshacerse de sobrantes 'f' elementos:

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; 
     } 
    } 
    } 
}); 

También tengo que añadir que no recuerdo por qué tenía que reemplazar a las entidades "nbsp" antes borrando el lapso Pero funciona. Y no sé por qué borrarlo usa "nombre.sí" en lugar de solo "s".

Espero que ayude a alguien.

2

que enfrentan el mismo problema y yo era capaz de tener cursor antes y después de mi contenido no editable (elemento SVG) envolviendo mi elemento SVG en <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. 

Esto funcionó bien para mí, ahora soy capaz obtener curación al principio y al final al final en el elemento SVG.

Cuestiones relacionadas