Created
December 23, 2017 05:38
-
-
Save NetOpWibby/aa9ec6a89981474e3503a96286d7ab7c to your computer and use it in GitHub Desktop.
I struggled with webpack to make this work. UGH.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function webpackUniversalModuleDefinition(root, factory) { | |
if(typeof exports === 'object' && typeof module === 'object') | |
module.exports = factory(); | |
else if(typeof define === 'function' && define.amd) | |
define([], factory); | |
else { | |
var a = factory(); | |
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; | |
} | |
})(typeof self !== 'undefined' ? self : this, function() { | |
return /******/ (function(modules) { // webpackBootstrap | |
/******/ // The module cache | |
/******/ var installedModules = {}; | |
/******/ | |
/******/ // The require function | |
/******/ function __webpack_require__(moduleId) { | |
/******/ | |
/******/ // Check if module is in cache | |
/******/ if(installedModules[moduleId]) { | |
/******/ return installedModules[moduleId].exports; | |
/******/ } | |
/******/ // Create a new module (and put it into the cache) | |
/******/ var module = installedModules[moduleId] = { | |
/******/ i: moduleId, | |
/******/ l: false, | |
/******/ exports: {} | |
/******/ }; | |
/******/ | |
/******/ // Execute the module function | |
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); | |
/******/ | |
/******/ // Flag the module as loaded | |
/******/ module.l = true; | |
/******/ | |
/******/ // Return the exports of the module | |
/******/ return module.exports; | |
/******/ } | |
/******/ | |
/******/ | |
/******/ // expose the modules object (__webpack_modules__) | |
/******/ __webpack_require__.m = modules; | |
/******/ | |
/******/ // expose the module cache | |
/******/ __webpack_require__.c = installedModules; | |
/******/ | |
/******/ // define getter function for harmony exports | |
/******/ __webpack_require__.d = function(exports, name, getter) { | |
/******/ if(!__webpack_require__.o(exports, name)) { | |
/******/ Object.defineProperty(exports, name, { | |
/******/ configurable: false, | |
/******/ enumerable: true, | |
/******/ get: getter | |
/******/ }); | |
/******/ } | |
/******/ }; | |
/******/ | |
/******/ // getDefaultExport function for compatibility with non-harmony modules | |
/******/ __webpack_require__.n = function(module) { | |
/******/ var getter = module && module.__esModule ? | |
/******/ function getDefault() { return module['default']; } : | |
/******/ function getModuleExports() { return module; }; | |
/******/ __webpack_require__.d(getter, 'a', getter); | |
/******/ return getter; | |
/******/ }; | |
/******/ | |
/******/ // Object.prototype.hasOwnProperty.call | |
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; | |
/******/ | |
/******/ // __webpack_public_path__ | |
/******/ __webpack_require__.p = ""; | |
/******/ | |
/******/ // Load entry module and return exports | |
/******/ return __webpack_require__(__webpack_require__.s = 5); | |
/******/ }) | |
/************************************************************************/ | |
/******/ ([ | |
/* 0 */ | |
/***/ (function(module, __webpack_exports__, __webpack_require__) { | |
"use strict"; | |
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return clean; }); | |
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_priority__ = __webpack_require__(2); | |
function clean(updatedBlock) { | |
for (var key in updatedBlock.ranges) { | |
updatedBlock.ranges[key] = cleanRanges(updatedBlock.ranges[key]); | |
} | |
return updatedBlock; | |
}; | |
function cleanRanges(ranges) { | |
ranges = new __WEBPACK_IMPORTED_MODULE_0__utils_priority__["a" /* Priority */]({ | |
prioritize: [{ | |
name: 'start', | |
priority: 'min' | |
}, { | |
name: 'end', | |
priority: 'max' | |
}], | |
initialNodes: ranges.slice() | |
}); | |
var cleanedRanges = []; | |
if (!ranges.peek()) { | |
return cleanedRanges; | |
} | |
var current = ranges.pop(); | |
var next; | |
if (!ranges.peek()) { | |
cleanedRanges.push(current); | |
} | |
while (ranges.peek()) { | |
next = ranges.pop(); | |
// overlapping | |
// current wholey contains next | |
// c -------------- | |
// n ----- | |
if (current.start <= next.start && current.end >= next.end) { | |
next = null; | |
// re-use current | |
} | |
// overlapping | |
// current left of next | |
// c ---------- | |
// n ------- | |
else if (current.start < next.start && current.end >= next.start) { | |
current.end = next.end; | |
next = null; | |
// re-use current | |
} | |
if (ranges.peek() && next === null) { | |
continue; | |
} else if (!ranges.peek() && next !== null) { | |
cleanedRanges.push(current); | |
cleanedRanges.push(next); | |
} else { | |
cleanedRanges.push(current); | |
current = next; | |
} | |
} | |
return cleanedRanges; | |
} | |
/* unused harmony default export */ var _unused_webpack_default_export = (clean); | |
/***/ }), | |
/* 1 */ | |
/***/ (function(module, __webpack_exports__, __webpack_require__) { | |
"use strict"; | |
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return updateRanges; }); | |
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return updateBlockRanges; }); | |
function updateRanges(ranges, index, length) { | |
var updated = []; | |
var current; | |
for (var i = 0; i < ranges.length; i++) { | |
current = ranges[i]; | |
// if adding text | |
if (length >= 0) { | |
// previously shrunk range, now to be expanded | |
if (index === current.start && index === current.end) { | |
current.end += length; | |
} | |
// if index is left of start, change start and end by length | |
// i | |
// c -------------- | |
else if (index <= current.start) { | |
current.start += length; | |
current.end += length; | |
} | |
// if index is right of start, but left of end, change end by length | |
// i | |
// c ---------- | |
else if (index >= current.start && index <= current.end) { | |
current.end += length; | |
} | |
// if index is right of end, do nothing | |
// i | |
// c ---- | |
else {} | |
// do nothing | |
// removing text | |
} else { | |
if (index === current.start && index === current.end) { | |
// do nothing, delete this range | |
continue; | |
} | |
// if index is left of start, change start and end by length | |
// i | |
// c -------------- | |
else if (index <= current.start) { | |
current.start += length; | |
current.end += length; | |
} | |
// if index is right of start, but left of end, change end by length | |
// i | |
// c ---------- | |
else if (index >= current.start && index <= current.end) { | |
// but what if the index change goes leftward past start of c? | |
if (current.start > index + length && index === current.end) { | |
// delete range, dont push to update | |
continue; | |
} else if (current.start > index + length) { | |
current.start += length; | |
if (current.start < 0) { | |
current.start = 0; | |
} | |
} | |
current.end += length; | |
} | |
// if index is right of end, do nothing | |
// i | |
// c ---- | |
else { | |
// but what if the index change goes leftward past end of c? | |
// if goes past c end, change end by length | |
if (current.end > index + length) { | |
current.end = index + length; | |
} | |
// but what if the index change goes leftward past start of c? | |
if (current.start >= index + length) { | |
// delete range, dont push to update | |
continue; | |
} | |
} | |
} | |
updated.push(current); | |
} | |
return updated; | |
} | |
function updateBlockRanges(blockRanges, index, length) { | |
var ranges = {}; | |
for (var key in blockRanges) { | |
ranges[key] = updateRanges(blockRanges[key], index, length); | |
} | |
return ranges; | |
} | |
/* unused harmony default export */ var _unused_webpack_default_export = (updateRanges); | |
/***/ }), | |
/* 2 */ | |
/***/ (function(module, __webpack_exports__, __webpack_require__) { | |
"use strict"; | |
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return Priority; }); | |
function Priority(options) { | |
var arr = options.initialNodes || []; | |
this.arr = arr.slice(); | |
this.prioritize = options.prioritize; | |
if (this.arr.length) { | |
this.add(); | |
} | |
} | |
Priority.prototype.add = function (node) { | |
var self = this; | |
if (node !== undefined) { | |
this.arr.push(node); | |
} | |
this.arr.sort(function (a, b) { | |
var firstCompare = self.compare(a, b, self.prioritize[0].name, self.prioritize[0].priority); | |
if (0 === firstCompare) { | |
if (self.prioritize[1]) { | |
var secondCompare = self.compare(a, b, self.prioritize[1].name, self.prioritize[1].priority); | |
return secondCompare; | |
} | |
} | |
return firstCompare; | |
}); | |
}; | |
Priority.prototype.pop = function (node) { | |
return this.arr.shift(); | |
}; | |
Priority.prototype.peek = function (node) { | |
return this.arr.length ? this.arr[0] : undefined; | |
}; | |
Priority.prototype.compare = function (a, b, prop, minOrMax) { | |
if (minOrMax === 'min') { | |
if (a[prop] > b[prop]) { | |
return 1; | |
} else if (a[prop] < b[prop]) { | |
return -1; | |
} else { | |
return 0; | |
} | |
} | |
if (minOrMax === 'max') { | |
if (a[prop] > b[prop]) { | |
return -1; | |
} else if (a[prop] < b[prop]) { | |
return 1; | |
} else { | |
return 0; | |
} | |
} | |
}; | |
Priority.prototype.toArray = function () { | |
return this.arr.slice(); | |
}; | |
/* unused harmony default export */ var _unused_webpack_default_export = (Priority); | |
/***/ }), | |
/* 3 */ | |
/***/ (function(module, __webpack_exports__, __webpack_require__) { | |
"use strict"; | |
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return insertText; }); | |
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__update_ranges__ = __webpack_require__(1); | |
function insertText(block, index, charsToInsert) { | |
var rawTextArr = block.rawText.split(''); | |
rawTextArr.splice(index, 0, charsToInsert); | |
var ranges = {}; | |
for (var key in block.ranges) { | |
ranges[key] = Object(__WEBPACK_IMPORTED_MODULE_0__update_ranges__["b" /* updateRanges */])(block.ranges[key], index, charsToInsert.length); | |
} | |
block.ranges = ranges; | |
block.rawText = rawTextArr.join(''); | |
return block; | |
} | |
/* unused harmony default export */ var _unused_webpack_default_export = (insertText); | |
/***/ }), | |
/* 4 */ | |
/***/ (function(module, __webpack_exports__, __webpack_require__) { | |
"use strict"; | |
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return removeText; }); | |
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__update_ranges__ = __webpack_require__(1); | |
function removeText(block, index, length) { | |
var rawTextArr = block.rawText.split(''); | |
rawTextArr.splice(index - length, length); | |
var ranges = {}; | |
for (var key in block.ranges) { | |
ranges[key] = Object(__WEBPACK_IMPORTED_MODULE_0__update_ranges__["b" /* updateRanges */])(block.ranges[key], index, -length); | |
} | |
block.ranges = ranges; | |
block.rawText = rawTextArr.join(''); | |
return block; | |
} | |
/* unused harmony default export */ var _unused_webpack_default_export = (removeText); | |
/***/ }), | |
/* 5 */ | |
/***/ (function(module, __webpack_exports__, __webpack_require__) { | |
"use strict"; | |
Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); | |
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Main", function() { return Main; }); | |
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__render_render_block__ = __webpack_require__(6); | |
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__model_apply_range__ = __webpack_require__(7); | |
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__model_clean__ = __webpack_require__(0); | |
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__handlers_input_handlers__ = __webpack_require__(8); | |
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__handlers_el_handlers__ = __webpack_require__(9); | |
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__cursor_get_cursor__ = __webpack_require__(12); | |
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__cursor_restore_cursor__ = __webpack_require__(13); | |
function Main(config) { | |
var self = this; | |
this.el = config.el; | |
this.debugEl = config.debugEl; | |
this.testUiEl = config.testUiEl; | |
this.data = config.data; | |
if (this.el) { | |
this.hiddenInput = document.createElement('textarea'); | |
this.hiddenInput.style.width = this.el.offsetWidth; | |
document.body.appendChild(this.hiddenInput); | |
this.el.setAttribute('contentEditable', true); | |
this.el.style.whiteSpace = 'pre'; | |
this.render(); | |
// EL HANDLERS | |
this.el.addEventListener('change', function (e) { | |
if (self.el.offsetWidth !== self.hiddenInput.offsetWidth) { | |
self.hiddenInput.style.width = self.el.offsetWidth; | |
} | |
}); | |
this.el.addEventListener('blur', function (e) { | |
// cache cursor for when clicking on styling UI | |
var cursor = self.getCursor(); | |
if (cursor) { | |
self.cursor = cursor; | |
} | |
return true; | |
}); | |
this.el.addEventListener('keydown', Object(__WEBPACK_IMPORTED_MODULE_4__handlers_el_handlers__["a" /* elKeydownHandler */])(self)); | |
// INPUT HANDLERS | |
this.hiddenInput.addEventListener('compositionstart', Object(__WEBPACK_IMPORTED_MODULE_3__handlers_input_handlers__["b" /* inputCompositionstartHandler */])(self)); | |
this.hiddenInput.addEventListener('compositionend', Object(__WEBPACK_IMPORTED_MODULE_3__handlers_input_handlers__["a" /* inputCompositionendHandler */])(self)); | |
this.hiddenInput.addEventListener('keydown', Object(__WEBPACK_IMPORTED_MODULE_3__handlers_input_handlers__["d" /* inputKeydownHandler */])(self)); | |
this.hiddenInput.addEventListener('input', Object(__WEBPACK_IMPORTED_MODULE_3__handlers_input_handlers__["c" /* inputInputHandler */])(self)); | |
window._testTome = this; | |
} | |
} | |
Main.prototype.applyRange = function (range) { | |
this.cursor = this.cursor || this.getCursor(); | |
if (!this.cursor) { | |
return; | |
} | |
var cursor = this.cursor; | |
var blockStart = cursor.startPath.slice(0, -1).pop(); | |
var blockEnd = cursor.endPath.slice(0, -1).pop(); | |
range.start = range.start || cursor.startPath.slice().pop(); | |
range.end = range.end || cursor.endPath.slice().pop(); | |
for (var i = blockStart; i !== blockEnd + 1; i++) { | |
this.data.blocks[i].ranges[range.name] = Object(__WEBPACK_IMPORTED_MODULE_1__model_apply_range__["a" /* applyRange */])(this.data.blocks[i].ranges[range.name], { | |
start: i === blockStart ? range.start : 0, | |
end: i === blockEnd ? range.end : this.data.blocks[i].rawText.length, | |
name: range.name, | |
value: range.value | |
}); | |
this.data.blocks[i] = Object(__WEBPACK_IMPORTED_MODULE_2__model_clean__["a" /* clean */])(this.data.blocks[i]); | |
} | |
this.render(); | |
this.restoreCursor(); | |
}; | |
Main.prototype.render = function () { | |
if (this.el) { | |
this.el.innerHTML = Object(__WEBPACK_IMPORTED_MODULE_0__render_render_block__["a" /* renderBlocks */])(this.data); | |
} else { | |
return Object(__WEBPACK_IMPORTED_MODULE_0__render_render_block__["a" /* renderBlocks */])(this.data); | |
} | |
if (this.debugEl) { | |
this.debugEl.innerHTML = `<pre>${JSON.stringify(this.data, null, 4)}</pre>`; | |
} | |
}; | |
Main.prototype.getCursor = function () { | |
return __WEBPACK_IMPORTED_MODULE_5__cursor_get_cursor__["a" /* getCursor */].call(this); | |
}; | |
Main.prototype.restoreCursor = function (cursor) { | |
__WEBPACK_IMPORTED_MODULE_6__cursor_restore_cursor__["a" /* restoreCursor */].call(this, cursor); | |
}; | |
Main.prototype.createTestUI = function (UI) { | |
var self = this; | |
if (this.testUiEl) { | |
var uiContainer = document.createElement('DIV'); | |
for (var i = 0; i < UI.length; i++) { | |
var data = UI[i]; | |
switch (data.el) { | |
case 'button': | |
var el = document.createElement('BUTTON'); | |
el.innerHTML = data.label; | |
el.addEventListener(data.event, data.handler(self)); | |
break; | |
} | |
uiContainer.appendChild(el); | |
} | |
this.testUiEl.innerHTML = ''; | |
this.testUiEl.appendChild(uiContainer); | |
} | |
}; | |
if (window) { | |
window.Tome = Main; | |
} | |
/* harmony default export */ __webpack_exports__["default"] = (Main); | |
/***/ }), | |
/* 6 */ | |
/***/ (function(module, __webpack_exports__, __webpack_require__) { | |
"use strict"; | |
/* unused harmony export renderBlock */ | |
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return renderBlocks; }); | |
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_priority__ = __webpack_require__(2); | |
function flattenRanges(obj) { | |
var arr = []; | |
for (var key in obj) { | |
arr.push(obj[key]); | |
} | |
return Array.prototype.concat.apply([], arr); | |
} | |
// serializes block model to to string representation of HTML | |
function renderBlock(block) { | |
var text = '<' + block.blockType.toLowerCase() + '>'; | |
// lowest start index has highest priority | |
// if two have same start index, the highest max index has priority | |
var toBeOpened = new __WEBPACK_IMPORTED_MODULE_0__utils_priority__["a" /* Priority */]({ | |
prioritize: [{ | |
name: 'start', | |
priority: 'min' | |
}, { | |
name: 'end', | |
priority: 'max' | |
}], | |
initialNodes: flattenRanges(block.ranges) | |
}); | |
// lowest end index value has highest priority | |
var toBeClosed = new __WEBPACK_IMPORTED_MODULE_0__utils_priority__["a" /* Priority */]({ | |
prioritize: [{ | |
name: 'end', | |
priority: 'min' | |
}] | |
}); | |
var char; | |
for (var i = 0; i < block.rawText.length; i++) { | |
char = block.rawText[i]; | |
if (toBeOpened.peek() && i === toBeOpened.peek().start) { | |
while (toBeOpened.peek() && i === toBeOpened.peek().start && toBeOpened.peek().end === toBeOpened.peek().start) { | |
toBeOpened.pop(); | |
} | |
text = openTags(text, i, toBeOpened, toBeClosed); | |
} | |
// render soft breaks | |
if (char === '\n') { | |
// use a zero width character to stand in for \n, | |
// so that our range code isnt off by one when subing out \n for <br> | |
text += '<br>​'; | |
} else { | |
text += char; | |
} | |
if (toBeClosed.peek() && i === toBeClosed.peek().end - 1) { | |
text = closeTags(text, i, toBeOpened, toBeClosed); | |
} | |
} | |
// if no characters, need a BR for something to click the cursor into | |
if (!char) { | |
text += '<br>'; | |
} | |
return text + '</' + block.blockType.toLowerCase() + '>'; | |
} | |
// newTag = toBeOpened.pop() | |
// lastOpen = toBeClosed.peek() | |
// if newTag.end > lastOpen.end, | |
// you need to close lastOpen, and re-open lastOpen after newTag | |
function openTags(text, i, toBeOpened, toBeClosed) { | |
if (toBeOpened.peek() && i === toBeOpened.peek().start) { | |
var range = toBeOpened.pop(); | |
if (toBeClosed.peek() && range.end > toBeClosed.peek().end) { | |
// NEED TO CLOSE ALL toBeCLosed, | |
// and REOPEN by closing latest priority (include the new range in this priority) | |
for (var j = 0; j < toBeClosed.toArray().length; j++) { | |
text = closeSpan(text, {}); | |
} | |
var reOpen = new __WEBPACK_IMPORTED_MODULE_0__utils_priority__["a" /* Priority */]({ | |
prioritize: [{ | |
name: 'end', | |
priority: 'max' | |
}], | |
initialNodes: toBeClosed.toArray().concat(range) | |
}); | |
while (reOpen.peek()) { | |
text = openSpan(text, reOpen.pop()); | |
} | |
} else { | |
text = openSpan(text, range); | |
} | |
toBeClosed.add(range); | |
text = openTags(text, i, toBeOpened, toBeClosed); | |
} | |
return text; | |
} | |
function closeTags(text, i, toBeOpened, toBeClosed) { | |
if (toBeClosed.peek() && i === toBeClosed.peek().end - 1) { | |
text = closeSpan(text, toBeClosed.pop()); | |
text = closeTags(text, i, toBeOpened, toBeClosed); | |
} | |
return text; | |
} | |
function openSpan(text, style) { | |
return text + '<span style="' + toCSSName(style.name) + ': ' + (style.value || '') + (style.unit || '') + ';">'; | |
} | |
function closeSpan(text, style) { | |
return text += '</span>'; | |
} | |
function toCSSName(str) { | |
return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); | |
} | |
function renderBlocks(data) { | |
var text = ''; | |
for (var block in data.blocks) { | |
text += renderBlock(data.blocks[block]); | |
} | |
return text; | |
} | |
/* unused harmony default export */ var _unused_webpack_default_export = (renderBlock); | |
/***/ }), | |
/* 7 */ | |
/***/ (function(module, __webpack_exports__, __webpack_require__) { | |
"use strict"; | |
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return applyRange; }); | |
function applyRange(ranges = [], newRange) { | |
// need to iterate the entire ranges array | |
// shrink ALL conflicting ranges (same type, different value) | |
// then insert the newRange at the very end | |
var deconflictedRanges = []; | |
var current; | |
for (var i = 0; i < ranges.length; i++) { | |
current = ranges[i]; | |
// let cleanRanges deal with deduping same value ranges | |
if (current.value === newRange.value) { | |
deconflictedRanges.push(current); | |
continue; | |
} | |
// different value, need to check | |
// overlapping | |
// current wholey contains new | |
// c -------------- | |
// n ----- | |
if (current.start <= newRange.start && current.end >= newRange.end) { | |
// need to split current into two ranges | |
// c --- n ---- c ---- | |
// current1 current start with new's start as end | |
// current2 new end current end | |
deconflictedRanges.push({ | |
name: current.name, | |
value: current.value, | |
start: current.start, | |
end: newRange.start | |
}); | |
deconflictedRanges.push({ | |
name: current.name, | |
value: current.value, | |
start: newRange.end, | |
end: current.end | |
}); | |
} | |
// overlapping | |
// current contained wholey inside new | |
// n -------------- | |
// c ---- | |
else if (newRange.start <= current.start && newRange.end >= current.end) { | |
continue; | |
} | |
// overlapping | |
// current left of new | |
// c ---------- | |
// n ------- | |
else if (current.start < newRange.start && current.end >= newRange.start) { | |
// need to subtract from current's end property | |
// c --- n ------ | |
current.end = newRange.start; | |
deconflictedRanges.push(current); | |
} | |
// overlapping | |
// current right of new | |
// n -------- | |
// c ------- | |
else if (newRange.start < current.start && newRange.end >= current.start) { | |
// need to add to current's start property | |
// n ------- c--- | |
current.start = newRange.end; | |
deconflictedRanges.push(current); | |
} else { | |
deconflictedRanges.push(current); | |
} | |
} | |
deconflictedRanges.push(newRange); | |
return deconflictedRanges; | |
} | |
/* unused harmony default export */ var _unused_webpack_default_export = (applyRange); | |
/***/ }), | |
/* 8 */ | |
/***/ (function(module, __webpack_exports__, __webpack_require__) { | |
"use strict"; | |
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return inputInputHandler; }); | |
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "d", function() { return inputKeydownHandler; }); | |
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return inputCompositionstartHandler; }); | |
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return inputCompositionendHandler; }); | |
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__model_clean__ = __webpack_require__(0); | |
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__model_insert_text__ = __webpack_require__(3); | |
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__model_remove_text__ = __webpack_require__(4); | |
function inputInputHandler(self) { | |
return function (e) { | |
var input = this; | |
var blockStart = self.cursor.startPath.slice(0, -1).pop(); | |
var cursorStart = self.cursor.startPath.slice().pop(); | |
var cursorEnd = self.cursor.endPath.slice().pop(); | |
// text composition | |
if (self.composition !== undefined) { | |
var chars = input.value.slice(self.composition.index, input.selectionEnd); | |
if (self.composition.state === 'start') { | |
self.data.blocks[blockStart] = Object(__WEBPACK_IMPORTED_MODULE_0__model_clean__["a" /* clean */])(Object(__WEBPACK_IMPORTED_MODULE_1__model_insert_text__["a" /* insertText */])(self.data.blocks[blockStart], self.composition.index, chars)); | |
self.render(); | |
self.composition.state = 'composing'; | |
} else if (self.composition.state === 'composing') { | |
self.data.blocks[blockStart] = Object(__WEBPACK_IMPORTED_MODULE_0__model_clean__["a" /* clean */])(Object(__WEBPACK_IMPORTED_MODULE_2__model_remove_text__["a" /* removeText */])(self.data.blocks[blockStart], self.composition.index + 1, chars.length)); | |
self.data.blocks[blockStart] = Object(__WEBPACK_IMPORTED_MODULE_0__model_clean__["a" /* clean */])(Object(__WEBPACK_IMPORTED_MODULE_1__model_insert_text__["a" /* insertText */])(self.data.blocks[blockStart], self.composition.index, chars)); | |
self.render(); | |
} else if (self.composition.state === 'end') { | |
self.data.blocks[blockStart] = Object(__WEBPACK_IMPORTED_MODULE_0__model_clean__["a" /* clean */])(Object(__WEBPACK_IMPORTED_MODULE_2__model_remove_text__["a" /* removeText */])(self.data.blocks[blockStart], self.composition.index + 1, chars.length)); | |
self.data.blocks[blockStart] = Object(__WEBPACK_IMPORTED_MODULE_0__model_clean__["a" /* clean */])(Object(__WEBPACK_IMPORTED_MODULE_1__model_insert_text__["a" /* insertText */])(self.data.blocks[blockStart], self.composition.index, chars)); | |
self.cursor.startPath.pop(); | |
self.cursor.startPath.push(input.selectionStart); | |
// self.cursor.start = input.selectionStart; | |
self.cursor.endPath.pop(); | |
self.cursor.endPath.push(input.selectionEnd); | |
// self.cursor.end = input.selectionEnd; | |
self.render(); | |
self.restoreCursor(); | |
self.composition = undefined; | |
} | |
return; | |
} | |
// regular text insertion | |
if (cursorStart === cursorEnd && input.selectionStart > cursorStart) { | |
var chars = input.value.slice(cursorStart, input.selectionStart); | |
self.data.blocks[blockStart] = Object(__WEBPACK_IMPORTED_MODULE_0__model_clean__["a" /* clean */])(Object(__WEBPACK_IMPORTED_MODULE_1__model_insert_text__["a" /* insertText */])(self.data.blocks[blockStart], cursorStart, chars)); | |
self.cursor.startPath.pop(); | |
self.cursor.startPath.push(input.selectionStart); | |
self.cursor.endPath.pop(); | |
self.cursor.endPath.push(input.selectionStart); | |
} | |
self.render(); | |
self.restoreCursor(); | |
}; | |
} | |
function inputKeydownHandler(self) { | |
return function (e) { | |
// prevent starting any new compositions when in the input | |
if (e.altKey) { | |
e.preventDefault(); | |
e.stopPropagation(); | |
return false; | |
} | |
}; | |
} | |
// http://blog.evanyou.me/2014/01/03/composition-event/ | |
function inputCompositionstartHandler(self) { | |
return function (e) { | |
var input = this; | |
self.composition = { | |
state: 'start', | |
index: input.selectionStart | |
}; | |
}; | |
} | |
function inputCompositionendHandler(self) { | |
return function (e) { | |
self.composition = { | |
state: 'end', | |
index: self.composition.index | |
}; | |
}; | |
} | |
/***/ }), | |
/* 9 */ | |
/***/ (function(module, __webpack_exports__, __webpack_require__) { | |
"use strict"; | |
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return elKeydownHandler; }); | |
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__model_clean__ = __webpack_require__(0); | |
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__model_insert_text__ = __webpack_require__(3); | |
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__model_remove_text__ = __webpack_require__(4); | |
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__model_merge_blocks__ = __webpack_require__(10); | |
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__model_split_block__ = __webpack_require__(11); | |
function elKeydownHandler(self) { | |
return function (e) { | |
// http://www.quirksmode.org/js/keys.html | |
// hot keys | |
if (e.metaKey || e.ctrlKey) { | |
switch (e.keyCode) { | |
case 73: | |
// i | |
e.preventDefault(); | |
e.stopPropagation(); | |
self.applyRange({ name: 'fontStyle', value: 'italic' }); | |
return false; | |
case 66: | |
// b | |
e.preventDefault(); | |
e.stopPropagation(); | |
self.applyRange({ name: 'fontWeight', value: 700 }); | |
return false; | |
case 85: | |
// u | |
e.preventDefault(); | |
e.stopPropagation(); | |
self.applyRange({ name: 'textDecoration', value: 'underline' }); | |
return false; | |
} | |
} | |
switch (e.keyCode) { | |
// ARROWS | |
case 37: // left | |
case 39: // right | |
case 38: // up | |
case 40: | |
// down | |
break; | |
case 13: | |
// enter | |
e.preventDefault(); | |
e.stopPropagation(); | |
if (e.shiftKey) { | |
interceptCrossBlockChanges.call(self); | |
handleShiftEnter.call(self); | |
} else { | |
interceptCrossBlockChanges.call(self); | |
handleEnter.call(self); | |
} | |
return false; | |
case 27: // escape | |
case 16: // shift | |
case 18: // alt / option | |
case 91: // command/meta | |
case 93: | |
// command/meta | |
break; | |
// case 9: // tab | |
// break; | |
// case ??: // fn ? | |
// fn keys? | |
case 46: | |
// backspace | |
e.preventDefault(); | |
e.stopPropagation(); | |
handleDelete.call(self, 46); | |
return false; | |
case 8: | |
// delete | |
e.preventDefault(); | |
e.stopPropagation(); | |
handleDelete.call(self, 8); | |
return false; | |
// FOCUS THE HIDDEN INPUT BOX | |
default: | |
interceptCrossBlockChanges.call(self); | |
focusInput.call(self); | |
} | |
return true; | |
}; | |
} | |
function focusInput() { | |
var cursor = this.getCursor(); | |
if (!cursor) { | |
return; | |
} else { | |
this.cursor = cursor; | |
} | |
var start = cursor.startPath.slice().pop(); | |
var end = cursor.endPath.slice().pop(); | |
var block = cursor.startPath.slice(0, -1).pop(); | |
this.hiddenInput.focus(); | |
this.hiddenInput.value = this.data.blocks[block].rawText; | |
this.hiddenInput.setSelectionRange(start, end); | |
} | |
function interceptCrossBlockChanges() { | |
var cursor = this.getCursor(); | |
if (!cursor) { | |
return; | |
} else { | |
this.cursor = cursor; | |
} | |
var charStart = cursor.startPath.slice().pop(); | |
var charEnd = cursor.endPath.slice().pop(); | |
var blockStart = cursor.startPath.slice(0, -1).pop(); | |
var blockEnd = cursor.endPath.slice(0, -1).pop(); | |
if (blockStart !== blockEnd) { | |
// delete partially text on first outside block | |
var deleteStart = this.data.blocks[blockStart].rawText.length; | |
var startLength = deleteStart - charStart; | |
this.data.blocks[blockStart] = Object(__WEBPACK_IMPORTED_MODULE_0__model_clean__["a" /* clean */])(Object(__WEBPACK_IMPORTED_MODULE_2__model_remove_text__["a" /* removeText */])(this.data.blocks[blockStart], deleteStart, startLength)); | |
// delete partially text on last outside block | |
this.data.blocks[blockEnd] = Object(__WEBPACK_IMPORTED_MODULE_0__model_clean__["a" /* clean */])(Object(__WEBPACK_IMPORTED_MODULE_2__model_remove_text__["a" /* removeText */])(this.data.blocks[blockEnd], charEnd, charEnd)); | |
// remove entirely any blocks in the middle | |
this.data.blocks.splice(blockStart + 1, blockEnd - blockStart - 1); | |
// merge startBlock and endBlock | |
this.data.blocks = Object(__WEBPACK_IMPORTED_MODULE_3__model_merge_blocks__["a" /* mergeBlocks */])(this.data.blocks, blockStart, blockStart + 1); | |
this.cursor.endPath.pop(); | |
this.cursor.endPath.pop(); | |
this.cursor.endPath.push(blockStart); | |
this.cursor.endPath.push(charStart); | |
this.render(); | |
this.restoreCursor(); | |
return true; | |
} else if (charStart !== charEnd) { | |
this.data.blocks[blockStart] = Object(__WEBPACK_IMPORTED_MODULE_0__model_clean__["a" /* clean */])(Object(__WEBPACK_IMPORTED_MODULE_2__model_remove_text__["a" /* removeText */])(this.data.blocks[blockStart], charEnd, charEnd - charStart)); | |
this.cursor.endPath.pop(); | |
this.cursor.endPath.push(charStart); | |
this.render(); | |
this.restoreCursor(); | |
return true; | |
} | |
return false; | |
} | |
function handleDelete(keyCode) { | |
var handled = interceptCrossBlockChanges.call(this); | |
if (handled) { | |
return; | |
} | |
var cursor = this.getCursor(); | |
if (!cursor) { | |
return; | |
} else { | |
this.cursor = cursor; | |
} | |
// TODO | |
// problem with the rendering engine, when start === end | |
// color 0s0e is sometimes making spans that wrap 3 or 4 chars | |
// debug in renderBlock | |
// more bugs when say color is 9 9 making whole 5 chars after green | |
var charStart = cursor.startPath.slice().pop(); | |
var charEnd = cursor.endPath.slice().pop(); | |
var blockStart = cursor.startPath.slice(0, -1).pop(); | |
// var blockEnd = cursor.endPath.slice(0, -1).pop(); | |
var blockLength = this.data.blocks[blockStart].rawText.length; | |
/* first char of paragraph */ | |
if (keyCode === 8 && charStart === 0) { | |
blockLength = this.data.blocks[blockStart - 1].rawText.length; | |
this.data.blocks = Object(__WEBPACK_IMPORTED_MODULE_3__model_merge_blocks__["a" /* mergeBlocks */])(this.data.blocks, blockStart - 1, blockStart); | |
this.cursor.startPath.pop(); | |
this.cursor.startPath.pop(); | |
this.cursor.startPath.push(blockStart - 1); | |
this.cursor.startPath.push(blockLength); | |
this.cursor.endPath.pop(); | |
this.cursor.endPath.pop(); | |
this.cursor.endPath.push(blockStart - 1); | |
this.cursor.endPath.push(blockLength); | |
/* last char of paragraph */ | |
} else if (keyCode === 46 && charEnd === blockLength) { | |
this.data.blocks = Object(__WEBPACK_IMPORTED_MODULE_3__model_merge_blocks__["a" /* mergeBlocks */])(this.data.blocks, blockStart, blockStart + 1); | |
this.cursor.startPath.pop(); | |
this.cursor.startPath.pop(); | |
this.cursor.startPath.push(blockStart); | |
this.cursor.startPath.push(blockLength); | |
this.cursor.endPath.pop(); | |
this.cursor.endPath.pop(); | |
this.cursor.endPath.push(blockStart); | |
this.cursor.endPath.push(blockLength); | |
/* regular delete */ | |
} else if (keyCode === 8) { | |
this.data.blocks[blockStart] = Object(__WEBPACK_IMPORTED_MODULE_0__model_clean__["a" /* clean */])(Object(__WEBPACK_IMPORTED_MODULE_2__model_remove_text__["a" /* removeText */])(this.data.blocks[blockStart], charEnd, 1)); | |
this.cursor.startPath.pop(); | |
this.cursor.startPath.push(charStart - 1); | |
this.cursor.endPath.pop(); | |
this.cursor.endPath.push(charStart - 1); | |
/* regular backspace */ | |
} else if (keyCode === 46) { | |
this.data.blocks[blockStart] = Object(__WEBPACK_IMPORTED_MODULE_0__model_clean__["a" /* clean */])(Object(__WEBPACK_IMPORTED_MODULE_2__model_remove_text__["a" /* removeText */])(this.data.blocks[blockStart], charEnd + 1, 1)); | |
this.cursor.endPath.pop(); | |
this.cursor.endPath.push(charStart); | |
} | |
this.render(); | |
this.restoreCursor(); | |
} | |
function handleEnter() { | |
var cursor = this.getCursor(); | |
if (!cursor) { | |
return; | |
} else { | |
this.cursor = cursor; | |
} | |
var charStart = cursor.startPath.slice().pop(); | |
var blockStart = cursor.startPath.slice(0, -1).pop(); | |
// splitBlock | |
this.data.blocks = Object(__WEBPACK_IMPORTED_MODULE_4__model_split_block__["a" /* splitBlock */])(this.data.blocks, blockStart, charStart); | |
this.cursor.startPath.pop(); | |
this.cursor.startPath.pop(); | |
this.cursor.startPath.push(blockStart + 1); | |
this.cursor.startPath.push(0); | |
this.cursor.endPath.pop(); | |
this.cursor.endPath.pop(); | |
this.cursor.endPath.push(blockStart + 1); | |
this.cursor.endPath.push(0); | |
this.render(); | |
this.restoreCursor(); | |
} | |
function handleShiftEnter() { | |
var cursor = this.getCursor(); | |
if (!cursor) { | |
return; | |
} else { | |
this.cursor = cursor; | |
} | |
var charStart = cursor.startPath.slice().pop(); | |
var blockStart = cursor.startPath.slice(0, -1).pop(); | |
this.data.blocks[blockStart] = Object(__WEBPACK_IMPORTED_MODULE_0__model_clean__["a" /* clean */])(Object(__WEBPACK_IMPORTED_MODULE_1__model_insert_text__["a" /* insertText */])(this.data.blocks[blockStart], charStart, '\n')); | |
this.cursor.startPath.pop(); | |
this.cursor.endPath.pop(); | |
this.cursor.startPath.push(charStart + 1); | |
this.cursor.endPath.push(charStart + 1); | |
this.render(); | |
this.restoreCursor(); | |
} | |
/***/ }), | |
/* 10 */ | |
/***/ (function(module, __webpack_exports__, __webpack_require__) { | |
"use strict"; | |
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return mergeBlocks; }); | |
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__update_ranges__ = __webpack_require__(1); | |
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__clean__ = __webpack_require__(0); | |
function mergeBlocks(blocks, blockIndexA, blockIndexB) { | |
var blockA = blocks[blockIndexA]; | |
var blockB = blocks[blockIndexB]; | |
var blockARanges = JSON.parse(JSON.stringify(blockA.ranges)); | |
var blockBRanges = Object(__WEBPACK_IMPORTED_MODULE_0__update_ranges__["a" /* updateBlockRanges */])(JSON.parse(JSON.stringify(blockB.ranges)), 0, blockA.rawText.length); | |
// merge blockBranges into blockAranges | |
var newRanges = Object.keys(blockBRanges).reduce(function (blockARanges, key) { | |
var rangeArray = blockARanges[key] || []; | |
blockARanges[key] = rangeArray.concat(blockBRanges[key]); | |
return blockARanges; | |
}, blockARanges || {}); | |
var newBlock = Object(__WEBPACK_IMPORTED_MODULE_1__clean__["a" /* clean */])({ | |
blockType: blockA.blockType, | |
rawText: blockA.rawText + blockB.rawText, | |
ranges: newRanges | |
}); | |
blocks.splice(blockIndexA, 2, newBlock); | |
return blocks; | |
} | |
/* unused harmony default export */ var _unused_webpack_default_export = (mergeBlocks); | |
/***/ }), | |
/* 11 */ | |
/***/ (function(module, __webpack_exports__, __webpack_require__) { | |
"use strict"; | |
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return splitBlock; }); | |
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__update_ranges__ = __webpack_require__(1); | |
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__clean__ = __webpack_require__(0); | |
function splitBlock(blocks, blockIndex, charIndex) { | |
var blockToSplit = blocks[blockIndex]; | |
var oldBlockText = blockToSplit.rawText.slice(0, charIndex); | |
var newBlockText = blockToSplit.rawText.slice(charIndex); | |
var oldBlockRanges = Object(__WEBPACK_IMPORTED_MODULE_0__update_ranges__["a" /* updateBlockRanges */])(JSON.parse(JSON.stringify(blockToSplit.ranges)), blockToSplit.rawText.length, -newBlockText.length); | |
var newBlockRanges = Object(__WEBPACK_IMPORTED_MODULE_0__update_ranges__["a" /* updateBlockRanges */])(JSON.parse(JSON.stringify(blockToSplit.ranges)), charIndex, -charIndex); | |
var oldBlock = Object(__WEBPACK_IMPORTED_MODULE_1__clean__["a" /* clean */])({ | |
blockType: blockToSplit.blockType, | |
rawText: oldBlockText, | |
ranges: oldBlockRanges | |
}); | |
var newBlock = Object(__WEBPACK_IMPORTED_MODULE_1__clean__["a" /* clean */])({ | |
blockType: blockToSplit.blockType, | |
rawText: newBlockText, | |
ranges: newBlockRanges | |
}); | |
blocks.splice(blockIndex, 1, oldBlock, newBlock); | |
return blocks; | |
} | |
/* unused harmony default export */ var _unused_webpack_default_export = (splitBlock); | |
/***/ }), | |
/* 12 */ | |
/***/ (function(module, __webpack_exports__, __webpack_require__) { | |
"use strict"; | |
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return getCursor; }); | |
function getCursor() { | |
if (!window.getSelection().rangeCount) { | |
return; | |
} | |
var nativeRange = window.getSelection().getRangeAt(0); | |
var deepestStartBlock = getTarget(nativeRange.startContainer, 'P, LI, UL, OL, H1, H2, H3, H4, H5'); | |
var startPath = []; | |
// get the character index of the block | |
startPath.unshift(countFromLeft(deepestStartBlock, nativeRange.startContainer, nativeRange.startOffset)); | |
// prepend the block paths | |
getFullBlockPath(startPath, deepestStartBlock); | |
var deepestEndBlock = getTarget(nativeRange.endContainer, 'P, LI, UL, OL, H1, H2, H3, H4, H5'); | |
var endPath = []; | |
// get the character index of the block | |
endPath.unshift(countFromLeft(deepestEndBlock, nativeRange.endContainer, nativeRange.endOffset)); | |
// prepend the block paths | |
getFullBlockPath(endPath, deepestEndBlock); | |
return { | |
startPath: startPath, | |
endPath: endPath, | |
nativeRange: nativeRange | |
}; | |
// // recurse upward until parent is contentEditable | |
// // get index of which block you are | |
// var startBlock = getTargetParentChild(nativeRange.startContainer, '[data-tome]'); | |
// var blockStart = indexOf( startBlock.parentElement.childNodes, startBlock ); | |
// // recurse upward until parent is contentEditable | |
// // get index of which block you are | |
// var endBlock = getTargetParentChild(nativeRange.endContainer, '[data-tome]'); | |
// var blockEnd = indexOf( endBlock.parentElement.childNodes, endBlock ); | |
// // walk left to beginning of block, count chars | |
// var start = countFromLeft(startBlock, nativeRange.startContainer, nativeRange.startOffset); | |
// // walk right to end of block, count chars | |
// var end = countFromLeft(endBlock, nativeRange.endContainer, nativeRange.endOffset); | |
// return { | |
// blockStart: blockStart, | |
// blockEnd: blockEnd, | |
// start: start, | |
// end: end, | |
// nativeRange: nativeRange | |
// }; | |
} | |
function getFullBlockPath(arr, block) { | |
if (matchesSelector(block, '[data-tome]')) { | |
return; | |
} | |
if (matchesSelector(block, 'P, LI, UL, OL, H1, H2, H3, H4, H5')) { | |
var i = indexOf(block.parentElement.childNodes, block); | |
arr.unshift(i); | |
} | |
if (block.parentElement) { | |
getFullBlockPath(arr, block.parentElement); | |
} | |
} | |
function countFromLeft(block, target, targetOffset) { | |
// if target not a text node, recurse down??? | |
var textNodes = collectTextNodes(block, []); | |
var count = 0; | |
for (var i = 0; i < textNodes.length; i++) { | |
if (textNodes[i] === target) { | |
count += targetOffset; | |
break; | |
} | |
count += textNodes[i].textContent.length; | |
} | |
return count; | |
} | |
// function countFromRight(block, target, targetOffset){ | |
// // if target not a text node, recurse down??? | |
// var textNodes = collectTextNodes(block, []); | |
// var count = 0; | |
// for (var i= textNodes.length - 1; i >= 0; i--){ | |
// if (textNodes[i] === target){ | |
// count += targetOffset; | |
// break; | |
// } | |
// count += textNodes[i].textContent.length; | |
// } | |
// return count; | |
// } | |
function collectTextNodes(element, texts) { | |
for (var child = element.firstChild; child !== null; child = child.nextSibling) { | |
if (child.nodeType === 3) { | |
texts.push(child); | |
} else if (child.nodeType === 1) { | |
collectTextNodes(child, texts); | |
} | |
} | |
return texts; | |
} | |
// function getTargetParentChild(el, selector){ | |
// if (matchesSelector(el.parentElement, selector)){ | |
// return el; | |
// } else { | |
// return getTargetParentChild(el.parentElement, selector); | |
// } | |
// } | |
function getTarget(el, selector) { | |
if (matchesSelector(el, selector)) { | |
return el; | |
} else { | |
return getTarget(el.parentElement, selector); | |
} | |
} | |
function matchesSelector(element, selector) { | |
var matches = (element.document || element.ownerDocument).querySelectorAll(selector); | |
var i = 0; | |
while (matches[i] && matches[i] !== element) { | |
i++; | |
} | |
return matches[i] ? true : false; | |
} | |
function indexOf(arr, node) { | |
return Array.prototype.indexOf.call(arr, node); | |
} | |
/* unused harmony default export */ var _unused_webpack_default_export = (getCursor); | |
/***/ }), | |
/* 13 */ | |
/***/ (function(module, __webpack_exports__, __webpack_require__) { | |
"use strict"; | |
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return restoreCursor; }); | |
function restoreCursor(cursor) { | |
cursor = cursor || this.cursor; | |
var nativeSelection = window.getSelection(); | |
var deepestStartBlock = getDeepestBlockFromPath(this.el, cursor.startPath); | |
var deepestEndBlock = getDeepestBlockFromPath(this.el, cursor.endPath); | |
var starting = getTextNodeFromCount(deepestStartBlock, last(cursor.startPath)); | |
var ending = getTextNodeFromCount(deepestEndBlock, last(cursor.endPath)); | |
// var startBlock = getBlockFromIndex(this.el, cursor.blockStart); | |
// var endBlock = getBlockFromIndex(this.el, cursor.blockEnd); | |
// var starting = getTextNodeFromCount(startBlock, cursor.start); | |
// var ending = getTextNodeFromCount(endBlock, cursor.end); | |
var range = document.createRange(); | |
range.setStart(starting.node || deepestStartBlock, starting.offset || 0); | |
range.setEnd(ending.node || deepestEndBlock, ending.offset || 0); | |
nativeSelection.removeAllRanges(); | |
nativeSelection.addRange(range); | |
} | |
function last(arr) { | |
return arr.length ? arr[arr.length - 1] : undefined; | |
} | |
function getDeepestBlockFromPath(block, path) { | |
var drill = path.slice(0, -1); | |
var current = block; | |
while (drill.length) { | |
current = current.childNodes[drill.shift()]; | |
} | |
return current; | |
} | |
// function getBlockFromIndex(editableRoot, index){ | |
// return editableRoot.children[index]; | |
// } | |
function getTextNodeFromCount(block, targetCount) { | |
var offset; | |
var node; | |
var textNodes = collectTextNodes(block, []); | |
var count = 0; | |
for (var i = 0; i < textNodes.length; i++) { | |
if (textNodes[i].textContent.length + count >= targetCount) { | |
node = textNodes[i]; | |
offset = targetCount - count; | |
break; | |
} | |
count += textNodes[i].textContent.length; | |
} | |
return { | |
node: node, | |
offset: offset | |
}; | |
} | |
function collectTextNodes(element, texts) { | |
for (var child = element.firstChild; child !== null; child = child.nextSibling) { | |
if (child.nodeType === 3) { | |
texts.push(child); | |
} else if (child.nodeType === 1) { | |
collectTextNodes(child, texts); | |
} | |
} | |
return texts; | |
} | |
/* unused harmony default export */ var _unused_webpack_default_export = (restoreCursor); | |
/***/ }) | |
/******/ ]); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment