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 = $(".motyw[theme-class='" + themeId + "']")[0];
 
  10         var e = $(".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 == 3) { // Text Node
 
  22             node = node.parentNode;
 
  25         if (node.nodeType != 1) {
 
  30         var xtype = node.attr('x-node');
 
  32         if (!xtype || (xtype.search(':') >= 0) ||
 
  39         // don't allow themes inside annotations
 
  40         if (node.is('*[x-annotation-box] *'))
 
  46     /* Convert HTML fragment to plaintext */
 
  47     var ANNOT_FORBIDDEN = ['pt', 'pa', 'pr', 'pe', 'begin', 'end', 'motyw'];
 
  49     function html2plainText(fragment){
 
  52         $(fragment.childNodes).each(function(){
 
  53             if (this.nodeType == 3) // textNode
 
  54                 text += this.nodeValue;
 
  56                 if (this.nodeType == 1 &&
 
  57                         $.inArray($(this).attr('x-node'), ANNOT_FORBIDDEN) == -1) {
 
  58                     text += html2plainText(this);
 
  67     /* Insert annotation using current selection */
 
  68     function addAnnotation(){
 
  69         var selection = window.getSelection();
 
  70         var n = selection.rangeCount;
 
  73             window.alert("Nie zaznaczono żadnego obszaru");
 
  77         // for now allow only 1 range
 
  79             window.alert("Zaznacz jeden obszar");
 
  83         // remember the selected range
 
  84         var range = selection.getRangeAt(0);
 
  86         if (!verifyTagInsertPoint(range.endContainer)) {
 
  87             window.alert("Nie można wstawić w to miejsce przypisu.");
 
  91         // BUG #273 - selected text can contain themes, which should be omitted from
 
  93         var text = html2plainText(range.cloneContents());
 
  94         var tag = $('<span></span>');
 
  95         range.collapse(false);
 
  96         range.insertNode(tag[0]);
 
  99             xml: '<pe><slowo_obce>' + text + '</slowo_obce> --- </pe>',
 
 100             success: function(text){
 
 107                 alert('Błąd przy dodawaniu przypisu:' + errors);
 
 113     /* Insert theme using current selection */
 
 116         var selection = window.getSelection();
 
 117         var n = selection.rangeCount;
 
 120             window.alert("Nie zaznaczono żadnego obszaru");
 
 124         // for now allow only 1 range
 
 126             window.alert("Zaznacz jeden obszar.");
 
 131         // remember the selected range
 
 132         var range = selection.getRangeAt(0);
 
 135         if ($(range.startContainer).is('.html-editarea') ||
 
 136         $(range.endContainer).is('.html-editarea')) {
 
 137             window.alert("Motywy można oznaczać tylko na tekście nie otwartym do edycji. \n Zamknij edytowany fragment i spróbuj ponownie.");
 
 141         // verify if the start/end points make even sense -
 
 142         // they must be inside a x-node (otherwise they will be discarded)
 
 143         // and the x-node must be a main text
 
 144         if (!verifyTagInsertPoint(range.startContainer)) {
 
 145             window.alert("Motyw nie może się zaczynać w tym miejscu.");
 
 149         if (!verifyTagInsertPoint(range.endContainer)) {
 
 150             window.alert("Motyw nie może się kończyć w tym miejscu.");
 
 154         var date = (new Date()).getTime();
 
 155         var random = Math.floor(4000000000 * Math.random());
 
 156         var id = ('' + date) + '-' + ('' + random);
 
 158         var spoint = document.createRange();
 
 159         var epoint = document.createRange();
 
 161         spoint.setStart(range.startContainer, range.startOffset);
 
 162         epoint.setStart(range.endContainer, range.endOffset);
 
 164         var mtag, btag, etag, errors;
 
 169             xml: '<end id="e' + id + '" />',
 
 170             success: function(text){
 
 171                 etag = $('<span></span>');
 
 172                 epoint.insertNode(etag[0]);
 
 173                 etag.replaceWith(text);
 
 175                     xml: '<motyw id="m' + id + '"></motyw>',
 
 176                     success: function(text){
 
 177                         mtag = $('<span></span>');
 
 178                         spoint.insertNode(mtag[0]);
 
 179                         mtag.replaceWith(text);
 
 181                             xml: '<begin id="b' + id + '" />',
 
 182                             success: function(text){
 
 183                                 btag = $('<span></span>');
 
 184                                 spoint.insertNode(btag[0])
 
 185                                 btag.replaceWith(text);
 
 186                                 selection.removeAllRanges();
 
 187                                 openForEdit($('.motyw[theme-class=' + id + ']'));
 
 196     function addSymbol() {
 
 197         if($('div.html-editarea textarea')[0]) {
 
 198             var specialCharsContainer = $("<div id='specialCharsContainer'><a href='#' id='specialCharsClose'>Zamknij</a><table id='tableSpecialChars' style='width: 600px;'></table></div>");
 
 199             var specialChars = ['Ą','ą','Ć','ć','Ę','ę','Ł','ł','Ń','ń','Ó','ó','Ś','ś','Ż','ż','Ź','ź','Á','á','À','à',
 
 200             'Â','â','Ä','ä','Å','å','Ā','ā','Ă','ă','Ã','ã',
 
 201             'Æ','æ','Ç','ç','Č','č','Ċ','ċ','Ď','ď','É','é','È','è',
 
 202             'Ê','ê','Ë','ë','Ē','ē','Ě','ě','Ġ','ġ','Ħ','ħ','Í','í','Î','î',
 
 203             'Ī','ī','Ĭ','ĭ','Ľ','ľ','Ñ','ñ','Ň','ň','Ó','ó','Ö','ö',
 
 204             'Ô','ô','Ō','ō','Ǒ','ǒ','Œ','œ','Ø','ø','Ř','ř','Š',
 
 205             'š','Ş','ş','Ť','ť','Ţ','ţ','Ű','ű','Ú','ú',
 
 206             'Ü','ü','Ů','ů','Ū','ū','Û','û','Ŭ','ŭ',
 
 207             'Ý','ý','Ž','ž','ß','Ð','ð','Þ','þ','А','а','Б',
 
 208             'б','В','в','Г','г','Д','д','Е','е','Ё','ё','Ж',
 
 209             'ж','З','з','И','и','Й','й','К','к','Л','л','М',
 
 210             'м','Н','н','О','о','П','п','Р','р','С','с',
 
 211             'Т','т','У','у','Ф','ф','Х','х','Ц','ц','Ч',
 
 212             'ч','Ш','ш','Щ','щ','Ъ','ъ','Ы','ы','Ь','ь','Э',
 
 213             'э','Ю','ю','Я','я','ѓ','є','і','ї','ј','љ','њ',
 
 214             'Ґ','ґ','Α','α','Β','β','Γ','γ','Δ','δ','Ε','ε',
 
 215             'Ζ','ζ','Η','η','Θ','θ','Ι','ι','Κ','κ','Λ','λ','Μ',
 
 216             'μ','Ν','ν','Ξ','ξ','Ο','ο','Π','π','Ρ','ρ','Σ','ς','σ',
 
 217             'Τ','τ','Υ','υ','Φ','φ','Χ','χ','Ψ','ψ','Ω','ω','–',
 
 218             '—','¡','¿','$','¢','£','€','©','®','°','¹','²','³',
 
 219             '¼','½','¾','†','§','‰','•','←','↑','→','↓',
 
 220             '„”','«»','’','[',']','[','~','|','−','·',
 
 221             '×','÷','≈','≠','±','≤','≥','∈'];
 
 222             var tableContent = "<tr>";
 
 224             for(var i in specialChars) {
 
 225                 if(i % 14 == 0 && i > 0) {
 
 226                     tableContent += "</tr><tr>";
 
 228                 tableContent += "<td><input type='button' class='specialBtn' value='"+specialChars[i]+"'/></td>";              
 
 231             tableContent += "</tr>";                                   
 
 232             $("#content").append(specialCharsContainer);
 
 233             $("#tableSpecialChars").append(tableContent);
 
 237             $('.specialBtn').click(function(){
 
 238                 insertAtCaret($('div.html-editarea textarea')[0], $(this).val());
 
 239                 $(specialCharsContainer).remove();
 
 241             $('#specialCharsClose').click(function(){
 
 242                 $(specialCharsContainer).remove();
 
 246             window.alert('Najedź na fragment tekstu, wybierz "Edytuj" i ustaw kursor na miejscu gdzie chcesz wstawić symbol.');
 
 250     function insertAtCaret(txtarea,text) { 
 
 251         /* http://www.scottklarr.com/topic/425/how-to-insert-text-into-a-textarea-where-the-cursor-is/ */
 
 252         var scrollPos = txtarea.scrollTop; 
 
 254         var br = ((txtarea.selectionStart || txtarea.selectionStart == '0') ? "ff" : (document.selection ? "ie" : false ) );
 
 257             var range = document.selection.createRange(); 
 
 258             range.moveStart ('character', -txtarea.value.length); 
 
 259             strPos = range.text.length; 
 
 260         } else if (br == "ff") strPos = txtarea.selectionStart; 
 
 261         var front = (txtarea.value).substring(0,strPos); 
 
 262         var back = (txtarea.value).substring(strPos,txtarea.value.length); 
 
 263         txtarea.value=front+text+back; 
 
 264         strPos = strPos + text.length; 
 
 267             var range = document.selection.createRange(); 
 
 268             range.moveStart ('character', -txtarea.value.length); 
 
 269             range.moveStart ('character', strPos); 
 
 270             range.moveEnd ('character', 0); 
 
 272         } else if (br == "ff") { 
 
 273             txtarea.selectionStart = strPos; 
 
 274             txtarea.selectionEnd = strPos; 
 
 277         txtarea.scrollTop = scrollPos; 
 
 280     /* open edition window for selected fragment */
 
 281     function openForEdit($origin){
 
 284         // annotations overlay their sub box - not their own box //
 
 285         if ($origin.is(".annotation-inline-box")) {
 
 286             $box = $("*[x-annotation-box]", $origin);
 
 292         /* always stick to the left to avoid interfering with gallery */
 
 294         var y = $origin.offset().top + $("#html-view").scrollTop();
 
 297         var w = $box.outerWidth();
 
 298         var h = $box.innerHeight();
 
 300         if ($origin.is(".annotation-inline-box")) {
 
 301             w = Math.max(w, 400);
 
 305         // start edition on this node
 
 306         var $overlay = $('<div class="html-editarea"><button class="accept-button">Zapisz</button><button class="delete-button">Usuń</button><textarea></textarea></div>').css({
 
 307             position: 'absolute',
 
 312         }).appendTo($('#html-view')).show();  /* appending outside of the document structure */
 
 315         if ($origin.is('.motyw')) {
 
 316             $('textarea', $overlay).autocomplete('/themes', {
 
 324         if ($origin.is('.motyw')){
 
 325             $('.delete-button', $overlay).click(function(){
 
 326                 if (window.confirm("Czy jesteś pewien, że chcesz usunąć ten motyw ?")) {
 
 327                     $('[theme-class=' + $origin.attr('theme-class') + ']').remove();
 
 329                     $(document).unbind('click.blur-overlay');
 
 334         else if($box.is('*[x-annotation-box]')) {
 
 335             $('.delete-button', $overlay).click(function(){
 
 336                 if (window.confirm("Czy jesteś pewien, że chcesz usunąć ten przypis?")) {
 
 339                     $(document).unbind('click.blur-overlay');
 
 345             $('.delete-button', $overlay).hide();
 
 349         var serializer = new XMLSerializer();
 
 354             success: function(text){
 
 355                 $('textarea', $overlay).val($.trim(text));
 
 357                 setTimeout(function(){
 
 358                     $('textarea', $overlay).elastic().focus();
 
 361                 function save(argument){
 
 362                     var nodeName = $box.attr('x-node') || 'pe';
 
 363                     var insertedText = $('textarea', $overlay).val();
 
 365                     if ($origin.is('.motyw')) {
 
 366                         insertedText = insertedText.replace(/,\s*$/, '');
 
 370                         xml: '<' + nodeName + '>' + insertedText + '</' + nodeName + '>',
 
 371                         success: function(element){
 
 372                             $origin.html($(element).html());
 
 375                         error: function(text){
 
 377                             alert('Błąd! ' + text);
 
 382                 $('.accept-button', $overlay).click(function(){
 
 386                 $(document).bind('click.blur-overlay', function(event){
 
 387                     if ($(event.target).parents('.html-editarea').length > 0) {
 
 392                     $(document).unbind('click.blur-overlay');
 
 396             error: function(text){
 
 397                 alert('Błąd! ' + text);
 
 402     function VisualPerspective(options){
 
 404         var old_callback = options.callback;
 
 406         options.callback = function(){
 
 407             var element = $("#html-view");
 
 408             var button = $('<button class="edit-button">Edytuj</button>');
 
 410             if (!CurrentDocument.readonly) {
 
 411                 $('#html-view').bind('mousemove', function(event){
 
 412                     var editable = $(event.target).closest('*[x-editable]');
 
 413                     $('.active', element).not(editable).removeClass('active').children('.edit-button').remove();
 
 415                     if (!editable.hasClass('active')) {
 
 416                         editable.addClass('active').append(button);
 
 418                     if (editable.is('.annotation-inline-box')) {
 
 419                         $('*[x-annotation-box]', editable).css({
 
 420                             position: 'absolute',
 
 421                             left: event.clientX - editable.offset().left + 5,
 
 422                             top: event.clientY - editable.offset().top + 5
 
 426                         $('*[x-annotation-box]').hide();
 
 430                 $('#insert-annotation-button').click(function(){
 
 435                 $('#insert-theme-button').click(function(){
 
 440                 $('#insert-symbol-button').click(function(){
 
 445                 $('.edit-button').live('click', function(event){
 
 446                     event.preventDefault();
 
 447                     openForEdit($(this).parent());
 
 452             $('.motyw').live('click', function(){
 
 453                 selectTheme($(this).attr('theme-class'));
 
 456             old_callback.call(this);
 
 459         $.wiki.Perspective.call(this, options);
 
 462     VisualPerspective.prototype = new $.wiki.Perspective();
 
 464     VisualPerspective.prototype.freezeState = function(){
 
 468     VisualPerspective.prototype.onEnter = function(success, failure){
 
 469         $.wiki.Perspective.prototype.onEnter.call(this);
 
 472             message: 'Uaktualnianie widoku...'
 
 475         function _finalize(callback){
 
 483             success: function(element){
 
 484                 $('#html-view').html(element);
 
 487             error: function(text){
 
 488                 /* only basic error message */
 
 489                 var errorArray = text.split("\n");
 
 490                 var errorLocation = errorArray[2].split(":")[0];
 
 491                 text = errorLocation;
 
 492                 $('#html-view').html('<p class="error">Wystąpił błąd: '+ text + '</p>');
 
 498     VisualPerspective.prototype.onExit = function(success, failure){
 
 502             message: 'Zapisywanie widoku...'
 
 505         function _finalize(callback){
 
 511         if ($('#html-view .error').length > 0)
 
 512             return _finalize(failure);
 
 515             element: $('#html-view div').get(0),
 
 516             success: function(text){
 
 517                 self.doc.setText(text);
 
 520             error: function(text){
 
 521                 $('#source-editor').html('<p>Wystąpił błąd:</p><pre>' + text + '</pre>');
 
 527     $.wiki.VisualPerspective = VisualPerspective;