| 
				   | 
				
| (같은 사용자의 중간 판 16개는 보이지 않습니다) | 
| 1번째 줄: | 
1번째 줄: | 
 | // See [[mw:Reference Tooltips]]  |  | // This code is licensed under CC BY-SA 3.0  | 
 | // Source https://en.wikipedia.org/wiki/MediaWiki:Gadget-ReferenceTooltips.js  |  | // Source: https://librewiki.net/wiki/미디어위키:Gadget-ReferenceTooltips-ko.js  | 
 | // Translated by Fracture_Ray  |  | // Contributors: https://librewiki.net/index.php?title=미디어위키:Gadget-ReferenceTooltips-ko.js&action=history  | 
 | 
  |  | 
  | 
 | ( function () {  |  | var isMobile = navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i);  | 
 |  | var drawer, origin, content;  | 
 |  | function showDrawer(id, name, orgId) {  | 
 |  | 	origin.attr("href", id);  | 
 |  | 	origin.attr("data-origin", orgId.replace(/\./g, "\\."));  | 
 |  | 	origin.text(name);  | 
 |  | 	content.html($(id.replace(/\./g, "\\.") + " > .reference-text").html());  | 
 |  | 	drawer.addClass("visible");  | 
 |  | }  | 
 | 
  |  | 
  | 
 | // enwiki settings
  |  | function getSettings(key, type) {  | 
 | var REF_LINK_SELECTOR = '.reference, a[href^="#CITEREF"]',
  |  | 	if ("localStorage" in window) {  | 
 | 	COMMENTED_TEXT_CLASS = 'rt-commentedText',  |  | 		if (type === "boolean") {  | 
 | 	COMMENTED_TEXT_SELECTOR = ( COMMENTED_TEXT_CLASS ? '.' + COMMENTED_TEXT_CLASS + ', ' : '') +
  |  | 			return (window.localStorage[key] === "true");  | 
 | 		'abbr[title]';  |  | 		} else {  | 
 |  | 			return window.localStorage[key];  | 
 |  | 		}  | 
 |  | 	} else {  | 
 |  | 		var value = "; " + document.cookie;  | 
 |  | 		var parts = value.split("; " + key + "=");  | 
 |  | 		if (parts.length == 2) {  | 
 |  | 			if (type === "boolean") {  | 
 |  | 				return (parts.pop().split(";").shift() === "true");  | 
 |  | 			} else {  | 
 |  | 				return parts.pop().split(";").shift();  | 
 |  | 			}  | 
 |  | 		}  | 
 |  | 	}  | 
 |  | }  | 
 | 
  |  | 
  | 
 | mw.messages.set( {
  |  | function setSettings(key, value) {  | 
 | 	'rt-settings': '각주 툴팁 설정',  |  | 	if ("localStorage" in window) {  | 
 | 	'rt-enable-footer': '각주 툴팁 활성화',
  |  | 		window.localStorage[key] = value;  | 
 | 	'rt-settings-title': '각주 툴팁',
  |  | 	} else {  | 
 | 	'rt-save': '저장',
  |  | 		var now = new Date();  | 
 | 	'rt-cancel': '취소',
  |  | 		var time = now.getTime();  | 
 | 	'rt-enable': '활성화',
  |  | 		var expireTime = time + (10 * 365 * 24 * 24);  | 
 | 	'rt-disable': '비활성화 (리버티 이외의 스킨에서만 재활성화 가능)',
  |  | 		now.setTime(expireTime);  | 
 | 	'rt-activationMethod': '툴팁 표시 설정',
  |  | 		document.cookie = key + "=" + value + ";expires=" + now.toGMTString() +";path=/";  | 
 | 	'rt-hovering': '마우스를 가져다 대면 표시하기',  |  | 	}  | 
 | 	'rt-clicking': '클릭하면 표시하기',
  |  | }  | 
 | 	'rt-delay': '툴팁 표시 지연 (밀리초(ms) 단위)',
  |  | 
 | 	'rt-tooltipsForComments': '각주를 <span title="툴팁 예시" class="' + ( COMMENTED_TEXT_CLASS || 'rt-commentedText' ) + '" style="border-bottom: 1px dotted; cursor: help;">점선으로 밑줄 친 텍스트</span> 위에서 각주 툴팁 스타일로 나타나게 설정하기 (마우스를 지원하지 않는 기기에서 툴팁을 볼 수 있게 해 줍니다.)',
  |  | 
 | 	'rt-disabledNote': '리버티 이외 스킨에서 페이지 밑에 있는 링크를 이용하여 툴팁을 다시 활성화하실 수 있습니다.',
  |  | 
 | 	'rt-done': '완료',
  |  | 
 | 	'rt-enabled': '각주 툴팁이 활성화되었습니다.'
  |  | 
 | } );
  |  | 
 |    |  | 
 | // "Global" variables
  |  | 
 | var SECONDS_IN_A_DAY = 60 * 60 * 24,  |  | 
 | 	CLASSES = {
  |  | 
 | 		FADE_IN_DOWN: 'rt-fade-in-down',  |  | 
 | 		FADE_IN_UP: 'rt-fade-in-up',
  |  | 
 | 		FADE_OUT_DOWN: 'rt-fade-out-down',
  |  | 
 | 		FADE_OUT_UP: 'rt-fade-out-up'
  |  | 
 | 	},
  |  | 
 | 	IS_TOUCHSCREEN = 'ontouchstart' in document.documentElement,
  |  | 
 | 	// Quite a rough check for mobile browsers, a mix of what is advised at
  |  | 
 | 	// https://stackoverflow.com/a/24600597 (sends to
  |  | 
 | 	// https://developer.mozilla.org/en-US/docs/Browser_detection_using_the_user_agent)
  |  | 
 | 	// and https://stackoverflow.com/a/14301832
  |  | 
 | 	IS_MOBILE = /Mobi|Android/i.test( navigator.userAgent ) ||
  |  | 
 | 		typeof window.orientation !== 'undefined',  |  | 
 | 	CLIENT_NAME = $.client.profile().name,
  |  | 
 | 	settingsString, settings, enabled, delay, activatedByClick, tooltipsForComments, cursorWaitCss,  |  | 
 | 	windowManager,
  |  | 
 | 	$body = $( document.body ),
  |  | 
 | 	$window = $( window );
  |  | 
 | 
  |  | 
  | 
 | function rt( $content ) {  |  | function initSettings() {  | 
 | 	// Popups gadget
  |  | 	if (document.getElementById("reference-settings")) {  | 
 | 	if ( window.pg ) {  |  | 		$("#reference-settings").show();  | 
 | 		return;  |  | 		return;  | 
 | 	}  |  | 	}  | 
 |  | 	var setbox = $("<form>").attr("id", "reference-settings").append(  | 
 |  | 		$("<div>").addClass("content").append(  | 
 |  | 			$("<label>").append(  | 
 |  | 				$("<input>").attr({"type": "checkbox", "name": "showRefOnHover", "checked": getSettings("showRefOnHover", "boolean")}),  | 
 |  | 				"갖다 대서 주석을 띄웁니다."  | 
 |  | 			)  | 
 |  | 		),  | 
 |  | 		$("<div>").addClass("foot").append(  | 
 |  | 			$("<input>").attr({"type": "button", "value": "취소"}).click(function() {  | 
 |  | 				$("#reference-settings").hide();  | 
 |  | 			}),  | 
 |  | 			$("<input>").addClass("save-settings").attr({"type": "submit", "value": "저장"})  | 
 |  | 		)  | 
 |  | 	).submit(function(e) {  | 
 |  | 		e.preventDefault();  | 
 |  | 		setSettings("showRefOnHover", $(this).find("[name=showRefOnHover]").is(":checked"));  | 
 |  | 		location.reload();  | 
 |  | 	});  | 
 |  | 	$(document.body).append(setbox);  | 
 |  | }  | 
 | 
  |  | 
  | 
 | 	var teSelector,  |  | function showTooltip(elem) {  | 
 | 		settingsDialogOpening = false;
  |  | 	showDrawer(elem.parentNode.getAttribute("href"), elem.textContent, elem.parentNode.parentNode.getAttribute("id"));  | 
 |  | 	drawer.show();  | 
 |  | 	drawer.css({ top: ($(elem).offset().top - drawer.outerHeight()), left: $(elem).offset().left });  | 
 |  | 	drawer.stop().animate({opacity: 1}, 100);  | 
 |  | }  | 
 | 
  |  | 
  | 
 | 	function setSettingsCookie() {
  |  | function hideTooltip() {  | 
 | 		mw.cookie.set(
  |  | 	drawer.removeClass("visible");  | 
 | 			'RTsettings',
  |  | 	drawer.animate({opacity: 0}, 100, function() { $(this).hide(); });  | 
 | 			Number( enabled ) + '|' + delay + '|' + Number( activatedByClick ) + '|' +
  |  | }  | 
 | 				Number( tooltipsForComments ),
  |  | 
 | 			{ path: '/', expires: 90 * SECONDS_IN_A_DAY, prefix: '' }
  |  | 
 | 		);
  |  | 
 | 	}
  |  | 
 | 
  |  | 
  | 
 | 	function enableRt() {
  |  | $(document).ready(function($) {  | 
 | 		enabled = true;
  |  | 	if (getSettings("showRefOnHover") === undefined) {  | 
 | 		setSettingsCookie();
  |  | 		setSettings("showRefOnHover", true);  | 
 | 		$( '.rt-enableItem' ).remove();
  |  | 
 | 		rt( $content );
  |  | 
 | 		mw.notify( mw.msg( 'rt-enabled' ) );  |  | 
 | 	}  |  | 	}  | 
 |    |  | 	if (isMobile) {  | 
 | 	function disableRt() {  |  | 		$(document.body).addClass("mode-drawer");  | 
 | 		$content.find( teSelector ).removeClass( 'rt-commentedText' ).off( '.rt' );  |  | 	} else {  | 
 | 		$body.off( '.rt' );
  |  | 		$(document.body).addClass("mode-tooltip");  | 
 | 		$window.off( '.rt' );
  |  | 
 | 	}  |  | 
 |    |  | 
 | 	function addEnableLink() {
  |  | 
 | 		// #footer-places – Vector  |  | 
 | 		// #f-list – Timeless, Monobook, Modern
  |  | 
 | 		// parent of #footer li – Cologne Blue
  |  | 
 | 		var $footer = $( '#footer-places, #f-list' );
  |  | 
 | 		if ( !$footer.length ) {
  |  | 
 | 			$footer = $( '#footer li' ).parent();
  |  | 
 | 		}
  |  | 
 | 		$footer.append(
  |  | 
 | 			$( '<li>' )
  |  | 
 | 				.addClass( 'rt-enableItem' )
  |  | 
 | 				.append(
  |  | 
 | 					$( '<a>' )
  |  | 
 | 						.text( mw.msg( 'rt-enable-footer' ) )
  |  | 
 | 						.attr( 'href', 'javascript:' )
  |  | 
 | 						.click( function ( e ) {
  |  | 
 | 							e.preventDefault();
  |  | 
 | 							enableRt();
  |  | 
 | 						} )
  |  | 
 | 			)
  |  | 
 | 		);
  |  | 
 | 	}  |  | 	}  | 
 |    |  | 	/* create drawer */  | 
 | 	function TooltippedElement( $element ) {  |  | 	drawer = $("<div>").attr("id", "reference-drawer");  | 
 | 		var tooltip,
  |  | 	origin = $("<a>").attr("id", "reference-origin").click(function() {  | 
 | 			events,
  |  | 		$('html, body').animate({scrollTop: ($($(this).attr("href")).offset().top - 60)}, 400);  | 
 | 			te = this;
  |  | 	});  | 
 |    |  | 	content = $("<span>").attr("id", "reference-drawer-text");  | 
 | 		function onStartEvent( e ) {
  |  | 	var settingsIcon = $("<span>").addClass("settings-icon").click(function() {  | 
 | 			var showRefArgs;
  |  | 		initSettings();  | 
 |    |  | 	});  | 
 | 			if ( activatedByClick && te.type !== 'commentedText' && e.type !== 'contextmenu' ) {
  |  | 	var closeDrawer = $("<span>").addClass("close-icon").click(function() {  | 
 | 				e.preventDefault();
  |  | 		drawer.removeClass("visible");  | 
 | 			}
  |  | 	});  | 
 | 			if ( !te.noRef ) {
  |  | 	drawer.append(settingsIcon);  | 
 | 				showRefArgs = [ $( this ) ];
  |  | 	drawer.append(closeDrawer);  | 
 | 				if ( te.type !== 'supRef' ) {
  |  | 	drawer.append(origin);  | 
 | 					showRefArgs.push( e.pageX, e.pageY );
  |  | 	drawer.append(content);  | 
 | 				}
  |  | 	$(document.body).append(drawer);  | 
 | 				te.showRef.apply( te, showRefArgs );
  |  | 	  | 
 | 			}
  |  | 	$(document).click(function(e) {  | 
 | 		}
  |  | 		if (!$(e.target).closest("#reference-drawer").length)  {  | 
 |    |  | 			if (!isMobile) {  | 
 | 		function onEndEvent() {
  |  | 				hideTooltip();  | 
 | 			if ( !te.noRef ) {
  |  | 
 | 				te.hideRef();
  |  | 
 | 			}
  |  | 
 | 		}
  |  | 
 |    |  | 
 | 		if ( !$element ) {
  |  | 
 | 			return;
  |  | 
 | 		}
  |  | 
 |    |  | 
 | 		// TooltippedElement.$element and TooltippedElement.$originalElement will be different when
  |  | 
 | 		// the first is changed after its cloned version is hovered in a tooltip
  |  | 
 | 		this.$element = $element;
  |  | 
 | 		this.$originalElement = $element;
  |  | 
 | 		if ( this.$element.is( REF_LINK_SELECTOR ) ) {  |  | 
 | 			if ( this.$element.prop( 'tagName' ) === 'SUP' ) {  |  | 
 | 				this.type = 'supRef';  |  | 
 | 			} else {  |  | 			} else {  | 
 | 				this.type = 'harvardRef';  |  | 				drawer.removeClass("visible");  | 
 | 			}
  |  | 
 | 		} else {
  |  | 
 | 			this.type = 'commentedText';
  |  | 
 | 			this.comment = this.$element.attr( 'title' );
  |  | 
 | 			if ( !this.comment ) {
  |  | 
 | 				return;
  |  | 
 | 			}  |  | 			}  | 
 | 			this.$element.addClass('rt-commentedText');
  |  | 
 | 		}  |  | 		}  | 
 | 		
  |  | 	}).scroll(function(e) {  | 
 | 		if ( activatedByClick ) {
  |  | 		if ("ontouchstart" in window && isMobile) {  | 
 | 			events = {
  |  | 			drawer.removeClass("visible");  | 
 | 				'click.rt': onStartEvent
  |  | 
 | 			};
  |  | 
 | 			// Adds an ability to see tooltips for links
  |  | 
 | 			if ( this.type === 'commentedText' &&
  |  | 
 | 				( this.$element.closest( 'a' ).length ||
  |  | 
 | 					this.$element.has( 'a' ).length
  |  | 
 | 				)
  |  | 
 | 			) {
  |  | 
 | 				events[ 'contextmenu.rt' ] = onStartEvent;
  |  | 
 | 			}
  |  | 
 | 		} else {
  |  | 
 | 			events = {
  |  | 
 | 				'mouseenter.rt': onStartEvent,
  |  | 
 | 				'mouseleave.rt': onEndEvent
  |  | 
 | 			};
  |  | 
 | 		}  |  | 		}  | 
 |    |  | 	});  | 
 | 		this.$element.on( events );
  |  | 	$(".reference a").each(function() {  | 
 |    |  | 		var span = document.createElement("span");  | 
 | 		this.hideRef = function ( immediately ) {
  |  | 		span.className = "reference-hooker";  | 
 | 			clearTimeout( te.showTimer );
  |  | 		span.appendChild(this.childNodes[0]);  | 
 |    |  | 		this.appendChild(span);  | 
 | 			if ( this.type === 'commentedText' ) {
  |  | 	});  | 
 | 				this.$element.attr( 'title', this.comment );
  |  | 	if (getSettings("showRefOnHover", "boolean") && !isMobile) {  | 
 | 			}
  |  | 		drawer.hover(function(e) {  | 
 |    |  | 			showTooltip($("#" + origin.attr("data-origin") + " .reference-hooker").get(0));  | 
 | 			if ( this.tooltip && this.tooltip.isPresent ) {
  |  | 		}, function(e) {  | 
 | 				if ( activatedByClick || immediately ) {
  |  | 			hideTooltip();  | 
 | 					this.tooltip.hide();
  |  | 		});  | 
 | 				} else {
  |  | 		$(".reference-hooker").hover(function(e) {  | 
 | 					this.hideTimer = setTimeout( function () {
  |  | 			showTooltip(this);  | 
 | 						te.tooltip.hide();
  |  | 		}, function(e) {  | 
 | 					}, 200 );
  |  | 			hideTooltip();  | 
 | 				}
  |  | 		});  | 
 | 			} else if ( this.$ref && this.$ref.hasClass( 'rt-target' ) ) {
  |  | 
 | 				this.$ref.removeClass( 'rt-target' );
  |  | 
 | 				if ( activatedByClick ) {
  |  | 
 | 					$body.off( 'click.rt touchstart.rt', this.onBodyClick );
  |  | 
 | 				}
  |  | 
 | 			}
  |  | 
 | 		};
  |  | 
 |    |  | 
 | 		this.showRef = function ( $element, ePageX, ePageY ) {  |  | 
 | 			// Popups gadget
  |  | 
 | 			if ( window.pg ) {
  |  | 
 | 				disableRt();
  |  | 
 | 				return;
  |  | 
 | 			}
  |  | 
 | 			
  |  | 
 | 			if ( this.tooltip && !this.tooltip.$content.length ) {
  |  | 
 | 				return;
  |  | 
 | 			}
  |  | 
 |    |  | 
 | 			var tooltipInitiallyPresent = this.tooltip && this.tooltip.isPresent;
  |  | 
 |    |  | 
 | 			function reallyShow() {
  |  | 
 | 				var viewportTop, refOffsetTop, teHref;
  |  | 
 |    |  | 
 | 				if ( !te.$ref && !te.comment ) {
  |  | 
 | 					teHref = te.type === 'supRef' ?
  |  | 
 | 						te.$element.find( 'a' ).attr( 'href' ) :
  |  | 
 | 						te.$element.attr( 'href' ); // harvardRef
  |  | 
 | 					te.$ref = teHref &&
  |  | 
 | 						$( '#' + $.escapeSelector( teHref.slice( 1 ) ) );
  |  | 
 | 					if ( !te.$ref || !te.$ref.length || !te.$ref.text() ) {
  |  | 
 | 						te.noRef = true;
  |  | 
 | 						return;
  |  | 
 | 					}
  |  | 
 | 				}
  |  | 
 |    |  | 
 | 				if ( !tooltipInitiallyPresent && !te.comment ) {
  |  | 
 | 					viewportTop = $window.scrollTop();
  |  | 
 | 					refOffsetTop = te.$ref.offset().top;
  |  | 
 | 					if ( !activatedByClick &&
  |  | 
 | 						viewportTop < refOffsetTop &&
  |  | 
 | 						viewportTop + $window.height() > refOffsetTop + te.$ref.height() &&
  |  | 
 | 						// There can be gadgets/scripts that make references horizontally scrollable.
  |  | 
 | 						$window.width() > te.$ref.offset().left + te.$ref.width()
  |  | 
 | 					) {
  |  | 
 | 						// Highlight the reference itself
  |  | 
 | 						te.$ref.addClass( 'rt-target' );
  |  | 
 | 						return;
  |  | 
 | 					}
  |  | 
 | 				}
  |  | 
 |    |  | 
 | 				if ( !te.tooltip ) {
  |  | 
 | 					te.tooltip = new Tooltip( te );
  |  | 
 | 					if ( !te.tooltip.$content.length ) {
  |  | 
 | 						return;
  |  | 
 | 					}
  |  | 
 | 				}
  |  | 
 |    |  | 
 | 				// If this tooltip is called from inside another tooltip. We can't define it
  |  | 
 | 				// in the constructor since a ref can be cloned but have the same Tooltip object;
  |  | 
 | 				// so, Tooltip.parent is a floating value.
  |  | 
 | 				te.tooltip.parent = te.$element.closest( '.rt-tooltip' ).data( 'tooltip' );
  |  | 
 | 				if ( te.tooltip.parent && te.tooltip.parent.disappearing ) {
  |  | 
 | 					return;
  |  | 
 | 				}
  |  | 
 |    |  | 
 | 				te.tooltip.show();
  |  | 
 |    |  | 
 | 				if ( tooltipInitiallyPresent ) {
  |  | 
 | 					if ( te.tooltip.$element.hasClass( 'rt-tooltip-above' ) ) {
  |  | 
 | 						te.tooltip.$element.addClass( CLASSES.FADE_IN_DOWN );
  |  | 
 | 					} else {
  |  | 
 | 						te.tooltip.$element.addClass( CLASSES.FADE_IN_UP );
  |  | 
 | 					}
  |  | 
 | 					return;
  |  | 
 | 				}
  |  | 
 |    |  | 
 | 				te.tooltip.calculatePosition( ePageX, ePageY );
  |  | 
 |    |  | 
 | 				$window.on( 'resize.rt', te.onWindowResize );
  |  | 
 | 			}
  |  | 
 |    |  | 
 | 			// We redefine this.$element here because e.target can be a reference link inside
  |  | 
 | 			// a reference tooltip, not a link that was initially assigned to this.$element
  |  | 
 | 			this.$element = $element;
  |  | 
 |    |  | 
 | 			if ( this.type === 'commentedText' ) {
  |  | 
 | 				this.$element.attr( 'title', '' );
  |  | 
 | 			}
  |  | 
 |    |  | 
 | 			if ( activatedByClick ) {
  |  | 
 | 				if ( tooltipInitiallyPresent ||
  |  | 
 | 					( this.$ref && this.$ref.hasClass( 'rt-target' ) )
  |  | 
 | 				) {
  |  | 
 | 					return;
  |  | 
 | 				} else {
  |  | 
 | 					setTimeout( function () {
  |  | 
 | 						$body.on( 'click.rt touchstart.rt', te.onBodyClick );
  |  | 
 | 					}, 0 );
  |  | 
 | 				}
  |  | 
 | 			}
  |  | 
 |    |  | 
 | 			if ( activatedByClick || tooltipInitiallyPresent ) {
  |  | 
 | 				reallyShow();
  |  | 
 | 			} else {
  |  | 
 | 				this.showTimer = setTimeout( reallyShow, delay );
  |  | 
 | 			}
  |  | 
 | 		};
  |  | 
 |    |  | 
 | 		this.onBodyClick = function ( e ) {
  |  | 
 | 			if ( !te.tooltip && !te.$ref.hasClass( 'rt-target' ) ) {  |  | 
 | 				return;
  |  | 
 | 			}
  |  | 
 |    |  | 
 | 			var $current = $( e.target );
  |  | 
 |    |  | 
 | 			function contextMatchesParameter( parameter ) {
  |  | 
 | 				return this === parameter;
  |  | 
 | 			}
  |  | 
 |    |  | 
 | 			// The last condition is used to determine cases when a clicked tooltip is the current
  |  | 
 | 			// element's tooltip or one of its descendants
  |  | 
 | 			while ( $current.length &&
  |  | 
 | 				( !$current.hasClass( 'rt-tooltip' ) ||
  |  | 
 | 					!$current.data( 'tooltip' ) ||
  |  | 
 | 					!$current.data( 'tooltip' ).upToTopParent(
  |  | 
 | 						contextMatchesParameter, [ te.tooltip ],
  |  | 
 | 						true
  |  | 
 | 					)
  |  | 
 | 				)
  |  | 
 | 			) {
  |  | 
 | 				$current = $current.parent();
  |  | 
 | 			}
  |  | 
 | 			if ( !$current.length ) {  |  | 
 | 				te.hideRef();
  |  | 
 | 			}
  |  | 
 | 		};  |  | 
 |    |  | 
 | 		this.onWindowResize = function () {
  |  | 
 | 			te.tooltip.calculatePosition();  |  | 
 | 		};  |  | 
 | 	}  |  | 	}  | 
 |    |  | 	$(".reference-hooker").click(function(e) {  | 
 | 	function Tooltip( te ) {  |  | 		if (isMobile) {  | 
 | 		function openSettingsDialog() {
  |  | 			e.preventDefault();  | 
 | 			var settingsDialog, settingsWindow;
  |  | 			e.stopPropagation();  | 
 |    |  | 			showDrawer(this.parentNode.getAttribute("href"), this.textContent, this.parentNode.parentNode.getAttribute("id"));  | 
 | 			if ( cursorWaitCss ) {
  |  | 			drawer.addClass("visible");  | 
 | 				cursorWaitCss.disabled = true;
  |  | 		} else if (!getSettings("showRefOnHover", "boolean")) {  | 
 | 			}
  |  | 			e.preventDefault();  | 
 |    |  | 			e.stopPropagation();  | 
 | 			function SettingsDialog() {
  |  | 			showTooltip(this);  | 
 | 				SettingsDialog.parent.call( this );
  |  | 
 | 			}
  |  | 
 | 			OO.inheritClass( SettingsDialog, OO.ui.ProcessDialog );
  |  | 
 |    |  | 
 | 			SettingsDialog.static.name = 'settingsDialog';
  |  | 
 | 			SettingsDialog.static.title = mw.msg( 'rt-settings-title' );
  |  | 
 | 			SettingsDialog.static.actions = [
  |  | 
 | 				{
  |  | 
 | 					modes: 'basic',
  |  | 
 | 					action: 'save',
  |  | 
 | 					label: mw.msg( 'rt-save' ),
  |  | 
 | 					flags: [ 'primary', 'progressive' ]
  |  | 
 | 				},
  |  | 
 | 				{
  |  | 
 | 					modes: 'basic',
  |  | 
 | 					label: mw.msg( 'rt-cancel' ),
  |  | 
 | 					flags: 'safe'
  |  | 
 | 				},
  |  | 
 | 				{
  |  | 
 | 					modes: 'disabled',
  |  | 
 | 					action: 'deactivated',
  |  | 
 | 					label: mw.msg( 'rt-done' ),
  |  | 
 | 					flags: [ 'primary', 'progressive' ]
  |  | 
 | 				}
  |  | 
 | 			];
  |  | 
 |    |  | 
 | 			SettingsDialog.prototype.initialize = function () {
  |  | 
 | 				var dialog = this;
  |  | 
 |    |  | 
 | 				SettingsDialog.parent.prototype.initialize.apply( this, arguments );
  |  | 
 |    |  | 
 | 				this.enableOption = new OO.ui.RadioOptionWidget( {
  |  | 
 | 					label: mw.msg( 'rt-enable' )
  |  | 
 | 				} );
  |  | 
 | 				this.disableOption = new OO.ui.RadioOptionWidget( {
  |  | 
 | 					label: mw.msg( 'rt-disable' )
  |  | 
 | 				} );
  |  | 
 | 				this.enableSelect = new OO.ui.RadioSelectWidget( {
  |  | 
 | 					items: [ this.enableOption, this.disableOption ],
  |  | 
 | 					classes: [ 'rt-enableSelect' ]
  |  | 
 | 				} );
  |  | 
 | 				this.enableSelect.selectItem( this.enableOption );
  |  | 
 | 				this.enableSelect.on( 'choose', function ( item ) {
  |  | 
 | 					if ( item === dialog.disableOption ) {
  |  | 
 | 						dialog.activationMethodSelect.setDisabled( true );
  |  | 
 | 						dialog.delayInput.setDisabled( true );
  |  | 
 | 						dialog.tooltipsForCommentsCheckbox.setDisabled( true );
  |  | 
 | 					} else {
  |  | 
 | 						dialog.activationMethodSelect.setDisabled( false );
  |  | 
 | 						dialog.delayInput.setDisabled( dialog.clickOption.isSelected() );
  |  | 
 | 						dialog.tooltipsForCommentsCheckbox.setDisabled( false );
  |  | 
 | 					}
  |  | 
 | 				} );
  |  | 
 |    |  | 
 | 				this.hoverOption = new OO.ui.RadioOptionWidget( {
  |  | 
 | 					label: mw.msg( 'rt-hovering' )
  |  | 
 | 				} );
  |  | 
 | 				this.clickOption = new OO.ui.RadioOptionWidget( {
  |  | 
 | 					label: mw.msg( 'rt-clicking' )
  |  | 
 | 				} );
  |  | 
 | 				this.activationMethodSelect = new OO.ui.RadioSelectWidget( {
  |  | 
 | 					items: [ this.hoverOption, this.clickOption ]
  |  | 
 | 				} );
  |  | 
 | 				this.activationMethodSelect.selectItem( activatedByClick ?
  |  | 
 | 					this.clickOption :
  |  | 
 | 					this.hoverOption
  |  | 
 | 				);
  |  | 
 | 				this.activationMethodSelect.on( 'choose', function ( item ) {
  |  | 
 | 					if ( item === dialog.clickOption ) {
  |  | 
 | 						dialog.delayInput.setDisabled( true );
  |  | 
 | 					} else {
  |  | 
 | 						dialog.delayInput.setDisabled( dialog.clickOption.isSelected() );
  |  | 
 | 					}
  |  | 
 | 				} );
  |  | 
 | 				this.activationMethodField = new OO.ui.FieldLayout( this.activationMethodSelect, {
  |  | 
 | 					label: mw.msg( 'rt-activationMethod' ),
  |  | 
 | 					align: 'top'
  |  | 
 | 				} );
  |  | 
 |    |  | 
 | 				this.delayInput = new OO.ui.NumberInputWidget( {
  |  | 
 | 					input: { value: delay },
  |  | 
 | 					step: 50,
  |  | 
 | 					min: 0,
  |  | 
 | 					max: 5000,
  |  | 
 | 					disabled: activatedByClick,
  |  | 
 | 					classes: [ 'rt-numberInput' ]
  |  | 
 | 				} );
  |  | 
 | 				this.delayField = new OO.ui.FieldLayout( this.delayInput, {
  |  | 
 | 					label: mw.msg( 'rt-delay' ),
  |  | 
 | 					align: 'top'
  |  | 
 | 				} );
  |  | 
 |    |  | 
 | 				this.tooltipsForCommentsCheckbox = new OO.ui.CheckboxInputWidget( {
  |  | 
 | 					selected: tooltipsForComments
  |  | 
 | 				} );
  |  | 
 | 				this.tooltipsForCommentsField = new OO.ui.FieldLayout(
  |  | 
 | 					this.tooltipsForCommentsCheckbox,
  |  | 
 | 					{
  |  | 
 | 						label: new OO.ui.HtmlSnippet( mw.msg( 'rt-tooltipsForComments' ) ),
  |  | 
 | 						align: 'inline',
  |  | 
 | 						classes: [ 'rt-tooltipsForCommentsField' ]
  |  | 
 | 					}
  |  | 
 | 				);
  |  | 
 | 				new TooltippedElement(
  |  | 
 | 					this.tooltipsForCommentsField.$element.find(
  |  | 
 | 						'.' + ( COMMENTED_TEXT_CLASS || 'rt-commentedText' )
  |  | 
 | 					)
  |  | 
 | 				);
  |  | 
 |    |  | 
 | 				this.fieldset = new OO.ui.FieldsetLayout();
  |  | 
 | 				this.fieldset.addItems( [
  |  | 
 | 					this.activationMethodField,
  |  | 
 | 					this.delayField,
  |  | 
 | 					this.tooltipsForCommentsField
  |  | 
 | 				] );
  |  | 
 |    |  | 
 | 				this.panelSettings = new OO.ui.PanelLayout( {
  |  | 
 | 					padded: true,
  |  | 
 | 					expanded: false
  |  | 
 | 				} );
  |  | 
 | 				this.panelSettings.$element.append(
  |  | 
 | 					this.enableSelect.$element,
  |  | 
 | 					$( '<hr>' ).addClass( 'rt-settingsFormSeparator' ),
  |  | 
 | 					this.fieldset.$element
  |  | 
 | 				);
  |  | 
 |    |  | 
 | 				this.panelDisabled = new OO.ui.PanelLayout( {
  |  | 
 | 					padded: true,
  |  | 
 | 					expanded: false
  |  | 
 | 				} );
  |  | 
 | 				this.panelDisabled.$element.append(
  |  | 
 | 					$( '<table>' )
  |  | 
 | 						.addClass( 'rt-disabledHelp' )
  |  | 
 | 						.append(
  |  | 
 | 							$( '<tr>' ).append(
  |  | 
 | 								$( '<td>' ).append(
  |  | 
 | 									$( '<img>' ).attr( 'src', 'https://wiki.studyforus.com/w/load.php?modules=ext.popups.images&image=footer&format=rasterized&lang=ru&skin=vector&version=0uotisb' )
  |  | 
 | 								),
  |  | 
 | 								$( '<td>' )
  |  | 
 | 									.addClass( 'rt-disabledNote' )
  |  | 
 | 									.text( mw.msg( 'rt-disabledNote' ) )
  |  | 
 | 							)
  |  | 
 | 						)
  |  | 
 | 				);
  |  | 
 |    |  | 
 | 				this.stackLayout = new OO.ui.StackLayout( {
  |  | 
 | 					items: [ this.panelSettings, this.panelDisabled ]
  |  | 
 | 				} );
  |  | 
 |    |  | 
 | 				this.$body.append( this.stackLayout.$element );
  |  | 
 | 			};  |  | 
 |    |  | 
 | 			SettingsDialog.prototype.getSetupProcess = function ( data ) {
  |  | 
 | 				return SettingsDialog.parent.prototype.getSetupProcess.call( this, data )
  |  | 
 | 					.next( function () {
  |  | 
 | 						this.stackLayout.setItem( this.panelSettings );
  |  | 
 | 						this.actions.setMode( 'basic' );
  |  | 
 | 					}, this );
  |  | 
 | 			};  |  | 
 |    |  | 
 | 			SettingsDialog.prototype.getActionProcess = function ( action ) {
  |  | 
 | 				var dialog = this;
  |  | 
 |    |  | 
 | 				if ( action === 'save' ) {
  |  | 
 | 					return new OO.ui.Process( function () {
  |  | 
 | 						var newDelay = Number( dialog.delayInput.getValue() );
  |  | 
 |    |  | 
 | 						enabled = dialog.enableOption.isSelected();
  |  | 
 | 						if ( newDelay >= 0 && newDelay <= 5000 ) {
  |  | 
 | 							delay = newDelay;
  |  | 
 | 						}
  |  | 
 | 						activatedByClick = dialog.clickOption.isSelected();
  |  | 
 | 						tooltipsForComments = dialog.tooltipsForCommentsCheckbox.isSelected();
  |  | 
 |    |  | 
 | 						setSettingsCookie();
  |  | 
 |    |  | 
 | 						if ( enabled ) {
  |  | 
 | 							dialog.close();
  |  | 
 | 							disableRt();
  |  | 
 | 							rt( $content );
  |  | 
 | 						} else {
  |  | 
 | 							dialog.actions.setMode( 'disabled' );
  |  | 
 | 							dialog.stackLayout.setItem( dialog.panelDisabled );
  |  | 
 | 							disableRt();
  |  | 
 | 							addEnableLink();
  |  | 
 | 						}
  |  | 
 | 					} );
  |  | 
 | 				} else if ( action === 'deactivated' ) {
  |  | 
 | 					dialog.close();
  |  | 
 | 				}
  |  | 
 | 				return SettingsDialog.parent.prototype.getActionProcess.call( this, action );
  |  | 
 | 			};  |  | 
 |    |  | 
 | 			SettingsDialog.prototype.getBodyHeight = function () {
  |  | 
 | 				return this.stackLayout.getCurrentItem().$element.outerHeight( true );
  |  | 
 | 			};
  |  | 
 |    |  | 
 | 			tooltip.upToTopParent( function adjustRightAndHide() {
  |  | 
 | 				if ( this.isPresent ) {
  |  | 
 | 					if ( this.$element[ 0 ].style.right ) {
  |  | 
 | 						this.$element.css(
  |  | 
 | 							'right',
  |  | 
 | 							'+=' + ( window.innerWidth - $window.width() )
  |  | 
 | 						);
  |  | 
 | 					}
  |  | 
 | 					this.te.hideRef( true );
  |  | 
 | 				}
  |  | 
 | 			} );
  |  | 
 |    |  | 
 | 			if ( !windowManager ) {
  |  | 
 | 				windowManager = new OO.ui.WindowManager();
  |  | 
 | 				$body.append( windowManager.$element );
  |  | 
 | 			}
  |  | 
 |    |  | 
 | 			settingsDialog = new SettingsDialog();
  |  | 
 | 			windowManager.addWindows( [ settingsDialog ] );
  |  | 
 | 			settingsWindow = windowManager.openWindow( settingsDialog );
  |  | 
 | 			settingsWindow.opened.then( function () {
  |  | 
 | 				settingsDialogOpening = false;
  |  | 
 | 			} );
  |  | 
 | 			settingsWindow.closed.then( function () {
  |  | 
 | 				windowManager.clearWindows();
  |  | 
 | 			} );
  |  | 
 | 		}
  |  | 
 |    |  | 
 | 		var tooltip = this;
  |  | 
 |    |  | 
 | 		// This variable can change: one tooltip can be called from a harvard-style reference link
  |  | 
 | 		// that is put into different tooltips
  |  | 
 | 		this.te = te;
  |  | 
 |    |  | 
 | 		switch ( this.te.type ) {
  |  | 
 | 			case 'supRef':
  |  | 
 | 				this.id = 'rt-' + this.te.$originalElement.attr( 'id' );
  |  | 
 | 				this.$content = this.te.$ref
  |  | 
 | 					.contents()
  |  | 
 | 					.filter( function ( i ) {
  |  | 
 | 						var $this = $( this );
  |  | 
 | 						return this.nodeType === Node.TEXT_NODE ||
  |  | 
 | 							!( $this.is( '.mw-cite-backlink' ) ||
  |  | 
 | 								( i === 0 &&
  |  | 
 | 									// Template:Cnote, Template:Note
  |  | 
 | 									( $this.is( 'b' ) ||
  |  | 
 | 										// Template:Note_label
  |  | 
 | 										$this.is( 'a' ) &&
  |  | 
 | 										$this.attr( 'href' ).indexOf( '#ref' ) === 0
  |  | 
 | 									)
  |  | 
 | 								)
  |  | 
 | 							);
  |  | 
 | 					} )
  |  | 
 | 					.clone( true );
  |  | 
 | 				break;
  |  | 
 | 			case 'harvardRef':
  |  | 
 | 				this.id = 'rt-' + this.te.$originalElement.closest( 'li' ).attr( 'id' );
  |  | 
 | 				this.$content = this.te.$ref
  |  | 
 | 					.clone( true )
  |  | 
 | 					.removeAttr( 'id' );
  |  | 
 | 				break;
  |  | 
 | 			case 'commentedText':  |  | 
 | 				this.id = 'rt-' + String( Math.random() ).slice( 2 );
  |  | 
 | 				this.$content = $( document.createTextNode( this.te.comment ) );
  |  | 
 | 				break;
  |  | 
 | 		}  |  | 
 | 		if ( !this.$content.length ) {
  |  | 
 | 			return;
  |  | 
 | 		}
  |  | 
 |    |  | 
 | 		this.insideWindow = Boolean( this.te.$element.closest( '.oo-ui-window' ).length );
  |  | 
 |    |  | 
 | 		this.$element = $( '<div>' )
  |  | 
 | 			.addClass( 'rt-tooltip' )
  |  | 
 | 			.attr( 'id', this.id )
  |  | 
 | 			.attr( 'role', 'tooltip' )
  |  | 
 | 			.data( 'tooltip', this );
  |  | 
 | 		if ( this.insideWindow ) {
  |  | 
 | 			this.$element.addClass( 'rt-tooltip-insideWindow' );  |  | 
 | 		}
  |  | 
 |    |  | 
 | 		// We need the $content interlayer here in order for the settings icon to have correct
  |  | 
 | 		// margins
  |  | 
 | 		this.$content = this.$content
  |  | 
 | 			.wrapAll( '<div>' )  |  | 
 | 			.parent()
  |  | 
 | 			.addClass( 'rt-tooltipContent' )
  |  | 
 | 			.addClass( 'mw-parser-output' )
  |  | 
 | 			.appendTo( this.$element );
  |  | 
 |    |  | 
 | 		if ( !activatedByClick ) {
  |  | 
 | 			this.$element
  |  | 
 | 				.mouseenter( function () {
  |  | 
 | 					if ( !tooltip.disappearing ) {
  |  | 
 | 						tooltip.upToTopParent( function () {
  |  | 
 | 							this.show();
  |  | 
 | 						} );
  |  | 
 | 					}
  |  | 
 | 				} )
  |  | 
 | 				.mouseleave( function ( e ) {
  |  | 
 | 					// https://stackoverflow.com/q/47649442 workaround. Relying on relatedTarget
  |  | 
 | 					// alone has pitfalls: when alt-tabbing, relatedTarget is empty too
  |  | 
 | 					if ( CLIENT_NAME !== 'chrome' ||
  |  | 
 | 						( !e.originalEvent ||
  |  | 
 | 							e.originalEvent.relatedTarget !== null ||
  |  | 
 | 							!tooltip.clickedTime ||
  |  | 
 | 							$.now() - tooltip.clickedTime > 50
  |  | 
 | 						)
  |  | 
 | 					) {
  |  | 
 | 						tooltip.upToTopParent( function () {
  |  | 
 | 							this.te.hideRef();
  |  | 
 | 						} );
  |  | 
 | 					}
  |  | 
 | 				} )
  |  | 
 | 				.click( function () {
  |  | 
 | 					tooltip.clickedTime = $.now();
  |  | 
 | 				} );
  |  | 
 | 		}
  |  | 
 |    |  | 
 | 		if ( !this.insideWindow ) {
  |  | 
 | 			$( '<div>' )  |  | 
 | 				.addClass( 'rt-settingsLink' )
  |  | 
 | 				.attr( 'title', mw.msg( 'rt-settings' ) )
  |  | 
 | 				.click( function () {
  |  | 
 | 					if ( settingsDialogOpening ) {
  |  | 
 | 						return;
  |  | 
 | 					}
  |  | 
 | 					settingsDialogOpening = true;
  |  | 
 |    |  | 
 | 					if ( mw.loader.getState( 'oojs-ui' ) !== 'ready' ) {
  |  | 
 | 						if ( cursorWaitCss ) {
  |  | 
 | 							cursorWaitCss.disabled = false;
  |  | 
 | 						} else {
  |  | 
 | 							cursorWaitCss = mw.util.addCSS( 'body { cursor: wait; }' );
  |  | 
 | 						}
  |  | 
 | 					}
  |  | 
 | 					mw.loader.using( [ 'oojs', 'oojs-ui' ], openSettingsDialog );
  |  | 
 | 				} )
  |  | 
 | 				.prependTo( this.$content );
  |  | 
 | 		}  |  | 		}  | 
 |    |  | 	});  | 
 | 		// Tooltip tail element is inside tooltip content element in order for the tooltip
  |  | })  | 
 | 		// not to disappear when the mouse is above the tail
  |  | 
 | 		this.$tail = $( '<div>' )
  |  | 
 | 			.addClass( 'rt-tooltipTail' )
  |  | 
 | 			.prependTo( this.$element );
  |  | 
 |    |  | 
 | 		this.disappearing = false;
  |  | 
 |    |  | 
 | 		this.show = function () {
  |  | 
 | 			this.disappearing = false;
  |  | 
 | 			clearTimeout( this.te.hideTimer );
  |  | 
 | 			clearTimeout( this.te.removeTimer );
  |  | 
 |    |  | 
 | 			this.$element
  |  | 
 | 				.removeClass( CLASSES.FADE_OUT_DOWN )
  |  | 
 | 				.removeClass( CLASSES.FADE_OUT_UP );
  |  | 
 |    |  | 
 | 			if ( !this.isPresent ) {
  |  | 
 | 				$body.append( this.$element );
  |  | 
 | 			}
  |  | 
 |    |  | 
 | 			this.isPresent = true;
  |  | 
 | 		};
  |  | 
 |    |  | 
 | 		this.hide = function () {
  |  | 
 | 			var tooltip = this;
  |  | 
 |    |  | 
 | 			tooltip.disappearing = true;
  |  | 
 |    |  | 
 | 			if ( tooltip.$element.hasClass( 'rt-tooltip-above' ) ) {
  |  | 
 | 				tooltip.$element
  |  | 
 | 					.removeClass( CLASSES.FADE_IN_DOWN )
  |  | 
 | 					.addClass( CLASSES.FADE_OUT_UP );
  |  | 
 | 			} else {
  |  | 
 | 				tooltip.$element
  |  | 
 | 					.removeClass( CLASSES.FADE_IN_UP )
  |  | 
 | 					.addClass( CLASSES.FADE_OUT_DOWN );
  |  | 
 | 			}
  |  | 
 |    |  | 
 | 			tooltip.te.removeTimer = setTimeout( function () {
  |  | 
 | 				if ( tooltip.isPresent ) {
  |  | 
 | 					tooltip.$element.detach();
  |  | 
 | 					
  |  | 
 | 					tooltip.$tail.css( 'left', '' );
  |  | 
 |    |  | 
 | 					if ( activatedByClick ) {
  |  | 
 | 						$body.off( 'click.rt touchstart.rt', tooltip.te.onBodyClick );
  |  | 
 | 					}
  |  | 
 | 					$window.off( 'resize.rt', tooltip.te.onWindowResize );
  |  | 
 |    |  | 
 | 					tooltip.isPresent = false;
  |  | 
 | 				}
  |  | 
 | 			}, 200 );
  |  | 
 | 		};
  |  | 
 |    |  | 
 | 		this.calculatePosition = function ( ePageX, ePageY ) {
  |  | 
 | 			var teElement, teOffsets, teOffset, tooltipTailOffsetX, tooltipTailLeft,
  |  | 
 | 				offsetYCorrection = 0;
  |  | 
 |    |  | 
 | 			this.$tail.css( 'left', '' );
  |  | 
 |    |  | 
 | 			teElement = this.te.$element.get( 0 );
  |  | 
 | 			if ( ePageX !== undefined ) {
  |  | 
 | 				tooltipTailOffsetX = ePageX;
  |  | 
 | 				teOffsets = teElement.getClientRects &&
  |  | 
 | 					teElement.getClientRects() ||
  |  | 
 | 					teElement.getBoundingClientRect();
  |  | 
 | 				if ( teOffsets.length > 1 ) {
  |  | 
 | 					for (var i = teOffsets.length - 1; i >= 0; i--) {
  |  | 
 | 						if ( ePageY >= Math.round( $window.scrollTop() + teOffsets[i].top ) &&
  |  | 
 | 							ePageY <= Math.round(
  |  | 
 | 								$window.scrollTop() + teOffsets[i].top + teOffsets[i].height
  |  | 
 | 							)
  |  | 
 | 						) {
  |  | 
 | 							teOffset = teOffsets[i];
  |  | 
 | 						}
  |  | 
 | 					}
  |  | 
 | 				}
  |  | 
 | 			}
  |  | 
 |    |  | 
 | 			if ( !teOffset ) {
  |  | 
 | 				teOffset = teElement.getClientRects &&
  |  | 
 | 					teElement.getClientRects()[0] ||
  |  | 
 | 					teElement.getBoundingClientRect();
  |  | 
 | 			}
  |  | 
 | 			teOffset = {
  |  | 
 | 				top: $window.scrollTop() + teOffset.top,
  |  | 
 | 				left: $window.scrollLeft() + teOffset.left,
  |  | 
 | 				width: teOffset.width,
  |  | 
 | 				height: teOffset.height
  |  | 
 | 			};
  |  | 
 | 			if ( !tooltipTailOffsetX ) {
  |  | 
 | 				tooltipTailOffsetX = ( teOffset.left * 2 + teOffset.width ) / 2;
  |  | 
 | 			}
  |  | 
 | 			if ( CLIENT_NAME === 'msie' && this.te.type === 'supRef' ) {
  |  | 
 | 				offsetYCorrection = -Number(
  |  | 
 | 					this.te.$element.parent().css( 'font-size' ).replace( 'px', '' )
  |  | 
 | 				) / 2;
  |  | 
 | 			}
  |  | 
 | 			this.$element.css( {
  |  | 
 | 				top: teOffset.top - this.$element.outerHeight() - 7 + offsetYCorrection,
  |  | 
 | 				left: tooltipTailOffsetX - 20,
  |  | 
 | 				right: ''
  |  | 
 | 			} );
  |  | 
 |    |  | 
 | 			// Is it squished against the right side of the page?
  |  | 
 | 			if ( this.$element.offset().left + this.$element.outerWidth() > $window.width() - 1 ) {
  |  | 
 | 				this.$element.css( {
  |  | 
 | 					left: '',
  |  | 
 | 					right: 0
  |  | 
 | 				} );
  |  | 
 | 				tooltipTailLeft = tooltipTailOffsetX - this.$element.offset().left - 5;
  |  | 
 | 			}
  |  | 
 |    |  | 
 | 			// Is a part of it above the top of the screen?
  |  | 
 | 			if ( teOffset.top < this.$element.outerHeight() + $window.scrollTop() + 6 ) {
  |  | 
 | 				this.$element
  |  | 
 | 					.removeClass( 'rt-tooltip-above' )
  |  | 
 | 					.addClass( 'rt-tooltip-below' )
  |  | 
 | 					.addClass( CLASSES.FADE_IN_UP )
  |  | 
 | 					.css( {
  |  | 
 | 						top: teOffset.top + teOffset.height + 9 + offsetYCorrection
  |  | 
 | 					} );
  |  | 
 | 				if ( tooltipTailLeft ) {
  |  | 
 | 					this.$tail.css( 'left', ( tooltipTailLeft + 12 ) + 'px' );
  |  | 
 | 				}
  |  | 
 | 			} else {
  |  | 
 | 				this.$element
  |  | 
 | 					.removeClass( 'rt-tooltip-below' )
  |  | 
 | 					.addClass( 'rt-tooltip-above' )
  |  | 
 | 					.addClass( CLASSES.FADE_IN_DOWN )
  |  | 
 | 					// A fix for cases when a tooltip shown once is then wrongly positioned when it
  |  | 
 | 					// is shown again after a window resize. We just repeat what is above.
  |  | 
 | 					.css( {
  |  | 
 | 						top: teOffset.top - this.$element.outerHeight() - 7 + offsetYCorrection
  |  | 
 | 					} );
  |  | 
 | 				if ( tooltipTailLeft ) {
  |  | 
 | 					// 12 is the tail element width/height
  |  | 
 | 					this.$tail.css( 'left', tooltipTailLeft + 'px' );
  |  | 
 | 				}
  |  | 
 | 			}
  |  | 
 | 		};
  |  | 
 |    |  | 
 | 		// Run some function for all the tooltips up to the top one in a tree. Its context will be
  |  | 
 | 		// the tooltip, while its parameters may be passed to Tooltip.upToTopParent as an array
  |  | 
 | 		// in the second parameter. If the third parameter passed to ToolTip.upToTopParent is true,
  |  | 
 | 		// the execution stops when the function in question returns true for the first time,
  |  | 
 | 		// and ToolTip.upToTopParent returns true as well.
  |  | 
 | 		this.upToTopParent = function ( func, parameters, stopAtTrue ) {
  |  | 
 | 			var returnValue,
  |  | 
 | 				currentTooltip = this;
  |  | 
 |    |  | 
 | 			do {
  |  | 
 | 				returnValue = func.apply( currentTooltip, parameters );
  |  | 
 | 				if ( stopAtTrue && returnValue ) {
  |  | 
 | 					break;
  |  | 
 | 				}
  |  | 
 | 			} while ( currentTooltip = currentTooltip.parent );
  |  | 
 |    |  | 
 | 			if ( stopAtTrue ) {
  |  | 
 | 				return returnValue;
  |  | 
 | 			}
  |  | 
 | 		};
  |  | 
 | 	}  |  | 
 |    |  | 
 | 	if ( !enabled ) {
  |  | 
 | 		addEnableLink();
  |  | 
 | 		return;
  |  | 
 | 	}
  |  | 
 |    |  | 
 | 	teSelector = REF_LINK_SELECTOR;
  |  | 
 | 	if ( tooltipsForComments ) {
  |  | 
 | 		teSelector += ', ' + COMMENTED_TEXT_SELECTOR;
  |  | 
 | 	}
  |  | 
 | 	$content.find( teSelector ).each( function () {
  |  | 
 | 		new TooltippedElement( $( this ) );
  |  | 
 | 	} );
  |  | 
 | }
  |  | 
 |    |  | 
 | settingsString = mw.cookie.get( 'RTsettings', '' );
  |  | 
 | if ( settingsString ) {
  |  | 
 | 	settings = settingsString.split( '|' );
  |  | 
 | 	enabled = Boolean( Number( settings[ 0 ] ) );
  |  | 
 | 	delay = Number( settings[ 1 ] );
  |  | 
 | 	activatedByClick = Boolean( Number( settings[ 2 ] ) );
  |  | 
 | 	// The forth value was added later, so we provide for a default value. See comments below
  |  | 
 | 	// for why we use "IS_TOUCHSCREEN && IS_MOBILE".
  |  | 
 | 	tooltipsForComments = settings[ 3 ] === undefined ?
  |  | 
 | 		IS_TOUCHSCREEN && IS_MOBILE :
  |  | 
 | 		Boolean( Number( settings[ 3 ] ) );
  |  | 
 | } else {
  |  | 
 | 	enabled = true;
  |  | 
 | 	delay = 200;
  |  | 
 | 	// Since the mobile browser check is error-prone, adding IS_MOBILE condition here would probably
  |  | 
 | 	// leave cases where a user interacting with the browser using touches doesn't know how to call
  |  | 
 | 	// a tooltip in order to switch to activation by click. Some touch-supporting laptop users
  |  | 
 | 	// interacting by touch (though probably not the most popular use case) would not be happy too.
  |  | 
 | 	activatedByClick = IS_TOUCHSCREEN;
  |  | 
 | 	// Arguably we shouldn't convert native tooltips into gadget tooltips for devices that have
  |  | 
 | 	// mouse support, even if they have touchscreens (there are laptops with touchscreens).
  |  | 
 | 	// IS_TOUCHSCREEN check here is for reliability, since the mobile check is prone to false
  |  | 
 | 	// positives.
  |  | 
 | 	tooltipsForComments = IS_TOUCHSCREEN && IS_MOBILE;
  |  | 
 | }  |  | 
 |    |  | 
 | mw.hook( 'wikipage.content' ).add( rt );
  |  | 
 |    |  | 
 | }() );
  |  |