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, runtime*/ 26 27 (function() { 28 "use strict"; 29 30 /** 31 * A collection of query interfaces to determine attributes about a node such as whether it 32 * can contain text content, or is a field. This should be accessed via the singleton 33 * instance "odf.OdfSchema". 34 * 35 * @constructor 36 */ 37 odf.OdfSchemaImpl = function () { 38 var TEXT = "text", // Editable & selectable text 39 FIELD = "field", // Non-editable or selectable text 40 OBJECT = "object", // Non-text object 41 STYLE = "style", // Used only within document style definitions 42 DEPRECATED = "deprecated", // Deprecated entity 43 UNKNOWN = "uncategorized", // Uncategorized element 44 // Basic list of containers originally created using tools/odfRng2Config.js 45 // List has been hand-updated however, and should not simply be discarded! 46 /**@type{!Array.<!Array.<!string, !string>>}*/ 47 containers = [ 48 ["config:config-item" , UNKNOWN], 49 ["form:item" , OBJECT], 50 ["form:option" , UNKNOWN], 51 ["math:math" , FIELD], 52 ["meta:user-defined" , UNKNOWN], 53 ["number:currency-symbol" , UNKNOWN], 54 ["number:embedded-text" , UNKNOWN], 55 ["number:text" , UNKNOWN], 56 ["presentation:date-time-decl" , UNKNOWN], 57 ["presentation:footer-decl" , UNKNOWN], 58 ["presentation:header-decl" , UNKNOWN], 59 ["svg:desc" , TEXT], 60 ["svg:title" , TEXT], 61 ["table:desc" , UNKNOWN], 62 ["table:title" , UNKNOWN], 63 ["text:a" , TEXT], 64 ["text:author-initials" , FIELD], 65 ["text:author-name" , FIELD], 66 ["text:bibliography-mark" , FIELD], 67 ["text:bookmark-ref" , FIELD], 68 ["text:chapter" , FIELD], 69 ["text:character-count" , FIELD], 70 ["text:conditional-text" , FIELD], 71 ["text:creation-date" , FIELD], 72 ["text:creation-time" , FIELD], 73 ["text:creator" , FIELD], 74 ["text:database-display" , FIELD], 75 ["text:database-name" , FIELD], 76 ["text:database-row-number" , FIELD], 77 ["text:date" , FIELD], 78 ["text:dde-connection" , FIELD], 79 ["text:description" , FIELD], 80 ["text:editing-cycles" , FIELD], 81 ["text:editing-duration" , FIELD], 82 ["text:execute-macro" , UNKNOWN], 83 ["text:expression" , UNKNOWN], 84 ["text:file-name" , FIELD], 85 ["text:h" , TEXT], 86 ["text:hidden-paragraph" , TEXT], 87 ["text:hidden-text" , TEXT], 88 ["text:image-count" , FIELD], 89 ["text:index-entry-span" , UNKNOWN], 90 ["text:index-title-template" , UNKNOWN], 91 ["text:initial-creator" , FIELD], 92 ["text:keywords" , FIELD], 93 ["text:linenumbering-separator" , STYLE], 94 ["text:measure" , UNKNOWN], 95 ["text:meta" , UNKNOWN], 96 ["text:meta-field" , UNKNOWN], 97 ["text:modification-date" , FIELD], 98 ["text:modification-time" , FIELD], 99 ["text:note-citation" , FIELD], 100 ["text:note-continuation-notice-backward", STYLE], 101 ["text:note-continuation-notice-forward" , STYLE], 102 ["text:note-ref" , FIELD], 103 ["text:object-count" , FIELD], 104 ["text:p" , TEXT], 105 ["text:page-continuation" , UNKNOWN], 106 ["text:page-count" , FIELD], 107 ["text:page-number" , FIELD], 108 ["text:page-variable-get" , FIELD], 109 ["text:page-variable-set" , FIELD], 110 ["text:paragraph-count" , FIELD], 111 ["text:placeholder" , FIELD], 112 ["text:print-date" , FIELD], 113 ["text:print-time" , FIELD], 114 ["text:printed-by" , FIELD], 115 ["text:reference-ref" , FIELD], 116 ["text:ruby-base" , TEXT], 117 ["text:ruby-text" , TEXT], 118 ["text:script" , TEXT], 119 ["text:sender-city" , FIELD], 120 ["text:sender-company" , FIELD], 121 ["text:sender-country" , FIELD], 122 ["text:sender-email" , FIELD], 123 ["text:sender-fax" , FIELD], 124 ["text:sender-firstname" , FIELD], 125 ["text:sender-initials" , FIELD], 126 ["text:sender-lastname" , FIELD], 127 ["text:sender-phone-private" , FIELD], 128 ["text:sender-phone-work" , FIELD], 129 ["text:sender-position" , FIELD], 130 ["text:sender-postal-code" , FIELD], 131 ["text:sender-state-or-province" , FIELD], 132 ["text:sender-street" , FIELD], 133 ["text:sender-title" , FIELD], 134 ["text:sequence" , UNKNOWN], 135 ["text:sequence-ref" , UNKNOWN], 136 ["text:sheet-name" , UNKNOWN], 137 ["text:span" , TEXT], 138 ["text:subject" , FIELD], 139 ["text:table-count" , FIELD], 140 ["text:table-formula" , DEPRECATED], 141 ["text:template-name" , UNKNOWN], 142 ["text:text-input" , FIELD], 143 ["text:time" , FIELD], 144 ["text:title" , FIELD], 145 ["text:user-defined" , FIELD], 146 ["text:user-field-get" , FIELD], 147 ["text:user-field-input" , FIELD], 148 ["text:variable-get" , FIELD], 149 ["text:variable-input" , FIELD], 150 ["text:variable-set" , FIELD], 151 ["text:word-count" , FIELD], 152 ["xforms:model" , UNKNOWN] 153 ], 154 cache = {}; 155 156 /** 157 * Returns true if the supplied namespace + localName can contain selectable/editable text 158 * content. 159 * 160 * @param {!string} namespaceURI 161 * @param {!string} localName 162 * @return {!boolean} 163 */ 164 this.isTextContainer = function (namespaceURI, localName) { 165 return cache[namespaceURI + ":" + localName] === TEXT; 166 }; 167 168 /** 169 * Returns true if the supplied namespace + localName is an ODT field. 170 * 171 * @param {!string} namespaceURI 172 * @param {!string} localName 173 * @return {!boolean} 174 */ 175 this.isField = function (namespaceURI, localName) { 176 return cache[namespaceURI + ":" + localName] === FIELD; 177 }; 178 179 /** 180 * Return a list of all known ODF fields. These are prefixed with the standard prefixes. 181 * E.g., ["text:author-name"] 182 * 183 * @return {!Array.<!string>} 184 */ 185 this.getFields = function() { 186 return containers.filter(function(containerInfo) { return containerInfo[1] === FIELD; }) 187 .map(function(containerInfo) { return containerInfo[0]; }); 188 }; 189 190 function init() { 191 containers.forEach(function(containerInfo) { 192 var name = containerInfo[0], 193 type = containerInfo[1], 194 nameParts = name.split(":"), 195 prefix = nameParts[0], 196 localName = nameParts[1], 197 namespaceURI = odf.Namespaces.lookupNamespaceURI(prefix); 198 199 if (namespaceURI) { 200 cache[namespaceURI + ":" + localName] = type; 201 } else { 202 runtime.log("DEBUG: OdfSchema - unknown prefix '" + prefix + "'"); 203 } 204 }); 205 } 206 init(); 207 }; 208 209 /** 210 * @type {!odf.OdfSchemaImpl} 211 */ 212 odf.OdfSchema = new odf.OdfSchemaImpl(); 213 }()); 214 215