Browsing Assist 크롬 익스텐션 - 5

홍범선·2024년 12월 25일
0

Browsing-Assist

목록 보기
5/8

✔️ 페이지 접속 시 하이라이트 복원


📄 시도한 아이디어

💡 1. 브라우저에서 하이라이트의 상대적인 높이와 위치를 구한다.

⚠️ 에러: 이 방법은 이미지나 정적 파일이 늦게 로드될 경우, 높이와 위치가 지속적으로 변경되는 오류가 발생


💡 2. S3를 활용하여 변경된 body 내용을 저장하고, 페이지 접속 시 이를 적용한다.

  • 형광펜 생성, 수정, 삭제 시마다 현재 body.innerHTMLAWS의 텍스트 파일로 저장합니다.

  • 해당 url에 접속 시 AWS에 텍스트 파일을 읽어 body태그를 교체합니다.

⚠️ 에러: 이 방법은 본문 내용이 수정되어도 저장된 body 태그를 교체하므로 적용되지 않습니다. 또한, 매우 비효율적입니다.



이제부터 해결한 아이디어를 설명해드리겠습니다.

📄 최종 아이디어

💡 형광펜 칠한 TextNode를 Node Tree에서 인덱스로 표현한다. ex)0,1,5,4,3

  • Node Tree를 순회하여 각 TextNode의 위치를 인덱스로 변환한다.

  • 변환된 인덱스를 기준으로 TextNode를 식별한다.

  • 해당 태그에 하이라이트 커스텀 태그를 추가한다.

이해가 잘 안 가시죠?

여기서 "DOM 이란"을 인덱스로 표현하면 어떻게 될까요?

답은 0, 0, 1, 0, 0이 됩니다.

Document → 0 번째 인덱스
Html → 0 번째 인덱스
Body → 1 번째 인덱스
h1 → 0 번째 인덱스
"Dom 이란" → 0 번째 인덱스


그러면 접속할 때 해당 인덱스를 가지고 해당 Node에 접근할 수 있습니다.

코드로 알아볼까요?

function getTrack(Node) {
  const track = [];
  while (Node.nodeName !== "HTML") {
    const siblingNodes = Array.from(Node.parentNode.childNodes);
    for (let i = 0; i < siblingNodes.length; i++) {
      if (siblingNodes[i] === Node) track.push(i);
    }

    Node = Node.parentNode;
  }

  return track;
}

function getReverseTrack(rootNode, track) {
  let currentNode = rootNode;
  for (let i = track.length - 1; i >= 0; i--) {
    currentNode = currentNode.childNodes[track[i]];
  }
  return currentNode;
}

getTrack메서드는 루트인 HTML 요소까지 타고 올라가며 인덱스를 변환하는 함수입니다.

getReverseTrack은 인덱스를 토대로 Node를 반환해주는 함수입니다.

하지만 여기서 끝난다면 오류를 마주합니다.

생성 및 삭제가 있을 때마다 인덱스가 수시로 변경되므로, 인덱스가 제대로 작동하지 않을 수 있습니다.

따라서 추가적으로 로그를 기록해야 합니다.


💡 형광펜 생성, 삭제 로그 기록하기

형광펜 생성, 삭제할 때마다 데이터를 저장하기 위해 highlight_log테이블을 추가하였습니다.

기존에는 삭제 시 is_Deleted 값을 true로 변경하는 것만으로 끝났지만, 이제는 삭제 시 is_Deleted 값을 true로 변경하는 것 외에도 highlight_log 테이블에 로그를 추가합니다.

생성 시에도 마찬가지로 highlight_log 테이블에 로그를 추가합니다.

다음과 같이 highlight_log 테이블에 로그가 쌓입니다.

이제 복원 시에는 모든 로그를 가져와 처음부터 실행하여 복원하는 작업이 필요합니다.

코드를 통해 알아봅시다.

function processSelect(params) {
  for (const param of params) {
    try {
      if (!param.is_deleted) {
        processHighlight(param, getHoverColor(param.color));
      } else {
        removeElementByDataId(param.id);
      }
      
    } catch (error) {
      console.error("Error processing item:", param, error);
      // 오류가 발생해도 다음 항목으로 계속 진행합니다.
    }
  }
}

가져온 로그 데이터를 복원하는 과정입니다.




이렇게 하면 하이라이트 생성, 수정, 삭제, 복원까지 구현할 수 있습니다.

profile
알고리즘 정리 블로그입니다.

0개의 댓글