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*/ 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 true if a given node is odf node or a text node that has a odf parent. 40 * @param {!Node} node 41 * @return {!boolean} 42 */ 43 function shouldRemove(node) { 44 return odfUtils.isODFNode(node) 45 || (node.localName === "br" && odfUtils.isLineBreak(node.parentNode)) 46 || (node.nodeType === Node.TEXT_NODE && odfUtils.isODFNode(/** @type {!Node}*/(node.parentNode))); 47 } 48 49 /** 50 * Returns true if the supplied node should be automatically collapsed (i.e., removed) if it contains no 51 * text or ODF character elements. The only element that should always be kept is a paragraph element. 52 * Paragraph elements can only be deleted through merging 53 * @param {!Node} node 54 * @return {!boolean} 55 */ 56 function isCollapsibleContainer(node) { 57 return !odfUtils.isParagraph(node) && node !== rootNode && odfUtils.hasNoODFContent(node); 58 } 59 60 /** 61 * Merge all child nodes into the node's parent and remove the node entirely 62 * @param {!Node} targetNode Node to merge into parent 63 * @return {?Node} Final parent node collapsing ended at 64 */ 65 function mergeChildrenIntoParent(targetNode) { 66 var parent; 67 if (targetNode.nodeType === Node.TEXT_NODE) { 68 parent = targetNode.parentNode; 69 parent.removeChild(targetNode); 70 } else { 71 // removes all odf nodes 72 parent = domUtils.removeUnwantedNodes(targetNode, shouldRemove); 73 } 74 if (parent && isCollapsibleContainer(parent)) { 75 return mergeChildrenIntoParent(parent); 76 } 77 return parent; 78 } 79 this.mergeChildrenIntoParent = mergeChildrenIntoParent; 80 };