jsdom μ μΉ μ€ν¬λνμ μν νλ₯ν λꡬμ
λλ€. κ·Έλ¬λ textContent
λ html2text λ³νμ μν΄ μ½μ μ μλ ν
μ€νΈλ₯Ό μ»λ λ§€μ° λΆνΈν λ°©λ²μ
λλ€.
λ§μ κ²½μ°μ 무μν μ μλ innerText
μ μ©μ±μ λν λ©μ§ κΈ°μ¬κ° μμ΅λλ€.
http://perfectionkills.com/the-poor-misunderstood-innerText/
μ μλ getSelection().toString()
λ₯Ό λ§€μ° λλ¦° ν΄κ²° λ°©λ²μΌλ‘ μ μνμ§λ§ getSelection
λ μμ§ jsdomμ ꡬνλμ§ μμμ΅λλ€.
jsdom μμ innerText
ꡬνμ κ³ λ €ν μ μμ΅λκΉ? μ μλ κ·Έκ²μ λν΄ λλ¨ν νꡬλ₯Ό νκ³ , κ·Έλ μ¬μ§μ΄ λ§μ§λ§μ κ°λ¨ν μ¬μμ μΆκ°νμ΅λλ€.
κ·Έλ¦¬κ³ λ¬΄μ¨ μ κ°μ΄ λμ λ€λκΈ°μ μλ§μ 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
});
});
κ°μ₯ μ μ©ν λκΈ
λ€λ₯Έ μ¬λμ΄ μ΄ λ¬Έμ μ μ§λ©΄νλ κ²½μ°λ₯Ό λλΉνμ¬ ν λ¨κ³ λ λμκ°
sanitize-html
ν¨ν€μ§λ₯Ό μ¬μ©νμ¬ κΈ°λ³Έμ μΌλ‘ λΈλΌμ°μ κ° μννλ μμ μ νμΈνμ΅λλ€(μ°Έκ³ λ‘ JSDOM μ€μ μ νμνμ§ μμκΈ° λλ¬Έμ κ°μ Έμ€μ§ μμμ΅λλ€. μ΄κ²μ λ΄ Jest μ€μ νμΌμ λ£μ λ Jestλ₯Ό μ¬μ©νμ§ μλλ€λ©΄ @bennypowersκ° κΆμ₯νλglobal.Element = (new JSDOM()).window.Element
μ€μ μ μ¬μ©νκ³ μΆμ κ²μ λλ€.