Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module.exports = {
env: {
browser: true,
es2021: true
},
extends: [
'standard'
],
parserOptions: {
ecmaVersion: 13,
sourceType: 'module'
},
rules: {
},
globals: {
// Needs to kept in sync with helpers.js for now
chrome: 'readonly',
mouseOverAndClick: 'readonly',
openMoreActionsMenu: 'readonly',
waitAndClickWebLink: 'readonly',
clickElementAsap: 'readonly',
clickFullScreen: 'readonly',
mouseup: 'readonly',
mousedown: 'readonly',
mouseover: 'readonly'
}
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.temp/
node_modules/
98 changes: 29 additions & 69 deletions content_scripts/background.js
Original file line number Diff line number Diff line change
@@ -1,75 +1,35 @@
chrome.runtime.onInstalled.addListener(function() {
chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
chrome.runtime.onInstalled.addListener(function () {
chrome.declarativeContent.onPageChanged.removeRules(undefined, function () {
chrome.declarativeContent.onPageChanged.addRules([{
conditions: [new chrome.declarativeContent.PageStateMatcher({
pageUrl: {hostEquals: 'www.evernote.com', schemes: ['https']},
pageUrl: { hostEquals: 'www.evernote.com', schemes: ['https'] }
})
],
actions: [new chrome.declarativeContent.ShowPageAction()]
}]);
});
});
actions: [new chrome.declarativeContent.ShowPageAction()]
}])
})
})

const keyboardFileMappings = {
search: 'injectable_actions/clickSearch.js',
fullscreen: 'injectable_actions/toggleFullScreen.js',
opennote: 'injectable_actions/openNote.js',
deletenote: 'injectable_actions/deleteNote.js',
movenote: 'injectable_actions/moveNote.js',
copyinternallink: 'injectable_actions/copyInternalWebLink.js',
copyinternalapplink: 'injectable_actions/copyInternalAppLink.js',
newNote: 'injectable_actions/newNote.js',
insertMenu: 'injectable_actions/insertMenu.js',
editTags: 'injectable_actions/editTags.js',
strikeThroughText: 'injectable_actions/strikethroughText.js',
highlightText: 'injectable_actions/highlightText.js',
openNoteInNewWindow: 'injectable_actions/highlightText.js'
}

