Skip to content
This repository has been archived by the owner on Aug 30, 2023. It is now read-only.

Open links when shift-click on link or url #203

Merged
merged 8 commits into from
Oct 16, 2017
7 changes: 7 additions & 0 deletions app/less/editor.less
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@
.editor-searching();
}

.link-clickable {
.cm-link:not(.cm-formatting),
.cm-url:not(.cm-formatting) {
cursor: pointer
}
}

// Generic editor classes
// ======================

Expand Down
67 changes: 67 additions & 0 deletions app/renderer/abr-document.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,73 @@ function AbrDocument () {
}
};

// Listeners for opening links on shift-click.

// Helper method to tell us if we should open a link from
// the target that has been clicked on. Check the global
// link-clickable class first to see if there's some reason
// that we shouldn't open a valid link (like selected text),
// then check for Markdown indicators.
var shouldOpenLink = function(event) {
return document.body.classList.contains("link-clickable") &&
!event.target.classList.contains("cm-formatting") &&
(event.target.classList.contains("cm-link") ||
event.target.classList.contains("cm-url"));
}

that.cm.on("mousedown", function(cm, event) { // prevent selection by shift-click
if (shouldOpenLink(event)) {
event.preventDefault();
}
});

document.addEventListener("mouseup", function(event) { // actually open the browser on mouseup
if (shouldOpenLink(event)) {
event.preventDefault();
OpenLinkHandler(event);
}
});

// Handle ALT modifier key
var ShiftKeyHandler = function(e) {
var linkIsClickable = !that.cm.somethingSelected() &&
e.type === "keydown" &&
e.shiftKey;
document.body.classList.toggle("link-clickable", linkIsClickable);
}

window.addEventListener("keydown", ShiftKeyHandler, false);
window.addEventListener("keyup", ShiftKeyHandler, false);
// when leaving Abricotine to go the browser, the keyup event doesn't trigger
window.addEventListener("blur", ShiftKeyHandler, false);

var OpenLinkHandler = function(e) {
if (!document.body.classList.contains("link-clickable")) return;

var open = null;
var url = null;
if (e.target.classList.contains("cm-url")) { // link in standard MD format, url part was clicked on
open = $(e.target).prevUntil(":not(.cm-url)").andSelf().first();
url = open.nextUntil(".cm-formatting-link-string").text();
} else if (e.target.classList.contains("cm-link")) {
open = $(e.target).prevUntil(":not(.cm-link)");
if (open.first().is(".cm-formatting-link")) { // link in standard MD format, link text was clicked on
open = $(e.target).nextAll(".cm-formatting-link-string").first();
url = open.nextUntil(".cm-formatting-link-string").text();
} else { // link is a raw url
open = open.andSelf().first();
url = open.nextUntil(":not(.cm-link)").andSelf().text();
}
}

if (url === "") return;
var hasProtocol = /^[a-z]+:\/\//.test(url);
if (!hasProtocol) {
url = "http://" + url;
}
shell.openExternal(url);
}

// Handle CTRL+MouseWheel events
var MouseWheelHandler = function (e) {
var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
Expand Down