/**
* FragmentReader.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
*/
define(
'tinymce.core.selection.FragmentReader',
[
'ephox.katamari.api.Arr',
'ephox.katamari.api.Fun',
'ephox.sugar.api.dom.Compare',
'ephox.sugar.api.dom.Insert',
'ephox.sugar.api.dom.Replication',
'ephox.sugar.api.node.Element',
'ephox.sugar.api.node.Fragment',
'ephox.sugar.api.node.Node',
'ephox.sugar.api.search.SelectorFind',
'ephox.sugar.api.search.Traverse',
'tinymce.core.dom.ElementType',
'tinymce.core.dom.Parents',
'tinymce.core.selection.SelectionUtils',
'tinymce.core.selection.SimpleTableModel',
'tinymce.core.selection.TableCellSelection'
],
function (Arr, Fun, Compare, Insert, Replication, Element, Fragment, Node, SelectorFind, Traverse, ElementType, Parents, SelectionUtils, SimpleTableModel, TableCellSelection) {
var findParentListContainer = function (parents) {
return Arr.find(parents, function (elm) {
return Node.name(elm) === 'ul' || Node.name(elm) === 'ol';
});
};
var getFullySelectedListWrappers = function (parents, rng) {
return Arr.find(parents, function (elm) {
return Node.name(elm) === 'li' && SelectionUtils.hasAllContentsSelected(elm, rng);
}).fold(
Fun.constant([]),
function (li) {
return findParentListContainer(parents).map(function (listCont) {
return [
Element.fromTag('li'),
Element.fromTag(Node.name(listCont))
];
}).getOr([]);
}
);
};
var wrap = function (innerElm, elms) {
var wrapped = Arr.foldl(elms, function (acc, elm) {
Insert.append(elm, acc);
return elm;
}, innerElm);
return elms.length > 0 ? Fragment.fromElements([wrapped]) : wrapped;
};
var directListWrappers = function (commonAnchorContainer) {
if (ElementType.isListItem(commonAnchorContainer)) {
return Traverse.parent(commonAnchorContainer).filter(ElementType.isList).fold(
Fun.constant([]),
function (listElm) {
return [ commonAnchorContainer, listElm ];
}
);
} else {
return ElementType.isList(commonAnchorContainer) ? [ commonAnchorContainer ] : [ ];
}
};
var getWrapElements = function (rootNode, rng) {
var commonAnchorContainer = Element.fromDom(rng.commonAncestorContainer);
var parents = Parents.parentsAndSelf(commonAnchorContainer, rootNode);
var wrapElements = Arr.filter(parents, function (elm) {
return ElementType.isInline(elm) || ElementType.isHeading(elm);
});
var listWrappers = getFullySelectedListWrappers(parents, rng);
var allWrappers = wrapElements.concat(listWrappers.length ? listWrappers : directListWrappers(commonAnchorContainer));
return Arr.map(allWrappers, Replication.shallow);
};
var emptyFragment = function () {
return Fragment.fromElements([]);
};
var getFragmentFromRange = function (rootNode, rng) {
return wrap(Element.fromDom(rng.cloneContents()), getWrapElements(rootNode, rng));
};
var getParentTable = function (rootElm, cell) {
return SelectorFind.ancestor(cell, 'table', Fun.curry(Compare.eq, rootElm));
};
var getTableFragment = function (rootNode, selectedTableCells) {
return getParentTable(rootNode, selectedTableCells[0]).bind(function (tableElm) {
var firstCell = selectedTableCells[0];
var lastCell = selectedTableCells[selectedTableCells.length - 1];
var fullTableModel = SimpleTableModel.fromDom(tableElm);
return SimpleTableModel.subsection(fullTableModel, firstCell, lastCell).map(function (sectionedTableModel) {
return Fragment.fromElements([SimpleTableModel.toDom(sectionedTableModel)]);
});
}).getOrThunk(emptyFragment);
};
var getSelectionFragment = function (rootNode, ranges) {
return ranges.length > 0 && ranges[0].collapsed ? emptyFragment() : getFragmentFromRange(rootNode, ranges[0]);
};
var read = function (rootNode, ranges) {
var selectedCells = TableCellSelection.getCellsFromElementOrRanges(ranges, rootNode);
return selectedCells.length > 0 ? getTableFragment(rootNode, selectedCells) : getSelectionFragment(rootNode, ranges);
};
return {
read: read
};
}
);
|