/** * RangeNormalizer.js * * Released under LGPL License. * Copyright (c) 1999-2017 Ephox Corp. All rights reserved * * License: http://www.tinymce.com/license * Contributing: http://www.tinymce.com/contributing */ import CaretFinder from '../caret/CaretFinder'; import CaretPosition from '../caret/CaretPosition'; import * as CaretUtils from '../caret/CaretUtils'; const createRange = (sc: Node, so: number, ec: Node, eo: number): Range => { const rng = document.createRange(); rng.setStart(sc, so); rng.setEnd(ec, eo); return rng; }; // If you triple click a paragraph in this case: //
a
b
// It would become this range in webkit: //[a
]b
// We would want it to be: //[a]
b
// Since it would otherwise produces spans out of thin air on insertContent for example. const normalizeBlockSelectionRange = (rng: Range): Range => { const startPos = CaretPosition.fromRangeStart(rng); const endPos = CaretPosition.fromRangeEnd(rng); const rootNode = rng.commonAncestorContainer; return CaretFinder.fromPosition(false, rootNode, endPos) .map(function (newEndPos) { if (!CaretUtils.isInSameBlock(startPos, endPos, rootNode) && CaretUtils.isInSameBlock(startPos, newEndPos, rootNode)) { return createRange(startPos.container(), startPos.offset(), newEndPos.container(), newEndPos.offset()); } else { return rng; } }).getOr(rng); }; const normalize = (rng: Range): Range => rng.collapsed ? rng : normalizeBlockSelectionRange(rng); export default { normalize };