Fixes #4191: backward search.
[redakcja.git] / src / redakcja / static / js / wiki / view_annotations.js
1 (function($){
2
3     /*
4      * Perspective
5      */
6     function AnnotationsPerspective(options){
7         var old_callback = options.callback || function() { };
8
9         this.vsplitbar = 'PRZYPISY';
10
11         options.callback = function(){
12             var self = this;
13
14             this.$element = $("#side-annotations");
15             this.$error = $('.error-message', this.$element);
16             this.$annos = $('.annotations-list', this.$element);
17             this.$spinner = $('.spinner', this.$element);
18             this.$refresh = $('.refresh', this.$element);
19
20             this.$refresh.click(function() {
21                 var $this = $(this);
22
23                 self.$refresh.removeClass('active');
24                 $this.addClass('active');
25                 var atype = $this.attr('data-tag');
26
27                 self.$annos.hide();
28                 self.$error.hide();
29                 self.$spinner.fadeIn(100, function() {
30                     self.refresh(self, atype);
31                 });
32             });
33
34             old_callback.call(this);
35         };
36
37         $.wiki.SidebarPerspective.call(this, options);
38     }
39
40     AnnotationsPerspective.prototype = new $.wiki.SidebarPerspective();
41
42     AnnotationsPerspective.prototype.updateAnnotationIds = function(self){
43         self.annotationToAnchor = {};
44         $('#html-view').find('.annotation-inline-box').each(
45             function(i, annoBox) {
46                 var $annoBox = $(annoBox);
47                 var $anchor = $("a[name|=anchor]", $annoBox);
48                 var htmlContent = $('span', $annoBox).html();
49                 // TBD: perhaps use a hash of htmlContent as key
50                 self.annotationToAnchor[htmlContent] = $anchor.attr('name');
51                 });
52     };
53
54     AnnotationsPerspective.prototype.goToAnnotation = function(self, srcNode){
55         var content = $(srcNode).html();
56         content = content.replace(/&gt;/g, '>').replace(/&lt;/g, '<').replace(/&amp;/g, '&');
57         xml2html({
58             xml: '<root>'+content+'</root>',
59             success: function(txt) {
60                 content = $(txt).html();
61                 },
62             error: function(text) {
63                 $.unblockUI();
64                 self.$error.html('<div class="alert alert-danger">' + text + '</div>');
65                 self.$spinner.hide();
66                 self.$error.show();
67             }
68         });
69
70         var anchor = self.annotationToAnchor[content];
71         if (anchor != undefined) {
72             var $htmlView = $("#html-view");
73             var top = $htmlView.offset().top + 
74                 $("[name=" + anchor + "]", $htmlView).offset().top - 
75                 $htmlView.children().eq(0).offset().top;
76
77             $htmlView.animate({scrollTop: top}, 250);
78         }
79     };
80
81     AnnotationsPerspective.prototype.refresh = function(self, atype) {
82         var xml;
83
84         var persp = $.wiki.activePerspective();
85         if (persp == 'CodeMirrorPerspective') {
86             xml = $.wiki.perspectives[persp].codemirror.getValue();
87         }
88         else if (persp == 'VisualPerspective') {
89             html2text({
90                 element: $('#html-view').find('div').get(0),
91                 success: function(text){
92                     xml = text;
93                 },
94                 error: function(text){
95                     self.$error.html('<div class="alert alert-danger"><p>Wystąpił błąd:</p><pre>' + text + '</pre></div>');
96                     self.$spinner.hide();
97                     self.$error.show();
98                 }
99             });
100             self.updateAnnotationIds(self);
101         }
102         else {
103             xml = this.doc.text;
104         }
105
106         var parser = new DOMParser();
107         var serializer = new XMLSerializer();
108         var doc = parser.parseFromString(xml, 'text/xml');
109         var error = $('parsererror', doc);
110
111         if (error.length > 0) {
112             self.$error.html('<div class="alert alert-danger">Błąd parsowania XML.</a>');
113             self.$spinner.hide();
114             self.$error.show();
115         }
116         else {
117             self.$annos.html('');
118             var anno_list = [];
119             var annos = $(atype, doc);
120             var counter = annos.length;
121             var atype_rx = atype.replace(/,/g, '|');
122             var ann_expr = new RegExp("^<("+atype_rx+")[^>]*>|</("+atype_rx+")>$", "g");
123
124             if (annos.length == 0)
125             {
126                 self.$annos.html('<div class="alert alert-info">Nie ma żadnych przypisów</div>');
127                 self.$spinner.hide();
128                 self.$annos.show();
129             }
130             annos.each(function (i, elem) {
131                 var xml_text = serializer.serializeToString(elem).replace(ann_expr, "");
132                 xml2html({
133                     xml: "<akap>" + xml_text + "</akap>",
134                     success: function(xml_text){
135                         return function(elem){
136                             elem.sortby = $(elem).text().trim();
137                             $(elem).append("<div class='src'>"+ xml_text.replace(/&/g, "&amp;").replace(/</g, "&lt;") +"</div>");
138                             anno_list.push(elem);
139                             $(".src", elem).click(function() { self.goToAnnotation(self, this); });
140                             counter--;
141
142                             if (!counter) {
143                                 anno_list.sort(function(a, b){return a.sortby.localeCompare(b.sortby);});
144                                 for (i in anno_list)
145                                     self.$annos.append(anno_list[i]);
146                                 self.$spinner.hide();
147                                 self.$annos.show();
148                             }
149
150                         }
151                     }(xml_text),
152                     error: function(text) {
153                         $.unblockUI();
154                         self.$error.html('<div class="alert alert-danger">' + text + '</div>');
155                         self.$spinner.hide();
156                         self.$error.show();
157                     }
158                 });
159             });
160         }
161     };
162
163
164     AnnotationsPerspective.prototype.onEnter = function(){
165         $.wiki.SidebarPerspective.prototype.onEnter.call(this);
166
167         this.$refresh.filter('.active').trigger('click');
168
169     };
170
171         AnnotationsPerspective.prototype.onExit = function(success, failure) {
172
173         };
174
175     $.wiki.AnnotationsPerspective = AnnotationsPerspective;
176
177 })(jQuery);