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;