mirror of
https://github.com/notion-enhancer/notion-enhancer.git
synced 2025-04-06 21:49:03 +00:00
extension: word counter (moved to panel)
This commit is contained in:
parent
d5c45a8771
commit
1f9537b755
@ -23,5 +23,6 @@
|
||||
"collapse-properties",
|
||||
"scroll-to-top",
|
||||
"indentation-lines",
|
||||
"focus-mode"
|
||||
"focus-mode",
|
||||
"word-counter"
|
||||
]
|
||||
|
@ -4,6 +4,97 @@
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
/** layout **/
|
||||
|
||||
.notion-frame
|
||||
> .notion-scroller.vertical.horizontal
|
||||
> .pseudoSelection
|
||||
> div
|
||||
> div:nth-child(3)[style*='width: 900px'],
|
||||
.notion-frame
|
||||
> .notion-scroller.vertical.horizontal
|
||||
> .pseudoSelection
|
||||
+ div
|
||||
> :nth-child(1)[style*='width: 900px'],
|
||||
.notion-frame
|
||||
> .notion-scroller.vertical.horizontal
|
||||
> :nth-child(2)
|
||||
> :nth-child(2)[style*='display: flex; width: 100%; justify-content: center;']
|
||||
> :nth-child(1)[style*='width: 900px'] {
|
||||
width: var(--theme--page-width) !important;
|
||||
}
|
||||
.notion-frame
|
||||
> .notion-scroller.vertical.horizontal
|
||||
> .pseudoSelection
|
||||
> div
|
||||
> div:nth-child(3):not([style*='width: 900px']),
|
||||
.notion-frame
|
||||
> .notion-scroller.vertical.horizontal
|
||||
> .pseudoSelection
|
||||
+ div
|
||||
> :nth-child(1):not([style*='width: 900px']),
|
||||
.notion-frame
|
||||
> .notion-scroller.vertical.horizontal
|
||||
> :nth-child(2)
|
||||
> :nth-child(2)[style*='display: flex; width: 100%; justify-content: center;']
|
||||
> :nth-child(1):not([style*='width: 900px']) {
|
||||
width: var(--theme--page-width_full) !important;
|
||||
}
|
||||
.notion-page-content [style*='width: 100%; max-width:'][style*='align-self: center;'] {
|
||||
max-width: 100% !important;
|
||||
}
|
||||
.notion-frame [style*='padding-right: calc(96px + env(safe-area-inset-right));'] {
|
||||
padding-right: var(--theme--page-padding) !important;
|
||||
}
|
||||
.notion-frame [style*='padding-left: calc(96px + env(safe-area-inset-left));'] {
|
||||
padding-left: var(--theme--page-padding) !important;
|
||||
}
|
||||
[style^='position: relative; width: 100%; display: flex; flex-direction: column; align-items: center; height: 30vh;'],
|
||||
[style^='position: relative; width: 100%; display: flex; flex-direction: column; align-items: center; height: 30vh;']
|
||||
img {
|
||||
height: var(--theme--page_banner-height) !important;
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
.notion-peek-renderer > :nth-child(2) {
|
||||
max-width: var(--theme--page_preview-width) !important;
|
||||
}
|
||||
.notion-peek-renderer
|
||||
.notion-scroller.vertical
|
||||
[style*='padding-left: calc(126px + env(safe-area-inset-left));'] {
|
||||
padding-left: var(--theme--page_preview-padding) !important;
|
||||
}
|
||||
.notion-peek-renderer
|
||||
.notion-scroller.vertical
|
||||
[style*='padding-right: calc(126px + env(safe-area-inset-right));'] {
|
||||
padding-right: var(--theme--page_preview-padding) !important;
|
||||
}
|
||||
.notion-peek-renderer
|
||||
.notion-scroller.vertical
|
||||
[style*='margin-left: calc(126px + env(safe-area-inset-left));'] {
|
||||
margin-left: var(--theme--page_preview-padding) !important;
|
||||
}
|
||||
.notion-peek-renderer
|
||||
.notion-scroller.vertical
|
||||
[style*='margin-right: calc(126px + env(safe-area-inset-right));'] {
|
||||
margin-right: var(--theme--page_preview-padding) !important;
|
||||
}
|
||||
.notion-peek-renderer .notion-page-content {
|
||||
padding-left: var(--theme--page_preview-padding) !important;
|
||||
padding-right: var(--theme--page_preview-padding) !important;
|
||||
width: 100%;
|
||||
}
|
||||
.notion-peek-renderer
|
||||
.notion-scroller.vertical
|
||||
[style*='position: relative; width: 100%; display: flex; flex-direction: column; align-items: center; height: 20vh;'],
|
||||
.notion-peek-renderer
|
||||
.notion-scroller.vertical
|
||||
[style*='position: relative; width: 100%; display: flex; flex-direction: column; align-items: center; height: 20vh;']
|
||||
img {
|
||||
height: var(--theme--page_preview_banner-height) !important;
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
/* typography */
|
||||
|
||||
[style*='Segoe UI'] {
|
||||
@ -25,6 +116,19 @@
|
||||
border-radius: 0px !important;
|
||||
}
|
||||
|
||||
/** scrollbars **/
|
||||
|
||||
::-webkit-scrollbar-track,
|
||||
::-webkit-scrollbar-corner {
|
||||
background: var(--theme--scrollbar_track) !important;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--theme--scrollbar_thumb) !important;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--theme--scrollbar_thumb-hover) !important;
|
||||
}
|
||||
|
||||
/** consistent corner button styling **/
|
||||
|
||||
.notion-overlay-container
|
||||
@ -54,3 +158,59 @@
|
||||
box-shadow: var(--theme--ui_shadow, rgba(15, 15, 15, 0.15)) 0px 0px 0px 1px,
|
||||
var(--theme--ui_shadow, rgba(15, 15, 15, 0.15)) 0px 2px 4px !important;
|
||||
}
|
||||
|
||||
/* backgrounds */
|
||||
|
||||
.notion-discussion-input > div > div[style*='background'],
|
||||
.notion-body.dark
|
||||
.notion-default-overlay-container
|
||||
[style*='grid-template-columns: [boolean-start] 60px [boolean-end property-start] 120px [property-end opererator-start] 110px [operator-end value-start] auto [value-end menu-start] 32px [menu-end];']
|
||||
[style*='grid-column: property-start / value-end; background: rgba(255, 255, 255, 0.02);'],
|
||||
.notion-body:not(.dark)
|
||||
.notion-default-overlay-container
|
||||
[style*='grid-template-columns: [boolean-start] 60px [boolean-end property-start] 120px [property-end opererator-start] 110px [operator-end value-start] auto [value-end menu-start] 32px [menu-end];']
|
||||
[style*='grid-column: property-start / value-end; background: rgba(0, 0, 0, 0.02);'],
|
||||
.notion-board-view [style*='width: 20px; margin-left: -20px; margin-top: -8px;'],
|
||||
.notion-page-block > div > div > div[style*='background-color: white;'],
|
||||
.line-numbers.notion-code-block + div .notion-focusable:not(:hover),
|
||||
.notion-overlay-container
|
||||
[style*='position: relative; max-width: calc(100vw - 24px); box-shadow:']
|
||||
> [style*='display: flex; align-items: center; padding: 8px 10px; width: 100%; background:'],
|
||||
.notion-default-overlay-container
|
||||
> div:nth-child(3)
|
||||
> div
|
||||
> div:nth-child(2)
|
||||
> div:nth-child(2)
|
||||
> div
|
||||
> div
|
||||
> div
|
||||
> div
|
||||
> div
|
||||
> div:nth-child(2)[style*='position: absolute; display: inline-flex; min-width: 100%; height: 32px; z-index: 1; background:'],
|
||||
.notion-default-overlay-container
|
||||
> div:nth-child(2)
|
||||
> div
|
||||
> div:nth-child(2)
|
||||
> div:nth-child(2)
|
||||
> div
|
||||
> div
|
||||
> div
|
||||
> div
|
||||
> div
|
||||
> div:nth-child(2)[style*='position: absolute; display: inline-flex; min-width: 100%; height: 32px; z-index: 1; background:'],
|
||||
.notion-frame .notion-scroller[style*='background:'],
|
||||
.notion-page-template-modal .notion-scroller[style*='background:'],
|
||||
.notion-peek-renderer .notion-scroller[style*='background:'],
|
||||
.notion-frame > div > div > div[style*='max-width: 100%'][style*='background-color'],
|
||||
.notion-peek-renderer
|
||||
> div
|
||||
> .notion-scroller
|
||||
> div
|
||||
> div[style*='max-width: 100%'][style*='background-color'],
|
||||
.notion-page-template-modal
|
||||
> div
|
||||
> .notion-scroller
|
||||
> div
|
||||
> div[style*='max-width: 100%'][style*='background-color'] {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
@ -4,97 +4,6 @@
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
/** layout **/
|
||||
|
||||
.notion-frame
|
||||
> .notion-scroller.vertical.horizontal
|
||||
> .pseudoSelection
|
||||
> div
|
||||
> div:nth-child(3)[style*='width: 900px'],
|
||||
.notion-frame
|
||||
> .notion-scroller.vertical.horizontal
|
||||
> .pseudoSelection
|
||||
+ div
|
||||
> :nth-child(1)[style*='width: 900px'],
|
||||
.notion-frame
|
||||
> .notion-scroller.vertical.horizontal
|
||||
> :nth-child(2)
|
||||
> :nth-child(2)[style*='display: flex; width: 100%; justify-content: center;']
|
||||
> :nth-child(1)[style*='width: 900px'] {
|
||||
width: var(--theme--page-width) !important;
|
||||
}
|
||||
.notion-frame
|
||||
> .notion-scroller.vertical.horizontal
|
||||
> .pseudoSelection
|
||||
> div
|
||||
> div:nth-child(3):not([style*='width: 900px']),
|
||||
.notion-frame
|
||||
> .notion-scroller.vertical.horizontal
|
||||
> .pseudoSelection
|
||||
+ div
|
||||
> :nth-child(1):not([style*='width: 900px']),
|
||||
.notion-frame
|
||||
> .notion-scroller.vertical.horizontal
|
||||
> :nth-child(2)
|
||||
> :nth-child(2)[style*='display: flex; width: 100%; justify-content: center;']
|
||||
> :nth-child(1):not([style*='width: 900px']) {
|
||||
width: var(--theme--page-width_full) !important;
|
||||
}
|
||||
.notion-page-content [style*='width: 100%; max-width:'][style*='align-self: center;'] {
|
||||
max-width: 100% !important;
|
||||
}
|
||||
.notion-frame [style*='padding-right: calc(96px + env(safe-area-inset-right));'] {
|
||||
padding-right: var(--theme--page-padding) !important;
|
||||
}
|
||||
.notion-frame [style*='padding-left: calc(96px + env(safe-area-inset-left));'] {
|
||||
padding-left: var(--theme--page-padding) !important;
|
||||
}
|
||||
[style^='position: relative; width: 100%; display: flex; flex-direction: column; align-items: center; height: 30vh;'],
|
||||
[style^='position: relative; width: 100%; display: flex; flex-direction: column; align-items: center; height: 30vh;']
|
||||
img {
|
||||
height: var(--theme--page_banner-height) !important;
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
.notion-peek-renderer > :nth-child(2) {
|
||||
max-width: var(--theme--page_preview-width) !important;
|
||||
}
|
||||
.notion-peek-renderer
|
||||
.notion-scroller.vertical
|
||||
[style*='padding-left: calc(126px + env(safe-area-inset-left));'] {
|
||||
padding-left: var(--theme--page_preview-padding) !important;
|
||||
}
|
||||
.notion-peek-renderer
|
||||
.notion-scroller.vertical
|
||||
[style*='padding-right: calc(126px + env(safe-area-inset-right));'] {
|
||||
padding-right: var(--theme--page_preview-padding) !important;
|
||||
}
|
||||
.notion-peek-renderer
|
||||
.notion-scroller.vertical
|
||||
[style*='margin-left: calc(126px + env(safe-area-inset-left));'] {
|
||||
margin-left: var(--theme--page_preview-padding) !important;
|
||||
}
|
||||
.notion-peek-renderer
|
||||
.notion-scroller.vertical
|
||||
[style*='margin-right: calc(126px + env(safe-area-inset-right));'] {
|
||||
margin-right: var(--theme--page_preview-padding) !important;
|
||||
}
|
||||
.notion-peek-renderer .notion-page-content {
|
||||
padding-left: var(--theme--page_preview-padding) !important;
|
||||
padding-right: var(--theme--page_preview-padding) !important;
|
||||
width: 100%;
|
||||
}
|
||||
.notion-peek-renderer
|
||||
.notion-scroller.vertical
|
||||
[style*='position: relative; width: 100%; display: flex; flex-direction: column; align-items: center; height: 20vh;'],
|
||||
.notion-peek-renderer
|
||||
.notion-scroller.vertical
|
||||
[style*='position: relative; width: 100%; display: flex; flex-direction: column; align-items: center; height: 20vh;']
|
||||
img {
|
||||
height: var(--theme--page_preview_banner-height) !important;
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
/* backgrounds */
|
||||
|
||||
.OnboardingHighlight + div > [style*='background-color'] {
|
||||
@ -256,60 +165,6 @@ body,
|
||||
background: var(--theme--bg_card) !important;
|
||||
}
|
||||
|
||||
.notion-discussion-input > div > div[style*='background'],
|
||||
.notion-body.dark
|
||||
.notion-default-overlay-container
|
||||
[style*='grid-template-columns: [boolean-start] 60px [boolean-end property-start] 120px [property-end opererator-start] 110px [operator-end value-start] auto [value-end menu-start] 32px [menu-end];']
|
||||
[style*='grid-column: property-start / value-end; background: rgba(255, 255, 255, 0.02);'],
|
||||
.notion-body:not(.dark)
|
||||
.notion-default-overlay-container
|
||||
[style*='grid-template-columns: [boolean-start] 60px [boolean-end property-start] 120px [property-end opererator-start] 110px [operator-end value-start] auto [value-end menu-start] 32px [menu-end];']
|
||||
[style*='grid-column: property-start / value-end; background: rgba(0, 0, 0, 0.02);'],
|
||||
.notion-board-view [style*='width: 20px; margin-left: -20px; margin-top: -8px;'],
|
||||
.notion-page-block > div > div > div[style*='background-color: white;'],
|
||||
.line-numbers.notion-code-block + div .notion-focusable:not(:hover),
|
||||
.notion-overlay-container
|
||||
[style*='position: relative; max-width: calc(100vw - 24px); box-shadow:']
|
||||
> [style*='display: flex; align-items: center; padding: 8px 10px; width: 100%; background:'],
|
||||
.notion-default-overlay-container
|
||||
> div:nth-child(3)
|
||||
> div
|
||||
> div:nth-child(2)
|
||||
> div:nth-child(2)
|
||||
> div
|
||||
> div
|
||||
> div
|
||||
> div
|
||||
> div
|
||||
> div:nth-child(2)[style*='position: absolute; display: inline-flex; min-width: 100%; height: 32px; z-index: 1; background:'],
|
||||
.notion-default-overlay-container
|
||||
> div:nth-child(2)
|
||||
> div
|
||||
> div:nth-child(2)
|
||||
> div:nth-child(2)
|
||||
> div
|
||||
> div
|
||||
> div
|
||||
> div
|
||||
> div
|
||||
> div:nth-child(2)[style*='position: absolute; display: inline-flex; min-width: 100%; height: 32px; z-index: 1; background:'],
|
||||
.notion-frame .notion-scroller[style*='background:'],
|
||||
.notion-page-template-modal .notion-scroller[style*='background:'],
|
||||
.notion-peek-renderer .notion-scroller[style*='background:'],
|
||||
.notion-frame > div > div > div[style*='max-width: 100%'][style*='background-color'],
|
||||
.notion-peek-renderer
|
||||
> div
|
||||
> .notion-scroller
|
||||
> div
|
||||
> div[style*='max-width: 100%'][style*='background-color'],
|
||||
.notion-page-template-modal
|
||||
> div
|
||||
> .notion-scroller
|
||||
> div
|
||||
> div[style*='max-width: 100%'][style*='background-color'] {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
.notion-timeline-view
|
||||
> div
|
||||
> div
|
||||
@ -331,19 +186,6 @@ body,
|
||||
) !important;
|
||||
}
|
||||
|
||||
/** scrollbars **/
|
||||
|
||||
::-webkit-scrollbar-track,
|
||||
::-webkit-scrollbar-corner {
|
||||
background: var(--theme--scrollbar_track) !important;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--theme--scrollbar_thumb) !important;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--theme--scrollbar_thumb-hover) !important;
|
||||
}
|
||||
|
||||
/** ui **/
|
||||
|
||||
.notion-page-mention-token.notion-enable-hover:hover {
|
||||
|
59
repo/word-counter/app.css
Normal file
59
repo/word-counter/app.css
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* word counter
|
||||
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* under the MIT license
|
||||
*/
|
||||
|
||||
#word-counter-details {
|
||||
width: 100%;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
#word-counter-details > div {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: -0.5em;
|
||||
}
|
||||
#word-counter-details > div > p {
|
||||
margin: 0.5em;
|
||||
cursor: pointer;
|
||||
font-size: var(--theme--font_label-size);
|
||||
color: var(--theme--text);
|
||||
border-radius: 3px;
|
||||
padding: 0.25rem 0.5rem;
|
||||
background: var(--theme--interactive_hover);
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
#word-counter-details > div > p:hover {
|
||||
background: transparent;
|
||||
border: 1px solid var(--theme--interactive_hover);
|
||||
}
|
||||
|
||||
#word-counter-details > div > span {
|
||||
max-width: 10em;
|
||||
padding: 0.4rem 0.5rem 0.25rem 0.5rem;
|
||||
font-size: calc(var(--theme--font_label-size) * 0.8);
|
||||
color: var(--theme--text_ui_info);
|
||||
}
|
||||
|
||||
#word-counter-details > div > p > svg {
|
||||
height: 1em;
|
||||
width: 1em;
|
||||
margin: 0 0 -2px 0.3em;
|
||||
color: var(--theme--text_ui_info);
|
||||
}
|
||||
|
||||
#word-counter-details-tooltip {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
padding: 0.25em 0.5em;
|
||||
border-radius: 3px;
|
||||
box-shadow: var(--theme--box-shadow_strong);
|
||||
border-right-width: 1px;
|
||||
font-size: calc(var(--theme--font_label-size) * 0.8);
|
||||
background: var(--theme--interactive_hover);
|
||||
opacity: 0;
|
||||
transition: opacity 120ms ease-in;
|
||||
}
|
||||
#word-counter-details-tooltip.active {
|
||||
opacity: 1;
|
||||
}
|
39
repo/word-counter/client.css
Normal file
39
repo/word-counter/client.css
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* notion-enhancer: word counter
|
||||
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
#word-counter--notice {
|
||||
color: var(--theme--text_secondary);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.word-counter--stat {
|
||||
display: block;
|
||||
background: var(--theme--ui_interactive-hover);
|
||||
color: var(--theme--text);
|
||||
font-size: 14px;
|
||||
line-height: 1.2;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 3px;
|
||||
padding: 6px 8px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
.word-counter--stat:focus,
|
||||
.word-counter--stat:hover {
|
||||
background: transparent;
|
||||
border: 1px solid var(--theme--ui_interactive-hover);
|
||||
}
|
||||
.word-counter--stat:active {
|
||||
background: var(--theme--ui_interactive-active);
|
||||
}
|
||||
|
||||
.word-counter--stat svg {
|
||||
display: inline-block;
|
||||
height: 1em;
|
||||
width: 1em;
|
||||
margin: 0 0.4em -2px 0;
|
||||
color: var(--theme--icon_secondary);
|
||||
}
|
111
repo/word-counter/client.mjs
Normal file
111
repo/word-counter/client.mjs
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* notion-enhancer: word counter
|
||||
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
const copyToClipboard = async (str) => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(str);
|
||||
} catch {
|
||||
const el = document.createElement('textarea');
|
||||
el.value = str;
|
||||
el.setAttribute('readonly', '');
|
||||
el.style.position = 'absolute';
|
||||
el.style.left = '-9999px';
|
||||
document.body.appendChild(el);
|
||||
el.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(el);
|
||||
}
|
||||
},
|
||||
humanTime = (mins) => {
|
||||
let readable = '';
|
||||
if (1 <= mins) {
|
||||
readable += `${Math.floor(mins)} min`;
|
||||
if (2 <= mins) readable += 's';
|
||||
}
|
||||
const secs = Math.round((mins % 1) * 60);
|
||||
if (1 <= secs) {
|
||||
if (1 <= mins) readable += ' ';
|
||||
readable += `${secs} sec`;
|
||||
if (2 <= secs) readable += 's';
|
||||
}
|
||||
return readable;
|
||||
};
|
||||
|
||||
export default async function ({ web, components }, db) {
|
||||
const dbNoticeText = 'Open a normal page to see word count.',
|
||||
pageNoticeText = 'Click a stat to copy it.',
|
||||
$notice = web.html`<span id="word-counter--notice">${dbNoticeText}</span>`;
|
||||
|
||||
const $wordCount = web.html`<b>12</b>`,
|
||||
$characterCount = web.html`<b>12</b>`,
|
||||
$sentenceCount = web.html`<b>12</b>`,
|
||||
$blockCount = web.html`<b>12</b>`,
|
||||
$readingTime = web.html`<b>10 mins</b>`,
|
||||
$readingTooltip = web.html`${await components.feather('info')}`,
|
||||
$speakingTime = web.html`<b>18 secs</b>`,
|
||||
$speakingTooltip = web.html`${await components.feather('info')}`,
|
||||
$statContainer = web.render(
|
||||
web.html`<div></div>`,
|
||||
web.render(web.html`<p class="word-counter--stat"></p>`, $wordCount, ' words'),
|
||||
web.render(web.html`<p class="word-counter--stat"></p>`, $characterCount, ' characters'),
|
||||
web.render(web.html`<p class="word-counter--stat"></p>`, $sentenceCount, ' sentences'),
|
||||
web.render(web.html`<p class="word-counter--stat"></p>`, $blockCount, ' blocks'),
|
||||
web.render(
|
||||
web.html`<p class="word-counter--stat"></p>`,
|
||||
$readingTooltip,
|
||||
$readingTime,
|
||||
' reading time'
|
||||
),
|
||||
web.render(
|
||||
web.html`<p class="word-counter--stat"></p>`,
|
||||
$speakingTooltip,
|
||||
$speakingTime,
|
||||
' speaking time'
|
||||
)
|
||||
);
|
||||
$statContainer.querySelectorAll('.word-counter--stat').forEach(($stat) => {
|
||||
$stat.addEventListener('click', () => copyToClipboard($stat.innerText));
|
||||
});
|
||||
components.setTooltip($readingTooltip, '**~ 275 wpm**');
|
||||
components.setTooltip($speakingTooltip, '**~ 180 wpm**');
|
||||
await components.addPanelView({
|
||||
icon: await components.feather('type'),
|
||||
title: 'Word Counter',
|
||||
$content: web.render(web.html`<div></div>`, $notice, $statContainer),
|
||||
});
|
||||
|
||||
let $page;
|
||||
const updateStats = () => {
|
||||
if (!$page) return;
|
||||
const words = $page.innerText.split(/[^\w]+/).length;
|
||||
$wordCount.innerText = words;
|
||||
$characterCount.innerText = $page.innerText.length;
|
||||
$sentenceCount.innerText = $page.innerText.split('.').length;
|
||||
$blockCount.innerText = $page.querySelectorAll('[data-block-id]').length;
|
||||
$readingTime.innerText = humanTime(words / 275);
|
||||
$speakingTime.innerText = humanTime(words / 180);
|
||||
},
|
||||
pageObserver = () => {
|
||||
if (document.contains($page)) {
|
||||
updateStats();
|
||||
} else {
|
||||
$page = document.getElementsByClassName('notion-page-content')[0];
|
||||
if ($page) {
|
||||
$notice.innerText = pageNoticeText;
|
||||
$statContainer.style.display = '';
|
||||
updateStats();
|
||||
} else {
|
||||
$notice.innerText = dbNoticeText;
|
||||
$statContainer.style.display = 'none';
|
||||
}
|
||||
}
|
||||
};
|
||||
web.addDocumentObserver(pageObserver, [
|
||||
'.notion-page-content',
|
||||
'.notion-collection_view_page-block',
|
||||
]);
|
||||
pageObserver();
|
||||
}
|
166
repo/word-counter/mod.js
Normal file
166
repo/word-counter/mod.js
Normal file
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* word counter
|
||||
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (c) 2020 admiraldus (https://github.com/admiraldus)
|
||||
* under the MIT license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const { createElement } = require('../../pkg/helpers.js');
|
||||
|
||||
module.exports = {
|
||||
id: 'b99deb52-6955-43d2-a53b-a31540cd19a5',
|
||||
tags: ['extension'],
|
||||
name: 'word counter',
|
||||
desc:
|
||||
'add page details: word/character/sentence/block count & speaking/reading times.',
|
||||
version: '0.2.0',
|
||||
author: 'dragonwocky',
|
||||
options: [
|
||||
{
|
||||
key: 'hide_page_details_text',
|
||||
label: 'hide "page details" text',
|
||||
type: 'toggle',
|
||||
value: false,
|
||||
},
|
||||
],
|
||||
hacks: {
|
||||
'renderer/preload.js'(store, __exports) {
|
||||
const copyToClipboard = (str) => {
|
||||
const el = document.createElement('textarea');
|
||||
el.value = str;
|
||||
el.setAttribute('readonly', '');
|
||||
el.style.position = 'absolute';
|
||||
el.style.left = '-9999px';
|
||||
document.body.appendChild(el);
|
||||
el.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(el);
|
||||
},
|
||||
humanTime = (mins) => {
|
||||
let readable = '';
|
||||
if (1 <= mins) {
|
||||
readable += `${Math.floor(mins)} min`;
|
||||
if (2 <= mins) readable += 's';
|
||||
}
|
||||
const secs = Math.round((mins % 1) * 60);
|
||||
if (1 <= secs) {
|
||||
if (1 <= mins) readable += ' ';
|
||||
readable += `${secs} sec`;
|
||||
if (2 <= secs) readable += 's';
|
||||
}
|
||||
return readable;
|
||||
};
|
||||
|
||||
document.addEventListener('readystatechange', (event) => {
|
||||
if (document.readyState !== 'complete') return false;
|
||||
let queue = [],
|
||||
$page = document.getElementsByClassName('notion-page-content')[0];
|
||||
const DOCUMENT_OBSERVER = new MutationObserver((list, observer) => {
|
||||
if (!queue.length) requestIdleCallback(() => handle(queue));
|
||||
queue.push(...list);
|
||||
}),
|
||||
PAGE_OBSERVER = new MutationObserver(showPageWordDetails);
|
||||
DOCUMENT_OBSERVER.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
});
|
||||
function handle(list) {
|
||||
queue = [];
|
||||
for (let { addedNodes } of list) {
|
||||
if (
|
||||
addedNodes[0] &&
|
||||
addedNodes[0].className === 'notion-page-content'
|
||||
) {
|
||||
$page = addedNodes[0];
|
||||
showPageWordDetails();
|
||||
|
||||
PAGE_OBSERVER.disconnect();
|
||||
PAGE_OBSERVER.observe($page, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
characterData: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
const $container = createElement(
|
||||
`<div id="word-counter-details"><div></div></div>`
|
||||
),
|
||||
$tooltip = createElement(
|
||||
`<span id="word-counter-details-tooltip"></span>`
|
||||
);
|
||||
function showPageWordDetails() {
|
||||
const details = {
|
||||
words: $page.innerText.replace(/\s+/g, ' ').split(' ').length,
|
||||
characters: $page.innerText.length,
|
||||
sentences: $page.innerText.split('.').length,
|
||||
blocks: $page.querySelectorAll('[data-block-id]').length,
|
||||
};
|
||||
details['reading time'] = [
|
||||
humanTime(details.words / 275),
|
||||
'~275 wpm',
|
||||
];
|
||||
details['speaking time'] = [
|
||||
humanTime(details.words / 180),
|
||||
'~180 wpm',
|
||||
];
|
||||
|
||||
$container.children[0].innerHTML = `
|
||||
${store().hide_page_details_text ? '' : '<span><b>page details<br></b> (click to copy)</span>'}
|
||||
${Object.keys(details).reduce(
|
||||
(prev, key) =>
|
||||
prev +
|
||||
(Array.isArray(details[key])
|
||||
? `<p>
|
||||
<b>${details[key][0]}</b> ${key}
|
||||
<!-- from https://fontawesome.com/icons/question-circle?style=regular -->
|
||||
<svg data-tooltip="${details[key][1]}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003
|
||||
248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200
|
||||
0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200
|
||||
200zm107.244-255.2c0 67.052-72.421 68.084-72.421 92.863V300c0 6.627-5.373 12-12 12h-45.647c-6.627
|
||||
0-12-5.373-12-12v-8.659c0-35.745 27.1-50.034 47.579-61.516 17.561-9.845 28.324-16.541 28.324-29.579
|
||||
0-17.246-21.999-28.693-39.784-28.693-23.189 0-33.894 10.977-48.942 29.969-4.057 5.12-11.46 6.071-16.666
|
||||
2.124l-27.824-21.098c-5.107-3.872-6.251-11.066-2.644-16.363C184.846 131.491 214.94 112
|
||||
261.794 112c49.071 0 101.45 38.304 101.45 88.8zM298 368c0 23.159-18.841
|
||||
42-42 42s-42-18.841-42-42 18.841-42 42-42 42 18.841 42 42z"
|
||||
></path>
|
||||
</svg>
|
||||
</p>`
|
||||
: `<p><b>${details[key]}</b> ${key}</p>`),
|
||||
''
|
||||
)}`;
|
||||
$page.previousElementSibling.children[0].appendChild($container);
|
||||
if (!$container.offsetParent) return;
|
||||
$container.offsetParent.appendChild($tooltip);
|
||||
$container
|
||||
.querySelectorAll('p')
|
||||
.forEach((p) =>
|
||||
p.addEventListener('click', (e) =>
|
||||
copyToClipboard(e.target.innerText)
|
||||
)
|
||||
);
|
||||
$container.querySelectorAll('[data-tooltip]').forEach((el) => {
|
||||
el.addEventListener('mouseenter', (e) => {
|
||||
$tooltip.innerText = el.getAttribute('data-tooltip');
|
||||
$tooltip.style.top = el.parentElement.offsetTop + 2.5 + 'px';
|
||||
$tooltip.style.left =
|
||||
el.parentElement.offsetLeft +
|
||||
el.parentElement.offsetWidth -
|
||||
5 +
|
||||
'px';
|
||||
$tooltip.classList.add('active');
|
||||
});
|
||||
el.addEventListener('mouseleave', (e) =>
|
||||
$tooltip.classList.remove('active')
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
22
repo/word-counter/mod.json
Normal file
22
repo/word-counter/mod.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "word counter",
|
||||
"id": "b99deb52-6955-43d2-a53b-a31540cd19a5",
|
||||
"version": "0.3.0",
|
||||
"description": "view word/character/sentence/block count & speaking/reading times in the side panel.",
|
||||
"tags": ["extension", "panel"],
|
||||
"authors": [
|
||||
{
|
||||
"name": "dragonwocky",
|
||||
"email": "thedragonring.bod@gmail.com",
|
||||
"homepage": "https://dragonwocky.me/",
|
||||
"avatar": "https://dragonwocky.me/avatar.jpg"
|
||||
}
|
||||
],
|
||||
"js": {
|
||||
"client": ["client.mjs"]
|
||||
},
|
||||
"css": {
|
||||
"client": ["client.css"]
|
||||
},
|
||||
"options": []
|
||||
}
|
Loading…
Reference in New Issue
Block a user