Last active
December 29, 2022 16:14
-
-
Save ruter/f8a040a9efbe9b60b288ad90bd0f7d67 to your computer and use it in GitHub Desktop.
A script for Notion word count.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Notion Page Words Counter | |
// @name:zh-CN Notion 页面字数统计 | |
// @namespace https://notion.cx/ | |
// @version 0.1.0 | |
// @description Count current page words. | |
// @description:zh-cn 统计当前页面的字数。 | |
// @author Ruter Lü | |
// @match https://www.notion.so/* | |
// @grant none | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
/* Helper function to wait for the element ready */ | |
const waitFor = (...selectors) => new Promise(resolve => { | |
const delay = 500; | |
const f = () => { | |
const elements = selectors.map(selector => document.querySelector(selector)); | |
if (elements.every(element => element != null)) { | |
resolve(elements); | |
} else { | |
setTimeout(f, delay); | |
} | |
} | |
f(); | |
}); | |
/* Helper function to wait for the element ready */ | |
/* Word Count Function */ | |
let pattern = /[a-zA-Z0-9_\u0392-\u03c9\u00c0-\u00ff\u0600-\u06ff\u0400-\u04ff]+|[\u4e00-\u9fff\u3400-\u4dbf\uf900-\ufaff\u3040-\u309f\uac00-\ud7af]+/g; | |
function wordCount(str) { | |
let m = str.match(pattern); | |
let count = 0; | |
if (!m) { | |
return 0; | |
} | |
for (let i = 0; i < m.length; i++) { | |
if (m[i].charCodeAt(0) >= 0x4e00) { | |
count += m[i].length; | |
} else { | |
count += 1; | |
} | |
} | |
return count; | |
}; | |
/* Word Count Function */ | |
/* Word Count Element */ | |
const countCss = '-webkit-user-select: none; cursor: auto; position: absolute; display: flex; align-items: center; justify-content: center; bottom: 0px; right: 32px; height: 32px; font-size: 12px; z-index: 100; opacity: 1; background-position: initial initial; background-repeat: initial initial;'; | |
const countEl = document.createElement('div'); | |
countEl.setAttribute('class', 'notion-word-count'); | |
countEl.style.cssText = countCss; | |
countEl.innerHTML = 'Word count: <span class="notion-word-counter">0</span>'; | |
/* Word Count Element */ | |
/* Word Count Observer */ | |
let isCounterSet = false; | |
let oldHref = ''; | |
let callback = function(mutations) { | |
if (oldHref != document.location.href) { | |
oldHref = document.location.href; | |
const pageObserver = new MutationObserver(() => { | |
const firstContent = document.querySelector('div.notion-page-content'); | |
// Whether if the word count element was set | |
if (firstContent) { | |
if (!isCounterSet) { | |
isCounterSet = true; | |
const helpBtn = document.querySelector('div.notion-help-button'); | |
helpBtn.after(countEl); | |
} | |
countEl.children[0].innerText = wordCount(firstContent.innerText); | |
} | |
}); | |
waitFor('div.notion-page-content').then(([el]) => { | |
let pageContent = document.querySelector('div.notion-page-content'); | |
pageObserver.observe(pageContent, { childList: true, subtree: true, characterData: true }); | |
}); | |
} | |
}; | |
const observer = new MutationObserver(callback); | |
// Start observe | |
waitFor('div.notion-page-content').then(([el]) => { | |
// let pageContent = document.querySelector('div.notion-page-content'); | |
let notionApp = document.getElementById('notion-app'); | |
const config = { childList: true, subtree: true }; | |
observer.observe(notionApp, config); | |
}); | |
/* Word Count Observer */ | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Todo