Merriam-Webster helper (Tampermonkey)

A tiny script that makes merriam-webster.com/ work nicely with Vimium.

Features:

  • Removes the focus from the search bar so that you can use the vim commands to move around.
  • Adds a label below the word of the day to indicate whether the word is already in your list of saved words. Otherwise, it adds a convenient button to save the word right there and then.
// ==UserScript==
// @name Merriam-Webster Helper
// @namespace http://tampermonkey.net/
// @version 0.1
// @description A tiny script that makes merriam-webster.com/ work nicely with Vimium, namely, it removes the focus from the search bar so that you can use the vim commands to move around.
// @author Rafael Rendon Pablo
// @run-at document-idle
// @match https://www.merriam-webster.com/
// @match https://www.merriam-webster.com/word-of-the-day
// @match https://www.merriam-webster.com/word-of-the-day/*
// @match https://www.merriam-webster.com/dictionary/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=merriam-webster.com
// @grant GM_xmlhttpRequest
// ==/UserScript==
(function() {
'use strict';
// Merriam-Websters' search form gets focused every time a tab becomes visible,
// this interferes with Vimium.
// Remove the focus when the page loads
const searchButton = document.getElementsByClassName('btn position-absolute search-button search-dictionary');
if (searchButton.length > 0) {
console.log("Removing focus from search form")
document.activeElement.blur();
}
// Remove the focus when the page regains visibility
document.addEventListener("visibilitychange", function() {
if (!document.hidden){
console.log("Browser tab is visible, removing focus from search form")
document.activeElement.blur();
}
});
const wordElement = document.querySelectorAll('div.word-and-pronunciation h2');
if (wordElement.length === 0) {
return
}
console.log("On Word of the Day page")
const word = wordElement[0].textContent;
const wordAttributes = document.querySelectorAll('div.word-attributes');
const copyURLButton = document.createElement('button');
copyURLButton.append('Copy URL');
copyURLButton.addEventListener('click', function () {
const url = window.location.href.toString();
navigator.clipboard.write([
new ClipboardItem({
'text/plain': new Blob([url],
{type: 'text/plain'}
),
'text/html': new Blob(
['<a href="' + url + '">' + url + '</a>'],
{type: 'text/html'},
),
}),
]).then(() => {
console.log("Copied URL to the clipboard: " + url);
}).catch((err) => {
console.error("Failed to copy URL to the clipboard: " + err);
});
});
const copyURL = document.createElement('span');
copyURL.append(copyURLButton);
wordAttributes[0].append(copyURL);
const wordStatus = document.createElement('span');
wordStatus.setAttribute('class', 'word-syllables');
wordAttributes[0].append(wordStatus);
const savedLabel = document.createElement('span');
savedLabel.append('SAVED');
const getDefinition = function(url, callback) {
};
const handleSaveResponse = function(response) {
const data = JSON.parse(response.responseText);
if (data.status === 'success') {
wordStatus.removeChild(saveButton);
wordStatus.append(savedLabel);
console.log("Saved word successfully");
} else {
console.error("Unable to save word");
}
};
const saveButton = document.createElement('button');
saveButton.append('Save');
saveButton.addEventListener('click', function () {
GM_xmlhttpRequest({
method: 'POST',
url: 'https://www.merriam-webster.com/lapi/v1/wordlist/save',
onload: handleSaveResponse,
data: 'word=' + word + '&type=d',
headers: {
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
},
});
});
const handleIsSavedResponse = function(response) {
const isSaved = JSON.parse(response.responseText).data.data.saved;
if (isSaved) {
wordStatus.append(savedLabel);
} else {
wordStatus.append(saveButton);
}
};
GM_xmlhttpRequest({
method: 'GET',
url: 'https://www.merriam-webster.com/lapi/v1/wordlist/is-saved?word=' + word + '&type=d',
onload: handleIsSavedResponse
});
})();

Posted

in

,

by

Tags: