사용자:Stevage/EnhanceHistory.user.js

User:Stevage/EnhanceHistory.user.js
참고: 저장 후 변경 내용을 보려면 브라우저의 캐시를 바이패스해야 한다. Google Chrome, Firefox, Microsoft EdgeSafari: 키를 누른 채로 [다시 로드] 도구 모음 단추를 누르십시오. 다른 브라우저에 대한 자세한 내용과 지침은 위키백과를 참조하십시오.캐시를 바이패스하십시오.
// ==UserScript===  // @name 향상된 기록 표시  // @p10 스테비지  // @description 동일인으로부터의 연속적인 편집을 하나로 축소하고, 역사 페이지에 차이를 나타냄  // @p10 *.wikipedia.org/*action=history  // ==/UserScript== // 이 페이지는 http://en.wikipedia.org/wiki/User:Stevage/EnhanceHistory.user.js에서 찾을 수 있다.  // http://en.wikipedia.org/w/index.php?action=raw&ctype=text/javascript&dontcountme=s&title=User:Stevage/EnhanceHistory.user.js에서 설치  ( 기능을 하다() {   만일(활자의 GM_log === '정의되지 않음') 돌아오다;   GM_log('빈 함수');   기능을 하다 압축하다() {     GM_log('압축함수 중');      만일 (!문서화하다.GetElementBy아이디('바디콘텐츠')) {         돌아오다;     }          .add_message();        }    압축하다.원형을 뜨다.add_message = 기능을 하다() {     GM_log('in add_message');      // 압축 버턴 생성     시합을 하다 버튼1 = 문서화하다.createElement('input');     버튼1.setAttribute('id', 'compress_button1');     버튼1.className = '역사 제출';     버튼1.문체를 하다.왼쪽 여백 = '5px';     버튼1.setAttribute('타입', '버튼');     버튼1.가치를 매기다 = '역사를 압축하라';     버튼1.클릭을 하다 = 기능을 하다() { 압축하다.출발하다(); }      // ShowDiffs buttion 생성     시합을 하다 버튼1 = 문서화하다.createElement('input');     버튼1.setAttribute('id', '쇼디프1');     버튼1.className = '역사 제출';     버튼1.문체를 하다.왼쪽 여백 = '5px';     버튼1.setAttribute('타입', '버튼');     버튼1.가치를 매기다 = '차이프 표시';     버튼1.클릭을 하다 = 기능을 하다() { 압축하다.쇼디프스(); }      // 페이지에 버튼 추가     시합을 하다 역사 = 문서화하다.GetElementBy아이디('페이지히스토리');     역사.parentNode.삽입 전(버튼1, 역사);   }  /////////////////////////////////////////////////////////    기능을 하다 getPlainText(s) {     GM_log(">getPlainText");          만일 (s==무효의)       돌아오다 "";     시합을 하다  = s.길이;     만일 ( > 20) {       돌아오다 "[작다]" + s.기판을 달다(0,10)+'...'+ s.기판을 달다(-10,10)+ "[/작은]";     } 다른  {       돌아오다 "[작다]" + s + "[/작은]";     }     GM_log("<getPlainText");   }         기능을 하다 diffString(텍스트1, 텍스트2) {   시합을 하다 d = 산산이 흩어지다(텍스트1, 텍스트2);   시합을 하다 html = '';   을 위해 (시합을 하다 x=0; x<d.길이; x++) {     시합을 하다 m = d[x][0]; // 모드(-1=delete, 0=copy, 1=add)     시합을 하다 i = d[x][1]; // 변경 지수.     시합을 하다 t = d[x][2]; // 변경 텍스트.     t = t.대체하다(/&/g, "&amp;").대체하다(/</g, "&lt;").대체하다(/>/g, "&gt;");     만일 (m == -1)       html += "<델 스타일='백그라운드:#FFE6E6;' TITLE='i="+i+"'>"+t+"[/DEL]";     다른 만일 (m == 1)       html += "<인스 스타일='백그라운드:#E6FFE6;' TITLE='i="+i+"'>"+t+"[/INS]";     다른       html += "<스판 제목='i="+i+"'>" +getPlainText(t) + "[/SPAN]";   }   돌아오다 html; }  // 두 텍스트의 차이점을 찾아라.  변경사항의 배열을 반환하십시오. 기능을 하다 산산이 흩어지다(텍스트1, 텍스트2) {   // 동일성 확인(속도 상승)   만일 (텍스트1 == 텍스트2)     돌아오다 [[0, 0, 텍스트1]];    시합을 하다 a;   // 공통 접두사 잘라내기(속도 향상)   a = diff_diff(텍스트1, 텍스트2);   텍스트1 = a[0];   텍스트2 = a[1];   시합을 하다 공동의 사전 수정 = a[2];      // 공통 접미사 잘라내기(속도 상승)   a = diff_diff(텍스트1, 텍스트2);   텍스트1 = a[0];   텍스트2 = a[1];   시합을 하다 통속적인 = a[2];    만일 (!텍스트1) {  // 텍스트만 추가(스피드업)     a = [[1, 공동의 사전 수정.길이, 텍스트2]];   } 다른 만일 (!텍스트2) { // 일부 텍스트만 삭제(속도 향상)     a = [[-1, 공동의 사전 수정.길이, 텍스트1]];   } 다른 {      // 문제를 둘로 나눌 수 있는지 확인하십시오.     시합을 하다 장문의 = 텍스트1.길이 > 텍스트2.길이 ? 텍스트1 : 텍스트2;     시합을 하다 짧은 텍스트 = 텍스트1.길이 > 텍스트2.길이 ? 텍스트2 : 텍스트1;     시합을 하다 흐음 = diff_ 하프매치(장문의, 짧은 텍스트, 수학.천장을 치다(장문의.길이/4));     만일 (!흐음)       흐음 = diff_ 하프매치(장문의, 짧은 텍스트, 수학.천장을 치다(장문의.길이/2));     만일 (흐음) {       만일 (텍스트1.길이 > 텍스트2.길이) {         시합을 하다 text1_a = 흐음[0];         시합을 하다 text1_b = 흐음[1];         시합을 하다 text2_a = 흐음[2];         시합을 하다 text2_b = 흐음[3];       } 다른 {         시합을 하다 text2_a = 흐음[0];         시합을 하다 text2_b = 흐음[1];         시합을 하다 text1_a = 흐음[2];         시합을 하다 text1_b = 흐음[3];       }       시합을 하다 mid_common = 흐음[4];       시합을 하다 결과_a = 산산이 흩어지다(text1_a, text2_a);       시합을 하다 결과_b = 산산이 흩어지다(text1_b, text2_b);       만일 (공동의 사전 수정) // 공통 프리픽스로 인해 인디케이터를 앞으로 이동하십시오.         을 위해 (시합을 하다 x=0; x<결과_a.길이; x++)           결과_a[x][1] += 공동의 사전 수정.길이;       결과_a.밀다([0, 공동의 사전 수정.길이+text2_a.길이, mid_common]);       하는 동안에 (결과_b.길이) {         결과_b[0][1] += 공동의 사전 수정.길이+text2_a.길이+mid_common.길이;         결과_a.밀다(결과_b.교대시키다());       }       a = 결과_a;     } 다른 {       시합을 하다 결과 = diff_map(텍스트1, 텍스트2);       만일 (결과)         a = diffchar2sarray(결과, 공동의 사전 수정.길이);       다른 // 허용 가능한 결과가 없음.         a = [[-1, 공동의 사전 수정.길이, 텍스트1], [1, 공동의 사전 수정.길이, 텍스트2]];     }   }    만일 (공동의 사전 수정)     a.교대하지 않는([0, 0, 공동의 사전 수정]);   만일 (통속적인)     a.밀다([0, 공동의 사전 수정.길이 + 텍스트2.길이, 통속적인]);     돌아오다 a; }  기능을 하다 diff_map(텍스트1, 텍스트2) {   // 두 텍스트 사이의 교차점을 탐색하십시오.   시합을 하다 지금 당장 = 새로운 날짜();   시합을 하다 ms_end = 지금 당장.gettime() + 1000; // 1초 이상 뛰지 마라.   시합을 하다 맥스. = 텍스트1.길이 + 텍스트2.길이;   시합을 하다 v_map = 새로운 배열();   시합을 하다 v = 새로운 배열();   v[1] = 0;   시합을 하다 x, y;   을 위해 (시합을 하다 d=0; d<=맥스.; d++) {     지금 당장 = 새로운 날짜();     만일 (지금 당장.gettime() > ms_end) // JavaScript 시간 초과 도달       돌아오다 무효의;     v_map[d] = 새로운 오브젝트;     을 위해 (시합을 하다 k=-d; k<=d; k+=2) {       만일 (k == -d    k != d && v[k-1] < v[k+1])         x = v[k+1];       다른         x = v[k-1]+1;       y = x - k;       하는 동안에 (x < 텍스트1.길이 && y < 텍스트2.길이 && 텍스트1.챠랏(x) == 텍스트2.챠랏(y)) {         x++; y++;       }       v[k] = x;       v_map[d][k] = x;       만일 (x >= 텍스트1.길이 && y >= 텍스트2.길이) {         시합을 하다 발을 동동 구르다 = diff_path(v_map, 텍스트1, 텍스트2);         돌아오다 발을 동동 구르다;       }     }   }   빈틈이 없는("결과는 없다.  있을 수 없는 일이다. (reason_map)");   돌아오다 무효의; }  기능을 하다 diff_path(v_map, 텍스트1, 텍스트2) {   // 끝에서 시작까지 작업하여 경로를 결정한다.   시합을 하다 경로 = '';   시합을 하다 x = 텍스트1.길이;   시합을 하다 y = 텍스트2.길이;   을 위해 (시합을 하다 d=v_map.길이-2; d>=0; d--) {     하는 동안에(1) {       만일 (diff_match(v_map[d], x-1, y)) {         x--;         경로 = "-"+텍스트1.하위 문자열(x, x+1) + 경로;         부숴뜨리다;       } 다른 만일 (diff_match(v_map[d], x, y-1)) {         y--;         경로 = "+"+텍스트2.하위 문자열(y, y+1) + 경로;         부숴뜨리다;       } 다른 {         x--;         y--;         //if (text1)하위 문자열(x, x+1) != text2.하위 문자열(y, y+1)         // 경보 반환("대각선 없음")  있을 수 없는 일이다. (reason_path)";         경로 = "="+텍스트1.하위 문자열(x, x+1) + 경로;       }     }   }   돌아오다 경로; }  기능을 하다 diff_match(v, x, y) {   // 벡터 목록에 x/y 좌표가 있는가?   을 위해 (시합을 하다 k  v)     만일 (v[k] == x && x-k == y)       돌아오다 진실의;   돌아오다 거짓의; }  기능을 하다 diff_diff(텍스트1, 텍스트2) {   // 공통 접두사 잘라내기   시합을 하다 포인터민 = 0;   시합을 하다 양두막스 = 수학.(텍스트1.길이, 텍스트2.길이);   시합을 하다 양귀비속의 = 양두막스;   하는 동안에(포인터민 < 양귀비속의) {     만일 (텍스트1.하위 문자열(0, 양귀비속의) == 텍스트2.하위 문자열(0, 양귀비속의))       포인터민 = 양귀비속의;     다른       양두막스 = 양귀비속의;     양귀비속의 = 수학.마루를 깔다((양두막스 - 포인터민) / 2 + 포인터민);   }   시합을 하다 공동의 사전 수정 = 텍스트1.하위 문자열(0, 양귀비속의);   텍스트1 = 텍스트1.하위 문자열(양귀비속의);   텍스트2 = 텍스트2.하위 문자열(양귀비속의);   돌아오다 [텍스트1, 텍스트2, 공동의 사전 수정]; }  기능을 하다 diff_diff(텍스트1, 텍스트2) {   // 공통 접미사 잘라내기   시합을 하다 포인터민 = 0;   시합을 하다 양두막스 = 수학.(텍스트1.길이, 텍스트2.길이);   시합을 하다 양귀비속의 = 양두막스;   하는 동안에(포인터민 < 양귀비속의) {     만일 (텍스트1.하위 문자열(텍스트1.길이-양귀비속의) == 텍스트2.하위 문자열(텍스트2.길이-양귀비속의))       포인터민 = 양귀비속의;     다른       양두막스 = 양귀비속의;     양귀비속의 = 수학.마루를 깔다((양두막스 - 포인터민) / 2 + 포인터민);   }   시합을 하다 통속적인 = 텍스트1.하위 문자열(텍스트1.길이-양귀비속의);   텍스트1 = 텍스트1.하위 문자열(0, 텍스트1.길이-양귀비속의);   텍스트2 = 텍스트2.하위 문자열(0, 텍스트2.길이-양귀비속의);   돌아오다 [텍스트1, 텍스트2, 통속적인]; }  기능을 하다 diff_ 하프매치(장문의, 짧은 텍스트, i) {   // 두 텍스트가 긴 텍스트의 절반 이상 길이의 하위 문자열을 공유하는가?   // 1/4 길이의 하위 문자열로 시작하십시오.   만일 (장문의.길이 < 10    짧은 텍스트.길이 < 1)     돌아오다 무효의; // 무의미하다.   시합을 하다 씨를 뿌리다 = 장문의.하위 문자열(i, i+수학.마루를 깔다(장문의.길이/4));   시합을 하다 j=0;   시합을 하다 j_index;   시합을 하다 best_common = '';   하는 동안에 ((j_index = 짧은 텍스트.하위 문자열(j).인덱스오프(씨를 뿌리다)) != -1) {     j += j_index;     시합을 하다 my_properties = diff_diff(장문의.하위 문자열(i), 짧은 텍스트.하위 문자열(j));     시합을 하다 my_properties = diff_diff(장문의.하위 문자열(0, i), 짧은 텍스트.하위 문자열(0, j));     만일 (best_common.길이 < (my_properties[2] + my_properties[2]).길이) {       best_common = my_properties[2] + my_properties[2];       best_longtext_a = my_properties[0];       best_longtext_b = my_properties[0];       best_shorttext_a = my_properties[1];       best_shorttext_b = my_properties[1];     }     j++;   }   만일 (best_common.길이 >= 장문의.길이/2)     돌아오다 [best_longtext_a, best_longtext_b, best_shorttext_a, best_shorttext_b, best_common];   다른     돌아오다 무효의; }  기능을 하다 diffchar2sarray(문자 메시지를 보내다, 상쇄하다) {   // '-h+c=a=t'를 [-1, 0, 'h', [1, 0, 'c', [0, 1, 'at]로 변환한다]   // 이전 형식: - char 제거, = keep char, + char 추가   // 새 형식: [m, i, t] 배열   // 여기서 m: -1 제거 문자, 0 유지 문자, 1 추가 문자   // 여기서 i: 첫 번째 텍스트의 변경 색인   // 여기서 t: 추가/키프트/제거할 텍스트   시합을 하다 i = 0;   만일 (상쇄하다) i += 상쇄하다;   시합을 하다 a = 새로운 배열();   시합을 하다 m;   시합을 하다 last_m = 무효의;   을 위해 (시합을 하다 x=0; x<문자 메시지를 보내다.길이; x+=2) {     m = "-=+".인덱스오프(문자 메시지를 보내다.하위 문자열(x, x+1)) - 1;     만일 (m == -2) 돌아오다 빈틈이 없는("오류: '"+문자 메시지를 보내다.하위 문자열(x, x+1)+'+=-'가 아니다.');     만일 (last_m === m) {       a[a.길이-1][2] += 문자 메시지를 보내다.하위 문자열(x+1, x+2);     } 다른 {       a[a.길이] = 새로운 배열(m, i, 문자 메시지를 보내다.하위 문자열(x+1, x+2));     }     last_m = m;     만일 (m != -1) i++;   }   돌아오다 a; }  /*   // John Resig(http://ejohn.org) 덕분에 JavaScript diff 코드   // http://ejohn.org/files/jsdiff.js   함수 diffString( o, n ) {     GM_log(")" diffstring " + o.length + "/" + n.length);    var out = diff(/\s+/), n.div(/\s+/);     GM_log("1diffstring");    var str = ";     GM_log("2diffstring");    var 일반 텍스트 = ";     GM_log("3diffstring");    (var i = 0; i < out.n.length - 1; i++ )에 대해 {     if.n[i]이면텍스트 == null ) {      if (out.n[i]indexOf(''') == -1 &&gt;n[i]indexOf('<') = -1 &&gt;n[i]indexOf('=') = -1 ) {         str += getPlainText(plainText) + " " + "<b style='background:#E6FFE6;'클래스='diff'>" + 아웃n[i] +"</b";        일반 텍스트 = ";      }그 밖에       일반 텍스트 += " + 아웃.n[i];     } 다른 {      var pre = "";      if (out.n[i]text.indexOf(''') == -1 &&out.n[i]text.indexOf('=') = -1 = -1 &&n.n[i]text.indexOf('=') = -1 ) {              var n = out.n[i.row] + 1;       한편 (n < out.o.length &&gt;o[n.text==null]) {        if (''n.o[''indexOf' == -1 &&gt;o[n]indexOf('') = -1 &&gt;o(':') = -1 &&out.o('=') = -1 &&out.o[]indexOf('=') = -1.         사전 += "<s style='s style='s pre:#FFE6E6;' class='diff'>" + out.o[n] +" </s>";        n++;       }      }      일반 텍스트 = 일반 텍스트 + " " " + 아웃.n[i]텍스트      if (pre!=") {       str += getPlainText(plainText) + " " + pre;       일반 텍스트 = ";      }     } // if    } // for     GM_log("<diffstring");         반환 str +" " +getPlainText(일반 텍스트);  }       함수 diff( o, n ) {   var ns = 새 배열();   var os = 새 어레이();      (var i = 0; i < n.length; i++ )에 대해 {    if (ns[n[i] ] == null )인 경우     ns[n[i] ] = { 행: 새 어레이(), o: null };    ns[n[i].rows.lows(i );   }      (var i = 0; i < o.length; i++ )에 대해 {    if ( os[o[i] ] == null )인 경우     os[ o[i] ] = { 행: 새 어레이(), n: null };    os[o[i].rows.lows(i );   }      (var i in ns )에 대해 {    if (ns[i.rows.length == 1 &&gt;type(os[i]) != "정의되지 않은" && os[i.rows.length == 1 ) {     n[ns[ns]행[0] ] = { text: n[ns[i]행[0], 행: os[i]행[0] };     o[os[i]행[0] ] = { text: o[ os[i]행[0], 행: ns[i]행[0] };    }   }      (var i = 0; i < n.length - 1; i++ )에 대해 {    if[n]이면텍스트!)null&&n[i+1].텍스트,&o[n는 경우에는 나는].row+1].text== null&&null및 ==.        n[i+1]== o[n는 경우에는 나는].row+1 뻗는다){     N[i+1]){텍스트:n[i+1], 저어라:n[나는].row+1};.     o[n는 경우에는 나는].row+1 뻗는다){텍스트:o[n는 경우에는 나는].row+1 해결을 열:나는}1+.    }   }      (초본으로 나는 갈n.length-1;나는입니다.;0,...){ 들어.    만약(n[나는].텍스트!)null&&n[i-1].텍스트,&o[n는 경우에는 나는]null및 ==.로우-1].text== null&&.        n[i-1]== o[n는 경우에는 나는].행-1 뻗는다){     N[i-1]){텍스트:n[i-1], 저어라:n[나는].행-1};     O[n는 경우에는 나는].row-1]){텍스트:o[n는 경우에는 나는].row-1 해결을 열:나는-1};.    }   }      귀환{o:시, n:n};.  }  */   기능을 하다 stripHTML(oldString) {     시합을 하다 newString = "";     시합을 하다 inTag = 거짓의;     을 위해(시합을 하다 i = 0; i < oldString.길이; i++) {       만일(oldString.챠랏(i) == '<.')          inTag = 진실의;       만일(oldString.챠랏(i) == '>.') {         inTag = 거짓의;         i++;       }       만일(!inTag)          newString += oldString.챠랏(i);     }     돌아오다 newString;    }     압축하다.원형을 뜨다.mediawiki_content = 기능을 하다(문자 메시지를 보내다) {     GM_log(">mw_content:");     만일 (문자 메시지를 보내다 == "") {       돌아오다 문자 메시지를 보내다;     } 다른 {       문자 메시지를 보내다 = '' + 문자 메시지를 보내다;       시합을 하다 출발하다 = 문자 메시지를 보내다.인덱스오프('[[텍스트 영역]');       출발하다 += 문자 메시지를 보내다.기판을 달다(출발하다, 1000).인덱스오프('>') + 1;       시합을 하다 종지부를 찍다 = 문자 메시지를 보내다.인덱스오프('[/텍스트 영역]');       GM_log("<mw_content");       문자 메시지를 보내다 = 문자 메시지를 보내다.기판을 달다(출발하다, 종지부를 찍다 - 출발하다);       s = 문자 메시지를 보내다.대체하다(/</g, "&lt;");       s = s.대체하다(/>/g, "&gt;");       GM_log ("스트라이핑: " + s.기판을 달다(0,50));       돌아오다 s;     }   }     압축하다.원형을 뜨다.출발하다 = 기능을 하다() {     시합을 하다 히스 = 문서화하다.GetElementBy아이디('페이지히스토리');     만일 (히스) {       시합을 하다 흩어지다;       흩어지다 = 문서화하다.평가하다(         "LI",         히스,         무효의,         XPathResult.UNORDERED_NODE_Snapshot_TYPE,         무효의       );       시합을 하다 지난='*x!', 광고의 전언어;        을 위해 (시합을 하다 i = 0; i < 흩어지다.snapshotLength; i++) {          시합을 하다 산산이 흩어지다 = 흩어지다.스냅 사진을 찍다항목(i);         시합을 하다 댓글 = 문서화하다.평가하다(           '스PAN[@class="comment]',           산산이 흩어지다,           무효의,           XPathResult.UNORDERED_NODE_Snapshot_TYPE,           무효의         ).스냅 사진을 찍다항목(0);         //GM_log(comment.innerHTML);         시합을 하다 a = 문서화하다.평가하다(           "SPAN/A",           산산이 흩어지다,           무효의,           XPathResult.UNORDERED_NODE_Snapshot_TYPE,           무효의         );         각각의 = a.스냅 사진을 찍다항목(0);         만일 (각각의.칭호를 붙이다==지난) {           만일 (댓글) {             광고의 전언어.innerHTML = 광고의 전언어.innerHTML + '//' + 댓글.innerHTML;           } 다른 {             광고의 전언어.innerHTML = 광고의 전언어.innerHTML + '//---';           }           산산이 흩어지다.parentNode.제거차일드(산산이 흩어지다);         } 다른 {           지난 = 각각의.칭호를 붙이다;           만일 (!댓글) {             댓글 = 문서화하다.createElement('스팬');             댓글.className='comment';             댓글.innerHTML=' ---';             산산이 흩어지다.삽입 전(댓글, 무효의);           }           광고의 전언어 = 댓글;          } //if       }//용     } //이력이 있는 경우   } // '시작' 기능    압축하다.원형을 뜨다.loadDiff = 기능을 하다(urlno.) {     GM_log("loadDiff에서");     .urlno. = urlno.;     .호스트 이름 = "en.wikipedia.org";     시합을 하다 url = .URL들[urlno.] + '&action=편집';     만일 (.URL들[urlno.] == 무효의) {       시합을 하다 세부 사항 = 새로운 ("");       세부 사항.반응하다텍스트 = ""; // 빈 텍스트와 강제 비교;       압축하다.로드디프(세부 사항);       돌아오다;     }            GM_log(">><loading!" + url);     GM_xmlhttpRequest({      방법:'GET',      url:url,       머리글:{         '사용자-에이전트': '모질라/4.0 (호환성) Greasemonkey',         '수락하다': '응용프로그램/xml',         },       짐을 싣다:기능을 하다(세부 사항) {         //changeshello " + details.status + '/' + details.status텍스트 + '/' + 세부 정보.responseHeaders);         압축하다.로드디프(세부 사항);       }     });     GM_log("<loading!" + url);      }   압축하다.원형을 뜨다.로드디프 = 기능을 하다(세부 사항) {     GM_log(">loaded Diff "+.urlno.);     .페이지[.urlno.] = .mediawiki_content(세부 사항.반응하다텍스트);     GM_log("-loaded Diff "+.urlno.);     만일 (.urlno. > 0) {       s = diffString(.페이지[.urlno.], .페이지[.urlno.-1]);       GM_log("완료된 디프");       wh = 문서화하다.GetElementBy아이디(.정보[.urlno. -1]);       스판하다 = 문서화하다.createElement('스팬');       스판하다.innerHTML = s;       wh.삽입 전(스판하다, 무효의);     }     만일 (세부 사항.반응하다텍스트 != "") {       압축하다.loadDiff(.urlno.+1); // 빈 텍스트인 경우 중지하십시오.     }           GM_log("<로드디프");        }    압축하다.원형을 뜨다.쇼디프스 = 기능을 하다() {     시합을 하다 히스 = 문서화하다.GetElementBy아이디('페이지히스토리');      만일 (히스) {       시합을 하다 흩어지다;       흩어지다 = 문서화하다.평가하다(         'LI/A[text() != "cur" 및 text() != "last"[1],         히스,         무효의,         XPathResult.UNORDERED_NODE_Snapshot_TYPE,         무효의       );        .URL들 = 새로운 배열(흩어지다.snapshotLength);       .정보 = 새로운 배열(흩어지다.snapshotLength);       .페이지 = 새로운 배열(흩어지다.snapshotLength);              GM_log("A의 수: " + 흩어지다.snapshotLength);              을 위해 (시합을 하다 i = 0; i < 흩어지다.snapshotLength; i++) {          시합을 하다 산산이 흩어지다 = 흩어지다.스냅 사진을 찍다항목(i);                  산산이 흩어지다.id = "커플링크" + i;         산산이 흩어지다.parentNode.id = "diffli" + i;         .URL들[i] = 산산이 흩어지다.href;         .정보[i] = "diffli" + i;                  만일 (i==0) {           .loadDiff(0);         }       }//용     } //이력이 있는 경우   } // '시작' 기능       시합을 하다 압축하다 = 새로운 압축하다();   문서화하다.압축하다 = 압축하다;  } // 이름 없는 함수  ) ();