3 /* Show theme to the user */
4 function selectTheme(themeId){
5 var selection = window.getSelection();
6 selection.removeAllRanges();
8 var range = document.createRange();
9 var s = $("[x-node='motyw'][theme-class='" + themeId + "']")[0];
10 var e = $("[x-node='end'][theme-class='" + themeId + "']")[0];
13 range.setStartAfter(s);
14 range.setEndBefore(e);
15 selection.addRange(range);
19 /* Verify insertion port for annotation or theme */
20 function verifyTagInsertPoint(node){
21 if (node.nodeType == Node.TEXT_NODE) {
22 node = node.parentNode;
25 if (node.nodeType != Node.ELEMENT_NODE) {
30 if (node.attr('id') == 'caret') {
33 while (node.attr('x-pass-thru')) {
36 var xtype = node.attr('x-node');
38 if (!xtype || (xtype.search(':') >= 0) ||
48 function verifyThemeBoundaryPoint(node) {
49 if (!verifyTagInsertPoint(node)) return false;
51 // don't allow themes inside annotations
52 if (node.closest('[x-node="pe"]').length > 0)
58 /* Convert HTML fragment to plaintext */
59 var ANNOT_FORBIDDEN = ['pt', 'pa', 'pr', 'pe', 'ptrad', 'begin', 'end', 'motyw'];
61 function html2plainText(fragment){
64 $(fragment.childNodes).each(function(){
65 if (this.nodeType == Node.TEXT_NODE)
66 text += this.nodeValue;
68 if (this.nodeType == Node.ELEMENT_NODE &&
69 $.inArray($(this).attr('x-node'), ANNOT_FORBIDDEN) == -1) {
70 text += html2plainText(this);
79 /* Insert annotation using current selection */
80 function addAnnotation(){
81 var selection = window.getSelection();
82 var n = selection.rangeCount;
84 if (selection.isCollapsed) {
85 window.alert("Nie zaznaczono żadnego obszaru");
89 var range = selection.getRangeAt(n - 1);
91 if (!verifyTagInsertPoint(range.endContainer)) {
92 window.alert("Nie można wstawić w to miejsce przypisu.");
97 for (let i = 0; i < n; ++ i) {
98 let rangeI = selection.getRangeAt(i);
99 if (verifyTagInsertPoint(rangeI.startContainer) &&
100 verifyTagInsertPoint(rangeI.endContainer)) {
101 text += html2plainText(rangeI.cloneContents());
104 var tag = $('<span></span>');
105 range.collapse(false);
106 range.insertNode(tag[0]);
109 xml: '<pe><slowo_obce>' + text + '</slowo_obce> --- </pe>',
110 success: function(text){
113 openForEdit(t, trim=false);
117 alert('Błąd przy dodawaniu przypisu:' + errors);
124 /* Insert theme using current selection */
127 var selection = window.getSelection();
128 var n = selection.rangeCount;
131 window.alert("Nie zaznaczono żadnego obszaru");
135 // for now allow only 1 range
137 window.alert("Zaznacz jeden obszar.");
141 // remember the selected range
142 var range = selection.getRangeAt(0);
144 if ($(range.startContainer).is('.html-editarea') ||
145 $(range.endContainer).is('.html-editarea')) {
146 window.alert("Motywy można oznaczać tylko na tekście nie otwartym do edycji. \n Zamknij edytowany fragment i spróbuj ponownie.");
150 // verify if the start/end points make even sense -
151 // they must be inside a x-node (otherwise they will be discarded)
152 // and the x-node must be a main text
153 if (!verifyThemeBoundaryPoint(range.startContainer)) {
154 window.alert("Motyw nie może się zaczynać w tym miejscu.");
158 if (!verifyThemeBoundaryPoint(range.endContainer)) {
159 window.alert("Motyw nie może się kończyć w tym miejscu.");
163 var date = (new Date()).getTime();
164 var random = Math.floor(4000000000 * Math.random());
165 var id = ('' + date) + '-' + ('' + random);
167 var createPoint = function(container, offset) {
168 var offsetBetweenCommas = function(text, offset) {
169 if(text.length < 2 || offset < 1 || offset > text.length)
171 return text[offset-1] === ',' && text[offset] === ',';
173 var point = document.createRange();
174 offset = offsetBetweenCommas(container.textContent, offset) ? offset - 1 : offset;
175 point.setStart(container, offset);
179 var spoint = createPoint(range.startContainer, range.startOffset);
180 var epoint = createPoint(range.endContainer, range.endOffset);
182 var mtag, btag, etag, errors;
187 xml: '<end id="e' + id + '" />',
188 success: function(text){
189 etag = $('<span></span>');
190 epoint.insertNode(etag[0]);
191 etag.replaceWith(text);
193 xml: '<motyw id="m' + id + '"></motyw>',
194 success: function(text){
195 mtag = $('<span></span>');
196 spoint.insertNode(mtag[0]);
197 mtag.replaceWith(text);
199 xml: '<begin id="b' + id + '" />',
200 success: function(text){
201 btag = $('<span></span>');
202 spoint.insertNode(btag[0])
203 btag.replaceWith(text);
204 selection.removeAllRanges();
205 openForEdit($('[x-node="motyw"][theme-class="' + id + '"]'));
214 function addSymbol(caret) {
218 editArea = $("textarea", caret.element)[0];
220 editArea = $('div.html-editarea textarea')[0];
224 var specialCharsContainer = $("<div id='specialCharsContainer'><a href='#' id='specialCharsClose'>Zamknij</a><table id='tableSpecialChars' style='width: 600px;'></table></div>");
227 ' ', 'Ą','ą','Ć','ć','Ę','ę','Ł','ł','Ń','ń','Ó','ó','Ś','ś','Ż','ż','Ź','ź','Á','á','À','à',
228 'Â','â','Ä','ä','Å','å','Ā','ā','Ă','ă','Ã','ã',
229 'Æ','æ','Ç','ç','Č','č','Ċ','ċ','Ď','ď','É','é','È','è',
230 'Ê','ê','Ë','ë','Ē','ē','Ě','ě','Ġ','ġ','Ħ','ħ','Í','í','Î','î',
231 'Ī','ī','Ĭ','ĭ','Ľ','ľ','Ñ','ñ','Ň','ň','Ó','ó','Ö','ö',
232 'Ô','ô','Ō','ō','Ǒ','ǒ','Œ','œ','Ø','ø','Ř','ř','Š',
233 'š','Ş','ş','Ť','ť','Ţ','ţ','Ű','ű','Ú','ú','Ù','ù',
234 'Ü','ü','Ů','ů','Ū','ū','Û','û','Ŭ','ŭ',
235 'Ý','ý','Ž','ž','ß','Ð','ð','Þ','þ','А','а','Б',
236 'б','В','в','Г','г','Д','д','Е','е','Ё','ё','Ж',
237 'ж','З','з','И','и','Й','й','К','к','Л','л','М',
238 'м','Н','н','О','о','П','п','Р','р','С','с',
239 'Т','т','У','у','Ф','ф','Х','х','Ц','ц','Ч',
240 'ч','Ш','ш','Щ','щ','Ъ','ъ','Ы','ы','Ь','ь','Э',
241 'э','Ю','ю','Я','я','ѓ','є','і','ї','ј','љ','њ',
242 'Ґ','ґ','Α','α','Β','β','Γ','γ','Δ','δ','Ε','ε',
243 'Ζ','ζ','Η','η','Θ','θ','Ι','ι','Κ','κ','Λ','λ','Μ',
244 'μ','Ν','ν','Ξ','ξ','Ο','ο','Π','π','Ρ','ρ','Σ','ς','σ',
245 'Τ','τ','Υ','υ','Φ','φ','Χ','χ','Ψ','ψ','Ω','ω','–',
246 '—','¡','¿','$','¢','£','€','©','®','°','¹','²','³',
247 '¼','½','¾','†','§','‰','•','←','↑','→','↓',
248 '„','”','„”','«','»','«»','»«','’','[',']','~','|','−','·',
249 '×','÷','≈','≠','±','≤','≥','∈',
252 '\u05d0', '\u05d1', '\u05d2', '\u05d3', '\u05d4', '\u05d5', '\u05d6', '\u05d7',
253 '\u05d8', '\u05d9', '\u05da', '\u05db', '\u05dc', '\u05dd', '\u05de', '\u05df',
254 '\u05e0', '\u05e1', '\u05e2', '\u05e3', '\u05e4', '\u05e5', '\u05e6', '\u05e7',
255 '\u05e8', '\u05e9', '\u05e0', '\u05ea',
257 '\u0591', '\u0592', '\u0593', '\u0594', '\u0595', '\u0596', '\u0597',
258 '\u0598', '\u0599', '\u059a', '\u059b', '\u059c', '\u059d', '\u059e', '\u059f',
259 '\u05a0', '\u05a1', '\u05a2', '\u05a3', '\u05a4', '\u05a5', '\u05a6', '\u05a7',
260 '\u05a8', '\u05a9', '\u05aa', '\u05ab', '\u05ac', '\u05ad', '\u05ae', '\u05af',
261 '\u05b0', '\u05b1', '\u05b2', '\u05b3', '\u05b4', '\u05b5', '\u05b6', '\u05b7',
262 '\u05b8', '\u05b9', '\u05ba', '\u05bb', '\u05bc', '\u05bd', '\u05be', '\u05bf',
263 '\u05c0', '\u05c1', '\u05c2', '\u05c3', '\u05c4', '\u05c5', '\u05c6', '\u05c7',
265 '\ufb1d', '\ufb1e', '\ufb1f',
266 '\ufb20', '\ufb21', '\ufb22', '\ufb23', '\ufb24', '\ufb25', '\ufb26', '\ufb27',
267 '\ufb28', '\ufb29', '\ufb2a', '\ufb2b', '\ufb2c', '\ufb2d', '\ufb2e', '\ufb2f',
268 '\ufb30', '\ufb31', '\ufb32', '\ufb33', '\ufb34', '\ufb35', '\ufb36',
269 '\ufb38', '\ufb39', '\ufb3a', '\ufb3b', '\ufb3c', '\ufb3e',
270 '\ufb40', '\ufb41', '\ufb43', '\ufb44', '\ufb46', '\ufb47',
271 '\ufb48', '\ufb49', '\ufb4a', '\ufb4b', '\ufb4c', '\ufb4d', '\ufb4e', '\ufb4f',
273 var tableContent = "<tr>";
275 for(var i in specialChars) {
276 if(i % 14 == 0 && i > 0) {
277 tableContent += "</tr><tr>";
279 tableContent += "<td><input type='button' class='specialBtn' value='"+specialChars[i]+"'/></td>";
282 tableContent += "</tr>";
283 $("body").append(specialCharsContainer);
286 // localStorage for recently used characters - reading
287 if (typeof(localStorage) != 'undefined') {
288 if (localStorage.getItem("recentSymbols")) {
289 var recent = localStorage.getItem("recentSymbols");
290 var recentArray = recent.split(";");
292 for(var i in recentArray.reverse()) {
293 recentRow += "<td><input type='button' class='specialBtn recentSymbol' value='"+recentArray[i]+"'/></td>";
295 recentRow = "<tr>" + recentRow + "</tr>";
298 $("#tableSpecialChars").append(recentRow);
299 $("#tableSpecialChars").append(tableContent);
303 $('.specialBtn').click(function(){
304 var insertVal = $(this).val();
306 // if we want to surround text with quotes
307 // not sure if just check if value has length == 2
310 caret.insertChar(insertVal);
313 if (insertVal.length == 2) {
314 var startTag = insertVal[0];
315 var endTag = insertVal[1];
316 var textAreaOpened = editArea;
318 if (document.selection) {
319 textAreaOpened.focus();
320 sel = document.selection.createRange();
321 sel.text = startTag + sel.text + endTag;
323 //MOZILLA/NETSCAPE support
324 else if (textAreaOpened.selectionStart || textAreaOpened.selectionStart == '0') {
325 var startPos = textAreaOpened.selectionStart;
326 var endPos = textAreaOpened.selectionEnd;
327 textAreaOpened.value = textAreaOpened.value.substring(0, startPos)
328 + startTag + textAreaOpened.value.substring(startPos, endPos) + endTag + textAreaOpened.value.substring(endPos, textAreaOpened.value.length);
331 insertAtCaret(editArea, insertVal);
335 // localStorage for recently used characters - saving
336 if (typeof(localStorage) != 'undefined') {
337 if (localStorage.getItem("recentSymbols")) {
338 var recent = localStorage.getItem("recentSymbols");
339 var recentArray = recent.split(";");
340 var valIndex = $.inArray(insertVal, recentArray);
343 // value not present in array yet
344 if(recentArray.length > 13){
346 recentArray.push(insertVal);
348 recentArray.push(insertVal);
351 // value already in the array
352 for(var i = valIndex; i < recentArray.length; i++){
353 recentArray[i] = recentArray[i+1];
355 recentArray[recentArray.length-1] = insertVal;
357 localStorage.setItem("recentSymbols", recentArray.join(";"));
359 localStorage.setItem("recentSymbols", insertVal);
362 $(specialCharsContainer).remove();
364 $('#specialCharsClose').click(function(){
365 $(specialCharsContainer).remove();
369 window.alert('Najedź na fragment tekstu, wybierz "Edytuj" i ustaw kursor na miejscu gdzie chcesz wstawić symbol.');
373 function insertAtCaret(txtarea,text) {
374 /* http://www.scottklarr.com/topic/425/how-to-insert-text-into-a-textarea-where-the-cursor-is/ */
375 var scrollPos = txtarea.scrollTop;
378 var br = ((txtarea.selectionStart || txtarea.selectionStart == '0') ? "ff" : (document.selection ? "ie" : false ) );
381 var range = document.selection.createRange();
382 range.moveStart ('character', -txtarea.value.length);
383 strPos = backStart = range.text.length;
384 } else if (br == "ff") {
385 strPos = txtarea.selectionStart;
386 backStart = txtarea.selectionEnd;
388 var front = (txtarea.value).substring(0,strPos);
389 var back = (txtarea.value).substring(backStart,txtarea.value.length);
390 txtarea.value=front+text+back;
391 strPos = strPos + text.length;
394 var range = document.selection.createRange();
395 range.moveStart ('character', -txtarea.value.length);
396 range.moveStart ('character', strPos);
397 range.moveEnd ('character', 0);
399 } else if (br == "ff") {
400 txtarea.selectionStart = strPos;
401 txtarea.selectionEnd = strPos;
404 txtarea.scrollTop = scrollPos;
407 /* open edition window for selected fragment */
408 function openForEdit($origin, trim=true){
411 // annotations overlay their sub box - not their own box //
412 if ($origin.is(".annotation-inline-box")) {
413 $box = $("*[x-annotation-box]", $origin);
418 var x = $box[0].offsetLeft;
419 var y = $box[0].offsetTop;
421 var w = $box.outerWidth();
422 var h = $box.innerHeight();
424 if ($origin.is(".annotation-inline-box")) {
425 w = Math.max(w, 400);
427 if($('.htmlview div').offset().left + $('.htmlview div').width() > ($('.vsplitbar').offset().left - 480)){
428 x = -(Math.max($origin.offset().left, $origin.width()));
433 if ($origin.is('.reference-inline-box')) {
439 $('.htmlview div').offset().left + $('.htmlview div').width() - 400
443 // start edition on this node
444 var $overlay = $('<div class="html-editarea"><div class="html-editarea-toolbar"><div class="html-editarea-toolbar-left"><button class="accept-button">Zapisz</button><button class="delete-button">Usuń</button></div><div class="html-editarea-toolbar-right"><button class="akap-edit-button" data-tag="tytul_dziela">tytuł dzieła</button><button class="akap-edit-button" data-tag="wyroznienie">wyróżnienie</button><button class="akap-edit-button" data-tag="slowo_obce">słowo obce</button><button class="akap-edit-button" data-tag-selfclosing="br">br</button><button class="akap-edit-button" data-act="spec">znak spec.</button></div></div><textarea></textarea></div>').css({
445 position: 'absolute',
450 }).appendTo($box[0].offsetParent || $box.parent()).show();
453 if ($origin.is('*[x-edit-no-format]')) {
454 $('.akap-edit-button').remove();
457 if ($origin.is('[x-node="motyw"]')) {
458 $.themes.autocomplete($('textarea', $overlay));
461 if ($origin.is('[x-node="motyw"]')){
462 $('.delete-button', $overlay).click(function(){
463 if (window.confirm("Czy jesteś pewien, że chcesz usunąć ten motyw?")) {
464 $('[theme-class="' + $origin.attr('theme-class') + '"]').remove();
466 $(document).unbind('click.blur-overlay');
471 else if($box.is('*[x-annotation-box]') || $origin.is('*[x-edit-attribute]') || $origin.is('*[x-node="uwaga"]')) {
473 switch ($origin.attr('x-node')) {
483 $('.delete-button', $overlay).click(function(){
484 if (window.confirm("Czy jesteś pewien, że chcesz usunąć " + q + "?")) {
487 $(document).unbind('click.blur-overlay');
493 $('.delete-button', $overlay).html("Anuluj");
494 $('.delete-button', $overlay).click(function(){
495 if (window.confirm("Czy jesteś pewien, że chcesz anulować zmiany?")) {
497 $(document).unbind('click.blur-overlay');
504 var serializer = new XMLSerializer();
506 if($box.attr("x-edit-attribute")) {
507 source = $('<span x-pass-thru="true"/>');
508 source.text($box.attr("x-a-wl-" + $box.attr("x-edit-attribute")));
517 success: function(text){
520 ttext = ttext.trim();
522 $('textarea', $overlay).val(ttext);
524 setTimeout(function(){
525 $('textarea', $overlay).elastic().focus();
528 function save(argument){
529 var nodeName = $box.attr('x-node') || 'pe';
530 var insertedText = $('textarea', $overlay).val();
532 if ($origin.is('[x-node="motyw"]')) {
533 insertedText = insertedText.replace(/,\s*$/, '');
536 if($box.attr("x-edit-attribute")) {
537 xml = '<' + nodeName + ' ' + $box.attr("x-edit-attribute") + '="' + insertedText + '"/>';
539 xml = '<' + nodeName + '>' + insertedText + '</' + nodeName + '>';
544 success: function(element){
545 if (nodeName == 'out-of-flow-text') {
546 $(element).children().insertAfter($origin);
549 else if ($box.attr('x-edit-attribute')) {
550 $(element).insertAfter($origin);
554 $origin.html($(element).html());
557 $.wiki.activePerspective().flush();
559 error: function(text){
560 alert('Błąd! ' + text);
564 var msg = $("<div class='saveNotify'><p>Pamiętaj, żeby zapisać swoje zmiany.</p></div>");
565 $("#base").prepend(msg);
566 $('#base .saveNotify').fadeOut(3000, function(){
571 $('.akap-edit-button', $overlay).click(function(){
572 var textAreaOpened = $('textarea', $overlay)[0];
578 if ($this.data('tag')) {
579 tag = $this.data('tag');
580 startTag = "<" + $this.data('tag') + ">";
581 endTag = "</" + $this.data('tag') + ">";
582 } else if ($this.data('tag-selfclosing')){
583 startTag = "<" + $this.data('tag-selfclosing') + "/>";
584 } else if ($this.data('act')) {
585 if ($this.data('act') == 'spec') {
591 var myField = textAreaOpened;
594 if (document.selection) {
595 textAreaOpened.focus();
596 sel = document.selection.createRange();
597 sel.text = startTag + sel.text + endTag;
599 //MOZILLA/NETSCAPE support
600 else if (textAreaOpened.selectionStart || textAreaOpened.selectionStart == '0') {
601 var startPos = textAreaOpened.selectionStart;
602 var endPos = textAreaOpened.selectionEnd;
603 textAreaOpened.value = textAreaOpened.value.substring(0, startPos)
604 + startTag + textAreaOpened.value.substring(startPos, endPos) + endTag + textAreaOpened.value.substring(endPos, textAreaOpened.value.length);
608 $('.accept-button', $overlay).click(function(){
610 $(document).unbind('click.blur-overlay');
613 $(document).bind('click.blur-overlay', function(event){
614 if ($(event.target).closest('.html-editarea, #specialCharsContainer').length > 0) {
618 $(document).unbind('click.blur-overlay');
622 error: function(text){
623 alert('Błąd! ' + text);
628 function createUwagaBefore(before) {
631 success: function(element){
632 let $element = $(element);
633 $element.insertBefore(before);
634 openForEdit($element);
639 class VisualPerspective extends $.wiki.Perspective {
640 constructor(options) {
643 var element = $("#html-view");
644 var button = $('<button class="edit-button active-block-button">Edytuj</button>');
645 var uwagaButton = $('<button class="uwaga-button active-block-button">Uwaga</button>');
647 if (!CurrentDocument.readonly) {
649 $('#html-view').bind('mousemove', function(event){
650 var editable = $(event.target).closest('*[x-editable]');
651 $('.active', element).not(editable).removeClass('active').children('.html-editarea-toolbar').remove();
653 if (!editable.hasClass('active')) {
654 var toolbar = $("<div class='html-editarea-toolbar'><div class='html-editarea-toolbar-left'></div></div>")
655 editable.append(toolbar);
656 var buttonSpace = $('.html-editarea-toolbar-left', toolbar);
657 editable.addClass('active');
658 buttonSpace.append(button);
659 if (!editable.is('[x-edit-attribute]') &&
660 !editable.is('.annotation-inline-box') &&
661 !editable.is('[x-edit-no-format]')
663 buttonSpace.append(uwagaButton);
666 if (editable.is('.annotation-inline-box')) {
667 $('*[x-annotation-box]', editable).css({
670 if (editable.is('.reference-inline-box')) {
671 let preview = $('*[x-preview]', editable);
673 let link = $("a", preview);
674 let href = link.attr('href');
675 if (link.attr('title') == '?' && href.startsWith('https://www.wikidata.org/wiki/')) {
676 link.attr('title', '…');
677 let qid = href.split('/').reverse()[0];
679 url: 'https://www.wikidata.org/w/rest.php/wikibase/v1/entities/items/' + qid + '?_fields=labels',
681 success: function(data) {
684 data['labels']['pl'] || data['labels']['en']
692 self.caret = new Caret(element);
694 $('#insert-reference-button').click(function(){
700 $('#insert-annotation-button').click(function(){
706 $('#insert-theme-button').click(function(){
712 $(".insert-inline-tag").click(function() {
714 self.insertInlineTag($(this).attr('data-tag'));
718 $(".insert-char").click(function() {
720 addSymbol(caret=self.caret);
724 $(document).on('click', '.edit-button', function(event){
726 event.preventDefault();
727 openForEdit($(this).closest('.html-editarea-toolbar').parent());
730 $(document).on('click', '.uwaga-button', function(event){
732 event.preventDefault();
733 createUwagaBefore($(this).closest('.html-editarea-toolbar').parent());
737 $(document).on('click', '[x-node="motyw"]', function(){
738 selectTheme($(this).attr('theme-class'));
741 element.on('click', '.annotation', function(event) {
743 event.preventDefault();
744 event.redakcja_caret_ignore = true;
745 $('[x-annotation-box]', $(this).parent()).toggleClass('editing');
750 onEnter(success, failure) {
754 message: 'Uaktualnianie widoku...'
757 function _finalize(callback){
766 base: this.doc.getBase(),
767 success: function(element){
769 var htmlView = $('#html-view');
770 htmlView.html(element);
772 if ('PropertiesPerspective' in $.wiki.perspectives)
773 $.wiki.perspectives.PropertiesPerspective.enable();
777 error: function(text, source){
778 let err = '<p class="error">Wystąpił błąd:</p><p>'+text+'</p>';
780 err += '<pre>'+source.replace(/&/g, '&').replace(/</g, '<')+'</pre>'
781 $('#html-view').html(err);
789 return new Promise((resolve, reject) => {
790 if ($('#html-view .error').length > 0) {
793 //return _finalize(failure);
795 element: $('#html-view').get(0),
798 self.doc.setText(text);
803 //$('#source-editor').html('<p>Wystąpił błąd:</p><pre>' + text + '</pre>');
810 onExit(success, failure) {
815 if ('PropertiesPerspective' in $.wiki.perspectives)
816 $.wiki.perspectives.PropertiesPerspective.disable();
818 self.flush().then(() => {
819 success && success();
822 console.log('REJECTED!', e);
823 failure && failure();
827 insertInlineTag(tag) {
831 let selection = window.getSelection();
832 var n = selection.rangeCount;
833 if (n != 1 || selection.isCollapsed) {
834 window.alert("Nie zaznaczono obszaru");
837 let range = selection.getRangeAt(0);
840 // Both ends are in the same x-node container.
841 // Both ends are set to text nodes.
842 // TODO: That the container is a inline-text container.
843 let commonNode = range.endContainer;
845 if (commonNode.nodeType == Node.TEXT_NODE) {
846 commonNode = commonNode.parentNode;
848 let node = range.startContainer;
849 if (node.nodeType == Node.TEXT_NODE) {
850 node = node.parentNode;
852 if (node != commonNode) {
853 window.alert("Zły obszar.");
858 if (range.endContainer.nodeType == Node.TEXT_NODE) {
859 end = range.endContainer.splitText(range.endOffset);
861 end = document.createTextNode('');
862 let cont = $(range.endContainer).contents();
863 if (range.endOffset < cont.length) {
864 range.endContainer.insertBefore(end, cont[range.endOffset])
866 range.endContainer.append(end);
871 if (range.startContainer.nodeType == Node.TEXT_NODE) {
872 current = range.startContainer.splitText(range.startOffset);
874 current = document.createTextNode('');
875 let cont = $(range.startContainer).contents();
876 if (range.startOffset < cont.length) {
877 range.startContainer.insertBefore(current, cont[range.startOffset])
879 startNode.append(current);
883 // We will construct a HTML element with the range selected.
884 let div = $("<span x-pass-thru='true'>");
885 while (current != end) {
886 n = current.nextSibling;
887 $(current).appendTo(div);
893 success: function(d) {
895 xml: d = '<' + tag + '>' + d + '</' + tag + '>',
896 success: function(html) {
898 node.insertBefore($(html)[0], end);
903 error: function(a, b) {
909 insertAtRange(range, elem) {
911 let $end = $(range.endContainer);
912 if ($end.attr('id') == 'caret') {
913 self.caret.insert(elem);
915 range.insertNode(elem[0]);
921 var selection = window.getSelection();
922 var n = selection.rangeCount;
924 // TODO: if no selection, take caret position..
926 window.alert("Nie zaznaczono żadnego obszaru");
930 var range = selection.getRangeAt(n - 1);
931 if (!verifyTagInsertPoint(range.endContainer)) {
932 window.alert("Nie można wstawić w to miejsce referencji.");
936 var tag = $('<span></span>');
938 range.collapse(false);
939 self.insertAtRange(range, tag);
942 xml: '<ref href=""/>',
943 success: function(text){
950 alert('Błąd przy dodawaniu referncji:' + errors);
957 $('#html-view *').each((i, e) => {
959 if ($e.closest('[x-node="abstrakt"]').length) return;
960 if ($e.closest('[x-node="nota_red"]').length) return;
961 if ($e.closest('[x-annotation-box="true"]').length) return;
962 let node = $e.attr('x-node');
963 if (node == 'numeracja') {
965 } else if (['werset', 'akap', 'wers'].includes(node)) {
967 $e.attr('x-number', number);
973 $.wiki.VisualPerspective = VisualPerspective;