웹 페이지 HTML 구조 한눈에 보는 확장

kakasoo·2021년 9월 7일
1
post-thumbnail

이걸 하게 된 이유

이 글은 웹페이지 HTML 구조 한눈에 보는 꼼수 - oneook 을 보고 작성하게 되었습니다.

['div', 'span', 'ul', 'li', 'dd', 'dl', 'section', 'h1', 'a', 'img', 'form', 'button', 'header', 'footer', 'input', 'p'].forEach(e => {
    document.querySelectorAll(e).forEach(element => {
        element.style.outline = "1px solid dodgerblue"
    })
})

velog를 보다가 꼼수를 배웠다. 이 코드를 사용해서 모든 layout을 한 눈에 볼 수 있도록 해준다고 한다. 흥미롭지만 매번 해당 게시글을 방문해서 복사하고 다니기엔 귀찮으니 어딘가에 저장해둬야겠다는 생각이 들었다.
그런데 저장보다, 크롬 확장으로 있으면 더 낫지 않나?

그럼 직접 개발을 해볼까

그래서 직접 만들기로 했다. 구글 확장 앱 만드는 걸 평소에도 좀 해보고 싶었는데, 큰 사이즈가 아닐 것 같았다. 이미지는 금방 생각했다. 태그 이름, 색깔, 그리고 선의 굵기를 선택할 수 있도록 하고, 그게 반영되게 해보자.
크롬 확장을 어떻게 추가할 수 있는지는 다루지 않는다.

<!DOCTYPE html>
<html>
    <head>
        <script src="scripts.js"></script>
        <style type="text/css">
            .tagBox {
                display: flex;
                max-width: 100%;
            }

            .tagName {
                text-align: center;
                font-size: 16px;
                min-width: 20%;
                margin-right: 10px;
                letter-spacing: -0.5px;
                font-weight: 300;
            }

            .color {
                border: none;
                width: 8%;
                background-color: transparent;
            }

            .thickness {
                width: auto;
            }
        </style>
    </head>
    <body style="width: 300px"></body>
</html>

일단 css는 몇 가지 되지 않으므로 대충 때려 박았다. 그리고 body만을 만들고, 적당히 width는 300px 정도로 지정했다. HTML element가 될 수 있는 tag는 가짓수가 좀 되므로 동적으로 만드는 게 나을 것 같았다.

동적으로 페이지 구성

미리 tag들에 대한 정보를 객체 형태로 만들고, 그걸 배열에 담는다. forEach문을 돌면서 tag와 color 등을 가져다 쓴다. color는 적당히, 있어보이는 색깔들을 넣었다. 필자가 디자인 감각이 없다.

// variable
const tags = [
    { tag: "div", color: "#F54E3B" },
    { tag: "span", color: "#D6458A" },
    { tag: "ul", color: "#D04DEB" },
    { tag: "li", color: "#753BD4" },
    { tag: "dd", color: "#3744FA" },
    { tag: "dl", color: "#E36EF5" },
    { tag: "section", color: "#9C72D6" },
    { tag: "h1", color: "#7E82EB" },
    { tag: "a", color: "#689AD4" },
    { tag: "img", color: "#6BECFA" },
    { tag: "form", color: "#58C8F5" },
    { tag: "button", color: "#5ED6C3" },
    { tag: "header", color: "#6AEB9A" },
    { tag: "footer", color: "#65D455" },
    { tag: "input", color: "#C9FA55" },
    { tag: "p", color: "#FAE25B" },
];

// Create chrome extension body.
window.onload = () => {
    tags.forEach(({ tag, color }) => {
        console.log(color);
        const tagBox = document.createElement("div");
        tagBox.className = "tagBox";
        tagBox.innerHTML = `
			<div class="tagName">${tag}</div>
			<input id="${tag}Check" class ="tagCheck" type="checkbox" name="tags" />
			<input id="${tag}Color" class="color" type="color" value="${color}" />
			<input
				id="${tag}Thickness"
				class="thickness"
				type="range"
				min="1"
				max="10"
				step="0.1"
				value="1"
			/>`;
        document.body.appendChild(tagBox);
    });
};

