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 (280+), including 640+ 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();
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();
// Add a paragraph.
var paragraph = new TextOM.ParagraphNode();
root.append(paragraph);
// Add a sentence.
var sentence = new TextOM.SentenceNode();
paragraph.append(sentence);
// Add some actual contents.
var dogs = new TextOM.WordNode('Dogs')
var space0 = new TextOM.WhiteSpaceNode(' ')
var ampersand = new TextOM.PunctuationNode('&')
var space1 = new TextOM.WhiteSpaceNode(' ')
var cats = new TextOM.WordNode('cats')
var fullStop = new TextOM.PunctuationNode('.')
sentence.append(dogs);
sentence.append(space0);
sentence.append(ampersand);
sentence.append(space1);
sentence.append(cats);
sentence.append(fullStop);
new TextOM(); // An instance of RootNode.
Returns a new RootNode (the same as new TextOM.RootNode()
);
Constructor. Creates a new Node.
TextOM.WordNode.on('changetext', function (value, previousValue) {
this; // the node which text changed
value; // the current value
previousValue; // the previous value
});
Registers the specified listener on any instance of constructor, to events of the given name. Returns self.
TextOM.WordNode.off('changetext');
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('insertinside', function (node) {
node; // the inserted node
});
Registers the specified listener on the node it's called on, to events of the given name. Returns self.
root.off('insertinside');
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.
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
.
Constructor. Creates a new Parent. Inherits from Node (i.e., a node accepting children).
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 list (like Array#unshift).
sentence.tail; // fullStop
sentence.append(dogs);
sentence.tail; // dogs
Insert a child at the end of the list (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. Creates a new Child. Inherits from Node (i.e., a node accepting a parent).
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 node, null otherwise (when child
is the parents first child or detached).
cats.next; // fullStop
fullStop.next; // null
The next node, null otherwise (when child
is the parents last child or detached).
dogs.prev; // null
dogs.before(cats);
dogs.prev; // cats
Insert a given child before the operated on child in the parent.
cats.next; // null
cats.before(dogs);
cats.next; // dogs
Insert a given child after the operated on child in the 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 operated on child, and insert a given child at its previous position in the parent.
Constructor. Creates a new Element. Inherits from Parent and Child (i.e., a node accepting both children and a parent).
Constructor. Creates a new Element. Inherits from Child. Has a value.
dogs.toString(); // "Dogs"
space1.toString(); // " "
fullStop.toString(); // "."
Returns the internal value of a Text.
'' + root; // "Dogs & cats."
cats.fromString();
'' + root; // "Dogs & ."
cats.fromString("Cats");
'' + root; // "Dogs & Cats."
(Re)sets and returns the internal value of a Text with the stringified version of the given value.
cats.prev; // space1
cats.split(2);
'' + cats; // "ts"
'' + cats.prev; // "ca"
Split the node into two nodes, prepends a new node (an instance of the operated on text
s constructor), moving the internal value from 0–position to the prepended node, and removing it from the operated on node.
The following IDL document gives a short view of the defined interfaces by TextOM. Note: It not might be that valid in the eyes of W3C standardistas, buts its pretty readable for us simple developers :).
module textom
{
[Constructor]
interface Node {
const unsigned long ROOT_NODE = 1
const unsigned long PARAGRAPH_NODE = 2
const unsigned long SENTENCE_NODE = 3
const unsigned long WORD_NODE = 4
const unsigned long PUNCTUATION_NODE = 5
const unsigned long WHITE_SPACE_NODE = 6
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 unsigned long type = 1;
readonly attribute unsigned long hierarchy = 1;
};
RootNode implements Parent;
[Constructor]
interface ParagraphNode {
readonly attribute unsigned long type = 2;
readonly attribute unsigned long hierarchy = 2;
};
ParagraphNode implements Element;
[Constructor]
interface SentenceNode {
readonly attribute unsigned long type = 3;
readonly attribute unsigned long hierarchy = 3;
};
SentenceNode implements Element;
[Constructor(optional String value = "")]
interface WordNode {
readonly attribute unsigned long type = 4;
readonly attribute unsigned long hierarchy = 4;
};
WordNode implements Text;
[Constructor(optional String value = "")]
interface WhiteSpaceNode {
readonly attribute unsigned long type = 5;
};
WhiteSpaceNode implements Text;
[Constructor(optional String value = "")]
interface PunctuationNode {
readonly attribute unsigned long type = 6;
readonly attribute unsigned long hierarchy = 4;
};
PunctuationNode 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:
dogs.fromString('Poodles');
A "changetext"
event will fire on dogs, and because dogs is an instance of WordNode, the event will also fire on WordNode. Because a WordNode 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:
dogs.fromString('Poodles');
A "changetextinside"
event will fire on the parent of dogs (sentence), and because sentence is an instance of SentenceNode, this event will also fire on SentenceNode. The same would happen through sentences ancestors: paragraph and ParagraphNode, root and RootNode.
dogs.on('remove', function (parent) {
this === dogs; // true
parent === sentence; // true
})
dogs.remove();
Fired when a node is removed from its parent.
dogs.on('insert', function () {
this === dogs; // true
})
sentence.append(dogs);
Fired when a node is inserted into a parent.
dogs.on('changetext', function (value, previousValue) {
this === dogs; // true
value === 'Poodles'; // true
previousValue === 'Dogs'; // true
})
dogs.fromString('Poodles');
Fired when the internal value of an instance of Text (i.e., WhiteSpaceNode, PunctuationNode, or WordNode) 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 node, or inserting a node before the child).
prev
attribute, null otherwise;prev
node, null otherwise;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 node, or inserting a node after the child).
next
attribute, null otherwise;next
node, null otherwise;root.on('changetextinside', function (node, value, previousValue) {
this === root; // true
node === cats; // true
value === 'lions'; // true
previousValue === 'cats'; // true
})
cats.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 node is inserted inside an ancestor.
root.on('removeinside', function (node) {
this === root; // true
node === dogs; // true
})
dogs.remove();
Fired when a node 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.