-
Notifications
You must be signed in to change notification settings - Fork 104
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
import { decode } from 'he'; | ||
import NodeType from './type'; | ||
import HTMLElement from './html'; | ||
|
||
|
@@ -17,9 +18,10 @@ export default abstract class Node { | |
return this.rawText; | ||
} | ||
public get textContent() { | ||
return this.rawText; | ||
return decode(this.rawText); | ||
} | ||
public set textContent(val: string) { | ||
console.error('ssssssssssssssss', val); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong. |
||
this.rawText = val; | ||
This comment has been minimized.
Sorry, something went wrong.
nonara
Collaborator
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import { decode } from 'he'; | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong. |
||
import NodeType from './type'; | ||
import Node from './node'; | ||
import HTMLElement from './html'; | ||
|
||
/** | ||
* TextNode to contain a text element in DOM tree. | ||
* @param {string} value [description] | ||
*/ | ||
export default class TextNode extends Node { | ||
public constructor(rawText: string, parentNode: HTMLElement) { | ||
super(parentNode); | ||
this._rawText = rawText; | ||
} | ||
|
||
/** | ||
* Node Type declaration. | ||
* @type {Number} | ||
*/ | ||
public nodeType = NodeType.TEXT_NODE; | ||
|
||
private _rawText: string; | ||
private _trimmedRawText?: string; | ||
private _trimmedText?: string; | ||
|
||
public get rawText() { | ||
return this._rawText; | ||
} | ||
|
||
/** | ||
* Set rawText and invalidate trimmed caches | ||
*/ | ||
public set rawText(text: string) { | ||
this._rawText = text; | ||
this._trimmedRawText = void 0; | ||
this._trimmedText = void 0; | ||
} | ||
|
||
/** | ||
* Returns raw text with all whitespace trimmed except single leading/trailing non-breaking space | ||
*/ | ||
public get trimmedRawText() { | ||
if (this._trimmedRawText !== undefined) return this._trimmedRawText; | ||
this._trimmedRawText = trimText(this.rawText); | ||
return this._trimmedRawText; | ||
} | ||
|
||
/** | ||
* Returns text with all whitespace trimmed except single leading/trailing non-breaking space | ||
*/ | ||
public get trimmedText() { | ||
if (this._trimmedText !== undefined) return this._trimmedText; | ||
|
||
this._trimmedText = trimText(this.text); | ||
|
||
return this._trimmedText; | ||
} | ||
|
||
/** | ||
* Get unescaped text value of current node and its children. | ||
* @return {string} text content | ||
*/ | ||
public get text() { | ||
return decode(this.rawText); | ||
} | ||
|
||
/** | ||
* Detect if the node contains only white space. | ||
* @return {boolean} | ||
*/ | ||
public get isWhitespace() { | ||
return /^(\s| )*$/.test(this.rawText); | ||
} | ||
|
||
public toString() { | ||
return this.rawText; | ||
} | ||
} | ||
|
||
/** | ||
* Trim whitespace except single leading/trailing non-breaking space | ||
*/ | ||
function trimText(text: string): string { | ||
let i = 0; | ||
let startPos; | ||
let endPos; | ||
|
||
while (i >= 0 && i < text.length) { | ||
if (/\S/.test(text[i])) { | ||
if (startPos === undefined) { | ||
startPos = i; | ||
i = text.length; | ||
} else { | ||
endPos = i; | ||
i = void 0; | ||
} | ||
} | ||
|
||
if (startPos === undefined) i++; | ||
else i--; | ||
} | ||
|
||
if (startPos === undefined) startPos = 0; | ||
if (endPos === undefined) endPos = text.length - 1; | ||
|
||
const hasLeadingSpace = startPos > 0 && /[^\S\r\n]/.test(text[startPos - 1]); | ||
const hasTrailingSpace = endPos < (text.length - 1) && /[^\S\r\n]/.test(text[endPos + 1]); | ||
|
||
return (hasLeadingSpace ? ' ' : '') + text.slice(startPos, endPos + 1) + (hasTrailingSpace ? ' ' : ''); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
const { parse, TextNode, HTMLElement } = require('../dist'); | ||
|
||
describe('pr 135', function () { | ||
it('shoud not decode text', function () { | ||
This comment has been minimized.
Sorry, something went wrong.
nonara
Collaborator
|
||
const content = `<p> Not a p tag <br /> at all`; | ||
const root = parse(`<div>${content}</div>`); | ||
const div = root.firstChild; | ||
div.innerHTML.should.eql(content); | ||
div.textContent.should.eql('<p> Not a p tag <br /> at all'); | ||
// div.innerText.should.eql('<p> Not a p tag <br /> at all'); | ||
|
||
// const textNode = div.firstChild; | ||
// textNode.rawText.should.eql(content); | ||
// textNode.toString().should.eql('aaa') | ||
}); | ||
|
||
it('should not decode text from parseHTML()', function () { | ||
const content = `<p> Not a p tag <br /> at all`; | ||
const root = parse(`<div>${content}</div>`); | ||
root.childNodes.should.have.length(1); | ||
|
||
const divNode = root.firstChild; | ||
divNode.childNodes.should.have.length(1); | ||
|
||
const textNode = divNode.firstChild; | ||
textNode.rawText.should.eql(content); | ||
}); | ||
|
||
it(`should decode for node text property`, function () { | ||
const encodedText = `My>text`; | ||
const decodedText = `My>text`; | ||
const root = parse(`<p>${encodedText}</p>`); | ||
|
||
const pNode = root.firstChild; | ||
pNode.innerHTML.should.eql(encodedText); | ||
pNode.textContent.should.eql(decodedText); | ||
|
||
const textNode = pNode.firstChild; | ||
textNode.textContent.should.eql(decodedText); | ||
}); | ||
|
||
it('should remove whitespaces while preserving nodes with content', function () { | ||
This comment has been minimized.
Sorry, something went wrong. |
||
const root = parse('<p> \r \n \t <h5> 123 </h5></p>'); | ||
|
||
const textNode = new TextNode(' 123 '); | ||
textNode.rawText = textNode.trimmedText; | ||
textNode.rawText.should.eql(' 123 '); | ||
|
||
const p = new HTMLElement('p', {}, '', root); | ||
p | ||
.appendChild(new HTMLElement('h5', {}, '')) | ||
.appendChild(textNode); | ||
|
||
p.toString().should.eql('<p><h5> 123 </h5></p>'); | ||
root.firstChild.removeWhitespace().toString().should.eql('<p><h5> 123 </h5></p>'); | ||
root.firstChild.removeWhitespace().should.eql(p); | ||
}) | ||
}); |
DOM Spec issue - see notes in PR