/* * External parameter editor for Inspector. * * The external parameter editor allows to use URL and * other external parameters as values for the inspectable * properties. * */ +function ($) { "use strict"; // NAMESPACES // ============================ if ($.oc === undefined) $.oc = {} if ($.oc.inspector === undefined) $.oc.inspector = {} // CLASS DEFINITION // ============================ var Base = $.oc.foundation.base, BaseProto = Base.prototype 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) ExternalParameterEditor.prototype.constructor = Base ExternalParameterEditor.prototype.dispose = function() { this.disposeControls() 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() this.registerHandlers() this.setInitialValue() } /** * Builds the external parameter editor markup: * *
* <-- original property editing input/markup *
*
* * * * *
*
*
*/ ExternalParameterEditor.prototype.build = function() { var container = document.createElement('div'), editor = document.createElement('div'), controls = document.createElement('div'), input = document.createElement('input'), link = document.createElement('a'), icon = document.createElement('i') container.setAttribute('class', 'external-param-editor-container') editor.setAttribute('class', 'external-editor') controls.setAttribute('class', 'controls') input.setAttribute('type', 'text') input.setAttribute('tabindex', '-1') link.setAttribute('href', '#') link.setAttribute('class', 'external-editor-link') link.setAttribute('tabindex', '-1') link.setAttribute('title', this.tooltipText) $(link).tooltip({'container': 'body', delay: 500}) icon.setAttribute('class', 'oc-icon-terminal') link.appendChild(icon) controls.appendChild(input) controls.appendChild(link) editor.appendChild(controls) while (this.containerCell.firstChild) { var child = this.containerCell.firstChild container.appendChild(child) } container.appendChild(editor) this.containerCell.appendChild(container) } ExternalParameterEditor.prototype.setInitialValue = function() { if (!this.initialValue) { return } if (typeof this.initialValue !== 'string') { return } var matches = [] 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) } } } ExternalParameterEditor.prototype.showEditor = function(building) { var editor = this.getEditor(), input = this.getInput(), container = this.getContainer(), link = this.getLink() var position = $(editor).position() if (!building) { editor.style.right = 0 editor.style.left = position.left + 'px' } else { editor.style.right = 0 } setTimeout(this.proxy(this.repositionEditor), 0) $.oc.foundation.element.addClass(container, 'editor-visible') link.setAttribute('data-original-title', 'Click to enter the property value') this.toggleEditorVisibility(false) input.setAttribute('tabindex', 0) if (!building) { input.focus() } } ExternalParameterEditor.prototype.repositionEditor = function() { this.getEditor().style.left = 0 this.containerCell.scrollTop = 0 } ExternalParameterEditor.prototype.hideEditor = function() { var editor = this.getEditor(), container = this.getContainer() editor.style.left = 'auto' editor.style.right = '30px' $.oc.foundation.element.removeClass(container, 'editor-visible') $.oc.foundation.element.removeClass(this.containerCell, 'active') var propertyEditor = this.inspector.findPropertyEditor(this.propertyDefinition.property) if (propertyEditor) { propertyEditor.onExternalPropertyEditorHidden() } } ExternalParameterEditor.prototype.toggleEditor = function(ev) { $.oc.foundation.event.stop(ev) var link = this.getLink(), container = this.getContainer(), editor = this.getEditor() $(link).tooltip('hide') if (!this.isEditorVisible()) { this.showEditor() return } var left = container.offsetWidth editor.style.left = left + 'px' 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) } } // 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. height = Math.max(height, 19) for (var i = 0, len = children.length; i < len; i++) { var element = children[i] if ($.oc.foundation.element.hasClass(element, 'external-editor')) { continue } if (show) { $.oc.foundation.element.removeClass(element, 'hide') } else { container.style.height = height + 'px' $.oc.foundation.element.addClass(element, 'hide') } } } ExternalParameterEditor.prototype.focus = function() { this.getInput().focus() } ExternalParameterEditor.prototype.validate = function(silentMode) { var value = $.trim(this.getValue()) if (value.length === 0) { if (!silentMode) { $.oc.flashMsg({text: 'Please enter the external parameter name.', 'class': 'error', 'interval': 5}) this.focus() } return false } return true } // // Event handlers // ExternalParameterEditor.prototype.registerHandlers = function() { var input = this.getInput() this.getLink().addEventListener('click', this.proxy(this.toggleEditor)) input.addEventListener('focus', this.proxy(this.onInputFocus)) input.addEventListener('change', this.proxy(this.onInputChange)) } ExternalParameterEditor.prototype.onInputFocus = function() { this.inspector.makeCellActive(this.containerCell) } ExternalParameterEditor.prototype.onInputChange = function() { this.inspector.markPropertyChanged(this.propertyDefinition.property, true) } // // Disposing // ExternalParameterEditor.prototype.unregisterHandlers = function() { var input = this.getInput() this.getLink().removeEventListener('click', this.proxy(this.toggleEditor)) input.removeEventListener('focus', this.proxy(this.onInputFocus)) input.removeEventListener('change', this.proxy(this.onInputChange)) } ExternalParameterEditor.prototype.disposeControls = function() { $(this.getLink()).tooltip('destroy') } // // Helpers // ExternalParameterEditor.prototype.getInput = function() { return this.containerCell.querySelector('div.external-editor input') } ExternalParameterEditor.prototype.getValue = function() { return this.getInput().value } ExternalParameterEditor.prototype.getLink = function() { return this.containerCell.querySelector('a.external-editor-link') } ExternalParameterEditor.prototype.getContainer = function() { return this.containerCell.querySelector('div.external-param-editor-container') } ExternalParameterEditor.prototype.getEditor = function() { return this.containerCell.querySelector('div.external-editor') } ExternalParameterEditor.prototype.getPropertyName = function() { return this.propertyDefinition.property } ExternalParameterEditor.prototype.isEditorVisible = function() { return $.oc.foundation.element.hasClass(this.getContainer(), 'editor-visible') } $.oc.inspector.externalParameterEditor = ExternalParameterEditor }(window.jQuery);