define([
|
'dojo/_base/lang'
|
], function (lang) {
|
// A basic check to ensure a property name is valid. Will incorrectly flag some valid names,
|
// which is fine - they'll just get unnecessarily wrapped in quotes
|
var propertyNameRegex = /^[A-Za-z]+[A-Za-z0-9_]*$/;
|
|
// Check for dijit form widgets for editor property
|
var dijitFormWidgetRegex = /dijit\/form\/([A-Za-z]*)$/;
|
|
function tab(count) {
|
var tabString = '';
|
|
while (count--) {
|
tabString += '\t';
|
}
|
|
return tabString;
|
}
|
|
/**
|
* @param {Object|Array} obj: object to convert to JavaScript
|
* @param {Object} options: option bag object
|
* @param {number} options.indent: (integer) indentation level of output code
|
* @param {boolean} options.includeEmpty: if true, empty properties ('', null, undefined) will be included in output
|
* @param {boolean} options.inline: if true, print just properties, not wrapping braces
|
*/
|
function toJavaScript(obj, options) {
|
options = options || {};
|
|
var javascript = '';
|
var indent = options.indent || 0;
|
|
// TODO: does not handle some things, e.g. null, undefined
|
|
if (typeof obj === 'string') {
|
return escapeString(obj);
|
}
|
|
if (typeof obj !== 'object') {
|
return obj;
|
}
|
|
if (!options.inline) {
|
if (obj instanceof Array) {
|
javascript = '[';
|
}
|
else {
|
javascript = '{';
|
}
|
|
javascript += '\n';
|
}
|
|
indent++;
|
if (obj instanceof Array) {
|
javascript += printArray(obj, lang.delegate(options, { inline: false }), indent);
|
}
|
else {
|
javascript += printObject(obj, lang.delegate(options, { inline: false }), indent);
|
}
|
indent--;
|
|
if (!options.inline) {
|
javascript += '\n' + tab(indent);
|
|
if (obj instanceof Array) {
|
javascript += ']';
|
}
|
else {
|
javascript += '}';
|
}
|
}
|
|
return javascript;
|
}
|
|
function printObject(obj, options, indent) {
|
var javascript = '';
|
var property;
|
var firstProperty = true;
|
|
for (property in obj) {
|
// TODO: filtering with hasOwnProperty may not be necessary (or desirable?)
|
if (obj.hasOwnProperty(property)) {
|
if ((options.includeEmpty ||
|
(obj[property] !== '' && obj[property] !== null && obj[property] !== undefined))) {
|
if (firstProperty) {
|
firstProperty = false;
|
}
|
else {
|
javascript += ',\n';
|
}
|
|
javascript += tab(indent) + formatPropertyName(property) + ': ';
|
|
switch (typeof obj[property]) {
|
// Array, Object
|
case 'object':
|
javascript += toJavaScript(obj[property], lang.delegate(options, { indent: indent }));
|
|
break;
|
|
case 'string':
|
// Coerce string values that should be boolean
|
if (obj[property] === 'true' || obj[property] === 'false') {
|
javascript += obj[property];
|
}
|
else {
|
// Widget editors are received by module ID, so convert any of those to constructors
|
javascript += (property === 'editor' && formatDijitFormWidget(obj[property])) ||
|
'\'' + escapeString(obj[property]) + '\'';
|
}
|
|
break;
|
|
// number, boolean
|
default:
|
javascript += obj[property];
|
}
|
}
|
}
|
}
|
|
return javascript;
|
}
|
|
function printArray(array, options, indent) {
|
var javascript = '';
|
var i;
|
|
for (i = 0; i < array.length; i++) {
|
javascript += tab(indent);
|
javascript += toJavaScript(array[i], lang.delegate(options, { indent: indent }));
|
|
if (i < array.length - 1) {
|
javascript += ',\n';
|
}
|
}
|
|
return javascript;
|
}
|
|
function escapeString(str) {
|
return str.replace(/[\\']/g, '\\$&');
|
}
|
|
function formatDijitFormWidget(str) {
|
return typeof str === 'string' && dijitFormWidgetRegex.test(str) ?
|
str.replace(dijitFormWidgetRegex, '$1') :
|
'';
|
}
|
|
function formatPropertyName(str) {
|
if (!propertyNameRegex.test(str)) {
|
return '\'' + str + '\'';
|
}
|
else {
|
return str;
|
}
|
}
|
|
toJavaScript.escapeString = escapeString;
|
toJavaScript.formatDijitFormWidget = formatDijitFormWidget;
|
toJavaScript.formatPropertyName = formatPropertyName;
|
|
return toJavaScript;
|
});
|