Skip to content

Commit

Permalink
Add new URL bar based installation for Firefox 65+
Browse files Browse the repository at this point in the history
  • Loading branch information
evilpie committed Nov 3, 2018
1 parent b45d779 commit 381ad61
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 44 deletions.
53 changes: 53 additions & 0 deletions icons/arrow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/pageaction.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/urlbar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
62 changes: 29 additions & 33 deletions search.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,35 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">

<title>Add custom search engine</title>
<link rel="stylesheet" href="bootstrap.4.1.3.min.css" />
<link rel="icon" href="icons/search.svg" type="image/svg+xml" />

<meta charset="utf-8">
<link rel="stylesheet" href="bootstrap.4.1.3.min.css" />
<link rel="stylesheet" href="style.css" />

<style type="text/css">
body {
max-width: 800px;
margin: 0 auto 0 auto;
}

#icon-preview {
height: calc(2.25rem + 2px);
width: calc(2.25rem + 2px);
object-fit: contain;
}

/* advanced options are initially hidden */
.adv-hidden {
display: none;
}

#post-checkbox {
margin-bottom: .5rem;
}

input[type=file] {
display: none;
}

label[for=input-file-icon] {
width: 100%;
-moz-appearance: button;
}
</style>
<link rel="icon" href="icons/search.svg" type="image/svg+xml" />
</head>
<body class="bg-light">

<div id="instructions">
<div id="arrow"></div>
<div id="info" class="text-center">
<h3>Adding a new search engine via the URL bar</h3>
<div>
<img src="icons/urlbar.png">
<p><strong>Open the "Page actions" menu</strong></p>
<img src="icons/pageaction.png">
<p><strong>Click "Add Search Engine"</strong></p>
<p class="text-muted">This option will not appear if a search engine with that name already exists.<br>
Go to <mark>about:preferences#search</mark> to see your installed search engines.</p>

<button id="close" class="btn btn-primary">Go back</button>
</div>
</div>
</div>

<div id="main">
<div class="py-5 text-center">
<img src="icons/search.svg" width="35" height="35">
<h1>Add custom search engine</h1>
Expand Down Expand Up @@ -89,6 +79,11 @@ <h1>Add custom search engine</h1>
</p>
</div>

<div class="form-group">
<label>Keyword</label>
<p class="text-muted"><strong>Tip:</strong> A keyword can be added by going to <mark>about:preferences#search</mark> after adding the search engine and editing the <em>Keyword</em> column</p>
</div>

<div class="form-group">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="show-advanced">
Expand Down Expand Up @@ -128,6 +123,7 @@ <h1>Add custom search engine</h1>

<pre id="preview" class="advanced adv-hidden">
</pre>
</div>

<script type="text/javascript" src="search.js"></script>
</body>
Expand Down
65 changes: 54 additions & 11 deletions search.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,26 +79,59 @@ function createXMLString() {
return serialzer.serializeToString(doc);
}

document.querySelector("form").addEventListener("submit", event => {
document.querySelector("form").addEventListener("submit", async event => {
event.preventDefault();

const string = createXMLString();

// Upload the OpenSearch XML description to file.io, because AddSearchProvider
// requires http(s) URLs. After the xml is downloaded to start the installation
// process, the file should be automatically removed.

// NB: The documentation on file.io is wrong: 1d is 1 day, but just 1 is 1 week!
fetch("https://file.io/?expires=1d", {
method: "POST",
body: new URLSearchParams({text: string})
}).then(response => {
return response.json();
}).then(json => {
// Where the magic happens!
window.external.AddSearchProvider(json.link);
});
try {
let response = await fetch("https://file.io/?expires=1d", {
method: "POST",
body: new URLSearchParams({text: string})
});
let json = await response.json();

let {version} = await browser.runtime.getBrowserInfo();
if (+/(\d+)\./.exec(version)[1] >= 65) {
// Mozilla intentionally disabled AddSearchProvider :(
// https://bugzilla.mozilla.org/show_bug.cgi?id=1503551

let link = document.createElement("link");
link.rel = "search";
link.type = "application/opensearchdescription+xml";
link.title = document.querySelector("#input-name").value;
link.href = json.link;

// This doesn't actually seem to work. Firefox seems to cache.
let existing = document.querySelector("link[rel=search]");
if (existing) {
existing.remove();
}

document.head.append(link);

document.querySelector("#main").style.display = "none";
document.querySelector("#instructions").style.display = "block";
} else {
// Where the magic happens!
window.external.AddSearchProvider(json.link);
}
} catch(error) {
alert(error);
};
});

document.querySelector("#close").addEventListener("click", event => {
event.preventDefault();
});

document.querySelector("#main").style.display = "block";
document.querySelector("#instructions").style.display = "none";
})

document.querySelector("#show-preview").addEventListener("click", event => {
const string = createXMLString();
Expand Down Expand Up @@ -156,3 +189,13 @@ document.addEventListener("DOMContentLoaded", () => {
usePost();
loadIcon();
});

// One-click selection for convience, because we can't directly link about:preferences
document.querySelectorAll("mark").forEach(mark => mark.addEventListener("click", event => {
let range = document.createRange();
range.selectNodeContents(event.target);

let selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
}));
66 changes: 66 additions & 0 deletions style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
body {
max-width: 800px;
margin: 0 auto 0 auto;
}

#icon-preview {
height: calc(2.25rem + 2px);
width: calc(2.25rem + 2px);
object-fit: contain;
}

/* advanced options are initially hidden */
.adv-hidden {
display: none;
}

#post-checkbox {
margin-bottom: .5rem;
}

input[type=file] {
display: none;
}

label[for=input-file-icon] {
width: 100%;
-moz-appearance: button;
}

#instructions {
display: none;
}

#arrow {
position: fixed;
top: 40px;
left: 50%;
margin-left:-20px;
width: 40px;
height: 40px;
background-image: url(icons/arrow.svg);
background-size: contain;
animation: bounce 2s infinite;
}

#info {
margin: auto;
padding-top: 100px;
width: 800px;
}

#info p {
margin-top: 0.5em;
}

@keyframes bounce {
0%, 20%, 50%, 80%, 100% {
transform: translateY(0);
}
40% {
transform: translateY(-30px);
}
60% {
transform: translateY(-15px);
}
}

0 comments on commit 381ad61

Please sign in to comment.