Skip to content

Instantly share code, notes, and snippets.

@ruter
Last active December 29, 2022 16:14
Show Gist options
  • Save ruter/f8a040a9efbe9b60b288ad90bd0f7d67 to your computer and use it in GitHub Desktop.
Save ruter/f8a040a9efbe9b60b288ad90bd0f7d67 to your computer and use it in GitHub Desktop.
A script for Notion word count.
// ==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 */
})();
@ruter
Copy link
Author

ruter commented Jun 29, 2020

Todo

  • Make the counter automatic refresh when open new page
  • Add subpage counter

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment