Jsdom: λ‚΄λΆ€ν…μŠ€νŠΈ κ΅¬ν˜„

에 λ§Œλ“  2015λ…„ 09μ›” 25일  Β·  26μ½”λ©˜νŠΈ  Β·  좜처: jsdom/jsdom

jsdom 은 μ›Ή μŠ€ν¬λž˜ν•‘μ„ μœ„ν•œ ν›Œλ₯­ν•œ λ„κ΅¬μž…λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ textContent λŠ” html2text λ³€ν™˜μ„ μœ„ν•΄ 읽을 수 μžˆλŠ” ν…μŠ€νŠΈλ₯Ό μ–»λŠ” 맀우 λΆˆνŽΈν•œ λ°©λ²•μž…λ‹ˆλ‹€.

λ§Žμ€ κ²½μš°μ— λ¬΄μ‹œν•  수 μžˆλŠ” innerText μœ μš©μ„±μ— λŒ€ν•œ 멋진 기사가 μžˆμŠ΅λ‹ˆλ‹€.

http://perfectionkills.com/the-poor-misunderstood-innerText/

μ €μžλŠ” getSelection().toString() λ₯Ό 맀우 느린 ν•΄κ²° λ°©λ²•μœΌλ‘œ μ œμ•ˆν•˜μ§€λ§Œ getSelection λŠ” 아직 jsdom에 κ΅¬ν˜„λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.

jsdom μ—μ„œ innerText κ΅¬ν˜„μ„ κ³ λ €ν•  수 μžˆμŠ΅λ‹ˆκΉŒ? μ €μžλŠ” 그것에 λŒ€ν•΄ λŒ€λ‹¨ν•œ 탐ꡬλ₯Ό ν–ˆκ³ , κ·ΈλŠ” 심지어 λ§ˆμ§€λ§‰μ— κ°„λ‹¨ν•œ 사양을 μΆ”κ°€ν–ˆμŠ΅λ‹ˆλ‹€.

feature layout

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

