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