마크잇 하이라이터
이는 모든 웹페이지에서 중요한 텍스트를 강조표시할 수 있는 크롬 확장 링크입니다. 1분, 1주, 1년 후에 페이지를 다시 방문하세요. 데이터는 항상 그대로 유지됩니다.
기술
- (바닐라) 자바스크립트
- 구글 API
특징
- 텍스트를 강조 표시하고 Command+K를 눌러 자동으로 저장합니다.
- 사용자는 Command+Shift+A라는 간단한 명령 하나로 모든 URL에 대해 저장된 하이라이트를 지울 수 있습니다.
- 모든 기기에서 동기화 - 노트북에서 텍스트를 강조표시한 다음 휴대전화에서 동일한 웹페이지를 보면 강조표시가 표시됩니다(두 기기 모두에서 Chrome에 로그인한 경우).
내 저장된 데이터 구조(객체)
highlights = {
google.com: {
text1: ["query selector", index, note, color]
text2: ["query selector", index, note, color]
},
yahoo.com: {
text3: ["query selector", index, note, color],
text4: ["query selector", index, note, color]
},
https://developer.mozilla.org/en-US/docs/Web/API/document/execCommand: {
"When an HTML document has been switched to designMode, its document object exposes an execCommand": ["p.summary", 20],
"A DOMString specifying the name of the command to execute. See Commands for a list of possible commands.": ["p", 0, "example note", #CFFFDF]
}
}
작동 방식
모든 페이지에 로드되는 두 개의 스크립트가 있습니다. 첫 번째는 특정 이벤트를 수신하는 background.js입니다. Command+K 이벤트는 선택한 텍스트를 강조 표시하는 스크립트를 브라우저(injection_script.js)에 삽입하는 함수를 트리거합니다.
강조 표시하려면 일부 텍스트 위로 마우스를 끌고 Command+K를 누르세요. 이는 다른 여러 함수를 호출하는 함수를 트리거합니다. 이벤트 순서:
- 선택한 텍스트를 잡아요
- 디자인 모드를 "켜짐"으로 전환하여 DOM을 일시적으로 변경할 수 있습니다.
- 배경이 이미 강조표시된 경우 강조표시를 제거해야 합니다.
- 텍스트를 둘러싸는 <span> 태그를 선택하고 style.BackgroundColor=투명하게 설정합니다(강조 표시 제거).
- 저장소에서 '하이라이트' 객체를 가져옵니다 -
chrome.storage.get()
- 모든 키(저장된 하이라이트)를 반복하여 일치 항목을 찾고 저장소에서 삭제합니다.
- 그렇지 않으면 텍스트를 <span>으로 감싸고 배경색을 적용합니다.
- 페이지 새로 고침 시: 저장소에서 '하이라이트' 검색
- 활성 URL에 대한 데이터가 없으면 키를 현재 URL로 설정하고 값을 빈 객체(aol.com: {})로 설정합니다.
- 있는 경우 저장소(chrome.storage.get())에서 하이라이트 데이터 구조를 가져옵니다.
- 선택한 텍스트에 대해 유효한 쿼리 선택기 값을 검색하고 할당합니다. 이는 나중에 DOM을 쿼리하고 강조 표시를 적용하는 데 사용됩니다. 자세한 내용은 위의 개체 구조를 참조하세요.
- 강조 표시된 텍스트의 상위 요소에 클래스 이름이 있는 경우 문자열 "element.className"("p.firstParagraph", "h2.sectionHeader" 등)을 저장합니다.
- 클래스 이름이 없으면 문자열 "element"("p", "h2", "li" 등)를 저장합니다.
- 키(강조 표시된 텍스트)에 값(2개의 값을 포함하는 배열 - 첫 번째는 쿼리 선택기, 두 번째는 상위 요소에서 선택한 텍스트가 발생한 위치의 인덱스)을 제공합니다.
- 문자열의 인덱스를 저장하는 이유는 텍스트와 쿼리 선택기만 저장했다면 "p" 태그 아래에 "the"를 강조 표시했다고 가정하고, 페이지를 새로 고치면 강조 표시를 적용할 때 "the"가 나타날 때마다 "p" 태그가 강조 표시됩니다. indexOf 값을 추가하면 인덱스가 DOM과 일치하는지 확인한 다음 강조 표시를 적용할 수 있으므로 올바른 단어에 강조 표시를 적용합니다.
- chrome.storage.set()을 사용하여 새로 강조 표시된 텍스트를 포함하는 업데이트된 하이라이트 변수를 저장합니다.
- 디자인 모드를 "끄기"로 설정
각 페이지에서 실행되는 두 번째 JavaScript 파일은 content_script.js입니다. '하이라이트'라는 저장된 개체가 있는지 확인합니다. 그렇지 않은 경우 사용자가 아무 것도 강조 표시한 적이 없다는 의미입니다. 그런 다음 빈 개체를 생성하여 Chrome에 저장합니다.
'하이라이트' 개체를 찾으면 활성 URL에 대해 저장된 데이터가 있는지 확인합니다. 없으면 스크립트가 반환됩니다.
URL에 대해 하이라이트가 저장된 경우:
- applyHighlights() 함수가 실행됩니다.
- '하이라이트' 객체와 활성 URL이라는 두 개의 매개변수를 사용합니다.
- 저장된 객체의 키를 반복합니다(키는 저장된 하이라이트이고 해당 키의 값은 querySelector 및 indexOf 값을 포함하는 배열입니다).
- document.body.querySelectorAll()을 실행하여 일치하는 모든 노드의 배열을 가져옵니다.
- 반환된 각 노드를 반복하고 innerHTML에 객체 키(강조 표시된 텍스트)와 일치하고 동일한 indexOf 값에 일치하는 "문자열"이 포함되어 있는 경우: 1. <span> 태그에서 일치하는 텍스트를 다음과 같이 래핑하는 .replace() 함수를 실행합니다. 배경색에 대한 인라인 스타일 속성
- 참고: 원래 일치 항목을 확인하기 위해 모든 DOM 노드를 재귀적으로 살펴봤지만 querySelector 값을 저장하고 일치하는 노드의 HTML 값만 저장된 값과 비교하는 것이 훨씬 더 빠릅니다.
다음 버전을 위한 업그레이드
- 강조표시한 특정 문자열을 저장합니다.
- "jQuery.com에서 jQuery 라이브러리를 다운로드하세요."
- 두 번째 "jQuery"를 강조 표시하면 저장된 값은 첫 번째 인스턴스가 됩니다.
- 이는 내가 저장한 indexOf 값이 첫 번째 일치 후에 반환되기 때문입니다.
- PLAN - 스팬 태그 이후의 인덱스 계산 시작
- 블록 요소 전체를 강조 표시할 수 없습니다(h2의 강조 표시를 ap 태그로 드래그하면 h2만 등록됩니다).
- 진행 중: 사용자가 강조 색상을 선택할 수 있도록 허용
- 확장 popup.html에 페이지의 하이라이트 수 및 실제 하이라이트 표시
- 제한사항/극단적인 사례: 이메일, PDF
- 모든 사이트에 대한 권한을 요청합니다. 일부 사이트에서는 '*' 액세스를 차단합니다(cnn.com)
- 한 요소에서 "jQuery"를 강조 표시하고 다른 요소에서 다시 강조 표시하면 두 번째 요소가 첫 번째 요소를 재정의합니다(키가 동일하기 때문에).
- 상위 요소가 인라인 태그인 경우 innertext/html indexOf가 등록되지 않거나(-1) 인라인 태그 끝에서 강조 표시가 종료됩니다. 범위 태그의 인덱스를 찾아 거기에서 indexOf를 시작합니다.
- 축소 모드 - 저장된 하이라이트의 상위 요소로만 문서를 축소합니다.
해결된 문제
- 인라인 요소 태그(a, em, st 등)에 걸친 하이라이트 저장
- 이전에는 innerText를 저장했기 때문에 인라인 태그 앞의 텍스트만 저장되었습니다.
- 대신 innerHTML을 저장하여 문제를 해결했습니다.
- 이 변경으로 인해 발생한 문제는 "p" 태그와 같은 텍스트 요소 내부의 표준 텍스트에 강조 표시를 다시 적용하는 innerText의 indexOf를 저장하고 있다는 것입니다. 그러나 indexOf는 태그의 각 문자를 계산하기 때문에 인라인 요소 주위의 항목에 대해 다릅니다.
- 이 문제를 해결하기 위해 사용자가 다시 방문하는 페이지에 하이라이트를 적용할 때 innerText.indexOf와 innerHTML.indexOf 값을 비교하고 각 노드를 일치하는 노드와 비교합니다.
- 섹션을 강조 표시하기 위해 두 번 클릭하면 indexOf 값이 등록되지 않으므로 앱에서 강조 표시를 다시 적용할 수 없습니다.
- 이 문제를 해결하기 위해 indexOf(...)에 .toString() 및 .trim() 메서드를 추가했습니다.
- < a > 태그를 강조 표시하면 페이지 로드 시 링크가 제거됩니다.
향후 업그레이드
## 예시 이미지
엣지 케이스
- 수업명이 변경된 경우
- 해결 방법: 클래스 이름이 DOM에 없으면 쿼리 선택기에서 클래스 이름을 제거하고 요소 태그 노드만 검색하세요.
- 콘텐츠가 버튼으로 숨겨져 있으면 내 하이라이트는 on_load를 검색하기 때문에 등록되지 않으며 콘텐츠는 브라우저 이벤트 후에만 표시됩니다(이것이 이메일에서 작동하지 않는 이유입니다).
누군가가 popup.html의 모든 강조표시에 액세스할 수 있도록 허용합니다. 사용자가 형광펜 색상을 변경할 수 있도록 허용합니다. 인라인 요소 강조표시 버그 수정