1 /** 2 * Copyright (C) 2010-2014 KO GmbH <copyright@kogmbh.com> 3 * 4 * @licstart 5 * This file is part of WebODF. 6 * 7 * WebODF is free software: you can redistribute it and/or modify it 8 * under the terms of the GNU Affero General Public License (GNU AGPL) 9 * as published by the Free Software Foundation, either version 3 of 10 * the License, or (at your option) any later version. 11 * 12 * WebODF is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU Affero General Public License for more details. 16 * 17 * You should have received a copy of the GNU Affero General Public License 18 * along with WebODF. If not, see <http://www.gnu.org/licenses/>. 19 * @licend 20 * 21 * @source: http://www.webodf.org/ 22 * @source: https://github.com/kogmbh/WebODF/ 23 */ 24 25 /*global odf, core, Node, NodeFilter*/ 26 27 /** 28 * Defines a set of rules for how elements can be collapsed based on whether they contain ODT content (e.g., 29 * text or character elements). 30 * @constructor 31 * @param {!Node} rootNode Root text element of the odtDocument 32 */ 33 odf.CollapsingRules = function CollapsingRules(rootNode) { 34 "use strict"; 35 var odfUtils = odf.OdfUtils, 36 domUtils = core.DomUtils; 37 38 /** 39 * Returns NodeFilter value if a given node is odf node or a text node that has a odf parent. 40 * @param {!Node} node 41 * @return {!number} 42 */ 43 function filterOdfNodesToRemove(node) { 44 var isToRemove = odfUtils.isODFNode(node) 45 || (node.localName === "br" && odfUtils.isLineBreak(node.parentNode)) 46 || (node.nodeType === Node.TEXT_NODE && odfUtils.isODFNode(/** @type {!Node}*/(node.parentNode))); 47 return isToRemove ? NodeFilter.FILTER_REJECT : NodeFilter.FILTER_ACCEPT; 48 } 49 50 /** 51 * Returns true if the supplied node should be automatically collapsed (i.e., removed) if it contains no 52 * text or ODF character elements. The only element that should always be kept is a paragraph element. 53 * Paragraph elements can only be deleted through merging 54 * @param {!Node} node 55 * @return {!boolean} 56 */ 57 function isCollapsibleContainer(node) { 58 return !odfUtils.isParagraph(node) && node !== rootNode && odfUtils.hasNoODFContent(node); 59 } 60 61 /** 62 * Merge all child nodes into the node's parent and remove the node entirely 63 * @param {!Node} targetNode Node to merge into parent 64 * @return {?Node} Final parent node collapsing ended at 65 */ 66 function mergeChildrenIntoParent(targetNode) { 67 var parent; 68 if (targetNode.nodeType === Node.TEXT_NODE) { 69 parent = targetNode.parentNode; 70 parent.removeChild(targetNode); 71 } else { 72 // removes all odf nodes 73 parent = domUtils.removeUnwantedNodes(targetNode, filterOdfNodesToRemove); 74 } 75 if (parent && isCollapsibleContainer(parent)) { 76 return mergeChildrenIntoParent(parent); 77 } 78 return parent; 79 } 80 this.mergeChildrenIntoParent = mergeChildrenIntoParent; 81 };