winter/modules/system/assets/ui/js/inspector.datainteraction.js
2019-09-14 06:25:18 -06:00

163 lines
5.2 KiB
JavaScript

/*
* Inspector data interaction class.
*
* Provides methods for loading and writing Inspector configuration
* and values form and to inspectable elements.
*/
+function ($) { "use strict";
// CLASS DEFINITION
// ============================
var Base = $.oc.foundation.base,
BaseProto = Base.prototype
var DataInteraction = function(element) {
this.element = element
Base.call(this)
}
DataInteraction.prototype = Object.create(BaseProto)
DataInteraction.prototype.constructor = Base
DataInteraction.prototype.dispose = function() {
this.element = null
BaseProto.dispose.call(this)
}
DataInteraction.prototype.getElementValuesInput = function() {
return this.element.querySelector('input[data-inspector-values]')
}
DataInteraction.prototype.normalizePropertyCode = function(code, configuration) {
var lowerCaseCode = code.toLowerCase()
for (var index in configuration) {
var propertyInfo = configuration[index]
if (propertyInfo.property.toLowerCase() == lowerCaseCode) {
return propertyInfo.property
}
}
return code
}
DataInteraction.prototype.loadValues = function(configuration) {
var valuesField = this.getElementValuesInput()
if (valuesField) {
var valuesStr = $.trim(valuesField.value)
try {
return valuesStr.length === 0 ? {} : JSON.parse(valuesStr)
}
catch (err) {
throw new Error('Error parsing Inspector field values. ' + err)
}
}
var values = {},
attributes = this.element.attributes
for (var i=0, len = attributes.length; i < len; i++) {
var attribute = attributes[i],
matches = []
if (matches = attribute.name.match(/^data-property-(.*)$/)) {
// Important - values contained in data-property-xxx attributes are
// considered strings and never parsed with JSON. The use of the
// data-property-xxx attributes is very limited - they're only
// used in Pages for creating snippets from partials, where properties
// are created with a table UI widget, which doesn't allow creating
// properties of any complex types.
//
// There is no a technically reliable way to determine when a string
// is a JSON data or a regular string. Users can enter a value
// like [10], which is a proper JSON value, but meant to be a string.
//
// One possible way to resolve it, if to check the property type loaded
// from the configuration and see if the corresponding editor expects
// complex data.
var normalizedPropertyName = normalizePropertyCode(matches[1], configuration)
values[normalizedPropertyName] = attribute.value
}
}
return values
}
DataInteraction.prototype.loadConfiguration = function(onComplete) {
var configurationField = this.element.querySelector('input[data-inspector-config]'),
result = {
configuration: {},
title: null,
description: null
},
$element = $(this.element)
result.title = $element.data('inspector-title')
result.description = $element.data('inspector-description')
if (configurationField) {
result.configuration = this.parseConfiguration(configurationField.value)
onComplete(result, this)
return
}
var $form = $element.closest('form'),
data = $element.data(),
self = this
$.oc.stripeLoadIndicator.show()
$form.request('onGetInspectorConfiguration', {
data: data
}).done(function inspectorConfigurationRequestDoneClosure(data) {
self.configurartionRequestDone(data, onComplete, result)
}).always(function() {
$.oc.stripeLoadIndicator.hide()
})
}
//
// Internal methods
//
DataInteraction.prototype.parseConfiguration = function(configuration) {
if (!$.isArray(configuration) && !$.isPlainObject(configuration)) {
if ($.trim(configuration) === 0) {
return {}
}
try {
return JSON.parse(configuration)
}
catch(err) {
throw new Error('Error parsing Inspector configuration. ' + err)
}
}
else {
return configuration
}
}
DataInteraction.prototype.configurartionRequestDone = function(data, onComplete, result) {
result.configuration = this.parseConfiguration(data.configuration.properties)
if (data.configuration.title !== undefined) {
result.title = data.configuration.title
}
if (data.configuration.description !== undefined) {
result.description = data.configuration.description
}
onComplete(result, this)
}
$.oc.inspector.dataInteraction = DataInteraction
}(window.jQuery);