From 2e5dd5056596bd008e6ebe8cb12e09b7b3adabbe Mon Sep 17 00:00:00 2001 From: kjimlau Date: Mon, 6 Sep 2021 13:25:13 +0800 Subject: [PATCH] feat: renderer folder --- src/content-scripts/renderer/dom/logo-icon.ts | 55 +++ src/content-scripts/renderer/dom/rect.ts | 133 +++++++ src/content-scripts/renderer/highlight.ts | 15 - src/content-scripts/renderer/popup/index.vue | 47 +++ .../renderer/popup/note-book/index.vue | 64 ++++ .../renderer/popup/note-book/note-list.vue | 171 +++++++++ .../renderer/popup/note-book/note.vue | 355 ++++++++++++++++++ .../renderer/popup/tag-book/index.vue | 191 ++++++++++ .../renderer/popup/tag-book/tag-searcher.vue | 59 +++ .../popup/tag-book/tag-selector/index.vue | 92 +++++ .../popup/tag-book/tag-selector/tag-list.vue | 83 ++++ 11 files changed, 1250 insertions(+), 15 deletions(-) create mode 100644 src/content-scripts/renderer/dom/logo-icon.ts create mode 100644 src/content-scripts/renderer/dom/rect.ts delete mode 100644 src/content-scripts/renderer/highlight.ts create mode 100644 src/content-scripts/renderer/popup/index.vue create mode 100644 src/content-scripts/renderer/popup/note-book/index.vue create mode 100644 src/content-scripts/renderer/popup/note-book/note-list.vue create mode 100644 src/content-scripts/renderer/popup/note-book/note.vue create mode 100644 src/content-scripts/renderer/popup/tag-book/index.vue create mode 100644 src/content-scripts/renderer/popup/tag-book/tag-searcher.vue create mode 100644 src/content-scripts/renderer/popup/tag-book/tag-selector/index.vue create mode 100644 src/content-scripts/renderer/popup/tag-book/tag-selector/tag-list.vue diff --git a/src/content-scripts/renderer/dom/logo-icon.ts b/src/content-scripts/renderer/dom/logo-icon.ts new file mode 100644 index 0000000..7605066 --- /dev/null +++ b/src/content-scripts/renderer/dom/logo-icon.ts @@ -0,0 +1,55 @@ +const DOM_ICON_ID = "context-note-logo-icon"; + +let onClickEvt: EventListener; +/** + * generate a logo icon image dom on top left of selected text + * @param x mouse x + * @param y mouse y + * @param cb callback when clicked + * @returns + */ +export function genLogoIconAndRegisterClickCb( + x: number, + y: number, + cb: () => void +) { + const iconSize = 35; + + const ele = document + .querySelector("body") + ?.appendChild(document.createElement("img")) as HTMLImageElement; + if (!ele) return; + + ele.id = DOM_ICON_ID; + ele.style.position = "absolute"; + ele.style.left = `${x}px`; + ele.style.top = `${y - iconSize}px`; + ele.style.width = `${iconSize}px`; + ele.style.height = `${iconSize}px`; + ele.style.cursor = "pointer"; + ele.style.zIndex = '100'; + + // get assets of exteison by `chrome.runtime.getURL` + // https://stackoverflow.com/questions/11804332/insert-an-image-in-chrome-extension + ele.src = chrome.runtime.getURL("assets/icon16.png"); + + onClickEvt = (e) => { + e.preventDefault(); + e.stopPropagation(); + cb?.(); + clearLogoIcon(); + }; + ele.addEventListener("mouseup", onClickEvt); +} + +export function clearLogoIcon() { + // delete all logo icon doms + const eles = document.querySelectorAll(`#${DOM_ICON_ID}`); + eles.forEach((ele) => { + onClickEvt && ele.removeEventListener("mouseup", onClickEvt); + const parent = ele.parentElement; + if (parent) { + parent.removeChild(ele); + } + }); +} diff --git a/src/content-scripts/renderer/dom/rect.ts b/src/content-scripts/renderer/dom/rect.ts new file mode 100644 index 0000000..c32ea4b --- /dev/null +++ b/src/content-scripts/renderer/dom/rect.ts @@ -0,0 +1,133 @@ +import { v4 as uuid } from "uuid"; +import { Rect } from "@/types/common"; +import { + DOMATTR_RECT_GROUP, + PREFIX_RECT, + PREFIX_RECT_GROUP, +} from "@/utils/constant"; + +function setHighlightStyle(ele: HTMLElement, rect: Rect) { + const PADDING = 6; + ele.style.position = "absolute"; + ele.style.left = rect.x - PADDING / 2 + "px"; + ele.style.top = rect.y - PADDING / 2 + "px"; + ele.style.width = `${rect.width + PADDING}px`; + ele.style.height = `${rect.height + PADDING}px`; + ele.style.background = "yellow"; + ele.style.opacity = "0.3"; + ele.style.content = " "; +} + +function findRelatedIds( + id: string, + idMap: { [key: string]: string[] } +): [string, string[]] { + for (const key in idMap) { + const ids = idMap[key] || []; + if (ids.includes(id)) { + return [key, ids]; + } + } + return ["", []]; +} + +function setRectStyleWithIds(ids: string[], key: string, value: string) { + if (ids.length === 0) return; + + const rects = (document.querySelectorAll( + (ids.map((id) => `#${id}`) as unknown) as string + ) as unknown) as HTMLElement[]; + rects.forEach((rect) => { + ((rect.style as { [key: string]: any }) || {})[key] = value; + }); +} + +const groupRectIdsMap: { [key: string]: string[] } = {}; +/** + * Generate the highlight rect doms and register their click event. + */ +export function genHighlightRects( + noteId: string, + rects: Rect[] = [], + clickCb?: (groupId: string) => void +) { + const groupId = noteId || `${PREFIX_RECT_GROUP}-${uuid()}`; + groupRectIdsMap[groupId] = []; + for (const rect of rects) { + const ele = document.createElement("div"); + const id = `${PREFIX_RECT}-${uuid()}`; + ele.setAttribute("id", id); + ele.setAttribute(DOMATTR_RECT_GROUP, groupId); + // highlight the rect + setHighlightStyle(ele, rect); + document.querySelector("body")?.appendChild(ele); + groupRectIdsMap[groupId].push(ele.id); + + // click event + document.addEventListener("mouseup", (event) => { + const withinBoundaries = event.composedPath().includes(ele); + + if (withinBoundaries) { + const groupId = boldHighlightGroupRects(ele?.id, ""); + clickCb?.(groupId); + } else { + unboldHighlightGroupRects(ele?.id); + } + }); + } + return groupId; +} + +/** + * Delete all rects with `noteId`, if `noteId` is not provided, delete all rects. + */ +export function delHighlightRects(noteId?: string | undefined) { + const query = !noteId ? `[${DOMATTR_RECT_GROUP}]` : `[${DOMATTR_RECT_GROUP}=${noteId}]` + const rectDoms = document.querySelectorAll(query); + rectDoms.forEach(dom => { + dom.parentElement?.removeChild(dom); + }) +} + +/** + * Bold the group highlight rects. + * @param id one id of the group rects + * @param groupId the group id + * @param scrollIntoView if need scrollIntoView when bolding + * @returns groupId + */ +export function boldHighlightGroupRects( + id?: string, + groupId?: string, + scrollIntoView?: boolean +): string { + // set all related rects border to dotted + let relatedIds: string[]; + if (groupId) { + relatedIds = groupRectIdsMap[groupId] || []; + } else { + [groupId, relatedIds] = findRelatedIds(id || "", groupRectIdsMap); + } + setTimeout(() => { + setRectStyleWithIds(relatedIds, "border", "2px dotted #000"); + }); + if (groupId) { + if (scrollIntoView) { + // scroll to first rect + const firstRectId = relatedIds?.[0]; + const firstRect = document.querySelector(`#${firstRectId}`); + firstRect && firstRect.scrollIntoView({ block: "center" }); + } + } + return groupId; +} + +/** + * Unbold the group highlight rects. + * @param id one id of the group rects. + */ +export function unboldHighlightGroupRects(id: string) { + // set all related rects border to none + const [_, relatedIds] = findRelatedIds(id, groupRectIdsMap); + setRectStyleWithIds(relatedIds, "border", "none"); +} diff --git a/src/content-scripts/renderer/highlight.ts b/src/content-scripts/renderer/highlight.ts deleted file mode 100644 index 7e9378c..0000000 --- a/src/content-scripts/renderer/highlight.ts +++ /dev/null @@ -1,15 +0,0 @@ -/// 借助rect的坐标高亮rects(由于是坐标因此rects可以存储起来后续反显) -export function highlightRects(rects: DOMRect[] = []) { - for (const rect of rects) { - const ele = document.createElement('div') - ele.style.position = 'absolute' - ele.style.left = rect.x + 'px' - ele.style.top = rect.y + 'px' - ele.style.width = `${rect.width}px` - ele.style.height = `${rect.height}px` - ele.style.background = 'yellow' - ele.style.opacity = '0.2' - ele.style.content = ' ' - document.querySelector('body')?.appendChild(ele) - } -} \ No newline at end of file diff --git a/src/content-scripts/renderer/popup/index.vue b/src/content-scripts/renderer/popup/index.vue new file mode 100644 index 0000000..fc0043b --- /dev/null +++ b/src/content-scripts/renderer/popup/index.vue @@ -0,0 +1,47 @@ + + + + + diff --git a/src/content-scripts/renderer/popup/note-book/index.vue b/src/content-scripts/renderer/popup/note-book/index.vue new file mode 100644 index 0000000..e36d42d --- /dev/null +++ b/src/content-scripts/renderer/popup/note-book/index.vue @@ -0,0 +1,64 @@ + + + + + diff --git a/src/content-scripts/renderer/popup/note-book/note-list.vue b/src/content-scripts/renderer/popup/note-book/note-list.vue new file mode 100644 index 0000000..5987e9b --- /dev/null +++ b/src/content-scripts/renderer/popup/note-book/note-list.vue @@ -0,0 +1,171 @@ + + + + + diff --git a/src/content-scripts/renderer/popup/note-book/note.vue b/src/content-scripts/renderer/popup/note-book/note.vue new file mode 100644 index 0000000..23971c6 --- /dev/null +++ b/src/content-scripts/renderer/popup/note-book/note.vue @@ -0,0 +1,355 @@ + + + + + diff --git a/src/content-scripts/renderer/popup/tag-book/index.vue b/src/content-scripts/renderer/popup/tag-book/index.vue new file mode 100644 index 0000000..00ba0a3 --- /dev/null +++ b/src/content-scripts/renderer/popup/tag-book/index.vue @@ -0,0 +1,191 @@ + + + + + diff --git a/src/content-scripts/renderer/popup/tag-book/tag-searcher.vue b/src/content-scripts/renderer/popup/tag-book/tag-searcher.vue new file mode 100644 index 0000000..b7841d5 --- /dev/null +++ b/src/content-scripts/renderer/popup/tag-book/tag-searcher.vue @@ -0,0 +1,59 @@ + + + + + diff --git a/src/content-scripts/renderer/popup/tag-book/tag-selector/index.vue b/src/content-scripts/renderer/popup/tag-book/tag-selector/index.vue new file mode 100644 index 0000000..0c18338 --- /dev/null +++ b/src/content-scripts/renderer/popup/tag-book/tag-selector/index.vue @@ -0,0 +1,92 @@ + + + + + diff --git a/src/content-scripts/renderer/popup/tag-book/tag-selector/tag-list.vue b/src/content-scripts/renderer/popup/tag-book/tag-selector/tag-list.vue new file mode 100644 index 0000000..c74ebcf --- /dev/null +++ b/src/content-scripts/renderer/popup/tag-book/tag-selector/tag-list.vue @@ -0,0 +1,83 @@ + + + + +