Rename repo

This commit is contained in:
Rumperuu 2018-07-18 10:43:03 +01:00
commit 9e00cb84e7
14 changed files with 451 additions and 0 deletions

38
popups/choose_element.css Normal file
View file

@ -0,0 +1,38 @@
/**
Title: Pinpointer
Version: 1.0
Author: Ben Goldsworthy <me@bengoldsworthy.net>
This file is a part of Pinpointer, a browser extension that allows you to
create and share links to arbitrary content on a webpage.
This stylesheet styles the layout of the extension popup menu.
*/
html, body {
width: auto;
}
.hidden {
display: none;
}
.button {
color: white;
margin: 3% auto;
padding: 4px;
text-align: center;
font-size: 1.5em;
cursor: pointer;
background-color: green;
}
.button:hover {
background-color: darkgreen;
}
span {
border-radius: 25px;
padding: 4px;
font-weight: bold;
}

View file

@ -0,0 +1,36 @@
<!DOCTYPE html>
<!--
Title: Pinpointer
Version: 1.0
Author: Ben Goldsworthy <me@bengoldsworthy.net>
This file is a part of Pinpointer, a browser extension that allows you to
create and share links to arbitrary content on a webpage.
This markup represents the extension popup menu.
-->
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="choose_element.css"/>
</head>
<body>
<h1>Pinpointer</h1>
<div id="popup-content">
<p id="step1">Highlight the part of the page you want to create a link to, and then click the button below:</p>
<div class="button" id="grabElement">Click to select element.</div>
<p id="step2" class="hidden">Modify the exact selection below, and then click the button.</p>
<p id="selector" class="hidden"></p>
<div class="button hidden" id="generateLink">Click to generate link.</div>
<p id="link" class="hidden"></p>
</div>
<div id="error-content" class="hidden">
<p>Error.</p>
</div>
<script src="choose_element.js"></script>
</body>
</html>

147
popups/choose_element.js Normal file
View file

@ -0,0 +1,147 @@
/**
Title: Pinpointer
Version: 1.0
Author: Ben Goldsworthy <me@bengoldsworthy.net>
This file is a part of Pinpointer, a browser extension that allows you to
create and share links to arbitrary content on a webpage.
This script provides the logic of the extension popup menu.
*/
/**
* Listens for clicks within the pop-up. These will be to either grab a selected
* element's CSS selector, to change the selected element or to generate the
* URL.
*/
function listenForClicks() {
var maxIndex = 0;
var splitPath = new Array();
var currentURL;
document.addEventListener("click", (e) => {
switch (e.target.id) {
// Get the active tab, then request the path to the currently-selected
// element and display it.
case "grabElement":
browser.tabs.query({active: true, currentWindow: true}, function(tabs) {
// Strips the fragment identifier off of the current URL, if
// applicable.
currentURL = tabs[0].url.split('#')[0];
// Requests the unique path of the currently-selected element.
browser.tabs.sendMessage(tabs[0].id, {type: "grabElement"}, function(path) {
if (path != null) {
// Splits the path into constituent elements.
splitPath = path.split(' > ');
maxIndex = splitPath.length - 1;
// Builds and displays the precision selection form.
document.getElementById("selector").classList.remove("hidden");
var back = document.createElement("button");
back.id = "back";
back.setAttribute('type', 'button');
if (maxIndex <= 0) back.disabled = true;
back.appendChild(document.createTextNode("<"));
document.getElementById("selector").appendChild(back);
for (var i = 0; i <= maxIndex; i++) {
var segment = document.createElement("span");
segment.classList.add("segment");
var selector = document.createTextNode(splitPath[i]);
segment.appendChild(selector);
document.getElementById("selector").appendChild(segment);
if (i + 1 <= maxIndex) {
var sef = document.createElement("span");
var segSep = document.createElement("span");
segSep.classList.add("segSep");
segSep.appendChild(document.createTextNode(" > "));
document.getElementById("selector").appendChild(segSep);
}
}
var fwd = document.createElement("button");
fwd.id = "fwd";
fwd.setAttribute('type', 'button');
if (maxIndex == splitPath.length - 1) fwd.disabled = true;
fwd.appendChild(document.createTextNode(">"));
document.getElementById("selector").appendChild(fwd);
// Shows the next steps for the user.
document.getElementById("step2").classList.remove("hidden");
document.getElementById("generateLink").classList.remove("hidden");
} else {
// Otherwise, if nothing is currently highlighted, display
// a message.
document.getElementById("selector").innerHTML = 'Please select some text first.';
}
});
});
break;
// In this case, generate and display the URL.
case "generateLink":
// Re-form the selector into a string.
splitPath = splitPath.slice(0, maxIndex + 1);
var finalPath = splitPath.join(" > ");
// Encode it and append it to the current URL.
var encodedPath = encodeURIComponent(btoa(finalPath));
var linkURL = currentURL + '#' + encodedPath;
var linkElem = document.createElement('a');
linkElem.href = linkURL;
linkElem.target = "_blank";
linkElem.rel = "noopener noreferrer";
linkElem.id = "linkElement";
linkElem.appendChild(document.createTextNode(linkElem));
document.getElementById("link").appendChild(linkElem);
document.getElementById("link").classList.remove("hidden");
break;
// Selects the previous element in the selector.
case "back":
if (maxIndex > 0) {
document.getElementsByClassName("segment")[maxIndex--].classList.add("hidden");
document.getElementsByClassName("segSep")[maxIndex].classList.add("hidden");
browser.tabs.query({active: true, currentWindow: true}, function(tabs) {
browser.tabs.sendMessage(tabs[0].id, {type: "highlightElement", selector: splitPath.slice(0, maxIndex + 1).join(" > ") });
});
if (maxIndex <= 0)
e.target.disabled = true;
if (document.getElementById("fwd").disabled)
document.getElementById("fwd").disabled = false;
}
break;
// Selects the next element in the selector.
case "fwd":
if (maxIndex < splitPath.length - 1) {
document.getElementsByClassName("segSep")[maxIndex++].classList.remove("hidden");
document.getElementsByClassName("segment")[maxIndex].classList.remove("hidden");
browser.tabs.query({active: true, currentWindow: true}, function(tabs) {
browser.tabs.sendMessage(tabs[0].id, {type: "highlightElement", selector: splitPath.slice(0, maxIndex + 1).join(" > ") });
});
if (maxIndex == splitPath.length - 1)
e.target.disabled = true;
if (document.getElementById("back").disabled)
document.getElementById("back").disabled = false;
}
break;
default:
}
});
}
/**
* Displays the popup's error message if there is an error executing the script.
*/
function reportExecuteScriptError(error) {
document.getElementById("popup-content").classList.add("hidden");
document.getElementById("error-content").classList.remove("hidden");
console.error(`Failed to execute beastify content script: ${error.message}`);
}
/**
* Injects the content script into the active tab and adds a click handler.
* Handles errors if need be.
*/
browser.tabs.executeScript({file: "/content_scripts/pinpointer.js"})
.then(listenForClicks)
.catch(reportExecuteScriptError);