λ‹€λ₯Έ μ‚¬λžŒμ΄ 이 λ¬Έμ œμ— μ§λ©΄ν•˜λŠ” 경우λ₯Ό λŒ€λΉ„ν•˜μ—¬ ν•œ 단계 더 λ‚˜μ•„κ°€ sanitize-html νŒ¨ν‚€μ§€λ₯Ό μ‚¬μš©ν•˜μ—¬ 기본적으둜 λΈŒλΌμš°μ €κ°€ μˆ˜ν–‰ν•˜λŠ” μž‘μ—…μ„ ν™•μΈν–ˆμŠ΅λ‹ˆλ‹€(참고둜 JSDOM 섀정은 ν•„μš”ν•˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ— κ°€μ Έμ˜€μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€. 이것을 λ‚΄ Jest μ„€μ • νŒŒμΌμ— 넣을 λ•Œ Jestλ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ @bennypowersκ°€ ꢌμž₯ν•˜λŠ” global.Element = (new JSDOM()).window.Element 섀정을 μ‚¬μš©ν•˜κ³  싢을 κ²ƒμž…λ‹ˆλ‹€.

Object.defineProperty(global.Element.prototype, 'innerText', {
  get() {
    return sanitizeHtml(this.textContent, {
      allowedTags: [], // remove all tags and return text content only
      allowedAttributes: {}, // remove all tags and return text content only
    });
  },
  configurable: true, // make it so that it doesn't blow chunks on re-running tests with things like --watch
});

λͺ¨λ“  26 λŒ“κΈ€

그리고 무슨 유감이 λŒμ•„ λ‹€λ‹ˆκΈ°μ— μ•Œλ§žμ€ Selection 및 innerText λΌμ΄λΈŒλŸ¬λ¦¬κ°€ jsdom와 ν˜Έν™˜λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ : https://github.com/timdown/rangy/issues/348

λ”°λΌμ„œ innerTextλŠ” ν‘œμ€€μ΄ μ•„λ‹ˆλ©° 적어도 ν•˜λ‚˜μ˜ μ£Όμš” 엔진(Firefox)μ—μ„œ κ΅¬ν˜„λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. ν‘œμ€€μ΄ μ—†μœΌλ©΄ κ΅¬ν˜„ν•΄μ•Ό ν•œλ‹€κ³  μƒκ°ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

여기에 μ΄ˆμ•ˆ 사양이 μžˆλŠ” 이 λͺ¨λ“  일에 μ•½κ°„μ˜ μ›€μ§μž„μ΄ μžˆλŠ” 것 μ°Έμ‘°λ₯Ό μ°Έμ‘°ν•˜μ‹­μ‹œμ˜€ . ν•˜μ§€λ§Œ λ¦¬ν¬μ§€ν† λ¦¬μ—λŠ” λ¬Έμ œκ°€ μ—†μœΌλ―€λ‘œ 이미 μ™„λ£Œλ˜μ—ˆλŠ”μ§€/μ–Όλ§ˆλ‚˜ 빨리 μ§„ν–‰λ˜λŠ”μ§€ κΆκΈˆν•©λ‹ˆλ‹€.

Firefoxκ°€ κ΅¬ν˜„ν–ˆμŠ΅λ‹ˆλ‹€: https://bugzilla.mozilla.org/show_bug.cgi?id=264412

WHATWGλŠ” μŠΉμΈν•  것 κ°™μŠ΅λ‹ˆλ‹€: https://github.com/whatwg/compat/issues/5#issuecomment -168049752

μ‚¬μ–‘μ—μ„œ 보면 κΈ°λ³Έ λ ˆμ΄μ•„μ›ƒ 지원 μ—†μ΄λŠ” innerText μ œλŒ€λ‘œ κ΅¬ν˜„ν•  수 μ—†λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€.

λ„€, 이것은 λ§Žμ€ 인프라 μž‘μ—… μ—†μ΄λŠ” μ–΄μ¨Œλ“  jsdomμ—μ„œ κ΅¬ν˜„ν•  수 없을 κ²ƒμž…λ‹ˆλ‹€... 아무도 희망을 갖지 μ•ŠμŠ΅λ‹ˆλ‹€ :(.

λ ˆμ΄μ•„μ›ƒ 지원 μš”κ΅¬ 사항: https://github.com/rocallahan/innerText-spec/issues/2

WHATWG μ±„νƒμœΌλ‘œ 인해 κ΅¬ν˜„ν•  κ³„νšμ΄ μžˆμŠ΅λ‹ˆκΉŒ?

예... μ‚¬μ–‘μ—λŠ” jsdom에 μ—†λŠ” λ§Žμ€ 것듀이 ν•„μš”ν•˜μ§€λ§Œ CSS μƒμž μ£Όλ³€μ—λŠ” :(. 무엇을 ν•΄μ•Ό 할지 잘 λͺ¨λ₯΄κ² μŠ΅λ‹ˆλ‹€.

jsdomκ³Ό ν•¨κ»˜ μ—°κ²°ν•  λΌμ΄λΈŒλŸ¬λ¦¬κ°€ μžˆμŠ΅λ‹ˆκΉŒ?

@domenic careκ°€ μ™œ 이것이 κ·ΈλŸ¬ν•œ 인프라 점검인지에 λŒ€ν•œ 지식을 μ‚­μ œν•˜μ‹œκ² μŠ΅λ‹ˆκΉŒ? μš°λ¦¬λŠ” λ°©μ—μžˆλŠ” 800lb 고릴라가 lo-keyλ₯Ό λ– λ‚  것이라고 μƒκ°ν–ˆμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ 아무데도 가지 μ•ŠλŠ” κ²ƒμ²˜λŸΌ λ³΄μž…λ‹ˆλ‹€. μ•„μ‹œλ‹€μ‹œν”Ό jsdom의 λ‚΄λΆ€λ₯Ό λ‘˜λŸ¬μ‹Έκ³  μžˆμŠ΅λ‹ˆλ‹€. repoμ—μ„œ jsdom newb에 λŒ€ν•œ μ½”λ“œ κ²€ν† λ₯Ό μ‹œμž‘ν•˜κΈ°μ— 쒋은 μœ„μΉ˜λŠ” μ–΄λ””μΈκ°€μš”?

미리 κ°μ‚¬λ“œλ¦½λ‹ˆλ‹€πŸ™ /cc @vsemozhetbyt

μ£Όμš” λ¬Έμ œλŠ” innerText κ°€ μ•ˆλ‚΄λ₯Ό μœ„ν•΄ λ ˆμ΄μ•„μ›ƒ 엔진에 μ˜μ‘΄ν•˜κ³  jsdomμ—λŠ” λ ˆμ΄μ•„μ›ƒ 엔진이 μ—†λ‹€λŠ” μ‚¬μ‹€μž…λ‹ˆλ‹€. https://html.spec.whatwg.org/multipage/dom.html#the -innertext-idl-attribute 및
http://perfectionkills.com/the-poor-misunderstood-innerText/ . 두 번째 λ§ν¬μ—μ„œ:

innerTextκ°€ νŽ˜μ΄μ§€μ— ν…μŠ€νŠΈκ°€ ν‘œμ‹œλ˜λŠ” 방식을 거의 μ •ν™•ν•˜κ²Œ λ‚˜νƒ€λ‚΄λŠ” 방법에 μ£Όλͺ©ν•˜μ„Έμš”. λ°˜λ©΄μ— textContentλŠ” μ΄μƒν•œ 일을 ν•©λ‹ˆλ‹€.
그리고 styled-as-block μš”μ†Œ μ£Όλ³€( 이 경우).

μ—¬μ „νžˆ λ²”μœ„λ₯Ό 벗어났고 ν•΄κ²° 방법이 μ—†μŠ΅λ‹ˆκΉŒ?

λΆ„λͺ…νžˆ 사양은 λ‹€μŒκ³Ό 같이 λ§ν•©λ‹ˆλ‹€.

이 μš”μ†Œκ°€ λ Œλ”λ§λ˜μ§€ μ•Šκ±°λ‚˜ μ‚¬μš©μž μ—μ΄μ „νŠΈκ°€ λΉ„ CSS μ‚¬μš©μž μ—μ΄μ „νŠΈμΈ 경우 [κ°•μ‘° 좔가됨] 이 μš”μ†Œμ˜ textContent IDL 속성과 λ™μΌν•œ 값을 λ°˜ν™˜ν•©λ‹ˆλ‹€.

ν•΄κ²° 방법은 λ‹¨μˆœνžˆ textContent λ₯Ό λ°˜ν™˜ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

μš°λ¦¬λŠ” 그것이 μ μš©λ˜μ§€ μ•ŠλŠ”λ‹€κ³  μƒκ°ν•˜λŠ” μΆ©λΆ„ν•œ CSSλ₯Ό κ΅¬ν˜„ν•©λ‹ˆλ‹€. μš°λ¦¬λŠ” λ ˆμ΄μ•„μ›ƒ 뢀뢄을 κ΅¬ν˜„ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ ...

μ•ˆλ…•ν•˜μ„Έμš” μ—¬λŸ¬λΆ„, 이것에 λŒ€ν•œ μ†Œμ‹μ΄ μžˆμŠ΅λ‹ˆκΉŒ?

ν—€λ“œλ¦¬μŠ€ 크둬만 μ‚¬μš©ν•˜μ„Έμš” :)

@coreh κ°€ μ–ΈκΈ‰ν•œ ν•΄λ‹Ή μ‚¬μ–‘μ˜ @domenic :
https://html.spec.whatwg.org/multipage/dom.html#the -innertext-idl-attribute

이 μš”μ†Œκ°€ λ Œλ”λ§ λ˜μ§€ μ•Šκ±°λ‚˜ μ‚¬μš©μž μ—μ΄μ „νŠΈκ°€ CSSκ°€ μ•„λ‹Œ μ‚¬μš©μž μ—μ΄μ „νŠΈμΈ 경우 이 μš”μ†Œμ˜ textContent IDL 속성과 λ™μΌν•œ 값을 λ°˜ν™˜ν•©λ‹ˆλ‹€.

https://html.spec.whatwg.org/multipage/rendering.html#being -rendered

μ—°κ²°λœ CSS λ ˆμ΄μ•„μ›ƒ μƒμž, SVG λ ˆμ΄μ•„μ›ƒ μƒμž λ˜λŠ” 기타 μŠ€νƒ€μΌ μ–Έμ–΄μ˜ 이에 μƒμ‘ν•˜λŠ” μš”μ†Œκ°€ μžˆλŠ” 경우 μš”μ†Œκ°€ λ Œλ”λ§ λ˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

jsdom 이 λ ˆμ΄μ•„μ›ƒ 뢀뢄을 κ΅¬ν˜„ν•˜μ§€ μ•ŠμœΌλ©΄ "λ Œλ”λ§λ˜μ§€ μ•ŠμŒ"이 μ μš©λ˜μ§€ μ•ŠμŠ΅λ‹ˆκΉŒ?

이 λ©”μ‹œμ§€λŠ” ν•¨μˆ˜ κ΅¬ν˜„μ„ λ³€κ²½ν•˜μ§€ μ•Šκ³  ν…ŒμŠ€νŠΈλ₯Ό ν†΅κ³Όν•˜λŠ” 방법을 μ›ν•˜λŠ” 이 github μŠ€λ ˆλ“œμ— λ„λ‹¬ν•˜λŠ” λͺ¨λ“  μ‚¬λžŒμ„ μœ„ν•œ κ²ƒμž…λ‹ˆλ‹€.

ν…ŒμŠ€νŠΈ 파일 상단에 λŒ€ν•œ copypasta:

// Expose JSDOM Element constructor
global.Element = (new JSDOM()).window.Element;
// 'Implement' innerText in JSDOM: https://github.com/jsdom/jsdom/issues/1245
Object.defineProperty(global.Element.prototype, 'innerText', {
  get() {
    return this.textContent;
  },
});

λ‹Ήμ—°νžˆ μœ„μ˜ λ…Όμ˜μ—μ„œ λ‚˜μ˜¨ 주의 사항이 μ μš©λ©λ‹ˆλ‹€.

λ‹€λ₯Έ μ‚¬λžŒμ΄ 이 λ¬Έμ œμ— μ§λ©΄ν•˜λŠ” 경우λ₯Ό λŒ€λΉ„ν•˜μ—¬ ν•œ 단계 더 λ‚˜μ•„κ°€ sanitize-html νŒ¨ν‚€μ§€λ₯Ό μ‚¬μš©ν•˜μ—¬ 기본적으둜 λΈŒλΌμš°μ €κ°€ μˆ˜ν–‰ν•˜λŠ” μž‘μ—…μ„ ν™•μΈν–ˆμŠ΅λ‹ˆλ‹€(참고둜 JSDOM 섀정은 ν•„μš”ν•˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ— κ°€μ Έμ˜€μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€. 이것을 λ‚΄ Jest μ„€μ • νŒŒμΌμ— 넣을 λ•Œ Jestλ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ @bennypowersκ°€ ꢌμž₯ν•˜λŠ” global.Element = (new JSDOM()).window.Element 섀정을 μ‚¬μš©ν•˜κ³  싢을 κ²ƒμž…λ‹ˆλ‹€.

Object.defineProperty(global.Element.prototype, 'innerText', {
  get() {
    return sanitizeHtml(this.textContent, {
      allowedTags: [], // remove all tags and return text content only
      allowedAttributes: {}, // remove all tags and return text content only
    });
  },
  configurable: true, // make it so that it doesn't blow chunks on re-running tests with things like --watch
});

λΉ„μŠ·ν•œ ν•„μš”κ°€ μžˆμ—ˆμ§€λ§Œ textContent μ‚¬μš©ν•˜λŠ” 것보닀 μ•½κ°„ 더 λ‚˜μ•„κ°€κ³  μ‹Άμ—ˆμŠ΅λ‹ˆλ‹€. λ‹€μ‹œ λ§ν•˜μ§€λ§Œ, 이것은 특히 CSS에 μ˜ν•΄ μˆ¨κ²¨μ§„ μš”μ†Œμ™€ κ΄€λ ¨ν•˜μ—¬ λΈŒλΌμš°μ €κ°€ μ‹€μ œλ‘œ μˆ˜ν–‰ν•˜λŠ” μž‘μ—…μ— λŒ€ν•œ μ •ν™•ν•œ ν‘œν˜„μ€ μ•„λ‹ˆμ§€λ§Œ μ’‹μŠ΅λ‹ˆλ‹€. λ‚΄ μ‚¬μš© 사둀에 μΆ©λΆ„ν•©λ‹ˆλ‹€.

function innerText(el)
  el = el.cloneNode(true) // can skip if mutability isn't a concern
  el.querySelectorAll('script,style').forEach(s => s.remove())
  return el.textContent
}

μœ κ°μž…λ‹ˆλ‹€!

λΆ„λͺ…νžˆ 사양은 λ‹€μŒκ³Ό 같이 λ§ν•©λ‹ˆλ‹€.

이 μš”μ†Œκ°€ λ Œλ”λ§λ˜μ§€ μ•Šκ±°λ‚˜ μ‚¬μš©μž μ—μ΄μ „νŠΈκ°€ λΉ„ CSS μ‚¬μš©μž μ—μ΄μ „νŠΈμΈ 경우 [κ°•μ‘° 좔가됨] 이 μš”μ†Œμ˜ textContent IDL 속성과 λ™μΌν•œ 값을 λ°˜ν™˜ν•©λ‹ˆλ‹€.

ν•΄κ²° 방법은 λ‹¨μˆœνžˆ textContentλ₯Ό λ°˜ν™˜ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

μš°λ¦¬λŠ” 그것이 μ μš©λ˜μ§€ μ•ŠλŠ”λ‹€κ³  μƒκ°ν•˜λŠ” μΆ©λΆ„ν•œ CSSλ₯Ό κ΅¬ν˜„ν•©λ‹ˆλ‹€. μš°λ¦¬λŠ” λ ˆμ΄μ•„μ›ƒ 뢀뢄을 κ΅¬ν˜„ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ ...

@domenic 사양에 λŒ€ν•œ 보닀 자유둜운 해석을 κ³ λ €ν•˜μ‹­μ‹œμ˜€.

textContent λŠ” CSS κ·œμΉ™μ„ μ μš©ν•˜λŠ” 데 λΉ„μš©μ΄ λ„ˆλ¬΄ 많이 λ“œλŠ” 경우 λŒ€μ²΄λ‘œ λͺ…μ‹œμ μœΌλ‘œ ν—ˆμš©λ©λ‹ˆλ‹€.

λ˜ν•œ innerTextλŠ” getter 및 setter 둜 μ§€μ •λ©λ‹ˆλ‹€.

λ‚΄κ°€ 사양 νŽΈμ§‘μžμž„μ„ κ°μ•ˆν•  λ•Œ "CSS κ·œμΉ™μ„ μ μš©ν•˜λŠ” 데 λΉ„μš©μ΄ λ„ˆλ¬΄ 많이 λ“œλŠ” 경우"λŠ” μ‚¬μ–‘μ—μ„œ λ§ν•˜λŠ” 것이 μ•„λ‹˜μ„ μžμ‹  있게 말할 수 μžˆμŠ΅λ‹ˆλ‹€.

.. "μ‚¬μš©μž μ—μ΄μ „νŠΈκ°€ CSSκ°€ μ•„λ‹Œ μ‚¬μš©μž μ—μ΄μ „νŠΈμΈ 경우"에 λŒ€ν•œ λ‚΄ ν•΄μ„μ΄μ—ˆμŠ΅λ‹ˆλ‹€.

"CSS μ‚¬μš©μž μ—μ΄μ „νŠΈ"와 "λΉ„ CSS μ‚¬μš©μž μ—μ΄μ „νŠΈ"의 차이점은 λ¬΄μ—‡μž…λ‹ˆκΉŒ?

λŠ” μ–΄λ•Œ:
CSS μ‚¬μš©μž μ—μ΄μ „νŠΈλŠ” "CSS κ·œμΉ™μ„ 적용"ν•˜κ³  κ²°κ³Ό(κ·Έλž˜ν”½ λ˜λŠ” ν…μŠ€νŠΈ)λ₯Ό 좜λ ₯ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
λΉ„ CSS μ‚¬μš©μž μ—μ΄μ „νŠΈλŠ” "CSS κ·œμΉ™μ„ 적용"ν•˜κΈ°μ—λŠ” λ„ˆλ¬΄ λ©μ²­ν•©λ‹ˆλ‹€.

μš°λ¦¬λŠ” 그것이 μ μš©λ˜μ§€ μ•ŠλŠ”λ‹€κ³  μƒκ°ν•˜λŠ” μΆ©λΆ„ν•œ CSSλ₯Ό κ΅¬ν˜„ν•©λ‹ˆλ‹€.

무슨 λœ»μ΄μ—μš”? window.getComputedStyle?

textContent둜의 λŒ€μ²΄λŠ” ν‘œμ€€ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜μ§€ μ•ŠλŠ” 것보닀 μ—¬μ „νžˆ λ‚«μŠ΅λ‹ˆλ‹€.

μ–΄μ©Œλ©΄ μš°λ¦¬κ°€ μ‚¬μš©ν•  μˆ˜μžˆλŠ” textContent κ²°κ³Ό λŒ€μ²΄ ν•  값을 innerText λ°˜λ©΄μ— ν…ŒμŠ€νŠΈ μ‹€ν–‰ jsdom . 예λ₯Ό λ“€μ–΄:

describe('mytest', () => {
  beforeAll(() => {
    Object.defineProperty(HTMLElement.prototype, 'innerText', {
      get() {
        return this.textContent;
      }
    });
  });
  it('should ok', () => {
  // test assertions
  });
});
이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