upfront-editable
Version:
Friendly contenteditable API
161 lines (132 loc) • 5.72 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _keys = require('babel-runtime/core-js/object/keys');
var _keys2 = _interopRequireDefault(_keys);
var _jquery = require('jquery');
var _jquery2 = _interopRequireDefault(_jquery);
var _rangy = require('rangy');
var _rangy2 = _interopRequireDefault(_rangy);
var _content = require('./content');
var content = _interopRequireWildcard(_content);
var _highlightText2 = require('./highlight-text');
var _highlightText3 = _interopRequireDefault(_highlightText2);
var _textHighlighting = require('./plugins/highlighting/text-highlighting');
var _textHighlighting2 = _interopRequireDefault(_textHighlighting);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function isInHost(el, host) {
if (!el.closest) {
el = el.parentNode;
}
return el.closest('[data-editable]:not([data-word-id])') === host;
}
var highlightSupport = {
highlightText: function highlightText(editableHost, text, highlightId) {
if (this.hasHighlight(editableHost, highlightId)) return;
var blockText = _highlightText3.default.extractText(editableHost);
var marker = '<span class="highlight-comment"></span>';
var markerNode = highlightSupport.createMarkerNode(marker, 'highlight', this.win);
var textSearch = new _textHighlighting2.default(markerNode, 'text');
var matches = textSearch.findMatches(blockText, [text]);
if (matches && matches.length) {
if (highlightId) matches[0].id = highlightId;
_highlightText3.default.highlightMatches(editableHost, matches);
return matches[0].startIndex;
}
},
highlightRange: function highlightRange(editableHost, highlightId, startIndex, endIndex, dispatcher) {
if (this.hasHighlight(editableHost, highlightId)) {
this.removeHighlight(editableHost, highlightId);
}
var range = _rangy2.default.createRange();
range.selectCharacters(editableHost, startIndex, endIndex);
if (!isInHost(range.commonAncestorContainer, editableHost)) {
return -1;
}
var marker = highlightSupport.createMarkerNode('<span class="highlight-comment" data-word-id="' + highlightId + '"></span>', 'comment', this.win);
var fragment = range.extractContents();
marker.appendChild(fragment);
range.deleteContents();
range.insertNode(marker);
highlightSupport.cleanupStaleMarkerNodes(editableHost, 'comment');
if (dispatcher) {
dispatcher.notify('change', editableHost);
}
return startIndex;
},
updateHighlight: function updateHighlight(editableHost, highlightId, addCssClass, removeCssClass) {
if (!document.documentElement.classList) return;
(0, _jquery2.default)(editableHost).find('[data-word-id="' + highlightId + '"]').each(function (index, elem) {
if (removeCssClass) elem.classList.remove(removeCssClass);
if (addCssClass) elem.classList.add(addCssClass);
});
},
removeHighlight: function removeHighlight(editableHost, highlightId, dispatcher) {
(0, _jquery2.default)(editableHost).find('[data-word-id="' + highlightId + '"]').each(function (index, elem) {
content.unwrap(elem);
if (dispatcher) {
dispatcher.notify('change', editableHost);
}
});
},
hasHighlight: function hasHighlight(editableHost, highlightId) {
var matches = (0, _jquery2.default)(editableHost).find('[data-word-id="' + highlightId + '"]');
return !!matches.length;
},
extractHighlightedRanges: function extractHighlightedRanges(editableHost) {
var _this = this;
var markers = (0, _jquery2.default)(editableHost).find('[data-word-id]');
if (!markers.length) {
return;
}
var groups = {};
markers.each(function (_, marker) {
var highlightId = (0, _jquery2.default)(marker).data('word-id');
if (!groups[highlightId]) {
groups[highlightId] = (0, _jquery2.default)(editableHost).find('[data-word-id="' + highlightId + '"]');
}
});
var res = {};
(0, _keys2.default)(groups).forEach(function (highlightId) {
var position = _this.extractMarkerNodePosition(editableHost, groups[highlightId]);
if (position) {
res[highlightId] = position;
}
});
return res;
},
extractMarkerNodePosition: function extractMarkerNodePosition(editableHost, markers) {
var range = _rangy2.default.createRange();
if (markers.length > 1) {
range.setStartBefore(markers.first()[0]);
range.setEndAfter(markers.last()[0]);
} else {
range.selectNode(markers[0]);
}
var textRange = range.toCharacterRange(editableHost);
return {
start: textRange.start,
end: textRange.end,
text: range.text()
};
},
cleanupStaleMarkerNodes: function cleanupStaleMarkerNodes(editableHost, highlightType) {
editableHost.querySelectorAll('span[data-highlight="' + highlightType + '"]').forEach(function (node) {
if (!node.textContent.length) {
node.parentNode.removeChild(node);
}
});
},
createMarkerNode: function createMarkerNode(markerMarkup, highlightType, win) {
var marker = (0, _jquery2.default)(markerMarkup)[0];
if (win) {
marker = content.adoptElement(marker, win.document);
}
marker.setAttribute('data-editable', 'ui-unwrap');
marker.setAttribute('data-highlight', highlightType);
return marker;
}
};
exports.default = highlightSupport;