2012-01-18 21 views
7

Mam problemy z tworzeniem wtyczek CKEditor, które wstawiają zawartość nieedytowalną do przepływu tekstu. Próbowałem wykorzystać funkcje zakresu, ale z niewielkim powodzeniem, ponieważ dokumentacja jest mniej niż gwiezdna. Tak więc, biorąc pod uwagę jakiś tekst, powiedzmy wkładki plugin „[[nieedytowalny rzeczy]]”, a następnie na wyświetlaczu WYSIWYG owija że w rozpiętości więc może być stylizowany w kolorze:Pozycja kursora CKEditor po wstawieniu elementu, którego nie można edytować

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

Kiedy pierwszy wprowadzającej w przypadku plików nieedytowanych, chcemy, aby użytkownik mógł kontynuować pisanie lub wciskanie Enter w nowej linii. Poniższy kod (który mam tutaj: How to set cursor position to end of text in CKEditor?) działa w Firefox, ale (oczywiście) nie w IE9, 8 lub 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 

Więc co chcę się zdarzyć, że kursor przechodzi w pozycji „^” :

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

Jeśli nowy element nie znajduje się na końcu linii, a następnie po jego utworzeniu, kursor powinien udać się tutaj:

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

W FF, mogę ustawić kursor na końcu linii, ale nie na pozycji po nowym elemencie. W IE kursor nadal znajduje się wewnątrz nowego SPANU, które widzę po wpisaniu i nadal jest w kolorze css span, a po przejściu do widoku SOURCE tekst nie działa (ponieważ jest to niepodzielny zakres).

Wiem, że istnieje metoda range.setStartAfter, ale całkowicie nie udało się jej uruchomić nawet w FF/Chrome.

Czy ktoś ma naprawdę dobry chwyt przy użyciu metod wyboru i selekcji w CKEditorze? Wiem, I nie!

Zaczynam myśleć, że samo użycie editor.insertElement jest złe, i powinienem się nauczyć o funkcjach FakeElement (insertBogus?), Których jeszcze nie rozumiem. Wtyczki giełdowe, takie jak linki i obrazy, nie wydają się mieć tego problemu.

+0

Próbuję rozwiązać ten problem już teraz. Czy od tego czasu odniosłeś z nim sukces? – coyotesqrl

Odpowiedz

6

Musiałem zrobić kilka podstępnych rzeczy, aby rozwiązać ten problem, ale udało się to rozwiązać: Po utworzeniu nieedytowalnego przedmiotu (rozpiętości z atrybutem content-editable: false) musiałem stworzyć "obojętny" zakres z tekstem składający się z jednej spacji. Więc wstawiam rzeczywistą rozpiętość, a następnie manekina. Ale tylko podczas tworzenia nowego przedmiotu.

To dotyczy sekcji "jeśli nie zajmujesz się edytowaniem wybranego elementu". W tym przypadku "a" jest instancją edytora, "e" jest pożądanym nie podlegającym edycji elementem, "f" jest sztucznym spanem.

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

Muszę przyznać, że nie rozumiem w pełni mojego własnego kodu. Dotarłem tam przez wiele godzin prób i błędów. Aha, i musiałem dodać regułę htmlFilter pozbyć lewo-over „f” elementów:

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

Muszę też dodać, że nie pamiętam, dlaczego musiałem zastąpić „nbsp” jednostkach przed usuwanie zakresu. Ale działa. I nie wiem, dlaczego usunąć, użyj "s.name" zamiast "s".

Nadzieję, że pomaga komuś.

2

I w obliczu tego samego problemu i udało mi się mieć kursora przed i po moim nieedytowalnym treści (elementu SVG) owijając moje element SVG w <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. 

To działało w porządku dla mnie, teraz jestem w stanie zdobądź utwardzacz na początku i na końcu na elemencie SVG.

Powiązane problemy