Skip to content

Commit 97140e9

Browse files
committed
[CLEANUP] Improve documentation for Editor, Post, PostNodeBuilder, Range
1 parent 0822fa8 commit 97140e9

File tree

8 files changed

+158
-59
lines changed

8 files changed

+158
-59
lines changed

src/js/editor/editor.js

Lines changed: 62 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -78,21 +78,22 @@ const CALLBACK_QUEUES = {
7878
DID_REPARSE: 'didReparse'
7979
};
8080

81+
/**
82+
* The Editor is a core component of mobiledoc-kit. After instantiating
83+
* an editor, use {@link Editor#render} to display the editor on the web page.
84+
*
85+
* An editor uses a {@link Post} internally to represent the displayed document.
86+
* The post can be serialized as mobiledoc using {@link Editor#serialize}. Mobiledoc
87+
* is the transportable "over-the-wire" format (JSON) that is suited for persisting
88+
* and sharing between editors and renderers (for display, e.g.), whereas the Post
89+
* model is better suited for programmatic editing.
90+
*
91+
* The editor will call registered callbacks for certain state changes. These are:
92+
* * cursorDidChange
93+
* * didUpdate
94+
*/
8195
class Editor {
8296
/**
83-
* The Editor is a core component of mobiledoc-kit. After instantiating
84-
* an editor, use {@link Editor#render} to display the editor on the web page.
85-
*
86-
* An editor uses a {@link Post} internally to represent the displayed document.
87-
* The post can be serialized as mobiledoc using {@link Editor#serialize}. Mobiledoc
88-
* is the transportable "over-the-wire" format (JSON) that is suited for persisting
89-
* and sharing between editors and renderers (for display, e.g.), whereas the Post
90-
* model is better suited for programmatic editing.
91-
*
92-
* The editor will call registered callbacks for certain state changes. These are:
93-
* * cursorDidChange
94-
* * didUpdate
95-
*
9697
* @param {Object} [options]
9798
* @param {Object} [options.mobiledoc] The mobiledoc to load into the editor.
9899
* Supersedes `options.html`.
@@ -142,10 +143,10 @@ class Editor {
142143
this.hasRendered = false;
143144
}
144145

145-
addView(view) {
146-
this._views.push(view);
147-
}
148-
146+
/**
147+
* The editor's instance of a post node builder.
148+
* @type {PostNodeBuilder}
149+
*/
149150
get builder() {
150151
if (!this._builder) { this._builder = new PostNodeBuilder(); }
151152
return this._builder;
@@ -446,7 +447,7 @@ class Editor {
446447
}
447448

448449
/**
449-
* @return {array} The sections from the cursor's selection start to the selection end
450+
* @return {Section[]} The sections from the cursor's selection start to the selection end
450451
*/
451452
get activeSections() {
452453
return this._editState.activeSections;
@@ -468,6 +469,10 @@ class Editor {
468469
return this._editState.activeMarkups;
469470
}
470471

472+
/**
473+
* @param {Markup|String} markup A markup instance, or a string (e.g. "b")
474+
* @return {boolean}
475+
*/
471476
hasActiveMarkup(markup) {
472477
markup = this.builder._coerceMarkup(markup);
473478
return contains(this.activeMarkups, markup);
@@ -479,10 +484,9 @@ class Editor {
479484
}
480485

481486
/**
482-
* @public
483-
*
484-
* @param {string} version The mobiledoc version to serialize to.
487+
* @param {String} version The mobiledoc version to serialize to.
485488
* @return {Mobiledoc} Serialized mobiledoc
489+
* @public
486490
*/
487491
serialize(version=MOBILEDOC_VERSION) {
488492
return this.serializePost(this.post, 'mobiledoc', {version});
@@ -537,6 +541,10 @@ class Editor {
537541
}
538542
}
539543

544+
addView(view) {
545+
this._views.push(view);
546+
}
547+
540548
removeAllViews() {
541549
this._views.forEach((v) => v.destroy());
542550
this._views = [];
@@ -704,7 +712,7 @@ class Editor {
704712
}
705713

706714
/**
707-
* @param {Function} callback This callback will be called after the cursor
715+
* @param {Function} callback This callback will be called every time the cursor
708716
* position (or selection) changes.
709717
* @public
710718
*/
@@ -772,6 +780,16 @@ class Editor {
772780
});
773781
}
774782

783+
/**
784+
* Toggles the given markup at the editor's current {@link Range}.
785+
* If the range is collapsed this changes the editor's state so that the
786+
* next characters typed will be affected. If there is text selected
787+
* (aka a non-collapsed range), the selections' markup will be toggled.
788+
* If the editor is not focused and has no active range, nothing happens.
789+
* @param {String} markup E.g. "b", "em", "a"
790+
* @public
791+
* @see PostEditor#toggleMarkup
792+
*/
775793
toggleMarkup(markup) {
776794
markup = this.post.builder.createMarkup(markup);
777795
if (this.range.isCollapsed) {
@@ -822,6 +840,12 @@ class Editor {
822840
return false;
823841
}
824842

843+
/**
844+
* Inserts the text at the current cursor position. If the editor has
845+
* no current cursor position, nothing will be inserted.
846+
* @param {String} text
847+
* @public
848+
*/
825849
insertText(text) {
826850
let { activeMarkups, range, range: { head: position } } = this;
827851

@@ -859,6 +883,22 @@ class Editor {
859883
triggerEvent(context, eventName, event) {
860884
this._eventManager._trigger(context, eventName, event);
861885
}
886+
887+
addCallback(...args) {
888+
this._callbacks.addCallback(...args);
889+
}
890+
891+
addCallbackOnce(...args) {
892+
this._callbacks.addCallbackOnce(...args);
893+
}
894+
895+
runCallbacks(...args) {
896+
if (this._isDestroyed) {
897+
// warn -- should not run after destroyed
898+
return;
899+
}
900+
this._callbacks.runCallbacks(...args);
901+
}
862902
}
863903

864904
mixin(Editor, EventEmitter);

src/js/editor/post.js

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,22 @@ const CALLBACK_QUEUES = {
1818
AFTER_COMPLETE: 'afterComplete'
1919
};
2020

21+
/**
22+
* The PostEditor is used to modify a post. It should not be instantiated directly.
23+
* Instead, a new instance of a PostEditor is created by the editor and passed
24+
* as the argument to the callback in {@link Editor#run}.
25+
*
26+
* Usage:
27+
* ```
28+
* editor.run((postEditor) => {
29+
* // postEditor is an instance of PostEditor that can operate on the
30+
* // editor's post
31+
* });
32+
* ```
33+
*/
2134
class PostEditor {
2235
/**
23-
* The PostEditor is used to modify a post. It should not be instantiated directly.
24-
* Instead, a new instance of a PostEditor is created by the editor and passed
25-
* as the argument to the callback in {@link Editor#run}.
26-
*
27-
* Usage:
28-
* ```
29-
* editor.run((postEditor) => {
30-
* // postEditor is an instance of PostEditor that can operate on the
31-
* // editor's post
32-
* });
33-
* ```
34-
* @param {Editor} editor
35-
* @class PostEditor
36+
* @private
3637
*/
3738
constructor(editor) {
3839
this.editor = editor;

src/js/models/post-node-builder.js

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,25 @@ function findMarkupInCache(cache, tagName, attributes) {
3434
return cache[key];
3535
}
3636

37-
export default class PostNodeBuilder {
37+
/**
38+
* The PostNodeBuilder is used to create new {@link Post} primitives, such
39+
* as a MarkupSection, a CardSection, a Markup, etc. Every instance of an
40+
* {@link Editor} has its own builder instance. The builder can be used
41+
* inside an {@link Editor#run} callback to programmatically create new
42+
* Post primitives to insert into the document.
43+
* A PostNodeBuilder should be read from the Editor, *not* instantiated on its own.
44+
*/
45+
class PostNodeBuilder {
46+
/**
47+
* @private
48+
*/
3849
constructor() {
3950
this.markupCache = {};
4051
}
4152

53+
/**
54+
* @return {Post} A new, blank post
55+
*/
4256
createPost(sections=[]) {
4357
const post = new Post();
4458
post.builder = this;
@@ -59,6 +73,11 @@ export default class PostNodeBuilder {
5973
}
6074
}
6175

76+
/**
77+
* @param {tagName} [tagName='P']
78+
* @param {Marker[]} [markers=[]]
79+
* @return {MarkupSection}
80+
*/
6281
createMarkupSection(tagName=DEFAULT_MARKUP_SECTION_TAG_NAME, markers=[], isGenerated=false) {
6382
tagName = normalizeTagName(tagName);
6483
const section = new MarkupSection(tagName, markers);
@@ -91,26 +110,45 @@ export default class PostNodeBuilder {
91110
return section;
92111
}
93112

113+
/**
114+
* @param {String} name
115+
* @param {Object} [payload={}]
116+
* @return {CardSection}
117+
*/
94118
createCardSection(name, payload={}) {
95119
const card = new Card(name, payload);
96120
card.builder = this;
97121
return card;
98122
}
99123

124+
/**
125+
* @param {String} value
126+
* @param {Markup[]} [markups=[]]
127+
* @return {Marker}
128+
*/
100129
createMarker(value, markups=[]) {
101130
const marker = new Marker(value, markups);
102131
marker.builder = this;
103132
return marker;
104133
}
105134

135+
/**
136+
* @param {String} name
137+
* @param {String} [text='']
138+
* @param {Object} [payload={}]
139+
* @param {Markup[]} [markups=[]]
140+
* @return {Atom}
141+
*/
106142
createAtom(name, text='', payload={}, markups=[]) {
107143
const atom = new Atom(name, text, payload, markups);
108144
atom.builder = this;
109145
return atom;
110146
}
111147

112148
/**
113-
* @param {Object} attributes {key:value}
149+
* @param {String} tagName
150+
* @param {Object} attributes Key-value pairs of attributes for the markup
151+
* @return {Markup}
114152
*/
115153
createMarkup(tagName, attributes={}) {
116154
tagName = normalizeTagName(tagName);
@@ -128,9 +166,12 @@ export default class PostNodeBuilder {
128166
/**
129167
* @param {Markup|String} markupOrString
130168
* @return {Markup}
169+
* @private
131170
*/
132171
_coerceMarkup(markupOrString, attributes={}) {
133172
let tagName = typeof markupOrString === 'string' ? markupOrString : markupOrString.tagName;
134173
return this.createMarkup(tagName, attributes);
135174
}
136175
}
176+
177+
export default PostNodeBuilder;

src/js/models/post.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ import deprecate from 'mobiledoc-kit/utils/deprecate';
1414
* text) or non-markerable (e.g., a card).
1515
* When persisting a post, it must first be serialized (loss-lessly) into
1616
* mobiledoc using {@link Editor#serialize}.
17-
* @class Post
1817
*/
19-
export default class Post {
18+
class Post {
19+
/**
20+
* @private
21+
*/
2022
constructor() {
2123
this.type = POST_TYPE;
2224
this.sections = new LinkedList({
@@ -284,3 +286,5 @@ export default class Post {
284286
return post;
285287
}
286288
}
289+
290+
export default Post;

src/js/parsers/dom.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,11 @@ function walkMarkerableNodes(parent, callback) {
8989
}
9090
}
9191

92-
export default class DOMParser {
93-
/**
94-
* Parses DOM element -> Post
95-
*/
92+
/**
93+
* Parses DOM element -> Post
94+
* @private
95+
*/
96+
class DOMParser {
9697
constructor(builder, options={}) {
9798
this.builder = builder;
9899
this.sectionParser = new SectionParser(this.builder, options);
@@ -299,3 +300,5 @@ export default class DOMParser {
299300
}
300301
}
301302
}
303+
304+
export default DOMParser;

src/js/parsers/section.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,12 @@ const SKIPPABLE_ELEMENT_TAG_NAMES = [
4444
'style', 'head', 'title', 'meta'
4545
].map(normalizeTagName);
4646

47-
export default class SectionParser {
48-
/**
49-
* parses an element into a section, ignoring any non-markup
50-
* elements contained within
51-
*/
47+
/**
48+
* parses an element into a section, ignoring any non-markup
49+
* elements contained within
50+
* @private
51+
*/
52+
class SectionParser {
5253
constructor(builder, options={}) {
5354
this.builder = builder;
5455
this.plugins = options.plugins || [];
@@ -302,3 +303,5 @@ export default class SectionParser {
302303
normalizeTagName(element.tagName)));
303304
}
304305
}
306+
307+
export default SectionParser;

0 commit comments

Comments
 (0)