PageSourceSearch

https://www.turquieeuropeenne.eu/plugins-dist/porte_plume/javascript/jquery.markitup_pour_spip.js

js turquieeuropeenne.eu collected 2026-10-02 11:43:03 UTC 25,620 bytes, 787 lines download raw bytes

1var _____WB$wombat$assign$function_____=function(name){return (globalThis._wb_wombat && globalThis._wb_wombat.local_init && globalThis._wb_wombat.local_init(name))||globalThis[name];};if(!globalThis.__WB_pmw){globalThis.__WB_pmw=function(obj){this.__WB_source=obj;return this;}}{
2let window = _____WB$wombat$assign$function_____("window");
3let self = _____WB$wombat$assign$function_____("self");
4let document = _____WB$wombat$assign$function_____("document");
5let location = _____WB$wombat$assign$function_____("location");
6let top = _____WB$wombat$assign$function_____("top");
7let parent = _____WB$wombat$assign$function_____("parent");
8let frames = _____WB$wombat$assign$function_____("frames");
9let opener = _____WB$wombat$assign$function_____("opener");
10// ----------------------------------------------------------------------------
11// markItUp! Universal MarkUp Engine, JQuery plugin
12// v 1.1.12
13// Dual licensed under the MIT and GPL licenses.
14// ----------------------------------------------------------------------------
15// Copyright (C) 2007-2011 Jay Salvat
16// http://markitup.jaysalvat.com/
17// ----------------------------------------------------------------------------
18// Permission is hereby granted, free of charge, to any person obtaining a copy
19// of this software and associated documentation files (the "Software"), to deal
20// in the Software without restriction, including without limitation the rights
21// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
22// copies of the Software, and to permit persons to whom the Software is
23// furnished to do so, subject to the following conditions:
24// 
25// The above copyright notice and this permission notice shall be included in
26// all copies or substantial portions of the Software.
27// 
28// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
31// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
32// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
33// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
34// THE SOFTWARE.
35// ----------------------------------------------------------------------------
36
37/*
38 *   Le code original de markitup 1.1.12
39 *   a ete modifie pour prendre en compte
40 * 
41 *   1) la langue utilisee dans les textarea :
42 * 		- si un textarea possede un attribut lang='xx' alors
43 *   	  markitup n'affichera que les icones qui correspondent a cette langue
44 * 		- on peut passer une valeur de langue par defaut a markitup (le textarea peut ne pas en definir)
45 *   	  .markitup(set_spip,{lang:'fr'});
46 * 		- une option supplementaire optionnelle 'lang' est introduite dans les parametres 
47 *   	  des boutons (markupset), par exemple : lang:['fr','es','en']
48 * 		- si un bouton n'a pas ce parametre, l'icone s'affiche 
49 *   	  quelque soit la langue designee dans le textarea ou les parametres de markitup ;
50 *   	  sinon, il faut que la langue soit contenue dedans pour que l'icone s'affiche.
51
52 *   2) gerer des types de selections differentes : 
53 * 		- normales comme dans markitup (rien a faire)
54 * 		- 'selectionType':'word' : aux mots le plus proche si pas de selection (sinon la selection)
55 * 		- 'selectionType':'line' : aux lignes les plus proches
56 * 		- and 'return' : ugly hack to generate list (and so on) on key 'return' press
57 *
58 *   3) eviter a Opera de gerer les evenements apres tabulation ou entree...
59 *      il ne sait pas gerer (v11.51)
60 * 
61 * 		
62 */
63;(function($) {
64	$.fn.markItUp = function(settings, extraSettings) {
65		var options, ctrlKey, shiftKey, altKey;
66		ctrlKey = shiftKey = altKey = false;
67
68		options = {	id:						'',
69					nameSpace:				'',
70					root:					'',
71					lang:					'',
72					previewInWindow:		'', // 'width=800, height=600, resizable=yes, scrollbars=yes'
73					previewAutoRefresh:		true,
74					previewPosition:		'after',
75					previewTemplatePath:	'~/templates/preview.html',
76					previewParser:			false,
77					previewParserPath:		'',
78					previewParserVar:		'data',
79					resizeHandle:			true,
80					beforeInsert:			'',
81					afterInsert:			'',
82					onEnter:				{},
83					onShiftEnter:			{},
84					onCtrlEnter:			{},
85					onTab:					{},
86					markupSet:			[	{ /* set */ } ]
87				};
88		$.extend(options, settings, extraSettings);
89
90		// compute markItUp! path
91		if (!options.root) {
92			$('script').each(function(a, tag) {
93				miuScript = $(tag).get(0).src.match(/(.*)jquery\.markitup(\.pack)?\.js$/);
94				if (miuScript !== null) {
95					options.root = miuScript[1];
96				}
97			});
98		}
99
100		return this.each(function() {
101			var $$, textarea, levels, scrollPosition, caretPosition,
102				clicked, hash, header, footer, previewWindow, template, iFrame, abort,
103				before, after;
104			$$ = $(this);
105			textarea = this;
106			levels = [];
107			abort = false;
108			scrollPosition = caretPosition = 0;
109			caretOffset = -1;
110
111			options.previewParserPath = localize(options.previewParserPath);
112			options.previewTemplatePath = localize(options.previewTemplatePath);
113
114			// apply the computed path to ~/
115			function localize(data, inText) {
116				if (inText) {
117					return 	data.replace(/("|')~\//g, "$1"+options.root);
118				}
119				return 	data.replace(/^~\//, options.root);
120			}
121
122			// init and build editor
123			function init() {
124				id = ''; nameSpace = '';
125				if (options.id) {
126					id = 'id="'+options.id+'"';
127				} else if ($$.attr("id")) {
128					id = 'id="markItUp'+($$.attr("id").substr(0, 1).toUpperCase())+($$.attr("id").substr(1))+'"';
129
130				}
131				if (options.nameSpace) {
132					nameSpace = 'class="'+options.nameSpace+'"';
133				}
134				currentScrollPosition = $$.scrollTop();
135				$$.wrap('<div '+nameSpace+'></div>');
136				$$.wrap('<div '+id+' class="markItUp"></div>');
137				$$.wrap('<div class="markItUpContainer"></div>');
138				$$.addClass("markItUpEditor");
139				$$.scrollTop(currentScrollPosition);
140
141				// add the header before the textarea
142				header = $('<div class="markItUpHeader"></div>').insertBefore($$);
143				$(dropMenus(options.markupSet)).appendTo(header);
144				// remove empty dropMenu
145				$(header).find("li.markItUpDropMenu ul:empty").parent().remove();
146				
147				// add the footer after the textarea
148				footer = $('<div class="markItUpFooter"></div>').insertAfter($$);
149
150				// add the resize handle after textarea
151				
152				if (options.resizeHandle === true && $.browser.safari !== true) {
153					resizeHandle = $('<div class="markItUpResizeHandle"></div>')
154						.insertAfter($$)
155						.bind("mousedown", function(e) {
156							var h = $$.height(), y = e.clientY, mouseMove, mouseUp;
157							mouseMove = function(e) {
158								$$.css("height", Math.max(20, e.clientY+h-y)+"px");
159								return false;
160							};
161							mouseUp = function(e) {
162								$("html").unbind("mousemove", mouseMove).unbind("mouseup", mouseUp);
163								return false;
164							};
165							$("html").bind("mousemove", mouseMove).bind("mouseup", mouseUp);
166					});
167					footer.append(resizeHandle);
168				}
169
170				// listen key events
171				$$.keydown(keyPressed).keyup(keyPressed);
172				
173				// bind an event to catch external calls
174				$$.bind("insertion", function(e, settings) {
175					if (settings.target !== false) {
176						get();
177					}
178					if (textarea === $.markItUp.focused) {
179						markup(settings);
180					}
181				});
182
183				// remember the last focus
184				$$.focus(function() {
185					$.markItUp.focused = this;
186				});
187			}
188
189			// recursively build header with dropMenus from markupset
190			function dropMenus(markupSet) {
191				var ul = $('<ul></ul>'), i = 0;
192				var lang = ($$.attr('lang')||options.lang);
193				
194				$('li:hover > ul', ul).css('display', 'block');
195				$.each(markupSet, function() {
196					var button = this, t = '', title, li, j;
197					// pas de langue ou dans la langue ; et uniquement si langue autorisee
198					if ((!lang || !button.lang || ($.inArray(lang, button.lang) != -1))
199						&& (!button.lang_not || ($.inArray(lang, button.lang_not) == -1))) {
200						title = (button.key) ? (button.name||'')+' [Ctrl+'+button.key+']' : (button.name||'');
201						key   = (button.key) ? 'accesskey="'+button.key+'"' : '';
202						if (button.separator) {
203							li = $('<li class="markItUpSeparator">'+(button.separator||'')+'</li>').appendTo(ul);
204						} else {
205							i++;
206							for (j = levels.length -1; j >= 0; j--) {
207								t += levels[j]+"-";
208							}
209							li = $('<li class="markItUpButton markItUpButton'+t+(i)+' '+(button.className||'')+'"><a href="" '+key+' title="'+title+'"><em>'+(button.name||'')+'</em></a></li>')
210							.bind("contextmenu", function() { // prevent contextmenu on mac and allow ctrl+click
211								return false;
212							}).click(function() {
213								return false;
214							}).bind("focusin", function(){
215								$$.focus();
216							}).mouseup(function() {
217								if (button.call) {
218									eval(button.call)();
219								}
220								setTimeout(function() { markup(button) },1);
221								return false;
222							}).hover(function() {
223									$('> ul', this).show();
224									$(document).one('click', function() { // close dropmenu if click outside
225											$('ul ul', header).hide();
226										}
227									);
228								}, function() {
229									$('> ul', this).hide();
230								}
231							).appendTo(ul);
232							if (button.dropMenu) {
233								levels.push(i);
234								$(li).addClass('markItUpDropMenu').append(dropMenus(button.dropMenu));
235							}
236						}
237					}
238				}); 
239				levels.pop();
240				return ul;
241			}
242
243			// markItUp! markups
244			function magicMarkups(string) {
245				if (string) {
246					string = string.toString();
247					string = string.replace(/\(\!\(([\s\S]*?)\)\!\)/g,
248						function(x, a) {
249							var b = a.split('|!|');
250							if (altKey === true) {
251								return (b[1] !== undefined) ? b[1] : b[0];
252							} else {
253								return (b[1] === undefined) ? "" : b[0];
254							}
255						}
256					);
257					// [![prompt]!], [![prompt:!:value]!]
258					string = string.replace(/\[\!\[([\s\S]*?)\]\!\]/g,
259						function(x, a) {
260							var b = a.split(':!:');
261							if (abort === true) {
262								return false;
263							}
264							value = prompt(b[0], (b[1]) ? b[1] : '');
265							if (value === null) {
266								abort = true;
267							}
268							return value;
269						}
270					);
271					return string;
272				}
273				return "";
274			}
275
276			// prepare action
277			function prepare(action) {
278				if ($.isFunction(action)) {
279					action = action(hash);
280				}
281				return magicMarkups(action);
282			}
283
284			// build block to insert
285			function build(string) {
286				var openWith 			= prepare(clicked.openWith);
287				var placeHolder 		= prepare(clicked.placeHolder);
288				var replaceWith 		= prepare(clicked.replaceWith);
289				var closeWith 			= prepare(clicked.closeWith);
290				var openBlockWith 		= prepare(clicked.openBlockWith);
291				var closeBlockWith 		= prepare(clicked.closeBlockWith);
292				var multiline 			= clicked.multiline;
293
294				if (replaceWith !== "") {
295					block = openWith + replaceWith + closeWith;
296				} else if (selection === '' && placeHolder !== '') {
297					block = openWith + placeHolder + closeWith;
298				} else if (multiline === true) {
299					string = string || selection;
300
301					var lines = selection.split(/\r?\n/), blocks = [];
302
303					for (var l=0; l < lines.length; l++) {
304						line = lines[l];
305						var trailingSpaces;
306						if (trailingSpaces = line.match(/ *$/)) {
307							blocks.push(openWith + line.replace(/ *$/g, '') + closeWith + trailingSpaces);
308						} else {
309							blocks.push(openWith + line + closeWith);
310						}
311					}
312
313					block = blocks.join("\n");
314				} else {
315					block = openWith + (string || selection) + closeWith;
316				}
317
318				block = openBlockWith + block + closeBlockWith;
319				
320				return {	block:block, 
321							openWith:openWith, 
322							replaceWith:replaceWith, 
323							placeHolder:placeHolder,
324							closeWith:closeWith
325					};
326			}
327
328
329			function selectWord(){
330				selectionBeforeAfter(/\s|[.,;:!¡?¿()]/);
331				selectionSave();				
332			}
333			function selectLine(){
334				selectionBeforeAfter(/\r?\n/);
335				selectionSave();				
336			}			
337			
338			function selectionRemoveLast(pattern){
339					// Remove space by default
340					if (!pattern) pattern = /\s/;
341					last = selection[selection.length-1];
342					if (last && last.match(pattern)) {
343						set(caretPosition, selection.length-1);
344						get();
345						$.extend(hash, { caretPosition:caretPosition, scrollPosition:scrollPosition } );
346					}				
347			}
348			
349			function selectionBeforeAfter(pattern) {
350				if (!pattern) pattern = /\s/;
351
352				sautAvantIE = sautApresIE = 0;
353				if ($.browser.msie) {
354					 	// calcul du nombre reel de caracteres pour le substr()
355					 	// IE ne compte pas les sauts de lignes pour definir les selections
356					 	// mais les compte dans la fonction length()
357						lenSelection = selection.length - fixIeBug(selection);
358						// si le caractere avant mon debut est un saut le ligne,
359						// ie ne le prendra pas en compte dans la selection.
360						// il faut pouvoir le connaitre.
361						if (caretPosition) {
362							set(caretPosition - 1, 2);
363							sautAvantIE = fixIeBug(document.selection.createRange().text);
364						}
365						// idem pour le caractere apres la ligne !
366						set(caretPosition, 2);
367						sautApresIE = fixIeBug(document.selection.createRange().text);
368						// selection avant
369 						set(0,caretPosition);
370 						before = document.selection.createRange().text;
371 						// selection apres
372 						set(caretPosition + lenSelection, textarea.value.length);
373 						after = document.selection.createRange().text;
374 						// remettre la veritable selection
375 						set(caretPosition, lenSelection);
376 						selection = document.selection.createRange().text;
377				} else {
378					before = textarea.value.substring(0, caretPosition);
379					after = textarea.value.substring(caretPosition + selection.length - fixIeBug(selection));
380				}
381						
382				before = before.split(pattern);
383				after = after.split(pattern);
384				// ajouter ce fichu saut de ligne pour IE
385				if (sautAvantIE) before.push("");
386				if (sautApresIE) after.unshift("");
387					
388			}
389			
390			function selectionSave(){
391				nb_before = before ? before[before.length-1].length : 0;
392				nb_after = after ? after[0].length : 0;
393
394				nb = nb_before + selection.length + nb_after - fixIeBug(selection);
395				caretPosition =  caretPosition - nb_before;
396
397				set(caretPosition, nb);
398				get();
399				$.extend(hash, { selection:selection, caretPosition:caretPosition, scrollPosition:scrollPosition } );
400			}
401			
402			// define markup to insert
403			function markup(button) {
404				var len, j, n, i;
405				hash = clicked = button;
406				get();
407				
408				$.extend(hash, {	line:"", 
409						 			root:options.root,
410									textarea:textarea, 
411									selection:(selection||''), 
412									caretPosition:caretPosition,
413									ctrlKey:ctrlKey, 
414									shiftKey:shiftKey, 
415									altKey:altKey
416								}
417							);
418
419				// corrections des selections pour que
420				// - soit le curseur ne change pas
421				// - soit on prend le mot complet (si pas de selection)
422				// - soit on prend la ligne (avant, apres la selection)
423				if (button.selectionType) {
424
425					if (button.selectionType == "word") {
426						if (!selection) {
427							selectWord();
428						} else {
429							// win/ff add space on double click ? (hum, seems strange)
430							selectionRemoveLast(/\s/);
431						}
432					}				
433					if (button.selectionType == "line") {
434						selectLine();
435					}
436					// horrible chose, mais tellement plus pratique
437					// car on ne peut pas de l'exerieur (json) utiliser
438					// les fonctions internes de markitup
439					if (button.selectionType == "return"){
440						// le calcul de before et after sous IE
441						// necessitant de creer des selections
442						// c'est extremement vilain a chaque saut de ligne
443						// des qu'il y a un texte volumineux.
444						// on dit tant pis pour lui.
445						if (!$.browser.msie) {
446							selectionBeforeAfter(/\r?\n/);
447							before_last = before[before.length-1];
448							after = '';
449							// gestion des listes -# et -* 
450							if (r = before_last.match(/^-([*#]+) ?(.*)$/)) {
451								if (r[2]) {
452									button.replaceWith = "\n-"+r[1]+' ';
453									before_last = '';
454								} else {
455									// supprime le -* present
456									// (before le fera)
457									button.replaceWith = "\n";
458								}
459							} else {
460								before_last = '';
461								button.replaceWith = "\n";
462							}
463							before[before.length-1] = before_last;
464							selectionSave();
465						}
466					}
467				}
468				// / fin corrections
469				
470				// callbacks before insertion
471				prepare(options.beforeInsert);
472				prepare(clicked.beforeInsert);
473				if ((ctrlKey === true && shiftKey === true) || button.multiline === true) {
474					prepare(clicked.beforeMultiInsert);
475				}			
476				$.extend(hash, { line:1 });
477
478				if ((ctrlKey === true && shiftKey === true) || button.forceMultiline === true) {
479					lines = selection.split(/\r?\n/);
480					for (j = 0, n = lines.length, i = 0; i < n; i++) {
481						// si une seule ligne, on se fiche de savoir qu'elle est vide,
482						// c'est volontaire si on clique le bouton
483						if (n == 1 || $.trim(lines[i]) !== '') {
484							$.extend(hash, { line:++j, selection:lines[i] } );
485							lines[i] = build(lines[i]).block;
486						} else {
487							lines[i] = "";
488						}
489					}
490					string = { block:lines.join('\n')};
491					start = caretPosition;
492					len = string.block.length + (($.browser.opera) ? n-1 : 0);
493				} else if (ctrlKey === true) {
494					string = build(selection);
495					start = caretPosition + string.openWith.length;
496					len = string.block.length - string.openWith.length - string.closeWith.length;
497					len = len - (string.block.match(/ $/) ? 1 : 0);
498					len -= fixIeBug(string.block);
499				} else if (shiftKey === true) {
500					string = build(selection);
501					start = caretPosition;
502					len = string.block.length;
503					len -= fixIeBug(string.block);
504				} else {
505					string = build(selection);
506					start = caretPosition + string.block.length ;
507					len = 0;
508					start -= fixIeBug(string.block);
509				}
510
511				if ((selection === '' && string.replaceWith === '')) {
512					caretOffset += fixOperaBug(string.block);
513					
514					start = caretPosition + string.openWith.length;
515					len = string.block.length - string.openWith.length - string.closeWith.length;
516
517					caretOffset = $$.val().substring(caretPosition,  $$.val().length).length;
518					caretOffset -= fixOperaBug($$.val().substring(0, caretPosition));
519				}
520				$.extend(hash, { caretPosition:caretPosition, scrollPosition:scrollPosition } );
521
522				if (string.block !== selection && abort === false) {
523					insert(string.block);
524					set(start, len);
525				} else {
526					caretOffset = -1;
527				}
528				get();
529
530				$.extend(hash, { line:'', selection:selection });
531
532				// callbacks after insertion
533				if ((ctrlKey === true && shiftKey === true) || button.multiline === true) {
534					prepare(clicked.afterMultiInsert);
535				}
536
537				prepare(clicked.afterInsert);
538				prepare(options.afterInsert);
539
540				// refresh preview if opened
541				if (previewWindow && options.previewAutoRefresh) {
542					refreshPreview(); 
543				}
544				
545				// reinit keyevent
546				shiftKey = altKey = ctrlKey = abort = false;
547				
548			}
549
550			// Substract linefeed in Opera
551			function fixOperaBug(string) {
552				if ($.browser.opera) {
553					return string.length - string.replace(/\n*/g, '').length;
554				}
555				return 0;
556			}
557			// Substract linefeed in IE
558			function fixIeBug(string) {
559				if ($.browser.msie) {
560					return string.length - string.replace(/\r*/g, '').length;
561				}
562				return 0;
563			}
564				
565			// add markup
566			function insert(block) {	
567				if (document.selection) {
568					var newSelection = document.selection.createRange();
569					newSelection.text = block;
570				} else {
571					textarea.value =  textarea.value.substring(0, caretPosition)  + block + textarea.value.substring(caretPosition + selection.length, textarea.value.length);
572				}
573			}
574
575			// set a selection
576			function set(start, len) {
577				if (textarea.createTextRange){
578					// quick fix to make it work on Opera 9.5
579					if ($.browser.opera && $.browser.version >= 9.5 && len == 0) {
580						return false;
581					}
582					range = textarea.createTextRange();
583					range.collapse(true);
584					range.moveStart('character', start); 
585					range.moveEnd('character', len); 
586					range.select();
587				} else if (textarea.setSelectionRange ){
588					textarea.setSelectionRange(start, start + len);
589				}
590				textarea.scrollTop = scrollPosition;
591				textarea.focus();
592			}
593
594			// get the selection
595			function get() {
596				textarea.focus();
597
598				scrollPosition = textarea.scrollTop;
599				if (document.selection) {
600					selection = document.selection.createRange().text;
601					if ($.browser.msie) { // ie
602						var range = document.selection.createRange(), rangeCopy = range.duplicate();
603						rangeCopy.moveToElementText(textarea);
604						caretPosition = -1;
605						while(rangeCopy.inRange(range)) {
606							rangeCopy.moveStart('character');
607							caretPosition ++;
608						}
609					} else { // opera
610						caretPosition = textarea.selectionStart;
611					}
612				} else { // gecko & webkit
613					caretPosition = textarea.selectionStart;
614					selection = textarea.value.substring(caretPosition, textarea.selectionEnd);
615	
616				} 
617				return selection;
618			}
619
620			// open preview window
621			function preview() {
622				if (!previewWindow || previewWindow.closed) {
623					if (options.previewInWindow) {
624						previewWindow = window.open('', 'preview', options.previewInWindow);
625						$(window).unload(function() {
626							previewWindow.close();
627						});
628					} else {
629						iFrame = $('<iframe class="markItUpPreviewFrame"></iframe>');
630						if (options.previewPosition == 'after') {
631							iFrame.insertAfter(footer);
632						} else {
633							iFrame.insertBefore(header);
634						}
635						previewWindow = iFrame[iFrame.length - 1].contentWindow || frame[iFrame.length - 1];
636					}
637				} else if (altKey === true) {
638					if (iFrame) {
639						iFrame.remove();
640					} else {
641						previewWindow.close();
642					}
643					previewWindow = iFrame = false;
644				}
645				if (!options.previewAutoRefresh) {
646					refreshPreview(); 
647				}
648				if (options.previewInWindow) {
649					previewWindow.focus();
650				}
651			}
652
653			// refresh Preview window
654			function refreshPreview() {
655				renderPreview();
656			}
657
658			function renderPreview() {
659				var phtml;
660				if (options.previewParser && typeof options.previewParser === 'function') {
661					var data = options.previewParser( $$.val() );
662					writeInPreview( localize(data, 1) ); 
663				} else if (options.previewParserPath !== '') {
664					$.ajax({
665						type: 'POST',
666						dataType: 'text',
667						global: false,
668						url: options.previewParserPath,
669						data: options.previewParserVar+'='+encodeURIComponent($$.val()),
670						success: function(data) {
671							writeInPreview( localize(data, 1) ); 
672						}
673					});
674				} else {
675					if (!template) {
676						$.ajax( {
677							url: options.previewTemplatePath,
678							dataType: 'text',
679							global: false,
680							success: function(data) {
681								writeInPreview( localize(data, 1).replace(/<!-- content -->/g, $$.val()) );
682							}
683						});
684					}
685				}
686				return false;
687			}
688
689			function writeInPreview(data) {
690				if (previewWindow.document) {			
691					try {
692						sp = previewWindow.document.documentElement.scrollTop
693					} catch(e) {
694						sp = 0;
695					}	
696					previewWindow.document.open();
697					previewWindow.document.write(data);
698					previewWindow.document.close();
699					previewWindow.document.documentElement.scrollTop = sp;
700				}
701			}
702						
703			// set keys pressed
704			function keyPressed(e) {
705				shiftKey = e.shiftKey;
706				altKey = e.altKey;
707				ctrlKey = (!(e.altKey && e.ctrlKey)) ? (e.ctrlKey || e.metaKey) : false;
708
709				if (e.type === 'keydown') {
710					if (ctrlKey === true) {
711						li = $('a[accesskey="'+String.fromCharCode(e.keyCode)+'"]', header).parent('li');
712						if (li.length !== 0) {
713							ctrlKey = false;
714							setTimeout(function() {
715								li.triggerHandler('mouseup');
716							},1);
717							return false;
718						}
719					}
720					
721 					// si opera, on s'embete pas, il cree plus de problemes qu'autre chose
722 					// car il ne prend pas en compte l'arret de ces evenements
723					if (!$.browser.opera) {	
724						if (e.keyCode === 13 || e.keyCode === 10) { // Enter key
725							if (ctrlKey === true) {  // Enter + Ctrl
726								ctrlKey = false;
727								markup(options.onCtrlEnter);
728								return options.onCtrlEnter.keepDefault;
729							} else if (shiftKey === true) { // Enter + Shift
730								shiftKey = false;
731								markup(options.onShiftEnter);
732								return options.onShiftEnter.keepDefault;
733							} else { // only Enter
734								markup(options.onEnter);
735								return options.onEnter.keepDefault;
736							}
737						}
738						
739						if (e.keyCode === 9) { // Tab key
740							if (shiftKey == true || ctrlKey == true || altKey == true) {
741								// permettre un retour a l'action naturelle
742								// du navigateur via shift+tab 
743								return true; 
744							}
745							if (caretOffset !== -1) {
746								get();
747								caretOffset = $$.val().length - caretOffset;
748								set(caretOffset, 0);
749								caretOffset = -1;
750								return false;
751							} else {
752								markup(options.onTab);
753								return options.onTab.keepDefault;
754							}
755						}
756					}
757				}
758			}
759
760			init();
761		});
762	};
763
764	$.fn.markItUpRemove = function() {
765		return this.each(function() {
766				var $$ = $(this).unbind().removeClass('markItUpEditor');
767				$$.parent('div').parent('div.markItUp').parent('div').replaceWith($$);
768			}
769		);
770	};
771
772	$.markItUp = function(settings) {
773		var options = { target:false };
774		$.extend(options, settings);
775		if (options.target) {
776			return $(options.target).each(function() {
777				$(this).focus();
778				$(this).trigger('insertion', [options]);
779			});
780		} else {
781			$('textarea').trigger('insertion', [options]);
782		}
783	};
784
785})(jQuery);
786
787}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.