MediaWiki:Gadget-sel t.js

Z Wikiźródeł, wolnej biblioteki

Uwaga: aby zobaczyć zmiany po opublikowaniu, może zajść potrzeba wyczyszczenia pamięci podręcznej przeglądarki.

  • Firefox / Safari: Przytrzymaj Shift podczas klikania Odśwież bieżącą stronę, lub naciśnij klawisze Ctrl+F5, lub Ctrl+R (⌘-R na komputerze Mac)
  • Google Chrome: Naciśnij Ctrl-Shift-R (⌘-Shift-R na komputerze Mac)
  • Internet Explorer / Edge: Przytrzymaj Ctrl, jednocześnie klikając Odśwież, lub naciśnij klawisze Ctrl+F5
  • Opera: Naciśnij klawisze Ctrl+F5.
/* ------------------------------------------------------------------------ *\
	copyright:  (C) 2008-2010 Maciej Jaros (pl:User:Nux, en:User:EcceNux)
	licence:    GNU General Public License v2,
                http://opensource.org/licenses/gpl-license.php

	version:    (see below) = sel_t.version
\* ------------------------------------------------------------------------ */
/*
Modified by user:Wargo to use with jquery.textSelection & VE surface
https://phabricator.wikimedia.org/source/mediawiki/browse/master/resources/src/jquery/jquery.textSelection.js
*/


