1 /**
  2  * Copyright (C) 2013 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, xmldom, Node, NodeFilter, runtime*/
 26 
 27 /**
 28  * Serializes a provided node structure into plain text, eliminating everything
 29  * specified by the optional filter element.
 30  * This will attempt to generate reasonable plain text output including line-breaks
 31  * at new paragraphs
 32  * @constructor
 33  */
 34 odf.TextSerializer = function TextSerializer() {
 35     "use strict";
 36     var self = this,
 37         odfUtils = odf.OdfUtils;
 38 
 39     /**
 40      * @param {!Node} node
 41      * @return {!string}
 42      */
 43     function serializeNode(node) {
 44         var s = "",
 45             accept = (self.filter) ? self.filter.acceptNode(node) : NodeFilter.FILTER_ACCEPT,
 46             nodeType = node.nodeType,
 47             child;
 48 
 49         if ((accept === NodeFilter.FILTER_ACCEPT || accept === NodeFilter.FILTER_SKIP) &&
 50             odfUtils.isTextContentContainingNode(node)) {
 51             child = node.firstChild;
 52             while (child) {
 53                 s += serializeNode(child);
 54                 child = child.nextSibling;
 55             }
 56         }
 57         if (accept === NodeFilter.FILTER_ACCEPT) {
 58             if (nodeType === Node.ELEMENT_NODE && odfUtils.isParagraph(node)) {
 59                 s += "\n";
 60             } else if (nodeType === Node.TEXT_NODE && node.textContent) {
 61                 s += node.textContent;
 62             }
 63         }
 64         return s;
 65     }
 66     /**
 67      * @type {xmldom.LSSerializerFilter}
 68      */
 69     this.filter = null;
 70 
 71     /**
 72      * @param {?Node} node
 73      * @return {!string}
 74      */
 75     this.writeToString = function (node) {
 76         var plainText;
 77         if (!node) {
 78             return "";
 79         }
 80         plainText = serializeNode(node);
 81         if (plainText[plainText.length - 1] === "\n") {
 82             // By the serializing logic, the selection  <p>text</p> would generate "text\n"
 83             // This is slightly unexpected though, as partially selecting two paragraphs (<p>p1</p><p>p2</p>)
 84             // the user would expect the text to be "p1\np2"
 85             // Easiest way to meet this expectation is to throw away the last new line (if present)
 86             plainText = plainText.substr(0, plainText.length - 1);
 87         }
 88         return plainText;
 89     };
 90 };
 91