Skip to content

Instantly share code, notes, and snippets.

@with-heart
Last active March 19, 2022 21:47
Show Gist options
  • Save with-heart/78e459cc0ba2df21302153e26ea9f6b2 to your computer and use it in GitHub Desktop.
Save with-heart/78e459cc0ba2df21302153e26ea9f6b2 to your computer and use it in GitHub Desktop.
Tampermonkey script for toggling Hashnode editor tabs
// ==UserScript==
// @name Hashnode Editor Toggle
// @namespace https://github.com/with-heart
// @author with-heart <with.heart@pm.me>
// @version 0.0.6
// @description Toggle between the Write and Preview tabs in the Hashnode editor
// @match https://hashnode.com/draft/*
// @updateURL https://gist.githubusercontent.com/with-heart/78e459cc0ba2df21302153e26ea9f6b2/raw/hashnode-editor-toggle.js
// @downloadURL https://gist.githubusercontent.com/with-heart/78e459cc0ba2df21302153e26ea9f6b2/raw/hashnode-editor-toggle.js
// ==/UserScript==
;(function () {
'use strict'
let editorPosition = {
scroll: 0,
selection: {
start: 0,
end: 0,
},
}
const ui = {
tabs: {
get write() {
return document.querySelector('button[title="Write Markdown"]')
},
get preview() {
return document.querySelector('button[title="Preview Markdown"]')
},
},
get editor() {
return document.querySelector('textarea[name="editor"]')
},
}
document.addEventListener('keydown', onKeyDown)
function onKeyDown(event) {
// if event is not for Command-Shift-p, do nothing
if (!isTogglePreviewEvent(event)) return
const activeTab = findActiveTab()
// if active tab is 'guide', do nothing
if (activeTab === 'guide') return
if (activeTab === 'write') {
// active tab is 'write', so switch to 'preview'
switchToPreview()
}
// otherwise active tab is 'preview', so switch to 'write'
else {
switchToWrite()
}
}
function switchToPreview() {
// store the editor's current position
storeEditorPosition()
// click the 'preview' button
ui.tabs.preview.click()
}
function switchToWrite() {
// click the 'write' button
ui.tabs.write.click()
// restore the editor's position
restoreEditorPosition()
// focus the editor
ui.editor.focus()
}
function storeEditorPosition() {
editorPosition = {
// editor's scroll position is based on the window's scroll position
scroll: window.scrollY,
// editor's selection is derived from the textarea's selection
selection: {
start: ui.editor.selectionStart,
end: ui.editor.selectionEnd,
},
}
}
function restoreEditorPosition() {
const {scroll, selection} = editorPosition
// scroll to the stored position
window.scrollTo(0, scroll)
// restore the selection
ui.editor.setSelectionRange(selection.start, selection.end)
}
function isTogglePreviewEvent(event) {
return event.metaKey && event.shiftKey && event.key === 'p'
}
function findActiveTab() {
return isActiveTab(ui.tabs.write)
? 'write'
: isActiveTab(ui.tabs.preview)
? 'preview'
: 'guide'
}
function isActiveTab(element) {
return element.classList.contains('active')
}
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment