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