|
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 :</h3>' |
|
123 + '<textarea class="annotation-textarea" placeholder="Mon commentaire…"><%- 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 }); |