chrome.commands.onCommand.addListener(function (command) {
if (command === "search") {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.executeScript(
tabs[0].id,
{file: "injectable_actions/clickSearch.js"});
});
} else if (command === "fullscreen") {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.executeScript(
tabs[0].id,
{file: "injectable_actions/toggleFullScreen.js"});
});
} else if (command === "opennote") {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.executeScript(
tabs[0].id,
{file: "injectable_actions/openNote.js"});
});
} else if (command === "deletenote") {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.executeScript(
tabs[0].id,
{file: "injectable_actions/deleteNote.js"});
});
} else if (command === "movenote") {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.executeScript(
tabs[0].id,
{file: "injectable_actions/moveNote.js"});
});
} else if (command === "copyinternallink") {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.executeScript(
tabs[0].id,
{file: "injectable_actions/copyInternalWebLink.js"});
});
} else if (command === "copyinternalapplink") {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.executeScript(
tabs[0].id,
{file: "injectable_actions/copyInternalAppLink.js"});
});
} else if (command === "newNote") {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.executeScript(
tabs[0].id,
{file: "injectable_actions/newNote.js"});
});
} else if (command === "insertMenu") {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.executeScript(
tabs[0].id,
{file: "injectable_actions/insertMenu.js"});
});
} else if (command === "editTags") {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.executeScript(
tabs[0].id,
{file: "injectable_actions/editTags.js"});
});
}
});
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
chrome.tabs.executeScript(
tabs[0].id,
{ file: keyboardFileMappings[command] })
})
})
45 changes: 22 additions & 23 deletions content_scripts/contentScript.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
function getNoteId(element) {
const MAX_PARENTS_TO_CHECK = 4;
var noteId = null;
var currentId = element.id;

for (var i = 0; i < MAX_PARENTS_TO_CHECK; i++) {
if (currentId.includes("qa-NOTES_SIDEBAR_NOTE")) {
return currentId.split("_")[0];
}
element = element.parentElement;
currentId = element.id;
function getNoteId (element) {
const MAX_PARENTS_TO_CHECK = 4
let currentId = element.id
for (let i = 0; i < MAX_PARENTS_TO_CHECK; i++) {
if (currentId.includes('qa-NOTES_SIDEBAR_NOTE')) {
return currentId.split('_')[0]
}
return null;
element = element.parentElement
currentId = element.id
}
return null
}
document.addEventListener("click", function () {
if (event.altKey === true) {
var id = getNoteId(event.target);
if (id !== null) {
window.open(
`https://www.evernote.com/client/web?login=true#?fs=true&n=${ id }`,
'_blank',
'left=0,top=0'
);
}

document.addEventListener('click', function () {
if (event.altKey === true) {
const id = getNoteId(event.target)
if (id !== null) {
window.open(
`https://www.evernote.com/client/web?login=true#?fs=true&n=${id}`,
'_blank',
'left=0,top=0'
)
}
});
}
})
55 changes: 55 additions & 0 deletions content_scripts/helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
const mouseup = document.createEvent('MouseEvents')
mouseup.initEvent('mouseup', true, true)
const mousedown = document.createEvent('MouseEvents')
mousedown.initEvent('mousedown', true, true)
const mouseover = document.createEvent('MouseEvents')
mouseover.initEvent('mouseover', true, true)

function mouseOverAndClick (ele) {
ele.dispatchEvent(mouseover)
ele.click()
}

function waitAndClickWebLink (link) {
const MAX_WAIT = 1 * 1000 // 1 seconds seems like plenty
const interval = 5 // 5ms between checks
let curWait = 0
const checkExist = setInterval(function () {
curWait += interval
if (curWait > MAX_WAIT) {
clearInterval(checkExist)
alert('Evercuts had an error please email me')
}
const ele = document.getElementById(link)
if (ele) {
clearInterval(checkExist)
mouseOverAndClick(ele)
}
}, interval)
}

function openMoreActionsMenu () {
const button = document.getElementById('qa-NOTE_ACTIONS').parentElement
button.dispatchEvent(mouseup)
}

function clickElementAsap (ele, timeout = 2000, interval = 10) {
let curWait = 0
const checkExist = setInterval(function () {
curWait += interval
if (curWait >= timeout) {
clearInterval(checkExist)
console.log('Failed to click ' + ele)
}
const clickableElement = document.getElementById(ele)
if (clickableElement) {
clearInterval(checkExist)
mouseOverAndClick(clickableElement)
}
}, interval)
}

function clickFullScreen () {
const button = document.getElementById('qa-NOTE_FULLSCREEN_BTN')
mouseOverAndClick(button)
}
22 changes: 18 additions & 4 deletions injectable_actions/clickSearch.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
function clickSearch() {
var button = document.getElementById("qa-SEARCH_BAR_INITIAL");
button.click();
/**
* Evernote has this quirk in the url where the search params are split by a #
* the only search param before the # is login which I always assume to be true
*/
function getSearchParams (url) {
return url.split('#')[1].slice(1)
}
clickSearch();
function isFullScreen () {
const urlParams = new URLSearchParams(getSearchParams(window.location.toString()))
return urlParams.get('fs')
}
function clickSearch () {
if (isFullScreen()) {
clickFullScreen()
}
const button = document.getElementById('qa-SEARCH_BAR_INITIAL')
button.click()
}
clickSearch()
62 changes: 6 additions & 56 deletions injectable_actions/copyInternalAppLink.js
Original file line number Diff line number Diff line change
@@ -1,57 +1,7 @@
function mouseOverAndClick(ele) {
var evt = document.createEvent("MouseEvents");
evt.initEvent("mouseover", true, true);
ele.dispatchEvent(evt);
ele.click();
function copyInternalAppLink () {
openMoreActionsMenu()
const ele = document.getElementById('qa-ACTION_COPY_INTERNAL_LINK')
ele.dispatchEvent(mouseover)
clickElementAsap('qa-ACTION_COPY_APP_LINK')
}

function waitAndClickWebLink(link) {
const MAX_WAIT = 2 * 1000; // 2 seconds seems like plenty
const interval = 10; // 10ms between checks
var cur_wait = 0;
var checkExist = setInterval(function() {
cur_wait += interval;
if (cur_wait > MAX_WAIT) {
clearInterval(checkExist);
alert("Failed");
}
var ele = document.getElementById(link);
if (ele) {
clearInterval(checkExist);
mouseOverAndClick(ele);
}
}, interval);
}

function openMoreActionsMenu() {
const evt = document.createEvent("MouseEvents");
evt.initEvent("mouseup", true, true);
const button = document.getElementById("qa-NOTE_ACTIONS").parentElement;
button.dispatchEvent(evt);
}

function copyInternalWebLink() {
const MAX_WAIT = 2 * 1000;
const interval = 10;
const INTERNAL_LINK_ID = 'qa-ACTION_COPY_INTERNAL_LINK';
var evt = document.createEvent("MouseEvents");
evt.initEvent("mouseover", true, true);
var cur_wait = 0;

var checkExist = setInterval(function() {
cur_wait += interval;
if (cur_wait > MAX_WAIT) {
clearInterval(checkExist);
alert("Failed");
}
var ele = document.getElementById(INTERNAL_LINK_ID);
if (ele) {
clearInterval(checkExist);
ele.dispatchEvent(evt);
waitAndClickWebLink('qa-ACTION_COPY_APP_LINK');
}
}, interval);
}

openMoreActionsMenu();
copyInternalWebLink();
copyInternalAppLink()
62 changes: 6 additions & 56 deletions injectable_actions/copyInternalWebLink.js
Original file line number Diff line number Diff line change
@@ -1,57 +1,7 @@
function mouseOverAndClick(ele) {
var evt = document.createEvent("MouseEvents");
evt.initEvent("mouseover", true, true);
ele.dispatchEvent(evt);
ele.click();
function copyInternalWebLink () {
openMoreActionsMenu()
const ele = document.getElementById('qa-ACTION_COPY_INTERNAL_LINK')
ele.dispatchEvent(mouseover)
clickElementAsap('qa-ACTION_COPY_WEB_LINK')
}

function waitAndClickWebLink(link) {
const MAX_WAIT = 2 * 1000; // 2 seconds seems like plenty
const interval = 10; // 10ms between checks
var cur_wait = 0;
var checkExist = setInterval(function() {
cur_wait += interval;
if (cur_wait > MAX_WAIT) {
clearInterval(checkExist);
alert("Failed");
}
var ele = document.getElementById(link);
if (ele) {
clearInterval(checkExist);
mouseOverAndClick(ele);
}
}, interval);
}

function openMoreActionsMenu() {
const evt = document.createEvent("MouseEvents");
evt.initEvent("mouseup", true, true);
const button = document.getElementById("qa-NOTE_ACTIONS").parentElement;
button.dispatchEvent(evt);
}

function copyInternalWebLink() {
const MAX_WAIT = 2 * 1000;
const interval = 10;
const INTERNAL_LINK_ID = 'qa-ACTION_COPY_INTERNAL_LINK';
var evt = document.createEvent("MouseEvents");
evt.initEvent("mouseover", true, true);
var cur_wait = 0;

var checkExist = setInterval(function() {
cur_wait += interval;
if (cur_wait > MAX_WAIT) {
clearInterval(checkExist);
alert("Failed");
}
var ele = document.getElementById(INTERNAL_LINK_ID);
if (ele) {
clearInterval(checkExist);
ele.dispatchEvent(evt);
waitAndClickWebLink('qa-ACTION_COPY_WEB_LINK');
}
}, interval);
}

openMoreActionsMenu();
copyInternalWebLink();
copyInternalWebLink()
Loading