upfront-editable
Version:
Friendly contenteditable API
119 lines (102 loc) • 3.32 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _nodeType = require("./node-type");
// A DOM node iterator.
//
// Has the ability to replace nodes on the fly and continue
// the iteration.
var NodeIterator = /*#__PURE__*/function () {
function NodeIterator(root, method) {
(0, _classCallCheck2["default"])(this, NodeIterator);
this.current = this.previous = this.nextNode = this.root = root;
this.iteratorFunc = this[method || 'getNext'];
}
(0, _createClass2["default"])(NodeIterator, [{
key: Symbol.iterator,
value: function value() {
return this;
}
}, {
key: "getNextTextNode",
value: function getNextTextNode() {
var next;
while (next = this.getNext()) {
if (next.nodeType === _nodeType.textNode && next.data !== '') return next;
}
}
}, {
key: "getPreviousTextNode",
value: function getPreviousTextNode() {
var prev;
while (prev = this.getPrevious()) {
if (prev.nodeType === _nodeType.textNode && prev.data !== '') return prev;
}
}
}, {
key: "next",
value: function next() {
var value = this.iteratorFunc();
return value ? {
value: value
} : {
done: true
};
}
}, {
key: "getNext",
value: function getNext() {
var n = this.current = this.nextNode;
var child = this.nextNode = undefined;
if (this.current) {
child = n.firstChild; // Skip the children of elements with the attribute data-editable="remove"
// This prevents text nodes that are not part of the content to be included.
if (child && n.getAttribute('data-editable') !== 'remove') {
this.nextNode = child;
} else {
while (n !== this.root && !(this.nextNode = n.nextSibling)) {
n = n.parentNode;
}
}
}
return this.current;
}
}, {
key: "getPrevious",
value: function getPrevious() {
var n = this.current = this.previous;
var child = this.previous = undefined;
if (this.current) {
child = n.lastChild; // Skip the children of elements with the attribute data-editable="remove"
// This prevents text nodes that are not part of the content to be included.
if (child && n.getAttribute('data-editable') !== 'remove') {
this.previous = child;
} else {
while (n !== this.root && !(this.previous = n.previousSibling)) {
n = n.parentNode;
}
}
}
return this.current;
}
}, {
key: "replaceCurrent",
value: function replaceCurrent(replacement) {
this.current = replacement;
this.nextNode = undefined;
this.previous = undefined;
var n = this.current;
while (n !== this.root && !(this.nextNode = n.nextSibling)) {
n = n.parentNode;
}
}
}]);
return NodeIterator;
}();
exports["default"] = NodeIterator;
module.exports = exports.default;