From 2e9fd633ca2c31b201f1504f4c235a4106e8a728 Mon Sep 17 00:00:00 2001 From: Felix <188768+fb55@users.noreply.github.com> Date: Sat, 30 Apr 2022 19:54:39 +0100 Subject: [PATCH] fix(text): Include script and style contents (#2509) --- src/__tests__/deprecated.spec.ts | 17 ++++------------- src/api/attributes.spec.ts | 24 ++++++++++++++++++++++++ src/static.spec.ts | 17 ++++------------- src/static.ts | 18 +++++++----------- 4 files changed, 39 insertions(+), 37 deletions(-) diff --git a/src/__tests__/deprecated.spec.ts b/src/__tests__/deprecated.spec.ts index 42d5bff9b4..b3693f397e 100644 --- a/src/__tests__/deprecated.spec.ts +++ b/src/__tests__/deprecated.spec.ts @@ -340,25 +340,16 @@ describe('deprecated APIs', () => { ); }); - it('(cheerio object) : should omit script tags', () => { + it('(cheerio object) : should not omit script tags', () => { const $ = cheerio.load(''); - expect($.text()).toBe(''); + expect($.text()).toBe('console.log("test")'); }); it('(cheerio object) : should omit style tags', () => { const $ = cheerio.load( - '' - ); - expect($.text()).toBe(''); - }); - - it('(cheerio object) : should include text contents of children omitting style and script tags', () => { - const $ = cheerio.load( - 'Welcome
Hello, testing text function,
End of messege' - ); - expect($.text()).toBe( - 'Welcome Hello, testing text function,End of messege' + '' ); + expect($.text()).toBe('.cf-hidden { display: none; }'); }); }); }); diff --git a/src/api/attributes.spec.ts b/src/api/attributes.spec.ts index fccdf90265..340e78c6fe 100644 --- a/src/api/attributes.spec.ts +++ b/src/api/attributes.spec.ts @@ -305,6 +305,19 @@ describe('$(...)', () => { expect($(script).prop('textContent')).toBe('A var foo = "bar";B'); }); + it('("textContent") : should include style and script tags', () => { + const $ = cheerio.load( + 'Welcome
Hello, testing text function,
End of message' + ); + expect($('body').prop('textContent')).toBe( + 'Welcome Hello, testing text function,console.log("hello").cf-hidden { display: none; }End of message' + ); + expect($('style').prop('textContent')).toBe( + '.cf-hidden { display: none; }' + ); + expect($('script').prop('textContent')).toBe('console.log("hello")'); + }); + it('("innerText") : should render properly', () => { expect(selectMenu.children().prop('innerText')).toBe( 'Option not selected' @@ -313,6 +326,17 @@ describe('$(...)', () => { expect($(script).prop('innerText')).toBe('AB'); }); + it('("innerText") : should omit style and script tags', () => { + const $ = cheerio.load( + 'Welcome
Hello, testing text function,
End of message' + ); + expect($('body').prop('innerText')).toBe( + 'Welcome Hello, testing text function,End of message' + ); + expect($('style').prop('innerText')).toBe(''); + expect($('script').prop('innerText')).toBe(''); + }); + it('(inherited properties) : prop should support inherited properties', () => { expect(selectMenu.prop('childNodes')).toBe(selectMenu[0].childNodes); }); diff --git a/src/static.spec.ts b/src/static.spec.ts index 9f5aff2a72..6e20fe19b1 100644 --- a/src/static.spec.ts +++ b/src/static.spec.ts @@ -77,25 +77,16 @@ describe('cheerio', () => { ); }); - it('(cheerio object) : should omit script tags', () => { + it('(cheerio object) : should not omit script tags', () => { const $ = cheerio.load(''); - expect(cheerio.text($.root())).toBe(''); + expect(cheerio.text($.root())).toBe('console.log("test")'); }); it('(cheerio object) : should omit style tags', () => { const $ = cheerio.load( - '' - ); - expect($.text()).toBe(''); - }); - - it('(cheerio object) : should include text contents of children omitting style and script tags', () => { - const $ = cheerio.load( - 'Welcome
Hello, testing text function,
End of messege' - ); - expect(cheerio.text($.root())).toBe( - 'Welcome Hello, testing text function,End of messege' + '' ); + expect($.text()).toBe('.cf-hidden { display: none; }'); }); it('() : does not crash with `null` as `this` value', () => { diff --git a/src/static.ts b/src/static.ts index 463383bd82..2c3abd8c13 100644 --- a/src/static.ts +++ b/src/static.ts @@ -1,13 +1,13 @@ import type { BasicAcceptedElems } from './types.js'; import type { CheerioAPI, Cheerio } from '.'; -import { AnyNode, Document, isText, hasChildren } from 'domhandler'; +import type { AnyNode, Document } from 'domhandler'; +import { textContent } from 'domutils'; import { InternalOptions, CheerioOptions, default as defaultOptions, flatten as flattenOptions, } from './options.js'; -import { ElementType } from 'htmlparser2'; /** * Helper function to render a DOM. @@ -109,6 +109,10 @@ export function xml( /** * Render the document as text. * + * This returns the `textContent` of the passed elements. The result will + * include the contents of `script` and `stype` elements. To avoid this, use + * `.prop('innerText')` instead. + * * @param elements - Elements to render. * @returns The rendered document. */ @@ -121,15 +125,7 @@ export function text( let ret = ''; for (let i = 0; i < elems.length; i++) { - const elem = elems[i]; - if (isText(elem)) ret += elem.data; - else if ( - hasChildren(elem) && - elem.type !== ElementType.Script && - elem.type !== ElementType.Style - ) { - ret += text(elem.children); - } + ret += textContent(elems[i]); } return ret;