alcatel/static/js/annotation-article.js
changeset 44 3648b6dea2cc
equal deleted inserted replaced
43:d32f123bfb9e 44:3648b6dea2cc
       
     1 $(function() {
       
     2 
       
     3     $(".fancybox").fancybox();
       
     4     $('.font-up a').click(function(){
       
     5         var taille_police=parseFloat($('.content').css('font-size'),100)+2;
       
     6         if(taille_police<30){
       
     7             var taille_ligne=parseFloat($('.content').css('line-height'),100)+2;
       
     8             $('.content').css({
       
     9                 'line-height':taille_ligne+'px',
       
    10                 'font-size':taille_police+'px'
       
    11             });
       
    12         }
       
    13         return false;
       
    14     });
       
    15     $('.font-down a').click(function(){
       
    16         var taille_police=parseFloat($('.content').css('font-size'),100)-2;
       
    17         if(taille_police>11){
       
    18             var taille_ligne=parseFloat($('.content').css('line-height'),100)-2;
       
    19             $('.content').css({
       
    20                 'line-height':taille_ligne+'px',
       
    21                 'font-size':taille_police+'px'
       
    22             });
       
    23         }
       
    24         return false;
       
    25     });
       
    26     
       
    27     /* ANNOTATION HANDLING */
       
    28     
       
    29     var basenode = $(".content")[0],
       
    30         cleanHtml = cleanTextNodes(basenode).innerHtml,
       
    31         textinfo = parseContents(basenode);
       
    32         
       
    33     window.annotations = window.annotations || [];
       
    34     
       
    35     var colors = ["#ff8", "#f88", "#8f8", "#8ff", "#f8f", "#88f"],
       
    36         currentVisibleFrame = null,
       
    37         ncol = 0,
       
    38         mousedown = false,
       
    39         shownByClick = false,
       
    40         dragging = false;
       
    41     
       
    42     function cleanText(txt, keepbefore, keepafter) {
       
    43         var res = txt.replace(/[\n\r\t]+/gm,' ').replace(/ {2,}/g,' ');
       
    44         if (!keepbefore) {
       
    45             res = res.replace(/^ +/,'');
       
    46         }
       
    47         if (!keepafter) {
       
    48             res = res.replace(/ +$/,'');
       
    49         }
       
    50         return res;
       
    51     }
       
    52     
       
    53     function recursiveParse(node, info) {
       
    54         var children = node.childNodes;
       
    55         for (var i = 0, l = children.length; i < l; i++) {
       
    56             var childnode = children[i];
       
    57             switch(childnode.nodeType) {
       
    58                 case node.ELEMENT_NODE:
       
    59                     recursiveParse(childnode, info);
       
    60                 break;
       
    61                 case node.TEXT_NODE:
       
    62                     var startpos = info.text.length;
       
    63                     info.text += childnode.textContent;
       
    64                     var endpos = info.text.length,
       
    65                         nodeinfo = {
       
    66                             start: startpos,
       
    67                             end: endpos,
       
    68                             length: endpos - startpos,
       
    69                             textNode: childnode
       
    70                         };
       
    71                     childnode._nodeInfo = nodeinfo;
       
    72                     info.nodes.push(nodeinfo);
       
    73                 break;
       
    74             }
       
    75         }
       
    76     }
       
    77     
       
    78     
       
    79     function parseContents(node) {
       
    80         var res = {
       
    81             text: '',
       
    82             nodes: []
       
    83         };
       
    84         recursiveParse(node, res);
       
    85         return res;
       
    86     }
       
    87     
       
    88     function cleanTextNodes(node) {
       
    89         var children = node.childNodes;
       
    90         for (var i = 0, l = children.length; i < l; i++) {
       
    91             var childnode = children[i];
       
    92             switch(childnode.nodeType) {
       
    93                 case node.ELEMENT_NODE:
       
    94                     cleanTextNodes(childnode);
       
    95                 break;
       
    96                 case node.TEXT_NODE:
       
    97                     var keepbefore = (i && children[i-1].nodeType == node.ELEMENT_NODE),
       
    98                         keepafter = (i < l-1 && children[i+1].nodeType == node.ELEMENT_NODE);
       
    99                     childnode.textContent = cleanText(childnode.textContent, keepbefore, keepafter);
       
   100                 break;
       
   101             }
       
   102         }
       
   103         return node;
       
   104     }
       
   105     
       
   106     function highlightText(start, end, color) {
       
   107 		alert('start'+start);
       
   108 		alert('end'+end);
       
   109 		alert('color'+color);
       
   110 
       
   111 		alert('textinfo.text.substring(start, end)'+textinfo.text.substring(start, end));
       
   112 		alert('currentDocumentaryFile'+currentDocumentaryFile);
       
   113 		
       
   114 		
       
   115         var annotation = {
       
   116             startOffset: start,
       
   117             length: end - start,
       
   118             color: color,
       
   119             comment: "",
       
   120             creator: "cobled",
       
   121             tags: [],
       
   122             annotatedText: textinfo.text.substring(start, end),
       
   123             beforeText: textinfo.text.substring(start - 40, start).replace(/^[\S]*\s+/,''),
       
   124             afterText: textinfo.text.substring(end, end + 40).replace(/\s+[\S]*$/,''),
       
   125             documentaryFile: currentDocumentaryFile
       
   126         }
       
   127 			alert('highlightText');
       
   128         annotations.push(annotation);
       
   129 			alert('highlightText');
       
   130         showAnnotation(annotation, true);
       
   131 			alert('highlightText');
       
   132         updateAnnotationCounts();
       
   133 			alert('highlightText');
       
   134     }
       
   135     
       
   136     var frameTpl = _.template(
       
   137         '<div class="annotation-frame" style="border-color: <%- annotation.color %>; top: <%-top %>px; left: <%- left %>px;">'
       
   138         + '<div class="annotation-area" style="background-color: <%- annotation.color %>; height: <%- height %>px;"></div>'
       
   139         + '<form class="annotation-form"><h3>Annoté par&nbsp;: <em><%- annotation.creator.name %></em></h3>'
       
   140         + '<h3>Dossier documentaire&nbsp;: <em><%- annotation.documentaryFile.name %></em></h3><h3>Commentaire&nbsp;:</h3>'
       
   141         + '<% if (editable) { %><textarea class="annotation-textarea" placeholder="Mon commentaire&hellip;"><%- annotation.comment || "" %></textarea>'
       
   142         + '<% } else { %><p><%- annotation.comment || "(sans commentaire)" %></p><% } %>'
       
   143         + '<h3>Mots-clés&nbsp;:</h3>'
       
   144         + '<ul class="<%- editable ? "annotation-tags-form" : "" %>"><% _(annotation.tags).forEach(function(tag) { %><li><%- tag %></li><% }) %></ul>'
       
   145         + '<% if (editable) { %><h3><input class="annotation-public" type="checkbox" <% if (annotation.isPublic) {%>checked <% } %>/>Annotation publique</h3><div><a class="annotation-remove" href="#">Supprimer</a><input class="annotation-submit" type="submit" value="Enregistrer" /></div><% } %>'
       
   146         + '</form></div>'
       
   147     );
       
   148     
       
   149     var liTpl = _.template(
       
   150         '<li style="border-color: <%- annotation.color %>;"><div class="annotation-longview"><h3>Texte annoté&nbsp;:</h3></div>'
       
   151         + '<p class="annotation-text"><%- annotation.beforeText %><b><%- annotation.annotatedText %></b><%- annotation.afterText %></p>'
       
   152         + '<h3>Annoté par&nbsp;: <em><%- annotation.creator.name %></em></h3>'
       
   153         + '<div class="annotation-longview"><h3>Commentaire&nbsp;:</h3><p class="annotation-comment"><%- annotation.comment || "(Sans commentaire)" %></p>'
       
   154         + '<h3>Mots-clés&nbsp;:</h3><p class="annotation-tags"><%- (annotation.tags || []).join(", ") || "(aucun mot-clé)" %></p></div>'
       
   155         + '</li>'
       
   156     );
       
   157     
       
   158     function showFrameBox() {
       
   159         if (currentVisibleFrame) {
       
   160             $(".annotation-frame-box").show();
       
   161             var offset = currentVisibleFrame.offset(),
       
   162                 width = currentVisibleFrame.outerWidth(),
       
   163                 height = currentVisibleFrame.outerHeight();
       
   164             $(".annotation-fb-top").css({
       
   165                 height: offset.top - 77
       
   166             });
       
   167             $(".annotation-fb-left").css({
       
   168                 top: offset.top,
       
   169                 height: height,
       
   170                 width: offset.left
       
   171             });
       
   172             $(".annotation-fb-right").css({
       
   173                 top: offset.top,
       
   174                 height: height,
       
   175                 left: offset.left + width
       
   176             });
       
   177             var fbbtop = offset.top + height;
       
   178             $(".annotation-fb-bottom").css({
       
   179                 top: fbbtop,
       
   180                 height: ($("body").height() - fbbtop)
       
   181             });
       
   182             currentVisibleFrame.find(".annotation-textarea").focus();
       
   183         } else {
       
   184             $(".annotation-frame-box").hide();
       
   185         }
       
   186     }
       
   187     
       
   188     function hideAllFrames() {
       
   189         if (currentVisibleFrame) {
       
   190             currentVisibleFrame.hide();
       
   191         }
       
   192         
       
   193         currentVisibleFrame = null;
       
   194         showFrameBox();
       
   195         $(".annotation-blocks li").removeClass("selected");
       
   196     }
       
   197     
       
   198     function showAnnotation(annotation, editAfterShow) {
       
   199         var start = annotation.startOffset,
       
   200             end = annotation.length + start,
       
   201             color = annotation.color;
       
   202         var spans = [];
       
   203         
       
   204         for (var i = 0, l = textinfo.nodes.length; i < l; i++) {
       
   205             var nodeinfo = textinfo.nodes[i];
       
   206             if (nodeinfo.end > start && nodeinfo.start <= end) {
       
   207                 var r = document.createRange(),
       
   208                     s = document.createElement('span'),
       
   209                     rangestart = Math.max(0, start - nodeinfo.start),
       
   210                     rangeend = Math.min(nodeinfo.length, end - nodeinfo.start);
       
   211                 s.style.backgroundColor = color;
       
   212                 r.setStart(nodeinfo.textNode, rangestart);
       
   213                 r.setEnd(nodeinfo.textNode, rangeend);
       
   214                 r.surroundContents(s);
       
   215                 spans.push(s);
       
   216             }
       
   217         }
       
   218         
       
   219         textinfo = parseContents(basenode);
       
   220         var top = Math.min.apply(Math, spans.map(function(s) { return s.offsetTop })),
       
   221             height = Math.max.apply(Math, spans.map(function(s) { return s.offsetHeight + s.offsetTop })) - top,
       
   222             frame = $(frameTpl({
       
   223                 annotation: annotation,
       
   224                 editable: (currentUser.id === annotation.creator.id),
       
   225                 top: top,
       
   226                 height: height,
       
   227                 left: basenode.offsetLeft
       
   228             })),
       
   229             li = $(liTpl({
       
   230                 annotation: annotation
       
   231             }));
       
   232         
       
   233         $(".annotation-frames").append(frame);
       
   234         $(annotation.documentaryFile.id === currentDocumentaryFile.id ? ".annotation-file-list" : ".annotation-other-list").append(li);
       
   235         
       
   236         frame.find(".annotation-textarea").on("keyup paste input change", function() {
       
   237             annotation.comment = $(this).val();
       
   238             li.find(".annotation-comment").text(annotation.comment || "(Sans commentaire)");
       
   239         });
       
   240         
       
   241         frame.find(".annotation-public").change(function() {
       
   242             annotation.isPublic = $(this).is(":checked");
       
   243         });
       
   244         
       
   245         frame.find("")
       
   246         
       
   247         var ontagchange = function(evt, ui) {
       
   248             annotation.tags = $(this).tagit("assignedTags");
       
   249             li.find(".annotation-tags").text((annotation.tags || []).join(", ") || "(aucun mot-clé)");
       
   250         };
       
   251         
       
   252         frame.find(".annotation-tags-form").tagit({
       
   253             afterTagAdded: ontagchange,
       
   254             afterTagRemoved: ontagchange
       
   255         });
       
   256         
       
   257         var show = function() {
       
   258             if (mousedown) {
       
   259                 return;
       
   260             }
       
   261             shownByClick = false;
       
   262             currentVisibleFrame = frame;
       
   263             frame.show();
       
   264             showFrameBox();
       
   265             li.addClass("selected");
       
   266         }
       
   267                 
       
   268         $(spans).mouseenter(show);
       
   269         
       
   270         frame
       
   271             .mouseleave(function() {
       
   272                 if (!shownByClick) {
       
   273                     hideAllFrames();
       
   274                 }
       
   275             })
       
   276             .click(function() {
       
   277                 shownByClick = true;
       
   278             });
       
   279         
       
   280         frame.find(".annotation-form").submit(function() {
       
   281             hideAllFrames();
       
   282             return false;
       
   283         });
       
   284         
       
   285         frame.find(".annotation-remove").click(function() {
       
   286             annotations = _(annotations).reject(function(a) {
       
   287                 return a === annotation
       
   288             });
       
   289             $(spans).css("background-color","").off("mouseenter",show);
       
   290             li.remove();
       
   291             frame.remove();
       
   292             hideAllFrames();
       
   293             updateAnnotationCounts();
       
   294             return false;
       
   295         });
       
   296         
       
   297         li
       
   298             .mouseenter(function() {
       
   299                 $(spans).addClass("annotation-selected");
       
   300                 li.addClass("selected");
       
   301                 li.find(".annotation-longview").stop().slideDown();
       
   302             })
       
   303             .mouseleave(function() {
       
   304                 $(spans).removeClass("annotation-selected");
       
   305                 li.removeClass("selected");
       
   306                 li.find(".annotation-longview").stop().slideUp();
       
   307             })
       
   308             .click(function() {
       
   309                 show();
       
   310                 shownByClick = true;
       
   311                 $(window).scrollTop(currentVisibleFrame.offset().top - 100);
       
   312             });
       
   313         
       
   314         if (editAfterShow) {
       
   315             show();
       
   316             shownByClick = true;
       
   317         }
       
   318         
       
   319     }
       
   320     
       
   321     function updateAnnotationCounts() {
       
   322         $(".annotation-blocks .block").each(function() {
       
   323             var $this = $(this), n = $this.find("li").length;
       
   324             $this.find(".annotations-count").text(n || "aucune");
       
   325             if (n > 1) {
       
   326                 $this.find(".annotation-plural").show();
       
   327             } else {
       
   328                 $this.find(".annotation-plural").hide();
       
   329             }
       
   330         })
       
   331     }
       
   332     
       
   333     annotations.forEach(function(annotation) {
       
   334         showAnnotation(annotation);
       
   335     });
       
   336     updateAnnotationCounts();
       
   337     
       
   338     var range = null;
       
   339         
       
   340     $(".content").mouseup(function(e) {
       
   341         range = document.getSelection().getRangeAt(0);
       
   342         var addann = $(".add-annotation");
       
   343         if (!range.collapsed && range.startContainer._nodeInfo && range.endContainer._nodeInfo && range.toString() !== " ") {
       
   344             addann.show();
       
   345             var doc = $(document), rect = range.getBoundingClientRect();
       
   346             addann.css({
       
   347                 left: doc.scrollLeft() + rect.right + 5,
       
   348                 top: doc.scrollTop() + (rect.top + rect.bottom - addann.outerHeight()) / 2,
       
   349             });
       
   350         } else {
       
   351             range = null;
       
   352             $(".add-annotation").hide();
       
   353         }
       
   354     }).mousedown(function() {
       
   355         $(".add-annotation").hide();
       
   356     });
       
   357     
       
   358     $(".add-annotation").click(function() {
       
   359 		
       
   360         $(".add-annotation").hide();
       
   361         if (range) {
       
   362 			
       
   363             var start = range.startOffset + range.startContainer._nodeInfo.start,
       
   364                 end = range.endOffset + range.endContainer._nodeInfo.start;
       
   365 				
       
   366             highlightText(start, end, colors[ncol++ % colors.length]);
       
   367             document.getSelection().removeAllRanges();
       
   368         }
       
   369     });
       
   370             
       
   371     $(window).mouseup(function() {
       
   372         mousedown = false;
       
   373         dragging = false;
       
   374     });
       
   375     
       
   376     $(".annotation-frame-box").click(hideAllFrames);
       
   377     
       
   378     $(window).resize(function() {
       
   379         showFrameBox();
       
   380         $(".annotation-frame").css({
       
   381             left: basenode.offsetLeft
       
   382         })
       
   383     });
       
   384     
       
   385     $(".add-annotation").css({
       
   386         left: (basenode.offsetLeft + 500)
       
   387     });
       
   388 
       
   389 });