Revision feb108b8

b/webodf/lib/xmldom/RelaxNGParser.js
109 109
        }
110 110
    }
111 111

  
112
    function trim(str) {
113
        str = str.replace(/^\s\s*/, '');
114
		var ws = /\s/,
115
            i = str.length - 1;
116
        while (ws.test(str.charAt(i))) {
117
            i -= 1;
118
        }
119
        return str.slice(0, i + 1);
120
    }
121

  
112 122
    function copyAttributes(atts, name, names) {
113 123
        var a = {}, i, att;
114 124
        for (i = 0; i < atts.length; i += 1) {
......
117 127
                if (att.localName === "name" &&
118 128
                        (name === "element" || name === "attribute")) {
119 129
                    names.push(att.value);
120
                    a[att.localName] = att.value;
121
                } else {
122
                    a[att.localName] = att.value;
123 130
                }
131
                if (att.localName === "name" || att.localName === "combine" ||
132
                        att.localName === "type") {
133
                    att.value = trim(att.value);
134
                }
135
                a[att.localName] = att.value;
124 136
            } else if (att.namespaceURI === xmlnsns) {
125 137
                nsmap[att.value] = att.localName;
126 138
            }
......
132 144
        var text = "", ce;
133 145
        while (c) {
134 146
            if (c.nodeType === 1 && c.namespaceURI === rngns) {
135
                ce = parse(c, elements);
136
                if (ce.name === "name") {
137
                    names.push(nsmap[ce.a.ns] + ":" + ce.text);
138
                    e.push(ce);
139
                } else if (ce.name === "choice" && ce.names &&
140
                        ce.names.length) {
141
                    names = names.concat(ce.names);
142
                    delete ce.names;
143
                    e.push(ce);
144
                } else {
145
                    e.push(ce);
147
                ce = parse(c, elements, e);
148
                if (ce) {
149
                    if (ce.name === "name") {
150
                        names.push(nsmap[ce.a.ns] + ":" + ce.text);
151
                        e.push(ce);
152
                    } else if (ce.name === "choice" && ce.names &&
153
                            ce.names.length) {
154
                        names = names.concat(ce.names);
155
                        delete ce.names;
156
                        e.push(ce);
157
                    } else {
158
                        e.push(ce);
159
                    }
146 160
                }
147 161
            } else if (c.nodeType === 3) {
148 162
                text += c.nodeValue;
......
152 166
        return text;
153 167
    }
154 168

  
155
    parse = function parse(element, elements) {
169
    function combineDefines(combine, name, e, siblings) {
170
        // combineDefines is called often enough that there can only be one
171
        // other element with the same name
172
        // if the found element still has the 'combine' attribute, nothing has
173
        // been combined with it yet, and a new child element is needed
174
        var i, ce, ne;
175
        for (i = 0; siblings && i < siblings.length; i += 1) {
176
            ce = siblings[i];
177
            if (ce.name === "define" && ce.a && ce.a.name === name) {
178
                if (ce.combine) {
179
                    ne = { name: ce.combine, e: ce.e.concat(e) };
180
                    delete ce.combine;
181
                    ce.e = [ ne ];
182
                } else {
183
                    ce.e = ce.e.concat(e);
184
                }
185
                return ce;
186
            }
187
        }
188
        return null;
189
    }
190

  
191
    parse = function parse(element, elements, siblings) {
156 192
        // parse all elements from the Relax NG namespace into JavaScript
157 193
        // objects
158 194
        var e = [], a, ce,
......
236 272
            name = "choice";
237 273
            e = [ {name: "oneOrMore", e: [ e[0] ] }, { name: "empty" } ];
238 274
        }
275
        // 4.17 combine attribute
276
        if (name === "define" && a.combine) {
277
            ce = combineDefines(a.combine, a.name, e, siblings);
278
            if (ce) {
279
                return;
280
            }
281
        }
282

  
239 283
        // create the definition
240 284
        ce = { name: name };
285
        if (name === "define" && a.combine) {
286
            ce.combine = a.combine;
287
        }
241 288
        if (e && e.length > 0) { ce.e = e; }
242 289
        for (i in a) {
243 290
            if (a.hasOwnProperty(i)) {

Also available in: Unified diff