User:Thundercraft5/global.js/Ace.js/hoverlink.js

/** Original source: https://jsbin.com/jehopaja/4/edit?html,output **/ /* jshint esversion: 6, forin: true, immed: true, indent: 4, latedef: true, newcap: true, noarg: true, undef: true, undef: true, unused: true, browser: true, jquery: true, onevar: true, eqeqeq: true, multistr: true, maxerr: 99999, -W082, -W084, /* global ace, mw */ /** * w:c:Test */ ace.define("ace/ext/hoverlink", [], function(require, exports) {	"use strict";	mw.util.addCSS(`.ace_link_marker { position: absolute; margin-top: -2px; border-radius: unset !important; border-bottom: 2px solid currentcolor; }`);	var oop = require("ace/lib/oop");	var event = require("ace/lib/event");	var Range = require("ace/range").Range;	var EventEmitter = require("ace/lib/event_emitter").EventEmitter;	function createClassList(tokens) {		return tokens.split(".").map(v => "ace_"+v).join(" ");	}	function wLinkToTitle(link) {		return link.replace(/^\[{2}(.*?)(?:\|.*?)?\]{2}$/, '$1');	}	var HoverLink = function(editor, interwikimap) {		if (editor.hoverLink)			return;		editor.hoverLink = this;		this.editor = editor;		this.interwikimap = interwikimap;		this.update = this.update.bind(this);		this.onMouseMove = this.onMouseMove.bind(this);		this.onMouseOut = this.onMouseOut.bind(this);		this.onClick = this.onClick.bind(this);		event.addListener(editor.renderer.scroller, "mousemove", this.onMouseMove);		event.addListener(editor.renderer.content, "mouseout", this.onMouseOut);		event.addListener(editor.renderer.content, "click", this.onClick); };	(function {		oop.implement(this, EventEmitter);		this.token = {};		this.range = new Range;		this.update = function {			this.$timer = null;			var editor = this.editor;			var renderer = editor.renderer;			var canvasPos = renderer.scroller.getBoundingClientRect;			var offset = (this.x + renderer.scrollLeft - canvasPos.left - renderer.$padding) / renderer.characterWidth;			var row = Math.floor((this.y + renderer.scrollTop - canvasPos.top) / renderer.lineHeight);			var col = Math.round(offset);			var screenPos = {row: row, column: col, side: offset - col > 0 ? 1 : -1};			var session = editor.session;			var docPos = session.screenToDocumentPosition(screenPos.row, screenPos.column);			var selectionRange = editor.selection.getRange;			if (!selectionRange.isEmpty) {				if (selectionRange.start.row <= row && selectionRange.end.row >= row)					return this.clear;			}			var line = editor.session.getLine(docPos.row); if (docPos.column === line.length) { var clippedPos = editor.session.documentToScreenPosition(docPos.row, docPos.column); if (clippedPos.column !== screenPos.column) { return this.clear; }			}			var token = this.findLink(docPos.row, docPos.column); this.link = token; if (!token) { return this.clear; }			this.isOpen = true; editor.renderer.setCursorStyle("pointer"); session.removeMarker(this.marker); this.removeEditorLink; this.range = new Range(token.row, token.start, token.row, token.start + token.value.length); this.marker = session.addMarker(this.range, "ace_link_marker " + token.tokens, "text", true); this.setEditorLink(token.type === 'local' ? this.createLink(token.value) : token.value, token.type === 'local' ? wLinkToTitle(token.value) : undefined); };		this.setEditorLink = function(href, title) { console.log(arguments); this.editor.container.setAttribute('title', title || href); this.editor.container.setAttribute('href', href); };		this.removeEditorLink = function { this.editor.container.removeAttribute('title'); this.editor.container.removeAttribute('href'); };		this.clear = function { if (this.isOpen) { this.editor.session.removeMarker(this.marker); this.editor.renderer.setCursorStyle(""); this.isOpen = false; this.removeEditorLink; }		};		this.getMatchAround = function(regExp, string, col) { var match; regExp.lastIndex = 0; string.replace(regExp, function(str) {				var offset = arguments[arguments.length-2];				var length = str.length;				if (offset <= col && offset + length >= col)					match = {						start: offset,						value: str,					};			}); return match; };		this.onClick = function { if (this.link) { this.link.editor = this.editor; this._signal("open", this.link); this.clear; }		};		this.findLink = function(row, column) { var editor = this.editor; var session = editor.session; var line = session.getLine(row); var extLinkMatch = this.getMatchAround(/\w+:\/\/((?!(?<![\{\[\(][^\s]*)([\}\]\)]))[^\s"'`>])+/g, line, column);			var intLinkMatch = this.getMatchAround(/\[\[((?!.*(~{3,}))[^\n<>\[\]\{\}\|])+?(\|.+?)?\]\]/, line, column);			var match = extLinkMatch || intLinkMatch;			if (!match) return;			match.row = row;			match.type = extLinkMatch ? 'external' : 'local';			match.tokens = createClassList(editor.session.getTokenAt(row, column-2).type);			return match;		};		this.onMouseMove = function(e) {			if (this.editor.$mouseHandler.isMousePressed) {				if (!this.editor.selection.isEmpty)					this.clear;				return;			}			this.x = e.clientX;			this.y = e.clientY;			this.update;		};		this.onMouseOut = function {			this.clear;		};		this.destroy = function {			this.onMouseOut;			event.removeListener(this.editor.renderer.scroller, "mousemove", this.onMouseMove);			event.removeListener(this.editor.renderer.content, "mouseout", this.onMouseOut); delete this.editor.hoverLink; };		this.createLink = function(pageText) { console.log(pageText); return pageText.replace(/^\[{2}(([\w\.]+)\:(.+?))\]{2}$/, ($0, $1, $2, $3) => {				var prefixedLink = this.interwikimap.find(link => link.prefix === $2);				if (prefixedLink) {					return prefixedLink.url.replace('$1', $3);				} else {					return $1;				}			}); };	}).call(HoverLink.prototype);	exports.HoverLink = HoverLink; }); new mw.Api.get({	action: "query",	meta: "siteinfo",	siprop: "interwikimap", }).then(({ query: { interwikimap }}) => {	var HoverLink = ace.require("ace/ext/hoverlink").HoverLink;	ace.editor.hoverLink = new HoverLink(ace.editor, interwikimap);	ace.editor.hoverLink.on("open", function(linkObj) { open(linkObj.value); }); });