프갤 하다가 링크 드래그해서 복사하고 붙여넣기 빡쳐서 만들어보기로 했음

글은 심심해서 씀


일단 만들려고 하는건 "사용자 스크립트"라는건데, 내가 지정한 주소에 들어가면 그 안에서 스크립트가 실행되도록 할 수 있음

자바스크립트로 짜는거고, 브라우저는 이 언어에서 HTML의 각 요소를 접근할 수 있도록 해놓는데

(body는 document.body, 최상위 태그는 document.documentElement 등)

보통 이런거 편하게 하려고 jQuery를 쓰던 하지


DOM은 트리형태로 되있어 대충


<html>

  <head>

    <title>야 제목이다</title>

  </head>

  <body>

    내용이다

    <span>여기 링크가 있다 http://naver.com/ </span>

  </body>

</html> 


이러면 html안에 head, body가 있고 head 안에 title이 있고, body와 title에는 각각 텍스트 1개씩이 있는거지

span은 body에 있고 ㅇㅇ


최상위 노드부터 쭉 트리를 돌아가면서 텍스트들에 대해 링크를 뽑아내는 정규식을 만들고,

정규식에 만족하는 텍스트들을 a태그로 감쌀거야


대충 뭐 DFS를 구현할건데, 보통 엄청 깊지는 않음


function traverse(node) {

  var childNodes = node.childNodes;

  if(childNodes) {

    var length = childNodes.length;

    for(var i = 0; i < length; i++)

      traverse(childNodes[i]);

  }

}

traverse(document.documentElement); 


여기서 텍스트인걸 뽑아야겠지?

텍스트만 있는것도 엄연히 하나의 노드에 포함되는데, 얘는 태그가 없잖아(div, body같은)?

어떻게 비교할까?
뭐 대충 nodeType 같은 이름의 멤버가 있겠지?
개발자 도구를 키고 콘솔에 대충 입력해봤어

document.body.childNodes[0]

결과: #text


안에 내용은 .textContent로 얻을수 있고 지정도 가능함

a = document.body.childNodes[0];
a.node

  a.nodeType (자동완성)


어 ㅁㅊ nodeType이 진짜 있잖아

a.nodeType

결과: 3


보통 이런 숫자가 있을때, 관련 상수들은 그 안에 있어 js에서는
그래서 a.text까지 쳐보니까 a.TEXT_NODE가 나오더라

a.TEXT_NODE

결과: 3 

ㅇㅋ 이제 node.nodeType == node.TEXT_NODE 이렇게 비교할거야

이제 링크를 얻어서 해당 링크에 a태그를 감싸야겠지?
링크 정규식은 https://stackoverflow.com/a/8234912 에 있는것에서 capturing group만 모두 non capturing group으로 바꿈

(그냥 괄호 여는걸 ?: 붙은걸로 바꿨다는 이야기)


문자열을 링크로 나눌건데, 자바스크립트에서 문자열을 나누는 함수인 ''.split은 정규식도 받음

그래서 문자열.split(/링크정규식/) 이렇게 하면 정규식으로 나뉠거고, 즉 링크는 따로 나눠질 것인데,

링크도 나눠진거에 포함되니까 어차피 ㅁㄴㅇㄹhttp://a.comㅁㄴㅇㄹ 이런식으로 링크 아닌거랑 맞는거랑 번갈아 있을테니

홀짝 중 하나 골라서 홀인거나 짝인거만 a태그로 만들면 되겠지


근데 해보니까 무조건 링크 아닌게 맨 처음껄로 왔음 (링크로 시작해도 ''가 맨 처음)

홀수번째꺼만 감싸면 되겠지


대충 이렇게 짬


// ==UserScript==

// @match http://gall.dcinside.com/*

// ==/UserScript==


var count = 0;

var regex = /((?:(?:[A-Za-z]{3,9}:(?://)?)(?:[-;:&=+$,w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=+$,w]+@)[A-Za-z0-9.-]+)(?:(?:/[+~%/.w-_]*)???(?:[-+=&;%@.w_]*)#?(?:[w]*))?)/g;

function traverse(node, parentNode) {

    if(node.tagName == 'A' && node.href) return;

    count++;

    var childNodes = node.childNodes;

    if(node.nodeType == node.TEXT_NODE) {

        var text = node.textContent;

        var parts = text.split(regex);

        var length = parts.length;

        var a;

        if(parts.length > 1) {

            for(var i = 0; i < length - 1; i++) {

                if(i%2) {

                    a = document.createElement('a');

                    a.textContent = a.href = parts[i];

                    a.target = '_blank';

                    parentNode.appendChild(a);

                } else {

                    parentNode.appendChild(document.createTextNode(parts[i]));

                }

            }

            parentNode.insertBefore(document.createTextNode(parts[length - 1]), node);

            parentNode.removeChild(node)

        }

    }

    if(childNodes) {

        childNodes = Array.apply(null, childNodes); // clone

        var length = childNodes.length;

        var nextNode = node.nextSibling;

        for(var i = 0; i < length; i++) traverse(childNodes[i], node);

    }

}


traverse(document.documentElement, document.documentElement) 


이제 이걸 사용자 스크립트라는거에 추가해야겠지?

파이어폭스면 Greasemonkey 쓰면 되는걸로 알고있고

크롬이면 설정->확장 프로그램 들어가봐





아까 그 스크립트 파일을 .user.js 확장자로 저장하고 (a.user.js같이) 이 화면에다가 끌어놓으면 됨


이제 직접 해보자



음..



잘 되는군