팝업창 이미지는 아래처럼

대충 이런 이미지가 되었다. 미리 말한대로 태그의 이름이 보이고, checkbox에서는 보고 싶은 것만 체크할 수 있게 해뒀다. 색깔을 고를 수 있고, 선의 굵기를 정할 수 있게 했다. 선의 굵기는 1부터 10 사이로, 0.1 단위로 선의 굵기를 조정할 수 있게 했다.

여기까지는 모양을 낸거고, 이제 체크한 것들이 페이지에 표시되기만 하면 됐다.

실제 동작을 담당하는 work()

// work process
const work = () => {
    tags.forEach(({ tag }) => {
        const tagChecked = document.getElementById(`${tag}Check`).checked;
        const tagColor = document.getElementById(`${tag}Color`).value;
        const tagThickness = document.getElementById(`${tag}Thickness`).value;

        console.log(tagChecked, tagColor, tagThickness);
        if (tagChecked) {
            // 컨텐츠 페이지를 대상으로 코드 작성

            chrome.tabs.executeScript({
                code: `document.querySelectorAll("${tag}").forEach((el) => {
			el.style.outline = "${tagThickness}px solid ${tagColor}";
			});`,
            });
        } else {
            chrome.tabs.executeScript({
                code: `document.querySelectorAll("${tag}").forEach((el) => {
			el.style.outline = "none";
			});`,
            });
        }
    });
};

작동 방법 역시 forEach문을 사용했다. 팝업창에서 사용자가 입력한 체크 여부, 색깔, 선의 굵기 등을 읽어내고 그것에 맞게 실제 페이지를 바꾼다.

chrome.tabs.executeScript({ code : "console.log(123)" });

확장을 써보지 않은 사람은 이 코드가 의아할 텐데, 익스텐션에서는 기본적으로 document.body는 확장의 body, 즉 확장 앱을 클릭했을 때 나오는 팝업창의 body를 의미한다. 실제 사용자가 보고 있는 페이지에 관여할려면 activeTab이라는 걸 사용해야 하는데, 이 부분은 chrome.tabs 객체에서 다룰 수 있다.

code에 들어간 string이 실제 코드로 해석되는 게, javascript로 치면 eval이라고 생각하면 편할 듯 하다.

사용한 모습

코드가 별 거 없어서 바로 실 사용을 볼 수 있었다. 사용하면 이런 모습이 된다. 우측 상단에 익스텐션을 클릭하면 팝업창이 나오고 거기서 조절할 수 있다. 아쉬운 부분은 팝업창을 껐다가 다시 켜면 이전의 설정이 유지가 되지 않는다는 점.

아쉽게도, 오늘 처음으로 크롬 앱을 만들어봤는데, 심사하는 데 시간이 걸리는 모양이다. 길게는 몇 주도 걸릴 수 있다는데, 그럴 만한 분량의 코드가 아니니 금방 될 거라 믿는다. 오늘 만들고 올린 다음 velog에 글을 써야 겠다고 생각했는데, 당장 chrome app 링크를 올릴 수 없어 아쉽게 생각한다.

대단한 걸 만든 건 아니지만, 크롬 확장이 어떻게 만들어지는지 배워서 좋은 경험이었다. 여담이지만 크롬 앱을 만들 때, 개발자 등록(?)을 하는 데에 5달러의 비용을 지불해야했다.

양아치 아니냐? 내가 너네 꺼 확장 만들어준건데 내가 돈을 낸다고?

09.07

벌써부터 버그가 났는데, React 처럼 Front framework를 쓰면, 페이지가 전환될 때 모든 element가 사라지고 root부터 다시 그려진다. 그래서 모든 outline이 사라지지만, root만 outline이 남게 된다.
심사에 통과한 다음에 고쳐야겠다.

대충 실 사용자가 있으면 고친다는 뜻이다.

github 레포지토리 링크 : https://github.com/kakasoo/showMeTheLayout

09.10

크롬 웹 스토어에 배포된 모습

profile
자바스크립트를 좋아하는 "백엔드" 개발자

0개의 댓글