Security News
JSR Working Group Kicks Off with Ambitious Roadmap and Plans for Open Governance
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
See Browser Support for more information (a.k.a. don’t worry about those grey icons above).
TextOM provides an object model for natural language in JavaScript. No dependencies. NodeJS, and the browser. Lots of tests (230+), including 350+ assertions. 100% coverage.
Note: This project is not a parser for natural language, or an extensible system for analysing and manipulating natural language, its rather the core that lies underneath such systems. Its like a simplified and modified version of the DOM, without any parsing capabilities, for natural language. If you need the above-mentioned functionalities, use the following project—both build on top of this module.
NPM:
$ npm install textom
Component.js:
$ component install wooorm/textom
TextOM = require('textom')();
var root = new TextOM.RootNode();
Note that the exported object is a function, which in turn returns brand-new TextOM objects. There’s whole slew of issues that can arise from extending prototypes like (DOM) Node, NodeList, or Array—this feature however allows for multiple sandboxed environments (i.e., prototypes) without those disadvantages.
See below for an abbreviated IDL definition.
Lets say all the following examples start with this code. Any changes made by below examples are discarded upon their ending.
// Import TextOM.
var TextOM = require('textom')();
// Create a root.
var root = new TextOM.RootNode();
// Add a paragraph.
var paragraph = new TextOM.ParagraphNode();
root.append(paragraph);
// Add a sentence.
var sentence = new TextOM.SentenceNode();
paragraph.append(sentence);
// Add some words, punctuation, and white space.
var dogs = sentence.append(new TextOM.WordNode()),
space0 = sentence.append(new TextOM.WhiteSpaceNode()),
ampersand = sentence.append(new TextOM.PunctuationNode()),
space1 = sentence.append(new TextOM.WhiteSpaceNode()),
cats = sentence.append(new TextOM.WordNode()),
fullStop = sentence.append(new TextOM.PunctuationNode());
// Add some actual contents.
var dogsText = dogs.append(new TextOM.TextNode('Dogs')),
space0Text = space0.append(new TextOM.TextNode(' ')),
ampersandText = ampersand.append(new TextOM.TextNode('&')),
space1Text = space1.append(new TextOM.TextNode(' ')),
catsText = cats.append(new TextOM.TextNode('cats')),
fullStopText = fullStop.append(new TextOM.TextNode('.'));
// Check what the current textual value is:
root.toString(); // 'Dogs & cats.'
Constructor.
TextOM.RootNode.on('someeventname', function () {});
Registers the specified listener on any instance of constructor, to events of the given name. Returns self.
TextOM.WordNode.off('someeventname');
Removes the specified listener on all instances of constructor, to events of the given name. If no listener is given, removes all listeners to events of the given type. If no name and node listener are given, removes all listeners to all events. Returns self.
root.on('someeventname', function () {});
Registers the specified listener on the node it's called on, to events of the given name. Returns self.
root.off('someeventname');
Removes the specified listener on the node it's called on, to events of the given name. If no listener is given, removes all listeners to events of the given type. If no name and node listener are given, removes all listeners to all events. Returns self.
TextOM.WordNode.on('custom-emitted-event', function () {
this; // dogs
})
dogs.trigger('custom-emitted-event');
Fire's an event of name name
on the node, and bubbles up through its constructors.
root.on('custom-triggered-event', function () {
this; // dogs
})
dogs.trigger('custom-triggered-event');
Fire's an event of name name
on the node, and bubbles up through its parents.
root.TextOM === TextOM; // true
Every node contains a TextOM
attribute linking back to the original TextOM.
root.type === root.ROOT_NODE; // true
root.type === TextOM.ROOT_NODE; // true
Unique identifier for all instances of RootNode.
paragraph.type === paragraph.PARAGRAPH_NODE; // true
paragraph.type === TextOM.PARAGRAPH_NODE; // true
Unique identifier for all instances of ParagraphNode.
sentence.type === sentence.SENTENCE_NODE; // true
sentence.type === TextOM.SENTENCE_NODE; // true
Unique identifier for all instances of SentenceNode.
dogs.type === dogs.WORD_NODE; // true
dogs.type === TextOM.WORD_NODE; // true
Unique identifier for all instances of WordNode.
fullStop.type === fullStop.PUNCTUATION_NODE; // true
fullStop.type === TextOM.PUNCTUATION_NODE; // true
Unique identifier for all instances of PunctuationNode.
space0.type === space0.WHITE_SPACE_NODE; // true
space0.type === TextOM.WHITE_SPACE_NODE; // true
Unique identifier for all instances of WhiteSpaceNode.
Unique identifier for all instances of SourceNode.
Unique identifier for all instances of TextNode.
Constructor. Inherits from Node.
paragraph.head; // sentence
sentence.head; // dogs
The first child of a parent, null otherwise.
paragraph.tail; // null (see description below);
sentence.tail; // fullStop
The last child of a parent (unless the last child is also the first child), null otherwise.
root.length; // 1
sentence.length; // 6
The number of children in a parent.
sentence.head; // dogs
sentence.prepend(fullStop);
sentence.head; // fullStop
Insert a child at the beginning of the parent (like Array#unshift).
sentence.tail; // fullStop
sentence.append(dogs);
sentence.tail; // dogs
Insert a child at the end of the parent (like Array#push).
root.item(); // paragraph
sentence.item(0); // dogs
sentence.item(6); // fullStop
sentence.item(7); // null
Return a child at given position in parent, and null otherwise. (like NodeList#item).
root.toString(); // "Dogs & cats."
'' + sentence; // "Dogs & cats."
Return the result of calling toString
on each of Parent
s children.
Constructor. Inherits from Node.
dogs.parent; // sentence
sentence.parent; // paragraph
paragraph.parent; // root
The parent node, null otherwise (when the child is detached).
dogs.prev; // null
space1.prev; // dogs
The previous sibling, null otherwise (when the context object is the first of its parent's children or detached).
cats.next; // fullStop
fullStop.next; // null
The next sibling, null otherwise (when the context object is the last of its parent's children, or detached).
dogs.prev; // null
dogs.before(cats);
dogs.prev; // cats
Insert a given child before the context object's position in its parent.
cats.next; // null
cats.before(dogs);
cats.next; // dogs
Insert a given child after the context object's position in its parent.
root.toString(); // "Dogs & cats."
fullStop.remove();
root.toString(); // "Dogs & cats"
Remove the operated on child.
root.toString(); // "Dogs & cats."
cats.replace(dogs);
root.toString(); // " & Dogs"
Remove the context object and insert a given child at its previous position in its parent.
Constructor. Inherits from Parent and Child (i.e., a node accepting both children and a parent).
Constructor. Inherits from Child. Has a value.
dogsText.toString(); // "Dogs"
space1Text.toString(); // " "
fullStopText.toString(); // "."
Returns the internal value of the context object.
root.toString(); // "Dogs & cats."
catsText.fromString();
root.toString(); // "Dogs & ."
catsText.fromString("Lions");
root.toString(); // "Dogs & Lions."
(Re)sets and returns the internal value of the context object with the stringified version of the given value.
catsText.prev; // null
catsText.toString(); // "cats"
catsText.split(2);
catsText.toString(); // "ts"
catsText.prev.toString(); // "ca"
Split the context object into two nodes: prepends a new node (an instance of the context object's constructor), moving the internal value from 0–position to the prepended node, and removing the internal value from 0–position of the context object.
Constructor. Inherits from Parent.
Semantics: Root (Parent) represents the root of a TextOM document. Any subsequent nodes are the children of this root element.
Constructor. Inherits from Element.
Semantics: Paragraph (Element) represents a self-contained unit of a discourse in writing dealing with a particular point or idea.
Constructor. Inherits from Element.
Semantics: Sentence (Element) represents a grouping of grammatically linked words, that in principle tells a complete thought (although it may make little sense taken in isolation out of context).
Constructor. Inherits from Element.
Semantics: Word (Element) represents the smallest element that may be uttered in isolation with semantic or pragmatic content.
Constructor. Inherits from Element.
Semantics: Punctuation (Element) represents typographical devices which aid the understanding and correct reading of other grammatical units.
Constructor. Inherits from PunctuationNode.
Semantics: White Space (Punctuation) represents typographical devices devoid of content, separating other grammatical units.
Constructor. Inherits from Text.
Semantics: Source (Text) represents an external (non-grammatical) value embedded into a grammatical unit, for example a hyperlink or an emoticon.
Constructor. Inherits from Text.
Semantics: Text (Text) represents actual content in a TextOM document: One or more characters.
The following IDL document gives a short view of the defined interfaces by TextOM. Note: It might not be that valid in the eyes of W3C standardistas, but it gives a nice overview nonetheless.
module textom
{
[Constructor]
interface Node {
const string ROOT_NODE = "RootNode"
const string PARAGRAPH_NODE = "ParagraphNode"
const string SENTENCE_NODE = "SentenceNode"
const string WORD_NODE = "WordNode"
const string PUNCTUATION_NODE = "PunctuationNode"
const string WHITE_SPACE_NODE = "WhiteSpaceNode"
const string SOURCE_NODE = "SourceNode"
const string TEXT_NODE = "TextNode"
void on(String type, Function callback);
void off(optional String type = null, optional Function callback = null);
};
[Constructor,
ArrayClass]
interface Parent {
getter Child? item(unsigned long index);
readonly attribute unsigned long length;
readonly attribute Child? head;
readonly attribute Child? tail;
Child prepend(Child child);
Child append(Child child);
[NewObject] Parent split(unsigned long position);
string toString();
};
Parent implements Node;
[Constructor]
interface Child {
readonly attribute Parent? parent;
readonly attribute Child? prev;
readonly attribute Child? next;
Child before(Child child);
Child after(Child child);
Child replace(Child child);
Child remove(Child child);
};
Child implements Node;
[Constructor]
interface Element {
};
Element implements Child;
Element implements Parent;
[Constructor(optional String value = "")]
interface Text {
string toString();
string fromString(String value);
[NewObject] Text split(unsigned long position);
};
Text implements Child;
[Constructor]
interface RootNode {
readonly attribute string type = "RootNode";
};
RootNode implements Parent;
[Constructor]
interface ParagraphNode {
readonly attribute string type = "ParagraphNode";
};
ParagraphNode implements Element;
[Constructor]
interface SentenceNode {
readonly attribute string type = "SentenceNode";
};
SentenceNode implements Element;
[Constructor]
interface WordNode {
readonly attribute string type = "WordNode";
};
WordNode implements Parent;
[Constructor]
interface PunctuationNode {
readonly attribute string type = "PunctuationNode";
};
PunctuationNode implements Parent;
[Constructor]
interface WhiteSpaceNode {
readonly attribute string type = "WhiteSpaceNode";
};
WhiteSpaceNode implements PunctuationNode;
[Constructor(optional String value = "")]
interface TextNode {
readonly attribute string type = "TextNode";
};
[Constructor(optional String value = "")]
interface SourceNode {
readonly attribute string type = "SourceNode";
};
SourceNode implements Text;
}
TextOM provides a few handy events, listened to through the on
—and its opposite silencing functionality, off
—methods. These on
and off
methods exist on every instance of Node, and on every constructor (e.g., Node, Element, and WhiteSpaceNode). When used on an instance, only events on that specific instance will be exposed to the listener. When however used on a constructor, all events on all instances will be exposed to the listener.
TextOM provides two different types of events: Bubbling, and non-bubbling. In API terms, bubbling event names end with "inside"
.
Normal events fire on instances of Child (and thus also on Element, or Text—which both subclass Child), and do not continue firing on through ancestors. They do however, fire on all constructors of the instance.
Lets say, for example, we have the example in API, and add the following code to it:
dogsText.fromString('Poodles');
A "changetext"
event will fire on dogsText, and because dogs is an instance of TextNode, the event will also fire on TextNode. Because a TextNode also inherits from Text, the event will also fire on Text, continuing with Child, and finally on Node.
Bubbling events start at a parent, and continue up through its ancestors, until no higher ancestor exists. These events also fire on the (single) parents constructor.
Lets say, for example, we have the example in API, and add the following code to it:
dogsText.fromString('Wolves');
A "changetextinside"
event will fire on the parent of dogsText (dogs), and because dogs is an instance of WordNode, this event will also fire on WordNode. The same would happen through dogs ancestors: sentence and SentenceNode, paragraph and ParagraphNode, and root and RootNode.
dogs.on('remove', function (previousParent) {
this === dogs; // true
previousParent === sentence; // true
})
dogs.remove();
Fired when a child is removed from its parent.
dogs.on('insert', function () {
this === dogs; // true
})
sentence.append(dogs);
Fired when a child is inserted into a parent.
dogsText.on('changetext', function (value, previousValue) {
this === dogsText; // true
value === 'Poodles'; // true
previousValue === 'Dogs'; // true
})
dogsText.fromString('Poodles');
Fired when the internal value of an instance of Text (i.e., TextNode, SourceNode) changes.
cats.on('changeprev', function (node, previousNode) {
this === cats; // true
node === ampersand; // true
previousNode === space1; // true
})
space1.remove();
Fired when the prev
attribute on a child is changed (i.e., by removing the previous sibling, or inserting a sibling before the child).
cats.on('changenext', function (node, previousNode) {
this === cats; // true
node === null; // true
previousNode === fullStop; // true
})
fullStop.remove();
Fired when the next
attribute on a child is changed (i.e., by removing the next sibling, or inserting a sibling after the child).
root.on('changetextinside', function (node, value, previousValue) {
this === root; // true
node === catsText; // true
value === 'lions'; // true
previousValue === 'cats'; // true
})
catsText.fromString('lions');
Fired when a child’s internal value changes inside an ancestor.
sentence.on('insertinside', function (node) {
this === sentence; // true
node === ampersand; // true
})
sentence.append(ampersand);
Fired when a child is inserted inside an ancestor.
root.on('removeinside', function (node, parent) {
this === root; // true
parent === sentence; // true;
node === dogs; // true
})
dogs.remove();
Fired when a child is removed from an ancestor.
Pretty much every browser (available through browserstack) runs all TextOM unit tests; just make sure Array#indexOf()
is polyfill’d in browser that need it.
MIT
FAQs
Deprecated. I don’t believe in DOM-like models anymore. [**retext**](https://github.com/wooorm/retext) lives on without them.
The npm package textom receives a total of 23 weekly downloads. As such, textom popularity was classified as not popular.
We found that textom demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
Security News
Research
An advanced npm supply chain attack is leveraging Ethereum smart contracts for decentralized, persistent malware control, evading traditional defenses.
Security News
Research
Attackers are impersonating Sindre Sorhus on npm with a fake 'chalk-node' package containing a malicious backdoor to compromise developers' projects.