if ( !window.sel_t ) {
	window.sel_t = {};
	sel_t.version = '2alpha';
	
	sel_t.getEditor = function ()
	{
		EditorType = 'textarea';
		if(mw.user.options.get('usebetatoolbar') === 1) EditorType = 'WikiEd';
		if(mw.user.options.get('visualeditor-newwikitext') === "1" && typeof ve.init != 'undefined') EditorType = '2017';	
		
		return EditorType;
	};
	
	// --
	// --
	// --
	sel_t.getSelStr = function (input, nonempty)
	{
		sel_t.noSelection = true;
		sel_t.isWikEdOn = false;
		EditorType = sel_t.getEditor();
	
		// check for wikEd (always choose whole area)
		if (typeof wikEdUseWikEd != 'undefined' && wikEdUseWikEd)
		{
			sel_t.isWikEdOn = true;
			WikEdUpdateTextarea();	// update before get
			return input.value;
		}
		else if (EditorType == 'WikiEd' || EditorType == 'textarea')
		{
			sel_range = $(input).textSelection('getCaretPosition', {startAndEnd: true});
			
			if(mw.config.get('wgPageContentModel') == 'proofread-page' && input.selectionStart === input.selectionEnd) $(input).select();
			
			sel_t.sel_s = input.selectionStart;
			sel_t.sel_e = input.selectionEnd;
			
			selected_text = $(input).textSelection('getSelection');
			if(selected_text.length > 0)
			{
				sel_t.noSelection = false;
				return selected_text;
			}
			else if(nonempty)
			{
				return $(input).textSelection('getContents');
			}
		}
		else if (EditorType == '2017')
		{
			surfacem = ve.init.target.getSurface().model;
			
			sel_t.sel_s = surfacem.selection.range.start;
			sel_t.sel_e = surfacem.selection.range.end;
			
			if(sel_t.sel_s != sel_t.sel_e)
			{
				sel_t.noSelection = false;
				return surfacem.getLinearFragment(new ve.Range(sel_t.sel_s, sel_t.sel_e)).getText();
			}
			else if(nonempty)
			{
				return surfacem.getDom();
			}
		}
		
		// other cases then above
		return (nonempty) ? input.value : '';
	};
	
	// --
	// --
	// --
	// for quick set after getSelStr (same selection)
	sel_t.qsetSelStr = function (input, str, nonempty)
	{
		EditorType = sel_t.getEditor();
		
		if (sel_t.noSelection)
		{
			if (nonempty)
			{
				if(EditorType == 'WikiEd') $(input).textSelection('setContents', str);
				if(EditorType == '2017')
				{
					surfacem = ve.init.target.getSurface().model;
					surfacem.getLinearFragment(new ve.Range(0, surfacem.getDocument().data.getLength())).insertContent(str);
				}
				if(EditorType == 'textarea') input.value = str;
			}
			else
			{
				input.value += str;
				input.scrollTop = input.scrollHeight;
			}
		}
		else if (sel_t.sel_s !== undefined)
		{
			//input.value = input.value.substring(0, sel_t.sel_s) + str + input.value.substring(sel_t.sel_e);
			//sel_t.ScrollIntoView(input, sel_t.sel_s, sel_t.sel_e);
			if(EditorType == 'WikiEd' || EditorType == 'textarea')
			{
				$(input).textSelection('replaceSelection', str);
			}
			
			if(EditorType == '2017')
			{
				ve.init.target.getSurface().model.getLinearFragment(new ve.Range(sel_t.sel_s, sel_t.sel_e)).insertContent(str);
			}
		}
		// IE...
		/*else if (document.selection && sel_t.range !== undefined)
		{
			sel_t.range.text = str;
			sel_t.range.scrollIntoView(false);// at bottom
		}*/
		// WikEd frame update
		if (sel_t.isWikEdOn)
		{
			WikEdUpdateFrame();
		}
	};
	
	// --
	// --
	// --
	// javascript:sel_t.setSelStr(sr$t, 'testin123', false)
	// tested: fox2, fox3, IE6 wired behaviour when nothing is selected...
	sel_t.setSelStr = function (input, str, nonempty)
	{
		// IE
		if (document.selection)
		{
			input.focus();
			var range = document.selection.createRange();
			if (range.parentElement()==input)
			{
				if (range.text !== '' || nonempty === false)
				{
					range.text = str;
					range.scrollIntoView(true); // at top
					return;
				}
			}
		}
		// fox/opera
		else if (input.selectionStart !== undefined)
		{
			var sTop=input.scrollTop;
			var sel_s = input.selectionStart;
			var sel_e = input.selectionEnd;
			if (sel_s!=sel_e)
			{
				input.value = input.value.substring(0, sel_s) + str + input.value.substring(sel_e);
				input.selectionStart=sel_s;
				input.selectionEnd=sel_s + str.length;
				input.scrollTop=sTop;
				return;
			}
			else if (sel_s==sel_e && !nonempty)
			{
				input.value = input.value.substring(0, sel_s) + str + input.value.substring(sel_e);
				input.selectionEnd=sel_s + str.length;
				input.selectionStart=input.selectionEnd;
				input.scrollTop=sTop;
				sel_t.ScrollIntoView(input, sel_s, sel_e);
				return;
			}
		}
	
		// other cases then above
		if (nonempty)
			input.value = str;
		else
		{
			input.value += str;
			input.scrollTop = input.scrollHeight;
		}
	};
	
	// --
	// --
	// --
	// for FX/FF
	// try to replace this with scrollToCaretPosition from jquery.textSelection
	sel_t.ScrollIntoView = function(input, sel_start, sel_end)
	{
		//
		// quick checks
		//
		if (sel_start<20)
		{
			input.scrollTop = 0;
			return;
		}
		var text_len = input.value.length;	// in chars
		var text_height = input.scrollHeight;	// in pixels
		if (text_len - sel_start<20)
		{
			input.scrollTop = text_height;
			return;
		}
	
		/*
		//prove of concept...
		var h_before = input.scrollHeight;	// in pixels
		var val_pre = input.value;
		input.value += '\n'+input.value.substr(0,sel_start);
		var h_post = input.scrollHeight;	// in pixels
		input.value = val_pre;
		input.setSelectionRange(sel_start, sel_end);
		var line_h = document.defaultView.getComputedStyle(input, null).lineHeight.replace(/[a-z]+/, '');	// assuming px
		input.scrollTop = h_post - h_before - 2*line_h;
		*/
		// put pre-selection text into clone
		var fake;
		fake = input.cloneNode(false);
		fake.style.height = '50px';    // have to be bigger then about 40px so that scrolls can be rendered
		fake.style.visibility = 'hidden';    // display=none doesn't seem to set scrollHeight, hidden does
		fake.style.position='absolute';
		fake.style.bottom='0';
		input.parentNode.appendChild(fake);
		fake.value = input.value.substr(0,sel_start);
		var pre_h = fake.scrollHeight;
		input.parentNode.removeChild(fake);
		var line_h = 15;
		try
		{
			line_h = document.defaultView.getComputedStyle(input, null).lineHeight.replace(/[a-z]+/, '');	// assuming px...
			if (line_h<10)	// something probably went wrong...
			{
				line_h = 15;
			}
		}
		catch(e){}
		input.scrollTop = pre_h - 2*line_h;
	}
	
	// --
	// --
	// --
	sel_t.getSelBound = function (input)
	{
		var sel_s = 0;	// defaults to "nothing is selected"
		var sel_e = 0;
		if (input.selectionStart != undefined)
		{
			sel_s = input.selectionStart;
			sel_e = input.selectionEnd;
		}
		// IE...
		else if (document.selection)
		{
			input.focus();	// only way for it to work if nothing is selected (i.e. get caret position)
			var range = document.selection.createRange();
			if (range.parentElement()==input)
			{
				// duplicate range to select from start to end
				var tmp_range = range.duplicate();
				tmp_range.moveToElementText(input);
				tmp_range.setEndPoint('EndToEnd', range);
				// calculate
				sel_e = tmp_range.text.length;
				sel_s = sel_e - range.text.length;
			}
		}
	
		// return values
		var sel_boundaries = {
			start : sel_s,
			end   : sel_e
		};
		return sel_boundaries;
	
	}
	
	// --
	// --
	// --
	// parts borrowed from PD code by Fred Jounters and Martin Honnen
	sel_t.setSelBound = function (input, sel_boundaries, scroll)
	{
		if (input.setSelectionRange)
		{
			input.setSelectionRange(sel_boundaries.start, sel_boundaries.end);
			if (scroll)
			{
				input.focus();
				sel_t.ScrollIntoView(input, sel_boundaries.start, sel_boundaries.end);
			}
		}
		else if (input.createTextRange)
		{
			var range = input.createTextRange();
			range.collapse(true);
			// re-calculate boundaries as \r\n are treated as one character for moveEnd/moveStart
			var tmp;
			tmp = input.value.substr(0, sel_boundaries.start).match(/\r\n/g)
			tmp = (tmp ? tmp.length : 0);
			// ups... would change this outside of a scope of this function!
			//sel_boundaries.start -= tmp;
			var sel_start = sel_boundaries.start - tmp;
			tmp = input.value.substr(0, sel_boundaries.end).match(/\r\n/g)
			tmp = (tmp ? tmp.length : 0);
			//sel_boundaries.end -= tmp;
			var sel_end = sel_boundaries.end - tmp;
			// move
			range.moveEnd('character', sel_end);
			range.moveStart('character', sel_start);
			range.select();
			if (scroll)
			{
				range.scrollIntoView(true); // at top
				input.focus();
			}
		}
	}
	
	// --
	// --
	// --
	// for backward compatibility only
	sel_t.setSelRange = function(input, sel_s, sel_e)
	{
		var sel_boundaries = {
			start : sel_s,
			end   : sel_e
		};
		sel_t.setSelBound (input, sel_boundaries, true);
	}
}