/* * Copyright 2011 eBay Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Utility class to support sub-attributes in an XML attribute. Each sub-attribute must * be separated by a semicolon. Within each sub-attribute, the name/value pair must * be split using an equal sign. However, the name for the first sub-attribute * is optional and a default name can be provided when reading the sub-attributes. * *
* Sub-attribute format:
* (
* Supported options:
*
*
*
* @memberOf raptor/templating/compiler$AttributeSplitter
* @param attr {String} The attribute to split
* @param types {Object} Type definitions for the possible sub-attributes.
* @param options
* @returns
*/
exports.parse = function (attr, types, options) {
if (!options) {
options = {};
}
var partStart = 0;
var ordered = options.ordered === true;
var defaultName = options.defaultName;
var removeDashes = options.removeDashes === true;
var matches;
var equalIndex = -1;
var result = ordered ? [] : {};
function handleError(message) {
if (options.errorHandler) {
options.errorHandler(message);
return;
} else {
throw createError(new Error(message));
}
}
function finishPart(endIndex) {
if (partStart === endIndex) {
//The part is an empty string... ignore it
return;
}
var name;
var value;
if (equalIndex != -1) {
name = strings.trim(attr.substring(partStart, equalIndex));
value = attr.substring(equalIndex + 1, endIndex);
} else {
if (defaultName) {
name = defaultName;
value = attr.substring(partStart, endIndex);
if (!strings.trim(value).length) {
return; //ignore empty parts
}
} else {
name = attr.substring(partStart, endIndex);
}
}
if (name) {
name = strings.trim(name);
}
if (!strings.trim(name).length && !strings.trim(value).length) {
equalIndex = -1;
return; //ignore empty parts
}
if (types) {
var type = types[name] || types['*'];
if (type) {
if (value != null) {
value = TypeConverter.convert(value, type.type, type.allowExpressions !== false);
}
if (type.name) {
name = type.name;
}
} else {
handleError('Invalid sub-attribute name of "' + name + '"');
}
}
if (name && removeDashes) {
name = name.replace(/-([a-z])/g, function (match, lower) {
return lower.toUpperCase();
});
}
if (ordered) {
result.push({
name: name,
value: value
});
} else {
result[name] = value;
}
equalIndex = -1; //Reset the equal index
}
/*
* Keep searching the string for the relevant tokens.
*
* NOTE: The regular expression will also return matches for JavaScript strings,
* but they are just ignored. This ensures that semicolons inside strings
* are not treated as
*/
while ((matches = regExp.exec(attr))) {
//console.error(matches[0]);
if (matches[0] == ';') {
finishPart(matches.index);
partStart = matches.index + 1;
equalIndex = -1;
} else if (matches[0] == '=') {
if (equalIndex == -1) {
equalIndex = matches.index;
}
}
}
finishPart(attr.length);
//console.error("AttributeSplitter - result: ", result);
return result;
};