From 8cb5ec1c0eb3cd48f300c1edb94c503e1e483065 Mon Sep 17 00:00:00 2001 From: alekseybobkov Date: Fri, 29 Jan 2016 22:16:33 -0800 Subject: [PATCH] Fixed several minor bugs in Inspector. --- .../backend/traits/InspectableContainer.php | 18 ++++++- .../ui/js/inspector.editor.autocomplete.js | 2 +- .../assets/ui/js/inspector.editor.base.js | 12 +++++ .../assets/ui/js/inspector.editor.dropdown.js | 2 +- .../assets/ui/js/inspector.editor.set.js | 12 +++-- ...inspector.editor.stringlistautocomplete.js | 2 +- .../js/inspector.externalparametereditor.js | 20 +++++--- .../system/assets/ui/js/inspector.surface.js | 27 ++++++++-- modules/system/assets/ui/storm-min.js | 49 +++++++++++-------- 9 files changed, 103 insertions(+), 41 deletions(-) diff --git a/modules/backend/traits/InspectableContainer.php b/modules/backend/traits/InspectableContainer.php index 1376cb7e1..a3b5f5c70 100644 --- a/modules/backend/traits/InspectableContainer.php +++ b/modules/backend/traits/InspectableContainer.php @@ -33,7 +33,21 @@ trait InspectableContainer $obj = new $className(null); - $methodName = 'get'.ucfirst($property).'Options'; + // Nested properties have names like object.property. + // Convert them to Object.Property. + $propertyNameParts = explode('.', $property); + $propertyMethodName = ''; + foreach ($propertyNameParts as $part) { + $part = trim($part); + + if (!strlen($part)) { + continue; + } + + $propertyMethodName .= ucfirst($part); + } + + $methodName = 'get'.$propertyMethodName.'Options'; if (method_exists($obj, $methodName)) { $options = $obj->$methodName(); } @@ -53,4 +67,4 @@ trait InspectableContainer 'options' => $optionsArray ]; } -} +} \ No newline at end of file diff --git a/modules/system/assets/ui/js/inspector.editor.autocomplete.js b/modules/system/assets/ui/js/inspector.editor.autocomplete.js index c6a97733a..6e6215c09 100644 --- a/modules/system/assets/ui/js/inspector.editor.autocomplete.js +++ b/modules/system/assets/ui/js/inspector.editor.autocomplete.js @@ -200,7 +200,7 @@ return } - data['inspectorProperty'] = this.propertyDefinition.property + data['inspectorProperty'] = this.getPropertyPath() data['inspectorClassName'] = this.inspector.options.inspectorClass $form.request('onInspectableGetOptions', { diff --git a/modules/system/assets/ui/js/inspector.editor.base.js b/modules/system/assets/ui/js/inspector.editor.base.js index c0f0cd9f0..357404f77 100644 --- a/modules/system/assets/ui/js/inspector.editor.base.js +++ b/modules/system/assets/ui/js/inspector.editor.base.js @@ -81,6 +81,14 @@ BaseEditor.prototype.onInspectorPropertyChanged = function(property, value) { } + BaseEditor.prototype.notifyChildSurfacesPropertyChanged = function(property, value) { + if (!this.hasChildSurface()) { + return + } + + this.childInspector.notifyEditorsPropertyChanged(property, value) + } + BaseEditor.prototype.focus = function() { } @@ -92,6 +100,10 @@ return this.inspector.getRootSurface() } + BaseEditor.prototype.getPropertyPath = function() { + return this.inspector.getPropertyPath(this.propertyDefinition.property) + } + /** * Updates displayed value in the editor UI. The value is already set * in the Inspector and should be loaded from Inspector. diff --git a/modules/system/assets/ui/js/inspector.editor.dropdown.js b/modules/system/assets/ui/js/inspector.editor.dropdown.js index ea666597f..09cdb29b0 100644 --- a/modules/system/assets/ui/js/inspector.editor.dropdown.js +++ b/modules/system/assets/ui/js/inspector.editor.dropdown.js @@ -323,7 +323,7 @@ this.saveDependencyValues() } - data['inspectorProperty'] = this.propertyDefinition.property + data['inspectorProperty'] = this.getPropertyPath() data['inspectorClassName'] = this.inspector.options.inspectorClass this.showLoadingIndicator() diff --git a/modules/system/assets/ui/js/inspector.editor.set.js b/modules/system/assets/ui/js/inspector.editor.set.js index 6bc6f759f..ea40eda94 100644 --- a/modules/system/assets/ui/js/inspector.editor.set.js +++ b/modules/system/assets/ui/js/inspector.editor.set.js @@ -164,7 +164,7 @@ $.oc.foundation.element.addClass(link, 'loading-indicator-container size-small') this.showLoadingIndicator() - data['inspectorProperty'] = this.propertyDefinition.property + data['inspectorProperty'] = this.getPropertyPath() data['inspectorClassName'] = this.inspector.options.inspectorClass $form.request('onInspectableGetOptions', { @@ -309,6 +309,10 @@ } SetEditor.prototype.setPropertyValue = function(checkboxValue, isChecked) { + // In this method the Set Editor mimics the Surface. + // It acts as a parent surface for the children checkboxes, + // watching changes in them and updating the link text. + var currentValue = this.getNormalizedValue() if (currentValue === undefined) { @@ -319,8 +323,10 @@ currentValue = [] } - var resultValue = [] - for (var itemValue in this.propertyDefinition.items) { + var resultValue = [], + items = this.getItemsSource() + + for (var itemValue in items) { if (itemValue !== checkboxValue) { if (currentValue.indexOf(itemValue) !== -1) { resultValue.push(itemValue) diff --git a/modules/system/assets/ui/js/inspector.editor.stringlistautocomplete.js b/modules/system/assets/ui/js/inspector.editor.stringlistautocomplete.js index d363d7a3e..0b3963a54 100644 --- a/modules/system/assets/ui/js/inspector.editor.stringlistautocomplete.js +++ b/modules/system/assets/ui/js/inspector.editor.stringlistautocomplete.js @@ -428,7 +428,7 @@ return } - data['inspectorProperty'] = this.propertyDefinition.property + data['inspectorProperty'] = this.getPropertyPath() data['inspectorClassName'] = this.inspector.options.inspectorClass $form.request('onInspectableGetOptions', { diff --git a/modules/system/assets/ui/js/inspector.externalparametereditor.js b/modules/system/assets/ui/js/inspector.externalparametereditor.js index d373a9dcb..bf4e4dfde 100644 --- a/modules/system/assets/ui/js/inspector.externalparametereditor.js +++ b/modules/system/assets/ui/js/inspector.externalparametereditor.js @@ -23,10 +23,11 @@ var Base = $.oc.foundation.base, BaseProto = Base.prototype - var ExternalParameterEditor = function(inspector, propertyDefinition, containerCell) { + var ExternalParameterEditor = function(inspector, propertyDefinition, containerCell, initialValue) { this.inspector = inspector this.propertyDefinition = propertyDefinition this.containerCell = containerCell + this.initialValue = initialValue Base.call(this) @@ -43,6 +44,7 @@ this.inspector = null this.propertyDefinition = null this.containerCell = null + this.initialValue = null BaseProto.dispose.call(this) } @@ -108,18 +110,16 @@ } ExternalParameterEditor.prototype.setInitialValue = function() { - var propertyValue = this.inspector.getPropertyValue(this.propertyDefinition.property) - - if (!propertyValue) { + if (!this.initialValue) { return } - if (typeof propertyValue !== 'string') { + if (typeof this.initialValue !== 'string') { return } var matches = [] - if (matches = propertyValue.match(/^\{\{([^\}]+)\}\}$/)) { + if (matches = this.initialValue.match(/^\{\{([^\}]+)\}\}$/)) { var value = $.trim(matches[1]) if (value.length > 0) { @@ -209,15 +209,21 @@ ExternalParameterEditor.prototype.toggleEditorVisibility = function(show) { var container = this.getContainer(), children = container.children, - height = 0 + height = 19 + + // Fixed value instead of trying to get the container cell height. + // If the editor is contained in initially hidden editor (collapsed group), + // the container cell will be unknown. if (!show) { + /* height = this.containerCell.getAttribute('data-inspector-cell-height') if (!height) { height = $(this.containerCell).height() this.containerCell.setAttribute('data-inspector-cell-height', height) } + */ } for (var i = 0, len = children.length; i < len; i++) { diff --git a/modules/system/assets/ui/js/inspector.surface.js b/modules/system/assets/ui/js/inspector.surface.js index f6bbee90d..07828bcae 100644 --- a/modules/system/assets/ui/js/inspector.surface.js +++ b/modules/system/assets/ui/js/inspector.surface.js @@ -235,6 +235,7 @@ // if (property.property) { row.setAttribute('data-property', property.property) + row.setAttribute('data-property-path', this.getPropertyPath(property.property)) } this.applyGroupIndexAttribute(property, row, group) @@ -364,7 +365,13 @@ var cell = row.querySelector('td'), propertyDefinition = this.findPropertyDefinition(property), - editor = new $.oc.inspector.externalParameterEditor(this, propertyDefinition, cell) + initialValue = this.getPropertyValue(property) + + if (initialValue === undefined) { + initialValue = propertyEditor.getUndefinedValue() + } + + var editor = new $.oc.inspector.externalParameterEditor(this, propertyDefinition, cell, initialValue) this.externalParameterEditors.push(editor) } @@ -536,7 +543,8 @@ this.markPropertyChanged(property, false) } - this.notifyEditorsPropertyChanged(property, value) + var propertyPath = this.getPropertyPath(property) + this.getRootSurface().notifyEditorsPropertyChanged(propertyPath, value) if (this.options.onChange !== null) { this.options.onChange(property, value) @@ -553,11 +561,19 @@ return value } - Surface.prototype.notifyEditorsPropertyChanged = function(property, value) { + Surface.prototype.notifyEditorsPropertyChanged = function(propertyPath, value) { + // Editors use this event to watch changes in properties + // they depend on. All editors should be notified, including + // editors in nested surfaces. The property name is passed as a + // path object.property (if the property is nested), so that + // property depenencies could be defined as + // ['property', 'object.property'] + for (var i = 0, len = this.editors.length; i < len; i++) { var editor = this.editors[i] - editor.onInspectorPropertyChanged(property, value) + editor.onInspectorPropertyChanged(propertyPath, value) + editor.notifyChildSurfacesPropertyChanged(propertyPath, value) } } @@ -573,7 +589,8 @@ } Surface.prototype.markPropertyChanged = function(property, changed) { - var row = this.tableContainer.querySelector('tr[data-property="'+property+'"]') + var propertyPath = this.getPropertyPath(property), + row = this.tableContainer.querySelector('tr[data-property-path="'+propertyPath+'"]') if (changed) { $.oc.foundation.element.addClass(row, 'changed') diff --git a/modules/system/assets/ui/storm-min.js b/modules/system/assets/ui/storm-min.js index a40760eed..060efc0ce 100644 --- a/modules/system/assets/ui/storm-min.js +++ b/modules/system/assets/ui/storm-min.js @@ -3416,7 +3416,8 @@ if(!this.parentSurface){this.focusFirstEditor()}} Surface.prototype.moveToContainer=function(newContainer){this.container=newContainer this.container.appendChild(this.tableContainer)} Surface.prototype.buildRow=function(property,group){var row=document.createElement('tr'),th=document.createElement('th'),titleSpan=document.createElement('span'),description=this.buildPropertyDescription(property) -if(property.property){row.setAttribute('data-property',property.property)} +if(property.property){row.setAttribute('data-property',property.property) +row.setAttribute('data-property-path',this.getPropertyPath(property.property))} this.applyGroupIndexAttribute(property,row,group) $.oc.foundation.element.addClass(row,this.getRowCssClass(property,group)) this.applyHeadColspan(th,property) @@ -3462,7 +3463,9 @@ for(var i=0,len=rows.length;i-1} SetEditor.prototype.setPropertyValue=function(checkboxValue,isChecked){var currentValue=this.getNormalizedValue() if(currentValue===undefined){currentValue=this.propertyDefinition.default} if(!currentValue){currentValue=[]} -var resultValue=[] -for(var itemValue in this.propertyDefinition.items){if(itemValue!==checkboxValue){if(currentValue.indexOf(itemValue)!==-1){resultValue.push(itemValue)}} +var resultValue=[],items=this.getItemsSource() +for(var itemValue in items){if(itemValue!==checkboxValue){if(currentValue.indexOf(itemValue)!==-1){resultValue.push(itemValue)}} else{if(isChecked){resultValue.push(itemValue)}}} this.inspector.setPropertyValue(this.propertyDefinition.property,this.cleanUpValue(resultValue)) this.setLinkText(this.getLink())} @@ -4955,7 +4963,7 @@ return result} StringListAutocomplete.prototype.loadDynamicItems=function(){if(this.isDisposed()){return} var data=this.getRootSurface().getValues(),$form=$(this.popup).find('form') if(this.triggerGetItems(data)===false){return} -data['inspectorProperty']=this.propertyDefinition.property +data['inspectorProperty']=this.getPropertyPath() data['inspectorClassName']=this.inspector.options.inspectorClass $form.request('onInspectableGetOptions',{data:data,}).done(this.proxy(this.itemsRequestDone))} StringListAutocomplete.prototype.triggerGetItems=function(values){var $inspectable=this.getInspectableElement() @@ -5224,7 +5232,7 @@ var container=this.getContainer(),data=this.getRootSurface().getValues(),$form=$ $.oc.foundation.element.addClass(container,'loading-indicator-container size-small') this.showLoadingIndicator() if(this.triggerGetItems(data)===false){return} -data['inspectorProperty']=this.propertyDefinition.property +data['inspectorProperty']=this.getPropertyPath() data['inspectorClassName']=this.inspector.options.inspectorClass $form.request('onInspectableGetOptions',{data:data,}).done(this.proxy(this.itemsRequestDone)).always(this.proxy(this.hideLoadingIndicator))} AutocompleteEditor.prototype.triggerGetItems=function(values){var $inspectable=this.getInspectableElement() @@ -5364,9 +5372,10 @@ $.oc={} if($.oc.inspector===undefined) $.oc.inspector={} var Base=$.oc.foundation.base,BaseProto=Base.prototype -var ExternalParameterEditor=function(inspector,propertyDefinition,containerCell){this.inspector=inspector +var ExternalParameterEditor=function(inspector,propertyDefinition,containerCell,initialValue){this.inspector=inspector this.propertyDefinition=propertyDefinition this.containerCell=containerCell +this.initialValue=initialValue Base.call(this) this.init()} ExternalParameterEditor.prototype=Object.create(BaseProto) @@ -5376,6 +5385,7 @@ this.unregisterHandlers() this.inspector=null this.propertyDefinition=null this.containerCell=null +this.initialValue=null BaseProto.dispose.call(this)} ExternalParameterEditor.prototype.init=function(){this.tooltipText='Click to enter the external parameter name to load the property value from' this.build() @@ -5401,11 +5411,10 @@ while(this.containerCell.firstChild){var child=this.containerCell.firstChild container.appendChild(child)} container.appendChild(editor) this.containerCell.appendChild(container)} -ExternalParameterEditor.prototype.setInitialValue=function(){var propertyValue=this.inspector.getPropertyValue(this.propertyDefinition.property) -if(!propertyValue){return} -if(typeof propertyValue!=='string'){return} +ExternalParameterEditor.prototype.setInitialValue=function(){if(!this.initialValue){return} +if(typeof this.initialValue!=='string'){return} var matches=[] -if(matches=propertyValue.match(/^\{\{([^\}]+)\}\}$/)){var value=$.trim(matches[1]) +if(matches=this.initialValue.match(/^\{\{([^\}]+)\}\}$/)){var value=$.trim(matches[1]) if(value.length>0){this.showEditor(true) this.getInput().value=value this.inspector.setPropertyValue(this.propertyDefinition.property,null,true,true)}}} @@ -5440,10 +5449,8 @@ link.setAttribute('data-original-title',this.tooltipText) this.getInput().setAttribute('tabindex','-1') this.toggleEditorVisibility(true) setTimeout(this.proxy(this.hideEditor),200)} -ExternalParameterEditor.prototype.toggleEditorVisibility=function(show){var container=this.getContainer(),children=container.children,height=0 -if(!show){height=this.containerCell.getAttribute('data-inspector-cell-height') -if(!height){height=$(this.containerCell).height() -this.containerCell.setAttribute('data-inspector-cell-height',height)}} +ExternalParameterEditor.prototype.toggleEditorVisibility=function(show){var container=this.getContainer(),children=container.children,height=19 +if(!show){} for(var i=0,len=children.length;i