Rename repo
This commit is contained in:
commit
9e00cb84e7
14 changed files with 451 additions and 0 deletions
38
popups/choose_element.css
Normal file
38
popups/choose_element.css
Normal 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;
|
||||
}
|
36
popups/choose_element.html
Normal file
36
popups/choose_element.html
Normal 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
147
popups/choose_element.js
Normal 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);
|
Reference in a new issue