Created
October 23, 2014 21:43
-
-
Save orbitbot/27f042995d03372fecaa to your computer and use it in GitHub Desktop.
Ace editor with http-link highlighting and click action, from http://jsbin.com/jehopaja/30/edit?html,output
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>JS Bin</title> | |
<script src="http://ajaxorg.github.io/ace-builds/src/ace.js"></script> | |
<style> | |
#editor { position: absolute; top: 0; left: 0; right: 0; bottom: 0;} | |
.ace_link_marker { | |
position: absolute; | |
border-bottom: 1px solid blue; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="editor"> | |
text and link http://hello.world | |
</div> | |
</body> | |
<script> | |
editor = ace.edit("editor") | |
define("hoverlink", [], function(require, exports, module) { | |
"use strict"; | |
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; | |
var HoverLink = function(editor) { | |
if (editor.hoverLink) | |
return; | |
editor.hoverLink = this; | |
this.editor = editor; | |
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.range = new Range(token.row, token.start, token.row, token.start + token.value.length); | |
this.marker = session.addMarker(this.range, "ace_link_marker", "text", true); | |
}; | |
this.clear = function() { | |
if (this.isOpen) { | |
this.link = null; | |
this.editor.session.removeMarker(this.marker); | |
this.editor.renderer.setCursorStyle(""); | |
this.isOpen = false; | |
} | |
}; | |
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 match = this.getMatchAround(/https?:\/\/[^\s"']+/g, line, column); | |
if (!match) | |
return; | |
match.row = row; | |
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(e) { | |
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; | |
}; | |
}).call(HoverLink.prototype); | |
exports.HoverLink = HoverLink; | |
}); | |
HoverLink = require("hoverlink").HoverLink | |
editor.hoverLink = new HoverLink(editor); | |
editor.hoverLink.on("open", function() { | |
alert("trying to open") | |
}) | |
</script> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment