integration/js/annotation-article.js
changeset 31 059e197617bb
child 32 3612737630f4
equal deleted inserted replaced
30:719aed020d05 31:059e197617bb
       
     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         dragging = false;
       
    40     
       
    41     function cleanText(txt, keepbefore, keepafter) {
       
    42         var res = txt.replace(/[\n\r\t]+/gm,' ').replace(/ {2,}/g,' ');
       
    43         if (!keepbefore) {
       
    44             res = res.replace(/^ +/,'');
       
    45         }
       
    46         if (!keepafter) {
       
    47             res = res.replace(/ +$/,'');
       
    48         }
       
    49         return res;
       
    50     }
       
    51     
       
    52     function recursiveParse(node, info) {
       
    53         var children = node.childNodes;
       
    54         for (var i = 0, l = children.length; i < l; i++) {
       
    55             var childnode = children[i];
       
    56             switch(childnode.nodeType) {
       
    57                 case node.ELEMENT_NODE:
       
    58                     recursiveParse(childnode, info);
       
    59                 break;
       
    60                 case node.TEXT_NODE:
       
    61                     var startpos = info.text.length;
       
    62                     info.text += childnode.textContent;
       
    63                     var endpos = info.text.length,
       
    64                         nodeinfo = {
       
    65                             start: startpos,
       
    66                             end: endpos,
       
    67                             length: endpos - startpos,
       
    68                             textNode: childnode
       
    69                         };
       
    70                     childnode._nodeInfo = nodeinfo;
       
    71                     info.nodes.push(nodeinfo);
       
    72                 break;
       
    73             }
       
    74         }
       
    75     }
       
    76     
       
    77     
       
    78     function parseContents(node) {
       
    79         var res = {
       
    80             text: '',
       
    81             nodes: []
       
    82         };
       
    83         recursiveParse(node, res);
       
    84         return res;
       
    85     }
       
    86     
       
    87     function cleanTextNodes(node) {
       
    88         var children = node.childNodes;
       
    89         for (var i = 0, l = children.length; i < l; i++) {
       
    90             var childnode = children[i];
       
    91             switch(childnode.nodeType) {
       
    92                 case node.ELEMENT_NODE:
       
    93                     cleanTextNodes(childnode);
       
    94                 break;
       
    95                 case node.TEXT_NODE:
       
    96                     var keepbefore = (i && children[i-1].nodeType == node.ELEMENT_NODE),
       
    97                         keepafter = (i < l-1 && children[i+1].nodeType == node.ELEMENT_NODE);
       
    98                     childnode.textContent = cleanText(childnode.textContent, keepbefore, keepafter);
       
    99                 break;
       
   100             }
       
   101         }
       
   102         return node;
       
   103     }
       
   104     
       
   105     function highlightText(start, end, color) {
       
   106         var annotation = {
       
   107             startOffset: start,
       
   108             endOffset: end,
       
   109             color: color,
       
   110             comment: "",
       
   111             annotatedText: textinfo.text.substring(start, end),
       
   112             beforeText: textinfo.text.substring(start - 40, start).replace(/^[\S]*\s+/,''),
       
   113             afterText: textinfo.text.substring(end, end + 40).replace(/\s+[\S]*$/,'')
       
   114         }
       
   115         annotations.push(annotation);
       
   116         showAnnotation(annotation);
       
   117     }
       
   118     
       
   119     var frameTpl = _.template(
       
   120         '<div class="annotation-frame" style="border-color: <%- annotation.color %>; top: <%-top %>px; left: <%- left %>px;">'
       
   121         + '<div class="annotation-area" style="background-color: <%- annotation.color %>; height: <%- height %>px;"></div>'
       
   122         + '<form class="annotation-form"><h3>Annoter&nbsp;:</h3>'
       
   123         + '<textarea class="annotation-textarea" placeholder="Mon commentaire&hellip;"><%- annotation.comment || "" %></textarea>'
       
   124         + '</form></div>'
       
   125     );
       
   126     
       
   127     var liTpl = _.template(
       
   128         '<li style="border-color: <%- annotation.color %>;"><h3>Texte annoté</h3>'
       
   129         + '<p class="annotation-text"><%- annotation.beforeText %><b><%- annotation.annotatedText %></b><%- annotation.afterText %></p>'
       
   130         + '<h3>Commentaire</h3><p class="annotation-comment"><%- annotation.comment || "(Sans commentaire)" %></p>'
       
   131     );
       
   132     
       
   133     function showFrameBox() {
       
   134         if (currentVisibleFrame) {
       
   135             $(".annotation-frame-box").show();
       
   136             var offset = currentVisibleFrame.offset(),
       
   137                 width = currentVisibleFrame.outerWidth(),
       
   138                 height = currentVisibleFrame.outerHeight();
       
   139             $(".annotation-fb-top").css({
       
   140                 height: offset.top - 77
       
   141             });
       
   142             $(".annotation-fb-left").css({
       
   143                 top: offset.top,
       
   144                 height: height,
       
   145                 width: offset.left
       
   146             });
       
   147             $(".annotation-fb-right").css({
       
   148                 top: offset.top,
       
   149                 height: height,
       
   150                 left: offset.left + width
       
   151             });
       
   152             var fbbtop = offset.top + height;
       
   153             $(".annotation-fb-bottom").css({
       
   154                 top: fbbtop,
       
   155                 height: ($("body").height() - fbbtop)
       
   156             });
       
   157         } else {
       
   158             $(".annotation-frame-box").hide();
       
   159         }
       
   160     }
       
   161     
       
   162     function hideAllFrames() {
       
   163         if (currentVisibleFrame) {
       
   164             currentVisibleFrame.hide();
       
   165         }
       
   166         
       
   167         currentVisibleFrame = null;
       
   168         showFrameBox();
       
   169         $(".annotations-list li").removeClass("selected");
       
   170     }
       
   171     
       
   172     function showAnnotation(annotation) {
       
   173         var start = annotation.startOffset,
       
   174             end = annotation.endOffset,
       
   175             color = annotation.color;
       
   176         var spans = [];
       
   177         
       
   178         for (var i = 0, l = textinfo.nodes.length; i < l; i++) {
       
   179             var nodeinfo = textinfo.nodes[i];
       
   180             if (nodeinfo.end > start && nodeinfo.start <= end) {
       
   181                 var r = document.createRange(),
       
   182                     s = document.createElement('span'),
       
   183                     rangestart = Math.max(0, start - nodeinfo.start),
       
   184                     rangeend = Math.min(nodeinfo.length, end - nodeinfo.start);
       
   185                 s.style.backgroundColor = color;
       
   186                 r.setStart(nodeinfo.textNode, rangestart);
       
   187                 r.setEnd(nodeinfo.textNode, rangeend);
       
   188                 r.surroundContents(s);
       
   189                 spans.push(s);
       
   190             }
       
   191         }
       
   192         textinfo = parseContents(basenode);
       
   193         var top = Math.min.apply(Math, spans.map(function(s) { return s.offsetTop })),
       
   194             height = Math.max.apply(Math, spans.map(function(s) { return s.offsetHeight + s.offsetTop })) - top,
       
   195             frame = $(frameTpl({
       
   196                 annotation: annotation,
       
   197                 top: top,
       
   198                 height: height,
       
   199                 left: basenode.offsetLeft
       
   200             })),
       
   201             li = $(liTpl({
       
   202                 annotation: annotation
       
   203             }));
       
   204         
       
   205         $(".annotation-frames").append(frame);
       
   206         $(".annotation-list").append(li);
       
   207         
       
   208         frame.find(".annotation-textarea").on("keyup change", function() {
       
   209             annotation.comment = $(this).val();
       
   210             li.find(".annotation-comment").text(annotation.comment || "(Sans commentaire)");
       
   211         });
       
   212         
       
   213         var show = function() {
       
   214             if (mousedown) {
       
   215                 return;
       
   216             }
       
   217             currentVisibleFrame = frame;
       
   218             frame.show();
       
   219             showFrameBox();
       
   220             li.addClass("selected");
       
   221         }
       
   222         
       
   223         $(spans).hover(show, hideAllFrames);
       
   224         frame.hover(show, hideAllFrames);
       
   225         li.hover(
       
   226             function() {
       
   227                 $(spans).addClass("annotation-selected");
       
   228                 li.addClass("selected");
       
   229             },
       
   230             function() {
       
   231                 $(spans).removeClass("annotation-selected");
       
   232                 li.removeClass("selected");
       
   233             }
       
   234         ).click(function() {
       
   235             show();
       
   236             $(window).scrollTop(currentVisibleFrame.offset().top - 100);
       
   237         });
       
   238     }
       
   239     
       
   240     window.annotations.forEach(function(annotation) {
       
   241         showAnnotation(annotation);
       
   242     });
       
   243     
       
   244     $(".content")
       
   245         .mousedown(function() {
       
   246             mousedown = true;
       
   247             dragging = false;
       
   248         })
       
   249         .mousemove(function() {
       
   250             if (mousedown) {
       
   251                 dragging = true;
       
   252             }
       
   253         })
       
   254         .mouseup(function() {
       
   255             if (!dragging) {
       
   256                 return;
       
   257             }
       
   258             var range = document.getSelection().getRangeAt(0);
       
   259             if (!range.collapsed && range.startContainer._nodeInfo && range.endContainer._nodeInfo) {
       
   260                 var start = range.startOffset + range.startContainer._nodeInfo.start,
       
   261                     end = range.endOffset + range.endContainer._nodeInfo.start;
       
   262                 highlightText(start, end, colors[ncol++ % colors.length]);
       
   263                 document.getSelection().removeAllRanges();
       
   264             }
       
   265         });
       
   266         
       
   267     $(window).mouseup(function() {
       
   268         mousedown = false;
       
   269         dragging = false;
       
   270     });
       
   271     
       
   272     $(".annotation-frame-box").click(hideAllFrames);
       
   273     
       
   274     $(window).resize(function() {
       
   275         showFrameBox();
       
   276         $(".annotation-frame").css({
       
   277             left: basenode.offsetLeft
       
   278         })
       
   279     })
       
   280 
       
   281 });