From 6ddc3668082cce7aa47caf9272f9c040792b6a71 Mon Sep 17 00:00:00 2001 From: alekseybobkov Date: Tue, 13 Oct 2015 20:28:41 -0700 Subject: [PATCH] Added popup and container wrappers for Inspector, minor fixes in Inspector editors, minor extensions in the popup API. --- .../assets/ui/js/inspector.datainteraction.js | 160 ++ .../assets/ui/js/inspector.editor.base.js | 4 + .../ui/js/inspector.editor.objectlist.js | 2 + .../ui/js/inspector.editor.popupbase.js | 4 + .../assets/ui/js/inspector.editor.text.js | 1 - .../system/assets/ui/js/inspector.engine.js | 1 - .../system/assets/ui/js/inspector.helpers.js | 1 + .../system/assets/ui/js/inspector.manager.js | 141 ++ .../system/assets/ui/js/inspector.surface.js | 33 +- .../assets/ui/js/inspector.wrapper.base.js | 288 +++ .../ui/js/inspector.wrapper.container.js | 215 ++ .../assets/ui/js/inspector.wrapper.popup.js | 203 ++ modules/system/assets/ui/js/popover.js | 12 +- .../assets/ui/less/global.variables.less | 2 +- modules/system/assets/ui/less/popover.less | 5 + modules/system/assets/ui/storm-min.js | 1858 ++++++----------- modules/system/assets/ui/storm.css | 5 +- modules/system/assets/ui/storm.js | 1 - 18 files changed, 1755 insertions(+), 1181 deletions(-) create mode 100644 modules/system/assets/ui/js/inspector.datainteraction.js create mode 100644 modules/system/assets/ui/js/inspector.manager.js create mode 100644 modules/system/assets/ui/js/inspector.wrapper.base.js create mode 100644 modules/system/assets/ui/js/inspector.wrapper.container.js create mode 100644 modules/system/assets/ui/js/inspector.wrapper.popup.js diff --git a/modules/system/assets/ui/js/inspector.datainteraction.js b/modules/system/assets/ui/js/inspector.datainteraction.js new file mode 100644 index 000000000..3881fb4ed --- /dev/null +++ b/modules/system/assets/ui/js/inspector.datainteraction.js @@ -0,0 +1,160 @@ +/* + * 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 ? {} : $.parseJSON(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() + var request = $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 $.parseJSON(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); \ No newline at end of file diff --git a/modules/system/assets/ui/js/inspector.editor.base.js b/modules/system/assets/ui/js/inspector.editor.base.js index 5ff780c67..a45d63d4d 100644 --- a/modules/system/assets/ui/js/inspector.editor.base.js +++ b/modules/system/assets/ui/js/inspector.editor.base.js @@ -81,6 +81,10 @@ return this.childInspector !== null } + BaseEditor.prototype.getRootSurface = function() { + return this.inspector.getRootSurface() + } + /** * 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.objectlist.js b/modules/system/assets/ui/js/inspector.editor.objectlist.js index dd0681552..53dcf2821 100644 --- a/modules/system/assets/ui/js/inspector.editor.objectlist.js +++ b/modules/system/assets/ui/js/inspector.editor.objectlist.js @@ -631,6 +631,7 @@ this.popup = popup.get(0) this.buildPopupContents(this.popup) + this.getRootSurface().popupDisplayed() } ObjectListEditor.prototype.onPopupHidden = function(ev, link, popup) { @@ -642,6 +643,7 @@ $.oc.foundation.controlUtils.disposeControls(this.popup) this.popup = null + this.getRootSurface().popupHidden() } ObjectListEditor.prototype.onSubmit = function(ev) { diff --git a/modules/system/assets/ui/js/inspector.editor.popupbase.js b/modules/system/assets/ui/js/inspector.editor.popupbase.js index 47b51a2fb..4f9133068 100644 --- a/modules/system/assets/ui/js/inspector.editor.popupbase.js +++ b/modules/system/assets/ui/js/inspector.editor.popupbase.js @@ -110,11 +110,15 @@ this.popup = popup.get(0) this.configurePopup(popup) + + this.getRootSurface().popupDisplayed() } PopupBase.prototype.onPopupHidden = function(ev, link, popup) { $(popup).off('.inspector', 'form', this.proxy(this.onSubmit)) this.popup = null + + this.getRootSurface().popupHidden() } PopupBase.prototype.onSubmit = function(ev) { diff --git a/modules/system/assets/ui/js/inspector.editor.text.js b/modules/system/assets/ui/js/inspector.editor.text.js index 0fde344f0..28dc74026 100644 --- a/modules/system/assets/ui/js/inspector.editor.text.js +++ b/modules/system/assets/ui/js/inspector.editor.text.js @@ -78,7 +78,6 @@ value = $.trim($textarea.val()) this.inspector.setPropertyValue(this.propertyDefinition.property, value) -// TODO: validate here } $.oc.inspector.propertyEditors.text = TextEditor diff --git a/modules/system/assets/ui/js/inspector.engine.js b/modules/system/assets/ui/js/inspector.engine.js index 155bdcec5..b8abbb11a 100644 --- a/modules/system/assets/ui/js/inspector.engine.js +++ b/modules/system/assets/ui/js/inspector.engine.js @@ -87,5 +87,4 @@ return result } - }(window.jQuery); diff --git a/modules/system/assets/ui/js/inspector.helpers.js b/modules/system/assets/ui/js/inspector.helpers.js index 71afde027..728911f03 100644 --- a/modules/system/assets/ui/js/inspector.helpers.js +++ b/modules/system/assets/ui/js/inspector.helpers.js @@ -29,4 +29,5 @@ $.oc.inspector.helpers.generateUniqueId = function() { return "inspectorid-" + Math.floor(Math.random() * new Date().getTime()); } + }(window.jQuery) \ No newline at end of file diff --git a/modules/system/assets/ui/js/inspector.manager.js b/modules/system/assets/ui/js/inspector.manager.js new file mode 100644 index 000000000..3e138106c --- /dev/null +++ b/modules/system/assets/ui/js/inspector.manager.js @@ -0,0 +1,141 @@ +/* + * Inspector management functions. + * + * Watches inspectable elements clicks and creates Inspector surfaces in popups + * and containers. + */ ++function ($) { "use strict"; + var Base = $.oc.foundation.base, + BaseProto = Base.prototype + + var InspectorManager = function() { + Base.call(this) + + this.init() + } + + InspectorManager.prototype = Object.create(BaseProto) + InspectorManager.prototype.constructor = Base + + InspectorManager.prototype.init = function() { + $(document).on('click', '[data-inspectable]', this.proxy(this.onInspectableClicked)) + } + + InspectorManager.prototype.getContainerElement = function($element) { + var $containerHolder = $element.closest('[data-inspector-container]') + if ($containerHolder.length === 0) { + return null + } + + var $container = $containerHolder.find($containerHolder.data('inspector-container')) + if ($container.length === 0) { + throw new Error('Inspector container ' + $containerHolder.data['inspector-container'] + ' element is not found.') + } + + return $container + } + + InspectorManager.prototype.createInspectorPopup = function($element, containerSupported) { + new $.oc.inspector.wrappers.popup($element, null, { + containerSupported: containerSupported + }) + } + + InspectorManager.prototype.createInspectorContainer = function($element, $container) { + new $.oc.inspector.wrappers.container($element, null, { + containerSupported: true, + container: $container + }) + } + + InspectorManager.prototype.switchToPopup = function(wrapper) { + new $.oc.inspector.wrappers.popup(wrapper.$element, wrapper, { + containerSupported: true + }) + + wrapper.cleanupAfterSwitch() + this.setContainerPreference(false) + } + + InspectorManager.prototype.switchToContainer = function(wrapper) { + var $container = this.getContainerElement(wrapper.$element) + + if (!$container) { + throw new Error('Cannot switch to container: a container element is not found') + } + + new $.oc.inspector.wrappers.container(wrapper.$element, wrapper, { + containerSupported: true, + container: $container + }) + + wrapper.cleanupAfterSwitch() + this.setContainerPreference(true) + } + + InspectorManager.prototype.createInspector = function($element) { + var $container = this.getContainerElement($element) + + // If there's no container option, create the Inspector popup + // + if (!$container) { + this.createInspectorPopup($element, false) + } + else { + // If the container is already in use, apply values to the inspectable elements + if (!this.applyValuesFromContainer($container)) { + return + } + + // Dispose existing container wrapper, if any + $.oc.foundation.controlUtils.disposeControls($container.get(0)) + + if (!this.getContainerPreference()) { + // If container is not a preferred option, create Inspector popoup + this.createInspectorPopup($element, true) + } + else { + // Otherwise, create Inspector in the container + this.createInspectorContainer($element, $container) + } + } + } + + InspectorManager.prototype.getContainerPreference = function() { + if (!Modernizr.localstorage) { + return false + } + + return localStorage.getItem('oc.inspectorUseContainer') === "true" + } + + InspectorManager.prototype.setContainerPreference = function(value) { + if (!Modernizr.localstorage) { + return + } + + return localStorage.setItem('oc.inspectorUseContainer', value ? "true" : "false") + } + + InspectorManager.prototype.applyValuesFromContainer = function($container) { + var applyEvent = $.Event('apply.oc.inspector') + + $container.trigger(applyEvent) + if (applyEvent.isDefaultPrevented()) { + return false + } + + return true + } + + InspectorManager.prototype.onInspectableClicked = function(ev) { + var $element = $(ev.currentTarget) + + if ($element.data('oc.inspectorVisible')) + return false + + this.createInspector($element) + } + + $.oc.inspector.manager = new InspectorManager() +}(window.jQuery); \ No newline at end of file diff --git a/modules/system/assets/ui/js/inspector.surface.js b/modules/system/assets/ui/js/inspector.surface.js index 8f8196a07..b395f7a2d 100644 --- a/modules/system/assets/ui/js/inspector.surface.js +++ b/modules/system/assets/ui/js/inspector.surface.js @@ -48,6 +48,7 @@ this.values = values this.originalValues = $.extend(true, {}, values) // Clone the values hash this.idCounter = 1 + this.popupCounter = 0 this.parentSurface = parentSurface this.editors = [] @@ -88,6 +89,8 @@ this.values = null this.originalValues = null this.options.onChange = null + this.options.onPopupDisplayed = null + this.options.onPopupHidden = null this.parentSurface = null this.groupManager = null this.group = null @@ -212,6 +215,12 @@ } } + 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'), @@ -611,6 +620,26 @@ } } + Surface.prototype.popupDisplayed = function() { + if (this.popupCounter === 0 && this.options.onPopupDisplayed !== null) { + this.options.onPopupDisplayed() + } + + this.popupCounter++ + } + + Surface.prototype.popupHidden = function() { + this.popupCounter-- + + if (this.popupCounter < 0) { + this.popupCounter = 0 + } + + if (this.popupCounter === 0 && this.options.onPopupHidden !== null) { + this.options.onPopupHidden() + } + } + // // Nested surfaces support // @@ -809,7 +838,9 @@ Surface.DEFAULTS = { enableExternalParameterEditor: false, - onChange: null + onChange: null, + onPopupDisplayed: null, + onPopupHidden: null } // REGISTRATION diff --git a/modules/system/assets/ui/js/inspector.wrapper.base.js b/modules/system/assets/ui/js/inspector.wrapper.base.js new file mode 100644 index 000000000..12e4fbcf4 --- /dev/null +++ b/modules/system/assets/ui/js/inspector.wrapper.base.js @@ -0,0 +1,288 @@ +/* + * Inspector wrapper base class. + */ ++function ($) { "use strict"; + + // NAMESPACES + // ============================ + + if ($.oc.inspector === undefined) + $.oc.inspector = {} + + if ($.oc.inspector.wrappers === undefined) + $.oc.inspector.wrappers = {} + + // CLASS DEFINITION + // ============================ + + var Base = $.oc.foundation.base, + BaseProto = Base.prototype + + var BaseWrapper = function($element, sourceWrapper, options) { + this.$element = $element + + if (!sourceWrapper) { + this.surface = surface + this.title = null + this.description = null + } + else { + this.surface = sourceWrapper.surface + this.title = sourceWrapper.title + this.description = sourceWrapper.description + + sourceWrapper = null + } + + this.options = $.extend({}, BaseWrapper.DEFAULTS, typeof options == 'object' && options) + this.switched = false + + Base.call(this) + this.init() + } + + BaseWrapper.prototype = Object.create(BaseProto) + BaseWrapper.prototype.constructor = Base + + BaseWrapper.prototype.dispose = function() { + if (!this.switched) { + this.$element.removeClass('inspector-open') + this.setInspectorVisibleFlag(false) + } + + this.surface = null + this.$element = null + this.title = null + this.description = null + + BaseProto.dispose.call(this) + } + + BaseWrapper.prototype.init = function() { + // Wrappers can create a new surface or inject an existing + // surface to the UI they manage. + // + // If there is no surface provided in the wrapper constructor, + // the wrapper first loads the Inspector configuration and values + // and then calls the createSurfaceAndUi() method with all information + // required for creating a new Inspector surface and UI. + + if (!this.surface) { + this.loadConfiguration() + } + else { + this.adoptSurface() + } + + this.$element.addClass('inspector-open') + } + + // + // Helper methods + // + + BaseWrapper.prototype.getElementValuesInput = function() { + return this.$element.find('input[data-inspector-values]') + } + + BaseWrapper.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 + } + + BaseWrapper.prototype.isExternalParametersEditorEnabled = function() { + return this.$element.closest('[data-inspector-external-parameters]').length > 0 + } + + BaseWrapper.prototype.initSurface = function(containerElement, properties, values) { + var options = { + enableExternalParameterEditor: this.isExternalParametersEditorEnabled() + } + + this.surface = new $.oc.inspector.surface( + containerElement, + properties, + values, + $.oc.inspector.helpers.generateElementUniqueId(this.$element.get(0)), + options) + } + + // + // Wrapper API + // + + BaseWrapper.prototype.createSurfaceAndUi = function(properties, values) { + + } + + BaseWrapper.prototype.setInspectorVisibleFlag = function(value) { + this.$element.data('oc.inspectorVisible', value) + } + + BaseWrapper.prototype.adoptSurface = function() { + + } + + BaseWrapper.prototype.cleanupAfterSwitch = function() { + this.switched = true + this.dispose() + } + + // + // Values + // + + BaseWrapper.prototype.loadValues = function(configuration) { + var $valuesField = this.getElementValuesInput() + + if ($valuesField.length > 0) { + var valuesStr = $.trim($valuesField.val()) + + try { + return valuesStr.length === 0 ? {} : $.parseJSON(valuesStr) + } catch (err) { + throw new Error('Error parsing Inspector field values. ' + err) + } + } + + var values = {}, + attributes = this.$element.get(0).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 = this.normalizePropertyCode(matches[1], configuration) + values[normalizedPropertyName] = attribute.value + } + } + + return values + } + + BaseWrapper.prototype.applyValues = function() { + var $valuesField = this.getElementValuesInput(), + values = this.surface.getValues() + + if ($valuesField.length > 0) { + $valuesField.val(JSON.stringify(values)) + } + else { + for (var property in values) { + var value = values[property] + + if ($.isArray(value) ||$.isPlainObject(value)) { + throw new Error('Inspector data-property-xxx attributes do not support complex values. Property: ' + property) + } + + this.$element.attr('data-property-' + property, value) + } + } + } + + // + // Configuration + // + + BaseWrapper.prototype.loadConfiguration = function() { + var $configurationField = this.$element.find('input[data-inspector-config]'), + result = { + properties: {}, + title: null, + description: null + } + + result.title = this.$element.data('inspector-title') + result.description = this.$element.data('inspector-description') + + if ($configurationField.length > 0) { + result.properties = this.parseConfiguration($configurationField.val()) + + this.configurationLoaded(result) + return + } + + var $form = this.$element.closest('form'), + data = this.$element.data(), + self = this + + $.oc.stripeLoadIndicator.show() + var request = $form.request('onGetInspectorConfiguration', { + data: data + }).done(function inspectorConfigurationRequestDoneClosure(data) { + self.onConfigurartionRequestDone(data, result) + }).always(function() { + $.oc.stripeLoadIndicator.hide() + }) + } + + BaseWrapper.prototype.parseConfiguration = function(configuration) { + if (!$.isArray(configuration) && !$.isPlainObject(configuration)) { + if ($.trim(configuration) === 0) { + return {} + } + + try { + return $.parseJSON(configuration) + } catch(err) { + throw new Error('Error parsing Inspector configuration. ' + err) + } + } else { + return configuration + } + } + + BaseWrapper.prototype.configurationLoaded = function(configuration) { + var values = this.loadValues(configuration.properties) + + this.title = configuration.title + this.description = configuration.description + + this.createSurfaceAndUi(configuration.properties, values) + } + + BaseWrapper.prototype.onConfigurartionRequestDone = function(data, result) { + result.properties = 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 + } + + this.configurationLoaded(result) + } + + BaseWrapper.DEFAULTS = { + containerSupported: false + } + + $.oc.inspector.wrappers.base = BaseWrapper +}(window.jQuery); \ No newline at end of file diff --git a/modules/system/assets/ui/js/inspector.wrapper.container.js b/modules/system/assets/ui/js/inspector.wrapper.container.js new file mode 100644 index 000000000..f96205ab7 --- /dev/null +++ b/modules/system/assets/ui/js/inspector.wrapper.container.js @@ -0,0 +1,215 @@ +/* + * Inspector container wrapper. + */ ++function ($) { "use strict"; + + // CLASS DEFINITION + // ============================ + + var Base = $.oc.inspector.wrappers.base, + BaseProto = Base.prototype + + var InspectorContainer = function($element, surface, options) { + if (!options.container) { + throw new Error('Cannot create Inspector container wrapper without a container element.') + } + + this.surfaceContainer = null + + Base.call(this, $element, surface, options) + } + + InspectorContainer.prototype = Object.create(BaseProto) + InspectorContainer.prototype.constructor = Base + + InspectorContainer.prototype.init = function() { + this.registerHandlers() + + BaseProto.init.call(this) + } + + InspectorContainer.prototype.dispose = function() { + this.unregisterHandlers() + this.removeControls() + + this.surfaceContainer = null + + BaseProto.dispose.call(this) + } + + InspectorContainer.prototype.createSurfaceAndUi = function(properties, values) { + this.buildUi() + + this.initSurface(this.surfaceContainer, properties, values) + } + + InspectorContainer.prototype.adoptSurface = function() { + this.buildUi() + + this.surface.moveToContainer(this.surfaceContainer) + } + + InspectorContainer.prototype.buildUi = function() { + var scrollable = this.isScrollable(), + head = this.buildHead(), + layoutElements = this.buildLayout() + + layoutElements.headContainer.appendChild(head) + + if (scrollable) { + var scrollpad = this.buildScrollpad() + + this.surfaceContainer = scrollpad.container + layoutElements.bodyContainer.appendChild(scrollpad.scrollpad) + + $(scrollpad.scrollpad).scrollpad() + } + else { + this.surfaceContainer = layoutElements.bodyContainer + } + + this.setInspectorVisibleFlag(true) + } + + InspectorContainer.prototype.buildHead = function() { + var container = document.createElement('div'), + header = document.createElement('h3'), + paragraph = document.createElement('p'), + detachButton = document.createElement('span'), + closeButton = document.createElement('span') + + container.setAttribute('class', 'inspector-header') + detachButton.setAttribute('class', 'oc-icon-external-link-square detach') + closeButton.setAttribute('class', 'close') + + header.textContent = this.title + paragraph.textContent = this.description + closeButton.innerHTML = '×'; + + container.appendChild(header) + container.appendChild(paragraph) + container.appendChild(detachButton) + container.appendChild(closeButton) + + return container + } + + InspectorContainer.prototype.buildScrollpad = function() { + var scrollpad = document.createElement('div'), + scrollWrapper = document.createElement('div'), + scrollableContainer = document.createElement('div') + + scrollpad.setAttribute('class', 'control-scrollpad') + scrollpad.setAttribute('data-control', 'scrollpad') + scrollWrapper.setAttribute('class', 'scroll-wrapper inspector-wrapper') + + scrollpad.appendChild(scrollWrapper) + scrollWrapper.appendChild(scrollableContainer) + + return { + scrollpad: scrollpad, + container: scrollableContainer + } + } + + InspectorContainer.prototype.buildLayout = function() { + var layout = document.createElement('div'), + headRow = document.createElement('div'), + bodyRow = document.createElement('div'), + bodyCell = document.createElement('div'), + layoutRelative = document.createElement('div') + + layout.setAttribute('class', 'layout') + headRow.setAttribute('class', 'layout-row min-size') + bodyRow.setAttribute('class', 'layout-row') + bodyCell.setAttribute('class', 'layout-cell') + layoutRelative.setAttribute('class', 'layout-relative') + + bodyCell.appendChild(layoutRelative) + bodyRow.appendChild(bodyCell) + + layout.appendChild(headRow) + layout.appendChild(bodyRow) + + this.options.container.get(0).appendChild(layout) + + $.oc.foundation.controlUtils.markDisposable(layout) + this.registerLayoutHandlers(layout) + + return { + headContainer: headRow, + bodyContainer: layoutRelative + } + } + + InspectorContainer.prototype.validateAndApply = function() { + if (!this.surface.validate()) { + return false + } + + this.applyValues() + return true + } + + InspectorContainer.prototype.isScrollable = function() { + return this.options.container.data('inspector-scrollable') !== undefined + } + + InspectorContainer.prototype.getLayout = function() { + return this.options.container.get(0).querySelector('div.layout') + } + + InspectorContainer.prototype.registerLayoutHandlers = function(layout) { + var $layout = $(layout) + + $layout.one('dispose-control', this.proxy(this.dispose)) + $layout.on('click', 'span.close', this.proxy(this.onClose)) + $layout.on('click', 'span.detach', this.proxy(this.onDetach)) + } + + InspectorContainer.prototype.registerHandlers = function() { + this.options.container.on('apply.oc.inspector', this.proxy(this.onApplyValues)) + } + + InspectorContainer.prototype.unregisterHandlers = function() { + var $layout = $(this.getLayout()) + + this.options.container.off('apply.oc.inspector', this.proxy(this.onApplyValues)) + $layout.off('dispose-control', this.proxy(this.dispose)) + $layout.off('click', 'span.close', this.proxy(this.onClose)) + $layout.off('click', 'span.detach', this.proxy(this.onDetach)) + } + + InspectorContainer.prototype.removeControls = function() { + if (this.isScrollable()) { + this.options.container.find('.control-scrollpad').scrollpad('dispose') + } + + var layout = this.getLayout() + layout.parentNode.removeChild(layout) + } + + InspectorContainer.prototype.onApplyValues = function(ev) { + if (!this.validateAndApply()) { + ev.preventDefault() + return false + } + } + + InspectorContainer.prototype.onClose = function(ev) { + if (!this.validateAndApply()) { + ev.preventDefault() + return false + } + + this.surface.dispose() + + this.dispose() + } + + InspectorContainer.prototype.onDetach = function() { + $.oc.inspector.manager.switchToPopup(this) + } + + $.oc.inspector.wrappers.container = InspectorContainer +}(window.jQuery); \ No newline at end of file diff --git a/modules/system/assets/ui/js/inspector.wrapper.popup.js b/modules/system/assets/ui/js/inspector.wrapper.popup.js new file mode 100644 index 000000000..a8a22f09e --- /dev/null +++ b/modules/system/assets/ui/js/inspector.wrapper.popup.js @@ -0,0 +1,203 @@ +/* + * Inspector popup wrapper. + */ ++function ($) { "use strict"; + + // CLASS DEFINITION + // ============================ + + var Base = $.oc.inspector.wrappers.base, + BaseProto = Base.prototype + + var InspectorPopup = function($element, surface, options) { + this.$popoverContainer = null + this.popoverObj = null + this.cleaningUp = false + + Base.call(this, $element, surface, options) + } + + InspectorPopup.prototype = Object.create(BaseProto) + InspectorPopup.prototype.constructor = Base + + InspectorPopup.prototype.dispose = function() { + this.unregisterHandlers() + + this.$popoverContainer = null + this.popoverObj = null + + BaseProto.dispose.call(this) + } + + InspectorPopup.prototype.createSurfaceAndUi = function(properties, values, title, description) { + this.showPopover() + + this.initSurface(this.$popoverContainer.find('[data-surface-container]').get(0), properties, values) + this.registerPopupHandlers() + } + + InspectorPopup.prototype.adoptSurface = function() { + this.showPopover() + + this.surface.moveToContainer(this.$popoverContainer.find('[data-surface-container]').get(0)) + this.registerPopupHandlers() + } + + InspectorPopup.prototype.cleanupAfterSwitch = function() { + this.cleaningUp = true + this.switched = true + + this.forceClose() + + // The parent cleanupAfterSwitch() is not called because + // disposing happens in onHide() triggered by forceClose() + } + + InspectorPopup.prototype.getPopoverContents = function() { + return '
\ +

\ +

\ + \ +
\ +
\ +
\ + ' + } + + InspectorPopup.prototype.showPopover = function() { + var offset = this.$element.data('inspector-offset'), + offsetX = this.$element.data('inspector-offset-x'), + offsetY = this.$element.data('inspector-offset-y'), + placement = this.$element.data('inspector-placement'), + fallbackPlacement = this.$element.data('inspector-fallback-placement') + + if (offset === undefined) { + offset = 15 + } + + if (placement === undefined) { + placement = 'bottom' + } + + if (fallbackPlacement === undefined) { + fallbackPlacement = 'bottom' + } + + this.$element.ocPopover({ + content: this.getPopoverContents(), + highlightModalTarget: true, + modal: true, + placement: placement, + fallbackPlacement: fallbackPlacement, + containerClass: 'control-inspector', + container: this.$element.data('inspector-container'), + offset: offset, + offsetX: offsetX, + offsetY: offsetY, + width: 400 + }) + + this.setInspectorVisibleFlag(true) + + this.popoverObj = this.$element.data('oc.popover') + this.$popoverContainer = this.popoverObj.$container + + if (this.options.containerSupported) { + var moveToContainerButton = $('') + + this.$popoverContainer.find('.popover-head').append(moveToContainerButton) + } + + this.$popoverContainer.find('[data-inspector-title]').text(this.title) + this.$popoverContainer.find('[data-inspector-description]').text(this.description) + } + + InspectorPopup.prototype.forceClose = function() { + this.$popoverContainer.trigger('close.oc.popover') + } + + InspectorPopup.prototype.registerPopupHandlers = function() { + this.surface.options.onPopupDisplayed = this.proxy(this.onPopupEditorDisplayed) + this.surface.options.onPopupHidden = this.proxy(this.onPopupEditorHidden) + this.popoverObj.options.onCheckDocumentClickTarget = this.proxy(this.onCheckDocumentClickTarget) + + this.$element.on('hiding.oc.popover', this.proxy(this.onBeforeHide)) + this.$element.on('hide.oc.popover', this.proxy(this.onHide)) + this.$popoverContainer.on('keydown', this.proxy(this.onPopoverKeyDown)) + + if (this.options.containerSupported) { + this.$popoverContainer.on('click', 'span.inspector-move-to-container', this.proxy(this.onMoveToContainer)) + } + } + + InspectorPopup.prototype.unregisterHandlers = function() { + this.popoverObj.options.onCheckDocumentClickTarget = null + + this.$element.off('hiding.oc.popover', this.proxy(this.onBeforeHide)) + this.$element.off('hide.oc.popover', this.proxy(this.onHide)) + this.$popoverContainer.off('keydown', this.proxy(this.onPopoverKeyDown)) + + if (this.options.containerSupported) { + this.$popoverContainer.off('click', 'span.inspector-move-to-container', this.proxy(this.onMoveToContainer)) + } + + this.surface.options.onPopupDisplayed = null + this.surface.options.onPopupHidden = null + } + + InspectorPopup.prototype.onBeforeHide = function(ev) { + if (this.cleaningUp) { + return + } + + if (!this.surface.validate()) { + ev.preventDefault() + return false + } + + var hidingEvent = $.Event('hiding.oc.inspector'), + values = this.surface.getValues() + + this.$element.trigger(hidingEvent, [{values: values}]) + if (hidingEvent.isDefaultPrevented()) { + ev.preventDefault() + return false + } + + this.applyValues() + } + + InspectorPopup.prototype.onHide = function(ev) { + this.dispose() + } + + InspectorPopup.prototype.onPopoverKeyDown = function(ev) { + if(ev.keyCode == 13) { + $(ev.currentTarget).trigger('close.oc.popover') + } + } + + InspectorPopup.prototype.onPopupEditorDisplayed = function() { + this.popoverObj.options.closeOnPageClick = false + this.popoverObj.options.closeOnEsc = false + } + + InspectorPopup.prototype.onPopupEditorHidden = function() { + this.popoverObj.options.closeOnPageClick = true + this.popoverObj.options.closeOnEsc = true + } + + InspectorPopup.prototype.onCheckDocumentClickTarget = function(element) { + if ($.contains(this.$element, element) || this.$element.get(0) === element) { + return true + } + } + + InspectorPopup.prototype.onMoveToContainer = function() { + $.oc.inspector.manager.switchToContainer(this) + } + + $.oc.inspector.wrappers.popup = InspectorPopup +}(window.jQuery); \ No newline at end of file diff --git a/modules/system/assets/ui/js/popover.js b/modules/system/assets/ui/js/popover.js index 1b82a5b1d..e10bfc27c 100644 --- a/modules/system/assets/ui/js/popover.js +++ b/modules/system/assets/ui/js/popover.js @@ -97,6 +97,7 @@ $(document).off('.oc.popover') this.docClickHandler = null + this.options.onCheckDocumentClickTarget = null } Popover.prototype.show = function(options) { @@ -185,6 +186,10 @@ if ($(e.target).hasClass('select2-offscreen')) return false + if (!self.options.closeOnEsc) { // The value of the option could be changed after the popover is displayed + return false + } + if (e.keyCode == 27) { self.hide() return false @@ -320,6 +325,10 @@ if (!this.options.closeOnPageClick) return + if (this.options.onCheckDocumentClickTarget && this.options.onCheckDocumentClickTarget(e.target)) { + return + } + if ($.contains(this.$container.get(0), e.target)) return @@ -338,7 +347,8 @@ container: false, containerClass: null, offset: 15, - useAnimation: false + useAnimation: false, + onCheckDocumentClickTarget: null } // POPOVER PLUGIN DEFINITION diff --git a/modules/system/assets/ui/less/global.variables.less b/modules/system/assets/ui/less/global.variables.less index 65e39afc4..7cc9393b1 100644 --- a/modules/system/assets/ui/less/global.variables.less +++ b/modules/system/assets/ui/less/global.variables.less @@ -59,10 +59,10 @@ @zindex-navbar: 1000; @zindex-dropdown: 1000; @zindex-popover: 1010; -@zindex-tooltip: 1030; @zindex-navbar-fixed: 1030; @zindex-modal-background: 1040; @zindex-modal: 1050; +@zindex-tooltip: 1060; // Tooltips should always be on the top // // Typography diff --git a/modules/system/assets/ui/less/popover.less b/modules/system/assets/ui/less/popover.less index 149d0394d..5477dbeda 100644 --- a/modules/system/assets/ui/less/popover.less +++ b/modules/system/assets/ui/less/popover.less @@ -153,6 +153,10 @@ div.control-popover { font-size: 13px; font-weight: 100; margin: 10px 0 0 0; + + &:empty { + display: none; + } } .close { @@ -162,6 +166,7 @@ div.control-popover { top: 12px; color: @color-popover-head-text; outline: none; + .opacity(0.4); &:hover { .opacity(1); diff --git a/modules/system/assets/ui/storm-min.js b/modules/system/assets/ui/storm-min.js index 7f7bfd4c8..4a5e548ff 100644 --- a/modules/system/assets/ui/storm-min.js +++ b/modules/system/assets/ui/storm-min.js @@ -113,233 +113,142 @@ FlashMessage.DEFAULTS={class:'success',text:'Default text',interval:2} if($.oc===undefined) $.oc={} $.oc.flashMsg=FlashMessage -$(document).render(function(){$('[data-control=flash-message]').each(function(){$.oc.flashMsg($(this).data(),this)})})}(window.jQuery);;window.Modernizr=(function(window,document,undefined){var version='2.8.3',Modernizr={},enableClasses=true,docElement=document.documentElement,mod='modernizr',modElem=document.createElement(mod),mStyle=modElem.style,inputElem=document.createElement('input'),smile=':)',toString={}.toString,prefixes=' -webkit- -moz- -o- -ms- '.split(' '),omPrefixes='Webkit Moz O ms',cssomPrefixes=omPrefixes.split(' '),domPrefixes=omPrefixes.toLowerCase().split(' '),ns={'svg':'http://www.w3.org/2000/svg'},tests={},inputs={},attrs={},classes=[],slice=classes.slice,featureName,injectElementWithStyles=function(rule,callback,nodes,testnames){var style,ret,node,docOverflow,div=document.createElement('div'),body=document.body,fakeBody=body||document.createElement('body');if(parseInt(nodes,10)){while(nodes--){node=document.createElement('div');node.id=testnames?testnames[nodes]:mod+(nodes+1);div.appendChild(node);}} -style=['­',''].join('');div.id=mod;(body?div:fakeBody).innerHTML+=style;fakeBody.appendChild(div);if(!body){fakeBody.style.background='';fakeBody.style.overflow='hidden';docOverflow=docElement.style.overflow;docElement.style.overflow='hidden';docElement.appendChild(fakeBody);} -ret=callback(div,rule);if(!body){fakeBody.parentNode.removeChild(fakeBody);docElement.style.overflow=docOverflow;}else{div.parentNode.removeChild(div);} -return!!ret;},testMediaQuery=function(mq){var matchMedia=window.matchMedia||window.msMatchMedia;if(matchMedia){return matchMedia(mq)&&matchMedia(mq).matches||false;} -var bool;injectElementWithStyles('@media '+mq+' { #'+mod+' { position: absolute; } }',function(node){bool=(window.getComputedStyle?getComputedStyle(node,null):node.currentStyle)['position']=='absolute';});return bool;},isEventSupported=(function(){var TAGNAMES={'select':'input','change':'input','submit':'form','reset':'form','error':'img','load':'img','abort':'img'};function isEventSupported(eventName,element){element=element||document.createElement(TAGNAMES[eventName]||'div');eventName='on'+eventName;var isSupported=eventName in element;if(!isSupported){if(!element.setAttribute){element=document.createElement('div');} -if(element.setAttribute&&element.removeAttribute){element.setAttribute(eventName,'');isSupported=is(element[eventName],'function');if(!is(element[eventName],'undefined')){element[eventName]=undefined;} -element.removeAttribute(eventName);}} -element=null;return isSupported;} -return isEventSupported;})(),_hasOwnProperty=({}).hasOwnProperty,hasOwnProp;if(!is(_hasOwnProperty,'undefined')&&!is(_hasOwnProperty.call,'undefined')){hasOwnProp=function(object,property){return _hasOwnProperty.call(object,property);};} -else{hasOwnProp=function(object,property){return((property in object)&&is(object.constructor.prototype[property],'undefined'));};} -if(!Function.prototype.bind){Function.prototype.bind=function bind(that){var target=this;if(typeof target!="function"){throw new TypeError();} -var args=slice.call(arguments,1),bound=function(){if(this instanceof bound){var F=function(){};F.prototype=target.prototype;var self=new F();var result=target.apply(self,args.concat(slice.call(arguments)));if(Object(result)===result){return result;} -return self;}else{return target.apply(that,args.concat(slice.call(arguments)));}};return bound;};} -function setCss(str){mStyle.cssText=str;} -function setCssAll(str1,str2){return setCss(prefixes.join(str1+';')+(str2||''));} -function is(obj,type){return typeof obj===type;} -function contains(str,substr){return!!~(''+str).indexOf(substr);} -function testProps(props,prefixed){for(var i in props){var prop=props[i];if(!contains(prop,"-")&&mStyle[prop]!==undefined){return prefixed=='pfx'?prop:true;}} -return false;} -function testDOMProps(props,obj,elem){for(var i in props){var item=obj[props[i]];if(item!==undefined){if(elem===false)return props[i];if(is(item,'function')){return item.bind(elem||obj);} -return item;}} -return false;} -function testPropsAll(prop,prefixed,elem){var ucProp=prop.charAt(0).toUpperCase()+prop.slice(1),props=(prop+' '+cssomPrefixes.join(ucProp+' ')+ucProp).split(' ');if(is(prefixed,"string")||is(prefixed,"undefined")){return testProps(props,prefixed);}else{props=(prop+' '+(domPrefixes).join(ucProp+' ')+ucProp).split(' ');return testDOMProps(props,prefixed,elem);}}tests['flexbox']=function(){return testPropsAll('flexWrap');};tests['flexboxlegacy']=function(){return testPropsAll('boxDirection');};tests['canvas']=function(){var elem=document.createElement('canvas');return!!(elem.getContext&&elem.getContext('2d'));};tests['canvastext']=function(){return!!(Modernizr['canvas']&&is(document.createElement('canvas').getContext('2d').fillText,'function'));};tests['webgl']=function(){return!!window.WebGLRenderingContext;};tests['touch']=function(){var bool;if(('ontouchstart'in window)||window.DocumentTouch&&document instanceof DocumentTouch){bool=true;}else{injectElementWithStyles(['@media (',prefixes.join('touch-enabled),('),mod,')','{#modernizr{top:9px;position:absolute}}'].join(''),function(node){bool=node.offsetTop===9;});} -return bool;};tests['geolocation']=function(){return'geolocation'in navigator;};tests['postmessage']=function(){return!!window.postMessage;};tests['websqldatabase']=function(){return!!window.openDatabase;};tests['indexedDB']=function(){return!!testPropsAll("indexedDB",window);};tests['hashchange']=function(){return isEventSupported('hashchange',window)&&(document.documentMode===undefined||document.documentMode>7);};tests['history']=function(){return!!(window.history&&history.pushState);};tests['draganddrop']=function(){var div=document.createElement('div');return('draggable'in div)||('ondragstart'in div&&'ondrop'in div);};tests['websockets']=function(){return'WebSocket'in window||'MozWebSocket'in window;};tests['rgba']=function(){setCss('background-color:rgba(150,255,150,.5)');return contains(mStyle.backgroundColor,'rgba');};tests['hsla']=function(){setCss('background-color:hsla(120,40%,100%,.5)');return contains(mStyle.backgroundColor,'rgba')||contains(mStyle.backgroundColor,'hsla');};tests['multiplebgs']=function(){setCss('background:url(https://),url(https://),red url(https://)');return(/(url\s*\(.*?){3}/).test(mStyle.background);};tests['backgroundsize']=function(){return testPropsAll('backgroundSize');};tests['borderimage']=function(){return testPropsAll('borderImage');};tests['borderradius']=function(){return testPropsAll('borderRadius');};tests['boxshadow']=function(){return testPropsAll('boxShadow');};tests['textshadow']=function(){return document.createElement('div').style.textShadow==='';};tests['opacity']=function(){setCssAll('opacity:.55');return(/^0.55$/).test(mStyle.opacity);};tests['cssanimations']=function(){return testPropsAll('animationName');};tests['csscolumns']=function(){return testPropsAll('columnCount');};tests['cssgradients']=function(){var str1='background-image:',str2='gradient(linear,left top,right bottom,from(#9f9),to(white));',str3='linear-gradient(left top,#9f9, white);';setCss((str1+'-webkit- '.split(' ').join(str2+str1)+ -prefixes.join(str3+str1)).slice(0,-str1.length));return contains(mStyle.backgroundImage,'gradient');};tests['cssreflections']=function(){return testPropsAll('boxReflect');};tests['csstransforms']=function(){return!!testPropsAll('transform');};tests['csstransforms3d']=function(){var ret=!!testPropsAll('perspective');if(ret&&'webkitPerspective'in docElement.style){injectElementWithStyles('@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}',function(node,rule){ret=node.offsetLeft===9&&node.offsetHeight===3;});} -return ret;};tests['csstransitions']=function(){return testPropsAll('transition');};tests['fontface']=function(){var bool;injectElementWithStyles('@font-face {font-family:"font";src:url("https://")}',function(node,rule){var style=document.getElementById('smodernizr'),sheet=style.sheet||style.styleSheet,cssText=sheet?(sheet.cssRules&&sheet.cssRules[0]?sheet.cssRules[0].cssText:sheet.cssText||''):'';bool=/src/i.test(cssText)&&cssText.indexOf(rule.split(' ')[0])===0;});return bool;};tests['generatedcontent']=function(){var bool;injectElementWithStyles(['#',mod,'{font:0/0 a}#',mod,':after{content:"',smile,'";visibility:hidden;font:3px/1 a}'].join(''),function(node){bool=node.offsetHeight>=3;});return bool;};tests['video']=function(){var elem=document.createElement('video'),bool=false;try{if(bool=!!elem.canPlayType){bool=new Boolean(bool);bool.ogg=elem.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,'');bool.h264=elem.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,'');bool.webm=elem.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,'');}}catch(e){} -return bool;};tests['audio']=function(){var elem=document.createElement('audio'),bool=false;try{if(bool=!!elem.canPlayType){bool=new Boolean(bool);bool.ogg=elem.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,'');bool.mp3=elem.canPlayType('audio/mpeg;').replace(/^no$/,'');bool.wav=elem.canPlayType('audio/wav; codecs="1"').replace(/^no$/,'');bool.m4a=(elem.canPlayType('audio/x-m4a;')||elem.canPlayType('audio/aac;')).replace(/^no$/,'');}}catch(e){} -return bool;};tests['localstorage']=function(){try{localStorage.setItem(mod,mod);localStorage.removeItem(mod);return true;}catch(e){return false;}};tests['sessionstorage']=function(){try{sessionStorage.setItem(mod,mod);sessionStorage.removeItem(mod);return true;}catch(e){return false;}};tests['webworkers']=function(){return!!window.Worker;};tests['applicationcache']=function(){return!!window.applicationCache;};tests['svg']=function(){return!!document.createElementNS&&!!document.createElementNS(ns.svg,'svg').createSVGRect;};tests['inlinesvg']=function(){var div=document.createElement('div');div.innerHTML='';return(div.firstChild&&div.firstChild.namespaceURI)==ns.svg;};tests['smil']=function(){return!!document.createElementNS&&/SVGAnimate/.test(toString.call(document.createElementNS(ns.svg,'animate')));};tests['svgclippaths']=function(){return!!document.createElementNS&&/SVGClipPath/.test(toString.call(document.createElementNS(ns.svg,'clipPath')));};function webforms(){Modernizr['input']=(function(props){for(var i=0,len=props.length;i';supportsHtml5Styles=('hidden'in a);supportsUnknownElements=a.childNodes.length==1||(function(){(document.createElement)('a');var frag=document.createDocumentFragment();return(typeof frag.cloneNode=='undefined'||typeof frag.createDocumentFragment=='undefined'||typeof frag.createElement=='undefined');}());}catch(e){supportsHtml5Styles=true;supportsUnknownElements=true;}}());function addStyleSheet(ownerDocument,cssText){var p=ownerDocument.createElement('p'),parent=ownerDocument.getElementsByTagName('head')[0]||ownerDocument.documentElement;p.innerHTML='x';return parent.insertBefore(p.lastChild,parent.firstChild);} -function getElements(){var elements=html5.elements;return typeof elements=='string'?elements.split(' '):elements;} -function getExpandoData(ownerDocument){var data=expandoData[ownerDocument[expando]];if(!data){data={};expanID++;ownerDocument[expando]=expanID;expandoData[expanID]=data;} -return data;} -function createElement(nodeName,ownerDocument,data){if(!ownerDocument){ownerDocument=document;} -if(supportsUnknownElements){return ownerDocument.createElement(nodeName);} -if(!data){data=getExpandoData(ownerDocument);} -var node;if(data.cache[nodeName]){node=data.cache[nodeName].cloneNode();}else if(saveClones.test(nodeName)){node=(data.cache[nodeName]=data.createElem(nodeName)).cloneNode();}else{node=data.createElem(nodeName);} -return node.canHaveChildren&&!reSkip.test(nodeName)&&!node.tagUrn?data.frag.appendChild(node):node;} -function createDocumentFragment(ownerDocument,data){if(!ownerDocument){ownerDocument=document;} -if(supportsUnknownElements){return ownerDocument.createDocumentFragment();} -data=data||getExpandoData(ownerDocument);var clone=data.frag.cloneNode(),i=0,elems=getElements(),l=elems.length;for(;i":">",'"':'"',"'":''',"/":'/'};function escapeHtml(string){return String(string).replace(/[&<>"'\/]/g,function(s){return entityMap[s];});} -var whiteRe=/\s*/;var spaceRe=/\s+/;var equalsRe=/\s*=/;var curlyRe=/\s*\}/;var tagRe=/#|\^|\/|>|\{|&|=|!/;function parseTemplate(template,tags){if(!template) -return[];var sections=[];var tokens=[];var spaces=[];var hasTag=false;var nonSpace=false;function stripSpace(){if(hasTag&&!nonSpace){while(spaces.length) -delete tokens[spaces.pop()];}else{spaces=[];} -hasTag=false;nonSpace=false;} -var openingTagRe,closingTagRe,closingCurlyRe;function compileTags(tags){if(typeof tags==='string') -tags=tags.split(spaceRe,2);if(!isArray(tags)||tags.length!==2) -throw new Error('Invalid tags: '+tags);openingTagRe=new RegExp(escapeRegExp(tags[0])+'\\s*');closingTagRe=new RegExp('\\s*'+escapeRegExp(tags[1]));closingCurlyRe=new RegExp('\\s*'+escapeRegExp('}'+tags[1]));} -compileTags(tags||mustache.tags);var scanner=new Scanner(template);var start,type,value,chr,token,openSection;while(!scanner.eos()){start=scanner.pos;value=scanner.scanUntil(openingTagRe);if(value){for(var i=0,valueLength=value.length;i0?sections[sections.length-1][4]:nestedTokens;break;default:collector.push(token);}} -return nestedTokens;} -function Scanner(string){this.string=string;this.tail=string;this.pos=0;} -Scanner.prototype.eos=function(){return this.tail==="";};Scanner.prototype.scan=function(re){var match=this.tail.match(re);if(!match||match.index!==0) -return'';var string=match[0];this.tail=this.tail.substring(string.length);this.pos+=string.length;return string;};Scanner.prototype.scanUntil=function(re){var index=this.tail.search(re),match;switch(index){case-1:match=this.tail;this.tail="";break;case 0:match="";break;default:match=this.tail.substring(0,index);this.tail=this.tail.substring(index);} -this.pos+=match.length;return match;};function Context(view,parentContext){this.view=view;this.cache={'.':this.view};this.parent=parentContext;} -Context.prototype.push=function(view){return new Context(view,this);};Context.prototype.lookup=function(name){var cache=this.cache;var value;if(name in cache){value=cache[name];}else{var context=this,names,index,lookupHit=false;while(context){if(name.indexOf('.')>0){value=context.view;names=name.split('.');index=0;while(value!=null&&index')value=this._renderPartial(token,context,partials,originalTemplate);else if(symbol==='&')value=this._unescapedValue(token,context);else if(symbol==='name')value=this._escapedValue(token,context);else if(symbol==='text')value=this._rawValue(token);if(value!==undefined) -buffer+=value;} -return buffer;};Writer.prototype._renderSection=function(token,context,partials,originalTemplate){var self=this;var buffer='';var value=context.lookup(token[1]);function subRender(template){return self.render(template,context,partials);} -if(!value)return;if(isArray(value)){for(var j=0,valueLength=value.length;j').addClass('control-popover') -if(this.options.containerClass) -this.$container.addClass(this.options.containerClass) -if(this.options.useAnimation) -this.$container.addClass('fade') -var $content=$('
').html(this.getContent()) -this.$container.append($content) -if(this.options.width) -this.$container.width(this.options.width) -if(this.options.modal){this.$overlay=$('
').addClass('popover-overlay') -$(document.body).append(this.$overlay) -if(this.options.highlightModalTarget){this.$el.addClass('popover-highlight') -this.$el.blur()}}else{this.$overlay=false} -if(this.options.container) -$(this.options.container).append(this.$container) -else -$(document.body).append(this.$container) -var -placement=this.calcPlacement(),position=this.calcPosition(placement) -this.$container.css({left:position.x,top:position.y}).addClass('placement-'+placement) -this.$container.addClass('in') -if(this.$overlay)this.$overlay.addClass('in') -$(document.body).addClass('popover-open') -var showEvent=jQuery.Event('show.oc.popover',{relatedTarget:this.$container.get(0)}) -this.$el.trigger(showEvent) -this.$container.on('close.oc.popover',function(e){self.hide()}) -this.$container.on('click','[data-dismiss=popover]',function(e){self.hide() -return false}) -this.docClickHandler=$.proxy(this.onDocumentClick,this) -$(document).bind('mousedown',this.docClickHandler);if(this.options.closeOnEsc){$(document).on('keyup.oc.popover',function(e){if($(e.target).hasClass('select2-offscreen')) -return false -if(e.keyCode==27){self.hide() -return false}})}} -Popover.prototype.getContent=function(){return typeof this.options.content=='function'?this.options.content.call(this.$el[0],this):this.options.content} -Popover.prototype.calcDimensions=function(){var -documentWidth=$(document).width(),documentHeight=$(document).height(),targetOffset=this.$el.offset(),targetWidth=this.$el.outerWidth(),targetHeight=this.$el.outerHeight() -return{containerWidth:this.$container.outerWidth()+this.arrowSize,containerHeight:this.$container.outerHeight()+this.arrowSize,targetOffset:targetOffset,targetHeight:targetHeight,targetWidth:targetWidth,spaceLeft:targetOffset.left,spaceRight:documentWidth-(targetWidth+targetOffset.left),spaceTop:targetOffset.top,spaceBottom:documentHeight-(targetHeight+targetOffset.top),spaceHorizontalBottom:documentHeight-targetOffset.top,spaceVerticalRight:documentWidth-targetOffset.left,documentWidth:documentWidth}} -Popover.prototype.fitsLeft=function(dimensions){return dimensions.spaceLeft>=dimensions.containerWidth&&dimensions.spaceHorizontalBottom>=dimensions.containerHeight} -Popover.prototype.fitsRight=function(dimensions){return dimensions.spaceRight>=dimensions.containerWidth&&dimensions.spaceHorizontalBottom>=dimensions.containerHeight} -Popover.prototype.fitsBottom=function(dimensions){return dimensions.spaceBottom>=dimensions.containerHeight&&dimensions.spaceVerticalRight>=dimensions.containerWidth} -Popover.prototype.fitsTop=function(dimensions){return dimensions.spaceTop>=dimensions.containerHeight&&dimensions.spaceVerticalRight>=dimensions.containerWidth} -Popover.prototype.calcPlacement=function(){var -placement=this.options.placement,dimensions=this.calcDimensions();if(placement=='center') -return placement -if(placement!='bottom'&&placement!='top'&&placement!='left'&&placement!='right') -placement='bottom' -var placementFunctions={top:this.fitsTop,bottom:this.fitsBottom,left:this.fitsLeft,right:this.fitsRight} -if(placementFunctions[placement](dimensions)) -return placement -for(var index in placementFunctions){if(placementFunctions[index](dimensions)) -return index} -return this.options.fallbackPlacement} -Popover.prototype.calcPosition=function(placement){var -dimensions=this.calcDimensions(),result -switch(placement){case'left':var realOffset=this.options.offsetY===undefined?this.options.offset:this.options.offsetY -result={x:(dimensions.targetOffset.left-dimensions.containerWidth),y:dimensions.targetOffset.top+realOffset} -break;case'top':var realOffset=this.options.offsetX===undefined?this.options.offset:this.options.offsetX -result={x:dimensions.targetOffset.left+realOffset,y:(dimensions.targetOffset.top-dimensions.containerHeight)} -break;case'bottom':var realOffset=this.options.offsetX===undefined?this.options.offset:this.options.offsetX -result={x:dimensions.targetOffset.left+realOffset,y:(dimensions.targetOffset.top+dimensions.targetHeight+this.arrowSize)} -break;case'right':var realOffset=this.options.offsetY===undefined?this.options.offset:this.options.offsetY -result={x:(dimensions.targetOffset.left+dimensions.targetWidth+this.arrowSize),y:dimensions.targetOffset.top+realOffset} -break;case'center':var windowHeight=$(window).height() -result={x:(dimensions.documentWidth/2-dimensions.containerWidth/2),y:(windowHeight/2-dimensions.containerHeight/2)} -if(result.y<40) -result.y=40 -break;} -if(!this.options.container) -return result -var -$container=$(this.options.container),containerOffset=$container.offset() -result.x-=containerOffset.left -result.y-=containerOffset.top -return result} -Popover.prototype.onDocumentClick=function(e){if(!this.options.closeOnPageClick) -return -if($.contains(this.$container.get(0),e.target)) -return -this.hide();} -Popover.DEFAULTS={placement:'bottom',fallbackPlacement:'bottom',content:'

Popover content

',width:false,modal:false,highlightModalTarget:false,closeOnPageClick:true,closeOnEsc:true,container:false,containerClass:null,offset:15,useAnimation:false} -var old=$.fn.ocPopover -$.fn.ocPopover=function(option){var args=arguments;return this.each(function(){var $this=$(this) -var data=$this.data('oc.popover') -var options=$.extend({},Popover.DEFAULTS,$this.data(),typeof option=='object'&&option) -if(!data){if(typeof option=='string') -return;$this.data('oc.popover',(data=new Popover(this,options)))}else{if(typeof option!='string') -return;var methodArgs=[];for(var i=1;i').insertAfter($(this)).on('click',clearMenus)} +var relatedTarget={relatedTarget:this} +$parent.trigger(e=$.Event('show.bs.dropdown',relatedTarget)) +if(e.isDefaultPrevented())return +$parent.toggleClass('open').trigger('shown.bs.dropdown',relatedTarget) +$this.focus()} +return false} +Dropdown.prototype.keydown=function(e){if(!/(38|40|27)/.test(e.keyCode))return +var $this=$(this) +e.preventDefault() +e.stopPropagation() +if($this.is('.disabled, :disabled'))return +var $parent=getParent($this) +var isActive=$parent.hasClass('open') +if(!isActive||(isActive&&e.keyCode==27)){if(e.which==27)$parent.find(toggle).focus() +return $this.click()} +var desc=' li:not(.divider):visible a' +var $items=$parent.find('[role=menu]'+desc+', [role=listbox]'+desc) +if(!$items.length)return +var index=$items.index($items.filter(':focus')) +if(e.keyCode==38&&index>0)index-- +if(e.keyCode==40&&index<$items.length-1)index++ +if(!~index)index=0 +$items.eq(index).focus()} +function clearMenus(e){$(backdrop).remove() +$(toggle).each(function(){var $parent=getParent($(this)) +var relatedTarget={relatedTarget:this} +if(!$parent.hasClass('open'))return +$parent.trigger(e=$.Event('hide.bs.dropdown',relatedTarget)) +if(e.isDefaultPrevented())return +$parent.removeClass('open').trigger('hidden.bs.dropdown',relatedTarget)})} +function getParent($this){var selector=$this.attr('data-target') +if(!selector){selector=$this.attr('href') +selector=selector&&/#[A-Za-z]/.test(selector)&&selector.replace(/.*(?=#[^\s]*$)/,'')} +var $parent=selector&&$(selector) +return $parent&&$parent.length?$parent:$this.parent()} +var old=$.fn.dropdown +$.fn.dropdown=function(option){return this.each(function(){var $this=$(this) +var data=$this.data('bs.dropdown') +if(!data)$this.data('bs.dropdown',(data=new Dropdown(this))) +if(typeof option=='string')data[option].call($this)})} +$.fn.dropdown.Constructor=Dropdown +$.fn.dropdown.noConflict=function(){$.fn.dropdown=old +return this} +$(document).on('click.bs.dropdown.data-api',clearMenus).on('click.bs.dropdown.data-api','.dropdown form',function(e){e.stopPropagation()}).on('click.bs.dropdown.data-api',toggle,Dropdown.prototype.toggle).on('keydown.bs.dropdown.data-api',toggle+', [role=menu], [role=listbox]',Dropdown.prototype.keydown)}(jQuery);+function($){"use strict";$(document).on('shown.bs.dropdown','.dropdown',function(){$(document.body).addClass('dropdown-open') +var dropdown=$('.dropdown-menu',this),dropdownContainer=$(this).data('dropdown-container') +if($('.dropdown-container',dropdown).length==0){var title=$('[data-toggle=dropdown]',this).text(),titleAttr=dropdown.data('dropdown-title'),timer=null +if(titleAttr!==undefined) +title=titleAttr +$('li:first-child',dropdown).addClass('first-item') +dropdown.prepend($('

  • ').addClass('dropdown-title').text(title)) +var container=$('
  • ').addClass('dropdown-container'),ul=$('
      ') +container.prepend(ul) +ul.prepend(dropdown.children()) +dropdown.prepend(container) +dropdown.on('touchstart',function(){window.setTimeout(function(){dropdown.addClass('scroll')},200)}) +dropdown.on('touchend',function(){window.setTimeout(function(){dropdown.removeClass('scroll')},200)}) +dropdown.on('click','a',function(){if(dropdown.hasClass('scroll')) +return false})} +if(dropdownContainer!==undefined&&dropdownContainer=='body'){$(this).data('oc.dropdown',dropdown) +$(document.body).append(dropdown) +dropdown.css({'visibility':'hidden','left':0,'top':0,'display':'block'}) +var targetOffset=$(this).offset(),targetHeight=$(this).height(),targetWidth=$(this).width(),position={x:targetOffset.left,y:targetOffset.top+targetHeight},leftOffset=targetWidth<30?-16:0,documentHeight=$(document).height(),dropdownHeight=dropdown.height() +if((dropdownHeight+position.y)>$(document).height()){position.y=targetOffset.top-dropdownHeight-12 +dropdown.addClass('top')} +else{dropdown.removeClass('top')} +dropdown.css({'left':position.x+leftOffset,'top':position.y,'visibility':'visible'})} +if($('.dropdown-overlay',document.body).length==0){$(document.body).prepend($('
      ').addClass('dropdown-overlay'));}}) +$(document).on('hidden.bs.dropdown','.dropdown',function(){var dropdown=$(this).data('oc.dropdown') +if(dropdown!==undefined){dropdown.css('display','none') +$(this).append(dropdown)} +$(document.body).removeClass('dropdown-open');}) +var $dropdown,$container,$target +function fixDropdownPosition(){var position=$container.offset() +$dropdown.css({position:'fixed',top:position.top-1-$(window).scrollTop()+$target.outerHeight(),left:position.left})} +$(document).on('shown.bs.dropdown','.dropdown.dropdown-fixed',function(event,eventData){$container=$(this) +$dropdown=$('.dropdown-menu',$container) +$target=$(eventData.relatedTarget) +fixDropdownPosition() +$(window).on('scroll.oc.dropdown, resize.oc.dropdown',fixDropdownPosition)}) +$(document).on('hidden.bs.dropdown','.dropdown.dropdown-fixed',function(){$(window).off('scroll.oc.dropdown, resize.oc.dropdown',fixDropdownPosition)})}(window.jQuery);+function($){'use strict';var dismiss='[data-dismiss="callout"]' +var Callout=function(el){$(el).on('click',dismiss,this.close)} +Callout.prototype.close=function(e){var $this=$(this) +var selector=$this.attr('data-target') +if(!selector){selector=$this.attr('href') +selector=selector&&selector.replace(/.*(?=#[^\s]*$)/,'')} +var $parent=$(selector) +if(e)e.preventDefault() +if(!$parent.length){$parent=$this.hasClass('callout')?$this:$this.parent()} +$parent.trigger(e=$.Event('close.oc.callout')) +if(e.isDefaultPrevented())return +$parent.removeClass('in') +function removeElement(){$parent.trigger('closed.oc.callout').remove()} +$.support.transition&&$parent.hasClass('fade')?$parent.one($.support.transition.end,removeElement).emulateTransitionEnd(500):removeElement()} +var old=$.fn.callout +$.fn.callout=function(option){return this.each(function(){var $this=$(this) +var data=$this.data('oc.callout') +if(!data)$this.data('oc.callout',(data=new Callout(this))) +if(typeof option=='string')data[option].call($this)})} +$.fn.callout.Constructor=Callout +$.fn.callout.noConflict=function(){$.fn.callout=old +return this} +$(document).on('click.oc.callout.data-api',dismiss,Callout.prototype.close)}(jQuery);+function($){'use strict';var Tooltip=function(element,options){this.type=this.options=this.enabled=this.timeout=this.hoverState=this.$element=null this.init('tooltip',element,options)} Tooltip.DEFAULTS={animation:true,placement:'top',selector:false,template:'
      ',trigger:'hover focus',title:'',delay:0,html:false,container:false} Tooltip.prototype.init=function(type,element,options){this.enabled=true @@ -471,32 +380,555 @@ if(!data)$this.data('bs.tooltip',(data=new Tooltip(this,options))) if(typeof option=='string')data[option]()})} $.fn.tooltip.Constructor=Tooltip $.fn.tooltip.noConflict=function(){$.fn.tooltip=old -return this}}(jQuery);(function($){$(document).render(function(){$('[data-control="tooltip"], [data-toggle="tooltip"]').tooltip()})})(jQuery);+function($){"use strict";var BalloonSelector=function(element,options){this.$el=$(element) -this.$field=$('input',this.$el) -this.options=options||{};var self=this;$('li',this.$el).click(function(){if(self.$el.hasClass('control-disabled')) +return this}}(jQuery);(function($){$(document).render(function(){$('[data-control="tooltip"], [data-toggle="tooltip"]').tooltip()})})(jQuery);;window.Modernizr=(function(window,document,undefined){var version='2.8.3',Modernizr={},enableClasses=true,docElement=document.documentElement,mod='modernizr',modElem=document.createElement(mod),mStyle=modElem.style,inputElem=document.createElement('input'),smile=':)',toString={}.toString,prefixes=' -webkit- -moz- -o- -ms- '.split(' '),omPrefixes='Webkit Moz O ms',cssomPrefixes=omPrefixes.split(' '),domPrefixes=omPrefixes.toLowerCase().split(' '),ns={'svg':'http://www.w3.org/2000/svg'},tests={},inputs={},attrs={},classes=[],slice=classes.slice,featureName,injectElementWithStyles=function(rule,callback,nodes,testnames){var style,ret,node,docOverflow,div=document.createElement('div'),body=document.body,fakeBody=body||document.createElement('body');if(parseInt(nodes,10)){while(nodes--){node=document.createElement('div');node.id=testnames?testnames[nodes]:mod+(nodes+1);div.appendChild(node);}} +style=['­',''].join('');div.id=mod;(body?div:fakeBody).innerHTML+=style;fakeBody.appendChild(div);if(!body){fakeBody.style.background='';fakeBody.style.overflow='hidden';docOverflow=docElement.style.overflow;docElement.style.overflow='hidden';docElement.appendChild(fakeBody);} +ret=callback(div,rule);if(!body){fakeBody.parentNode.removeChild(fakeBody);docElement.style.overflow=docOverflow;}else{div.parentNode.removeChild(div);} +return!!ret;},testMediaQuery=function(mq){var matchMedia=window.matchMedia||window.msMatchMedia;if(matchMedia){return matchMedia(mq)&&matchMedia(mq).matches||false;} +var bool;injectElementWithStyles('@media '+mq+' { #'+mod+' { position: absolute; } }',function(node){bool=(window.getComputedStyle?getComputedStyle(node,null):node.currentStyle)['position']=='absolute';});return bool;},isEventSupported=(function(){var TAGNAMES={'select':'input','change':'input','submit':'form','reset':'form','error':'img','load':'img','abort':'img'};function isEventSupported(eventName,element){element=element||document.createElement(TAGNAMES[eventName]||'div');eventName='on'+eventName;var isSupported=eventName in element;if(!isSupported){if(!element.setAttribute){element=document.createElement('div');} +if(element.setAttribute&&element.removeAttribute){element.setAttribute(eventName,'');isSupported=is(element[eventName],'function');if(!is(element[eventName],'undefined')){element[eventName]=undefined;} +element.removeAttribute(eventName);}} +element=null;return isSupported;} +return isEventSupported;})(),_hasOwnProperty=({}).hasOwnProperty,hasOwnProp;if(!is(_hasOwnProperty,'undefined')&&!is(_hasOwnProperty.call,'undefined')){hasOwnProp=function(object,property){return _hasOwnProperty.call(object,property);};} +else{hasOwnProp=function(object,property){return((property in object)&&is(object.constructor.prototype[property],'undefined'));};} +if(!Function.prototype.bind){Function.prototype.bind=function bind(that){var target=this;if(typeof target!="function"){throw new TypeError();} +var args=slice.call(arguments,1),bound=function(){if(this instanceof bound){var F=function(){};F.prototype=target.prototype;var self=new F();var result=target.apply(self,args.concat(slice.call(arguments)));if(Object(result)===result){return result;} +return self;}else{return target.apply(that,args.concat(slice.call(arguments)));}};return bound;};} +function setCss(str){mStyle.cssText=str;} +function setCssAll(str1,str2){return setCss(prefixes.join(str1+';')+(str2||''));} +function is(obj,type){return typeof obj===type;} +function contains(str,substr){return!!~(''+str).indexOf(substr);} +function testProps(props,prefixed){for(var i in props){var prop=props[i];if(!contains(prop,"-")&&mStyle[prop]!==undefined){return prefixed=='pfx'?prop:true;}} +return false;} +function testDOMProps(props,obj,elem){for(var i in props){var item=obj[props[i]];if(item!==undefined){if(elem===false)return props[i];if(is(item,'function')){return item.bind(elem||obj);} +return item;}} +return false;} +function testPropsAll(prop,prefixed,elem){var ucProp=prop.charAt(0).toUpperCase()+prop.slice(1),props=(prop+' '+cssomPrefixes.join(ucProp+' ')+ucProp).split(' ');if(is(prefixed,"string")||is(prefixed,"undefined")){return testProps(props,prefixed);}else{props=(prop+' '+(domPrefixes).join(ucProp+' ')+ucProp).split(' ');return testDOMProps(props,prefixed,elem);}}tests['flexbox']=function(){return testPropsAll('flexWrap');};tests['flexboxlegacy']=function(){return testPropsAll('boxDirection');};tests['canvas']=function(){var elem=document.createElement('canvas');return!!(elem.getContext&&elem.getContext('2d'));};tests['canvastext']=function(){return!!(Modernizr['canvas']&&is(document.createElement('canvas').getContext('2d').fillText,'function'));};tests['webgl']=function(){return!!window.WebGLRenderingContext;};tests['touch']=function(){var bool;if(('ontouchstart'in window)||window.DocumentTouch&&document instanceof DocumentTouch){bool=true;}else{injectElementWithStyles(['@media (',prefixes.join('touch-enabled),('),mod,')','{#modernizr{top:9px;position:absolute}}'].join(''),function(node){bool=node.offsetTop===9;});} +return bool;};tests['geolocation']=function(){return'geolocation'in navigator;};tests['postmessage']=function(){return!!window.postMessage;};tests['websqldatabase']=function(){return!!window.openDatabase;};tests['indexedDB']=function(){return!!testPropsAll("indexedDB",window);};tests['hashchange']=function(){return isEventSupported('hashchange',window)&&(document.documentMode===undefined||document.documentMode>7);};tests['history']=function(){return!!(window.history&&history.pushState);};tests['draganddrop']=function(){var div=document.createElement('div');return('draggable'in div)||('ondragstart'in div&&'ondrop'in div);};tests['websockets']=function(){return'WebSocket'in window||'MozWebSocket'in window;};tests['rgba']=function(){setCss('background-color:rgba(150,255,150,.5)');return contains(mStyle.backgroundColor,'rgba');};tests['hsla']=function(){setCss('background-color:hsla(120,40%,100%,.5)');return contains(mStyle.backgroundColor,'rgba')||contains(mStyle.backgroundColor,'hsla');};tests['multiplebgs']=function(){setCss('background:url(https://),url(https://),red url(https://)');return(/(url\s*\(.*?){3}/).test(mStyle.background);};tests['backgroundsize']=function(){return testPropsAll('backgroundSize');};tests['borderimage']=function(){return testPropsAll('borderImage');};tests['borderradius']=function(){return testPropsAll('borderRadius');};tests['boxshadow']=function(){return testPropsAll('boxShadow');};tests['textshadow']=function(){return document.createElement('div').style.textShadow==='';};tests['opacity']=function(){setCssAll('opacity:.55');return(/^0.55$/).test(mStyle.opacity);};tests['cssanimations']=function(){return testPropsAll('animationName');};tests['csscolumns']=function(){return testPropsAll('columnCount');};tests['cssgradients']=function(){var str1='background-image:',str2='gradient(linear,left top,right bottom,from(#9f9),to(white));',str3='linear-gradient(left top,#9f9, white);';setCss((str1+'-webkit- '.split(' ').join(str2+str1)+ +prefixes.join(str3+str1)).slice(0,-str1.length));return contains(mStyle.backgroundImage,'gradient');};tests['cssreflections']=function(){return testPropsAll('boxReflect');};tests['csstransforms']=function(){return!!testPropsAll('transform');};tests['csstransforms3d']=function(){var ret=!!testPropsAll('perspective');if(ret&&'webkitPerspective'in docElement.style){injectElementWithStyles('@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}',function(node,rule){ret=node.offsetLeft===9&&node.offsetHeight===3;});} +return ret;};tests['csstransitions']=function(){return testPropsAll('transition');};tests['fontface']=function(){var bool;injectElementWithStyles('@font-face {font-family:"font";src:url("https://")}',function(node,rule){var style=document.getElementById('smodernizr'),sheet=style.sheet||style.styleSheet,cssText=sheet?(sheet.cssRules&&sheet.cssRules[0]?sheet.cssRules[0].cssText:sheet.cssText||''):'';bool=/src/i.test(cssText)&&cssText.indexOf(rule.split(' ')[0])===0;});return bool;};tests['generatedcontent']=function(){var bool;injectElementWithStyles(['#',mod,'{font:0/0 a}#',mod,':after{content:"',smile,'";visibility:hidden;font:3px/1 a}'].join(''),function(node){bool=node.offsetHeight>=3;});return bool;};tests['video']=function(){var elem=document.createElement('video'),bool=false;try{if(bool=!!elem.canPlayType){bool=new Boolean(bool);bool.ogg=elem.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,'');bool.h264=elem.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,'');bool.webm=elem.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,'');}}catch(e){} +return bool;};tests['audio']=function(){var elem=document.createElement('audio'),bool=false;try{if(bool=!!elem.canPlayType){bool=new Boolean(bool);bool.ogg=elem.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,'');bool.mp3=elem.canPlayType('audio/mpeg;').replace(/^no$/,'');bool.wav=elem.canPlayType('audio/wav; codecs="1"').replace(/^no$/,'');bool.m4a=(elem.canPlayType('audio/x-m4a;')||elem.canPlayType('audio/aac;')).replace(/^no$/,'');}}catch(e){} +return bool;};tests['localstorage']=function(){try{localStorage.setItem(mod,mod);localStorage.removeItem(mod);return true;}catch(e){return false;}};tests['sessionstorage']=function(){try{sessionStorage.setItem(mod,mod);sessionStorage.removeItem(mod);return true;}catch(e){return false;}};tests['webworkers']=function(){return!!window.Worker;};tests['applicationcache']=function(){return!!window.applicationCache;};tests['svg']=function(){return!!document.createElementNS&&!!document.createElementNS(ns.svg,'svg').createSVGRect;};tests['inlinesvg']=function(){var div=document.createElement('div');div.innerHTML='';return(div.firstChild&&div.firstChild.namespaceURI)==ns.svg;};tests['smil']=function(){return!!document.createElementNS&&/SVGAnimate/.test(toString.call(document.createElementNS(ns.svg,'animate')));};tests['svgclippaths']=function(){return!!document.createElementNS&&/SVGClipPath/.test(toString.call(document.createElementNS(ns.svg,'clipPath')));};function webforms(){Modernizr['input']=(function(props){for(var i=0,len=props.length;i';supportsHtml5Styles=('hidden'in a);supportsUnknownElements=a.childNodes.length==1||(function(){(document.createElement)('a');var frag=document.createDocumentFragment();return(typeof frag.cloneNode=='undefined'||typeof frag.createDocumentFragment=='undefined'||typeof frag.createElement=='undefined');}());}catch(e){supportsHtml5Styles=true;supportsUnknownElements=true;}}());function addStyleSheet(ownerDocument,cssText){var p=ownerDocument.createElement('p'),parent=ownerDocument.getElementsByTagName('head')[0]||ownerDocument.documentElement;p.innerHTML='x';return parent.insertBefore(p.lastChild,parent.firstChild);} +function getElements(){var elements=html5.elements;return typeof elements=='string'?elements.split(' '):elements;} +function getExpandoData(ownerDocument){var data=expandoData[ownerDocument[expando]];if(!data){data={};expanID++;ownerDocument[expando]=expanID;expandoData[expanID]=data;} +return data;} +function createElement(nodeName,ownerDocument,data){if(!ownerDocument){ownerDocument=document;} +if(supportsUnknownElements){return ownerDocument.createElement(nodeName);} +if(!data){data=getExpandoData(ownerDocument);} +var node;if(data.cache[nodeName]){node=data.cache[nodeName].cloneNode();}else if(saveClones.test(nodeName)){node=(data.cache[nodeName]=data.createElem(nodeName)).cloneNode();}else{node=data.createElem(nodeName);} +return node.canHaveChildren&&!reSkip.test(nodeName)&&!node.tagUrn?data.frag.appendChild(node):node;} +function createDocumentFragment(ownerDocument,data){if(!ownerDocument){ownerDocument=document;} +if(supportsUnknownElements){return ownerDocument.createDocumentFragment();} +data=data||getExpandoData(ownerDocument);var clone=data.frag.cloneNode(),i=0,elems=getElements(),l=elems.length;for(;i=9)?['wheel']:['mousewheel','DomMouseScroll','MozMousePixelScroll'],slice=Array.prototype.slice,nullLowestDeltaTimeout,lowestDelta;if($.event.fixHooks){for(var i=toFix.length;i;){$.event.fixHooks[toFix[--i]]=$.event.mouseHooks;}} +var special=$.event.special.mousewheel={version:'3.1.9',setup:function(){if(this.addEventListener){for(var i=toBind.length;i;){this.addEventListener(toBind[--i],handler,false);}}else{this.onmousewheel=handler;} +$.data(this,'mousewheel-line-height',special.getLineHeight(this));$.data(this,'mousewheel-page-height',special.getPageHeight(this));},teardown:function(){if(this.removeEventListener){for(var i=toBind.length;i;){this.removeEventListener(toBind[--i],handler,false);}}else{this.onmousewheel=null;}},getLineHeight:function(elem){return parseInt($(elem)['offsetParent'in $.fn?'offsetParent':'parent']().css('fontSize'),10);},getPageHeight:function(elem){return $(elem).height();},settings:{adjustOldDeltas:true}};$.fn.extend({mousewheel:function(fn){return fn?this.bind('mousewheel',fn):this.trigger('mousewheel');},unmousewheel:function(fn){return this.unbind('mousewheel',fn);}});function handler(event){var orgEvent=event||window.event,args=slice.call(arguments,1),delta=0,deltaX=0,deltaY=0,absDelta=0;event=$.event.fix(orgEvent);event.type='mousewheel';if('detail'in orgEvent){deltaY=orgEvent.detail*-1;} +if('wheelDelta'in orgEvent){deltaY=orgEvent.wheelDelta;} +if('wheelDeltaY'in orgEvent){deltaY=orgEvent.wheelDeltaY;} +if('wheelDeltaX'in orgEvent){deltaX=orgEvent.wheelDeltaX*-1;} +if('axis'in orgEvent&&orgEvent.axis===orgEvent.HORIZONTAL_AXIS){deltaX=deltaY*-1;deltaY=0;} +delta=deltaY===0?deltaX:deltaY;if('deltaY'in orgEvent){deltaY=orgEvent.deltaY*-1;delta=deltaY;} +if('deltaX'in orgEvent){deltaX=orgEvent.deltaX;if(deltaY===0){delta=deltaX*-1;}} +if(deltaY===0&&deltaX===0){return;} +if(orgEvent.deltaMode===1){var lineHeight=$.data(this,'mousewheel-line-height');delta*=lineHeight;deltaY*=lineHeight;deltaX*=lineHeight;}else if(orgEvent.deltaMode===2){var pageHeight=$.data(this,'mousewheel-page-height');delta*=pageHeight;deltaY*=pageHeight;deltaX*=pageHeight;} +absDelta=Math.max(Math.abs(deltaY),Math.abs(deltaX));if(!lowestDelta||absDelta=1?'floor':'ceil'](delta/lowestDelta);deltaX=Math[deltaX>=1?'floor':'ceil'](deltaX/lowestDelta);deltaY=Math[deltaY>=1?'floor':'ceil'](deltaY/lowestDelta);event.deltaX=deltaX;event.deltaY=deltaY;event.deltaFactor=lowestDelta;event.deltaMode=0;args.unshift(event,delta,deltaX,deltaY);if(nullLowestDeltaTimeout){clearTimeout(nullLowestDeltaTimeout);} +nullLowestDeltaTimeout=setTimeout(nullLowestDelta,200);return($.event.dispatch||$.event.handle).apply(this,args);} +function nullLowestDelta(){lowestDelta=null;} +function shouldAdjustOldDeltas(orgEvent,absDelta){return special.settings.adjustOldDeltas&&orgEvent.type==='mousewheel'&&absDelta%120===0;}}));+function($){"use strict";var Base=$.oc.foundation.base,BaseProto=Base.prototype +var DragScroll=function(element,options){this.options=$.extend({},DragScroll.DEFAULTS,options) +var +$el=$(element),el=$el.get(0),dragStart=0,startOffset=0,self=this,dragging=false,eventElementName=this.options.vertical?'pageY':'pageX';this.el=$el +this.scrollClassContainer=this.options.scrollClassContainer?$(this.options.scrollClassContainer):$el +Base.call(this) +if(this.options.scrollMarkerContainer){$(this.options.scrollMarkerContainer).append($(''))} +$el.mousewheel(function(event){if(!self.options.allowScroll) +return;var offset=self.options.vertical?((event.deltaFactor*event.deltaY)*-1):(event.deltaFactor*event.deltaX) +return!scrollWheel(offset)}) +if(!options.noDragSupport){$el.on('mousedown.dragScroll',function(event){if(event.target&&event.target.tagName==='INPUT') return -$('li',self.$el).removeClass('active') -$(this).addClass('active') -self.$field.val($(this).data('value')) -self.$el.trigger('change')})} -BalloonSelector.DEFAULTS={} -var old=$.fn.balloonSelector -$.fn.balloonSelector=function(option){return this.each(function(){var $this=$(this) -var data=$this.data('oc.balloon-selector') -var options=$.extend({},BalloonSelector.DEFAULTS,$this.data(),typeof option=='object'&&option) -if(!data)$this.data('oc.balloon-selector',(data=new BalloonSelector(this,options)))})} -$.fn.balloonSelector.Constructor=BalloonSelector -$.fn.balloonSelector.noConflict=function(){$.fn.balloonSelector=old +startDrag(event) +return false})} +$el.on('touchstart.dragScroll',function(event){var touchEvent=event.originalEvent;if(touchEvent.touches.length==1){startDrag(touchEvent.touches[0]) +event.stopPropagation()}}) +$el.on('click.dragScroll',function(){if($(document.body).hasClass('drag')) +return false}) +$(document).on('ready',this.proxy(this.fixScrollClasses)) +$(window).on('resize',this.proxy(this.fixScrollClasses)) +function startDrag(event){dragStart=event[eventElementName] +startOffset=self.options.vertical?$el.scrollTop():$el.scrollLeft() +if(Modernizr.touch){$(window).on('touchmove.dragScroll',function(event){var touchEvent=event.originalEvent +moveDrag(touchEvent.touches[0]) +event.preventDefault()}) +$(window).on('touchend.dragScroll',function(event){stopDrag()})} +else{$(window).on('mousemove.dragScroll',function(event){moveDrag(event) +$(document.body).addClass(self.options.dragClass) +return false}) +$(window).on('mouseup.dragScroll',function(mouseUpEvent){var isClick=event.pageX==mouseUpEvent.pageX&&event.pageY==mouseUpEvent.pageY +stopDrag(isClick) +return false})}} +function moveDrag(event){var current=event[eventElementName],offset=dragStart-current +if(Math.abs(offset)>2){if(!dragging){dragging=true +$el.trigger('start.oc.dragScroll') +self.options.start();} +self.options.vertical?$el.scrollTop(startOffset+offset):$el.scrollLeft(startOffset+offset) +$el.trigger('drag.oc.dragScroll') +self.options.drag()}} +function stopDrag(click){$(window).off('.dragScroll') +dragging=false;if(click) +$(document.body).removeClass(self.options.dragClass) +else +self.fixScrollClasses() +window.setTimeout(function(){if(!click){$(document.body).removeClass(self.options.dragClass) +$el.trigger('stop.oc.dragScroll') +self.options.stop() +self.fixScrollClasses()}},100)} +function scrollWheel(offset){startOffset=self.options.vertical?el.scrollTop:el.scrollLeft +self.options.vertical?$el.scrollTop(startOffset+offset):$el.scrollLeft(startOffset+offset) +var scrolled=self.options.vertical?el.scrollTop!=startOffset:el.scrollLeft!=startOffset +$el.trigger('drag.oc.dragScroll') +self.options.drag() +if(scrolled){if(self.wheelUpdateTimer!==undefined&&self.wheelUpdateTimer!==false) +window.clearInterval(self.wheelUpdateTimer);self.wheelUpdateTimer=window.setTimeout(function(){self.wheelUpdateTimer=false;self.fixScrollClasses()},100);} +return scrolled} +this.fixScrollClasses();} +DragScroll.prototype=Object.create(BaseProto) +DragScroll.prototype.constructor=DragScroll +DragScroll.DEFAULTS={vertical:false,allowScroll:true,scrollClassContainer:false,scrollMarkerContainer:false,dragClass:'drag',noDragSupport:false,start:function(){},drag:function(){},stop:function(){}} +DragScroll.prototype.fixScrollClasses=function(){this.scrollClassContainer.toggleClass('scroll-before',!this.isStart()) +this.scrollClassContainer.toggleClass('scroll-after',!this.isEnd()) +this.scrollClassContainer.toggleClass('scroll-active-before',this.isActiveBefore()) +this.scrollClassContainer.toggleClass('scroll-active-after',this.isActiveAfter())} +DragScroll.prototype.isStart=function(){if(!this.options.vertical) +return this.el.scrollLeft()<=0;else +return this.el.scrollTop()<=0;} +DragScroll.prototype.isEnd=function(){if(!this.options.vertical) +return(this.el[0].scrollWidth-(this.el.scrollLeft()+this.el.width()))<=0 +else +return(this.el[0].scrollHeight-(this.el.scrollTop()+this.el.height()))<=0} +DragScroll.prototype.goToStart=function(){if(!this.options.vertical) +return this.el.scrollLeft(0) +else +return this.el.scrollTop(0)} +DragScroll.prototype.isActiveAfter=function(){var activeElement=$('.active',this.el);if(activeElement.length==0) +return false +if(!this.options.vertical) +return activeElement.get(0).offsetLeft>(this.el.scrollLeft()+this.el.width()) +else +return activeElement.get(0).offsetTop>(this.el.scrollTop()+this.el.height())} +DragScroll.prototype.isActiveBefore=function(){var activeElement=$('.active',this.el);if(activeElement.length==0) +return false +if(!this.options.vertical) +return(activeElement.get(0).offsetLeft+activeElement.width())0){this.el.animate({'scrollLeft':$el.get(0).offsetLeft+$el.width()-this.el.width()},params) +animated=true}}}else{offset=$el.get(0).offsetTop-this.el.scrollTop() +if(offset<0){this.el.animate({'scrollTop':$el.get(0).offsetTop},params) +animated=true}else{offset=$el.get(0).offsetTop-(this.el.scrollTop()+this.el.height()) +if(offset>0){this.el.animate({'scrollTop':$el.get(0).offsetTop+$el.height()-this.el.height()},params) +animated=true}}} +if(!animated&&callback!==undefined) +callback()} +DragScroll.prototype.dispose=function(){this.scrollClassContainer=null +$(document).off('ready',this.proxy(this.fixScrollClasses)) +$(window).off('resize',this.proxy(this.fixScrollClasses)) +this.el.off('.dragScroll') +this.el.removeData('oc.dragScroll') +this.el=null +BaseProto.dispose.call(this)} +var old=$.fn.dragScroll +$.fn.dragScroll=function(option){var args=arguments;return this.each(function(){var $this=$(this) +var data=$this.data('oc.dragScroll') +var options=typeof option=='object'&&option +if(!data)$this.data('oc.dragScroll',(data=new DragScroll(this,options))) +if(typeof option=='string'){var methodArgs=[];for(var i=1;i":">",'"':'"',"'":''',"/":'/'};function escapeHtml(string){return String(string).replace(/[&<>"'\/]/g,function(s){return entityMap[s];});} +var whiteRe=/\s*/;var spaceRe=/\s+/;var equalsRe=/\s*=/;var curlyRe=/\s*\}/;var tagRe=/#|\^|\/|>|\{|&|=|!/;function parseTemplate(template,tags){if(!template) +return[];var sections=[];var tokens=[];var spaces=[];var hasTag=false;var nonSpace=false;function stripSpace(){if(hasTag&&!nonSpace){while(spaces.length) +delete tokens[spaces.pop()];}else{spaces=[];} +hasTag=false;nonSpace=false;} +var openingTagRe,closingTagRe,closingCurlyRe;function compileTags(tags){if(typeof tags==='string') +tags=tags.split(spaceRe,2);if(!isArray(tags)||tags.length!==2) +throw new Error('Invalid tags: '+tags);openingTagRe=new RegExp(escapeRegExp(tags[0])+'\\s*');closingTagRe=new RegExp('\\s*'+escapeRegExp(tags[1]));closingCurlyRe=new RegExp('\\s*'+escapeRegExp('}'+tags[1]));} +compileTags(tags||mustache.tags);var scanner=new Scanner(template);var start,type,value,chr,token,openSection;while(!scanner.eos()){start=scanner.pos;value=scanner.scanUntil(openingTagRe);if(value){for(var i=0,valueLength=value.length;i0?sections[sections.length-1][4]:nestedTokens;break;default:collector.push(token);}} +return nestedTokens;} +function Scanner(string){this.string=string;this.tail=string;this.pos=0;} +Scanner.prototype.eos=function(){return this.tail==="";};Scanner.prototype.scan=function(re){var match=this.tail.match(re);if(!match||match.index!==0) +return'';var string=match[0];this.tail=this.tail.substring(string.length);this.pos+=string.length;return string;};Scanner.prototype.scanUntil=function(re){var index=this.tail.search(re),match;switch(index){case-1:match=this.tail;this.tail="";break;case 0:match="";break;default:match=this.tail.substring(0,index);this.tail=this.tail.substring(index);} +this.pos+=match.length;return match;};function Context(view,parentContext){this.view=view;this.cache={'.':this.view};this.parent=parentContext;} +Context.prototype.push=function(view){return new Context(view,this);};Context.prototype.lookup=function(name){var cache=this.cache;var value;if(name in cache){value=cache[name];}else{var context=this,names,index,lookupHit=false;while(context){if(name.indexOf('.')>0){value=context.view;names=name.split('.');index=0;while(value!=null&&index')value=this._renderPartial(token,context,partials,originalTemplate);else if(symbol==='&')value=this._unescapedValue(token,context);else if(symbol==='name')value=this._escapedValue(token,context);else if(symbol==='text')value=this._rawValue(token);if(value!==undefined) +buffer+=value;} +return buffer;};Writer.prototype._renderSection=function(token,context,partials,originalTemplate){var self=this;var buffer='';var value=context.lookup(token[1]);function subRender(template){return self.render(template,context,partials);} +if(!value)return;if(isArray(value)){for(var j=0,valueLength=value.length;j').addClass('control-popover') +if(this.options.containerClass) +this.$container.addClass(this.options.containerClass) +if(this.options.useAnimation) +this.$container.addClass('fade') +var $content=$('
      ').html(this.getContent()) +this.$container.append($content) +if(this.options.width) +this.$container.width(this.options.width) +if(this.options.modal){this.$overlay=$('
      ').addClass('popover-overlay') +$(document.body).append(this.$overlay) +if(this.options.highlightModalTarget){this.$el.addClass('popover-highlight') +this.$el.blur()}}else{this.$overlay=false} +if(this.options.container) +$(this.options.container).append(this.$container) +else +$(document.body).append(this.$container) +var +placement=this.calcPlacement(),position=this.calcPosition(placement) +this.$container.css({left:position.x,top:position.y}).addClass('placement-'+placement) +this.$container.addClass('in') +if(this.$overlay)this.$overlay.addClass('in') +$(document.body).addClass('popover-open') +var showEvent=jQuery.Event('show.oc.popover',{relatedTarget:this.$container.get(0)}) +this.$el.trigger(showEvent) +this.$container.on('close.oc.popover',function(e){self.hide()}) +this.$container.on('click','[data-dismiss=popover]',function(e){self.hide() +return false}) +this.docClickHandler=$.proxy(this.onDocumentClick,this) +$(document).bind('mousedown',this.docClickHandler);if(this.options.closeOnEsc){$(document).on('keyup.oc.popover',function(e){if($(e.target).hasClass('select2-offscreen')) +return false +if(!self.options.closeOnEsc){return false} +if(e.keyCode==27){self.hide() +return false}})}} +Popover.prototype.getContent=function(){return typeof this.options.content=='function'?this.options.content.call(this.$el[0],this):this.options.content} +Popover.prototype.calcDimensions=function(){var +documentWidth=$(document).width(),documentHeight=$(document).height(),targetOffset=this.$el.offset(),targetWidth=this.$el.outerWidth(),targetHeight=this.$el.outerHeight() +return{containerWidth:this.$container.outerWidth()+this.arrowSize,containerHeight:this.$container.outerHeight()+this.arrowSize,targetOffset:targetOffset,targetHeight:targetHeight,targetWidth:targetWidth,spaceLeft:targetOffset.left,spaceRight:documentWidth-(targetWidth+targetOffset.left),spaceTop:targetOffset.top,spaceBottom:documentHeight-(targetHeight+targetOffset.top),spaceHorizontalBottom:documentHeight-targetOffset.top,spaceVerticalRight:documentWidth-targetOffset.left,documentWidth:documentWidth}} +Popover.prototype.fitsLeft=function(dimensions){return dimensions.spaceLeft>=dimensions.containerWidth&&dimensions.spaceHorizontalBottom>=dimensions.containerHeight} +Popover.prototype.fitsRight=function(dimensions){return dimensions.spaceRight>=dimensions.containerWidth&&dimensions.spaceHorizontalBottom>=dimensions.containerHeight} +Popover.prototype.fitsBottom=function(dimensions){return dimensions.spaceBottom>=dimensions.containerHeight&&dimensions.spaceVerticalRight>=dimensions.containerWidth} +Popover.prototype.fitsTop=function(dimensions){return dimensions.spaceTop>=dimensions.containerHeight&&dimensions.spaceVerticalRight>=dimensions.containerWidth} +Popover.prototype.calcPlacement=function(){var +placement=this.options.placement,dimensions=this.calcDimensions();if(placement=='center') +return placement +if(placement!='bottom'&&placement!='top'&&placement!='left'&&placement!='right') +placement='bottom' +var placementFunctions={top:this.fitsTop,bottom:this.fitsBottom,left:this.fitsLeft,right:this.fitsRight} +if(placementFunctions[placement](dimensions)) +return placement +for(var index in placementFunctions){if(placementFunctions[index](dimensions)) +return index} +return this.options.fallbackPlacement} +Popover.prototype.calcPosition=function(placement){var +dimensions=this.calcDimensions(),result +switch(placement){case'left':var realOffset=this.options.offsetY===undefined?this.options.offset:this.options.offsetY +result={x:(dimensions.targetOffset.left-dimensions.containerWidth),y:dimensions.targetOffset.top+realOffset} +break;case'top':var realOffset=this.options.offsetX===undefined?this.options.offset:this.options.offsetX +result={x:dimensions.targetOffset.left+realOffset,y:(dimensions.targetOffset.top-dimensions.containerHeight)} +break;case'bottom':var realOffset=this.options.offsetX===undefined?this.options.offset:this.options.offsetX +result={x:dimensions.targetOffset.left+realOffset,y:(dimensions.targetOffset.top+dimensions.targetHeight+this.arrowSize)} +break;case'right':var realOffset=this.options.offsetY===undefined?this.options.offset:this.options.offsetY +result={x:(dimensions.targetOffset.left+dimensions.targetWidth+this.arrowSize),y:dimensions.targetOffset.top+realOffset} +break;case'center':var windowHeight=$(window).height() +result={x:(dimensions.documentWidth/2-dimensions.containerWidth/2),y:(windowHeight/2-dimensions.containerHeight/2)} +if(result.y<40) +result.y=40 +break;} +if(!this.options.container) +return result +var +$container=$(this.options.container),containerOffset=$container.offset() +result.x-=containerOffset.left +result.y-=containerOffset.top +return result} +Popover.prototype.onDocumentClick=function(e){if(!this.options.closeOnPageClick) +return +if(this.options.onCheckDocumentClickTarget&&this.options.onCheckDocumentClickTarget(e.target)){return} +if($.contains(this.$container.get(0),e.target)) +return +this.hide();} +Popover.DEFAULTS={placement:'bottom',fallbackPlacement:'bottom',content:'

      Popover content

      ',width:false,modal:false,highlightModalTarget:false,closeOnPageClick:true,closeOnEsc:true,container:false,containerClass:null,offset:15,useAnimation:false,onCheckDocumentClickTarget:null} +var old=$.fn.ocPopover +$.fn.ocPopover=function(option){var args=arguments;return this.each(function(){var $this=$(this) +var data=$this.data('oc.popover') +var options=$.extend({},Popover.DEFAULTS,$this.data(),typeof option=='object'&&option) +if(!data){if(typeof option=='string') +return;$this.data('oc.popover',(data=new Popover(this,options)))}else{if(typeof option!='string') +return;var methodArgs=[];for(var i=1;i \ + \ +

      \ + \ +
      \ +
        \ + {{#available}} \ +
      • {{name}}
      • \ + {{/available}} \ + {{#loading}} \ +
      • \ + {{/loading}} \ +
      \ +
      \ +
      \ +
        \ + {{#active}} \ +
      • {{name}}
      • \ + {{/active}} \ +
      \ +
      \ +
      \ + \ + '} +FilterWidget.prototype.init=function(){var self=this +this.$el.on('change','.filter-scope input[type="checkbox"]',function(){var isChecked=$(this).is(':checked'),$scope=$(this).closest('.filter-scope'),scopeName=$scope.data('scope-name') +self.scopeValues[scopeName]=isChecked +self.checkboxToggle(scopeName,isChecked)}) +this.$el.on('click','a.filter-scope',function(){var $scope=$(this),scopeName=$scope.data('scope-name') +if($scope.hasClass('filter-scope-open'))return +self.$activeScope=$scope +self.activeScopeName=scopeName +self.isActiveScopeDirty=false +self.displayPopover($scope) +$scope.addClass('filter-scope-open')}) +this.$el.on('show.oc.popover','a.filter-scope',function(){self.focusSearch()}) +this.$el.on('hide.oc.popover','a.filter-scope',function(){var $scope=$(this) +self.pushOptions(self.activeScopeName) +self.activeScopeName=null +self.$activeScope=null +setTimeout(function(){$scope.removeClass('filter-scope-open')},200)}) +$(document).on('click','#controlFilterPopover .filter-items > ul > li',function(){self.selectItem($(this))}) +$(document).on('click','#controlFilterPopover .filter-active-items > ul > li',function(){self.selectItem($(this),true)}) +$(document).on('ajaxDone','#controlFilterPopover input.filter-search-input',function(event,context,data){self.filterAvailable(data.scopeName,data.options.available)})} +FilterWidget.prototype.focusSearch=function(){if(Modernizr.touch) +return +var $input=$('#controlFilterPopover input.filter-search-input'),length=$input.val().length +$input.focus() +$input.get(0).setSelectionRange(length,length)} +FilterWidget.prototype.updateScopeSetting=function($scope,amount){var $setting=$scope.find('.filter-setting') +if(amount){$setting.text(amount) +$scope.addClass('active')} +else{$setting.text('all') +$scope.removeClass('active')}} +FilterWidget.prototype.selectItem=function($item,isDeselect){var $otherContainer=isDeselect?$item.closest('.control-filter-popover').find('.filter-items:first > ul'):$item.closest('.control-filter-popover').find('.filter-active-items:first > ul') +$item.addClass('animate-enter').prependTo($otherContainer).one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend',function(){$(this).removeClass('animate-enter')}) +if(!this.scopeValues[this.activeScopeName]) +return +var +itemId=$item.data('item-id'),items=this.scopeValues[this.activeScopeName],fromItems=isDeselect?items.active:items.available,toItems=isDeselect?items.available:items.active,testFunc=function(item){return item.id==itemId},item=$.grep(fromItems,testFunc).pop(),filtered=$.grep(fromItems,testFunc,true) +if(isDeselect) +this.scopeValues[this.activeScopeName].active=filtered +else +this.scopeValues[this.activeScopeName].available=filtered +if(item) +toItems.push(item) +this.updateScopeSetting(this.$activeScope,items.active.length) +this.isActiveScopeDirty=true +this.focusSearch()} +FilterWidget.prototype.displayPopover=function($scope){var self=this,scopeName=$scope.data('scope-name'),data=this.scopeValues[scopeName],isLoaded=true +if(!data){data={loading:true} +isLoaded=false} +data.scopeName=scopeName +data.optionsHandler=self.options.optionsHandler +$scope.data('oc.popover',null) +$scope.ocPopover({content:Mustache.render(self.getPopoverTemplate(),data),modal:false,highlightModalTarget:true,closeOnPageClick:true,placement:'bottom'}) +if(!isLoaded){self.loadOptions(scopeName)}} +FilterWidget.prototype.loadOptions=function(scopeName){var $form=this.$el.closest('form'),self=this,data={scopeName:scopeName} +var populated=this.$el.data('filterScopes') +if(populated&&populated[scopeName]){self.fillOptions(scopeName,populated[scopeName]) +return false} +return $form.request(this.options.optionsHandler,{data:data,success:function(data){self.fillOptions(scopeName,data.options)}})} +FilterWidget.prototype.fillOptions=function(scopeName,data){if(this.scopeValues[scopeName]) +return +if(!data.active)data.active=[] +if(!data.available)data.available=[] +this.scopeValues[scopeName]=data +if(scopeName!=this.activeScopeName) +return +var container=$('#controlFilterPopover .filter-items > ul').empty() +this.addItemsToListElement(container,data.available) +var container=$('#controlFilterPopover .filter-active-items > ul') +this.addItemsToListElement(container,data.active)} +FilterWidget.prototype.filterAvailable=function(scopeName,available){if(this.activeScopeName!=scopeName) +return +if(!this.scopeValues[this.activeScopeName]) +return +var +self=this,filtered=[],items=this.scopeValues[scopeName] +if(items.active.length){var compareFunc=function(a,b){return a.id==b.id},inArrayFunc=function(elem,array,testFunc){var i=array.length +do{if(i--===0)return i}while(testFunc(array[i],elem)) +return i} +filtered=$.grep(available,function(item){return!inArrayFunc(item,items.active,compareFunc)})} +else{filtered=available} +var container=$('#controlFilterPopover .filter-items > ul').empty() +self.addItemsToListElement(container,filtered)} +FilterWidget.prototype.addItemsToListElement=function($ul,items){$.each(items,function(key,obj){var item=$('
    • ').data({'item-id':obj.id}).append($('').prop({'href':'javascript:;',}).text(obj.name)) +$ul.append(item)})} +FilterWidget.prototype.pushOptions=function(scopeName){if(!this.isActiveScopeDirty||!this.options.updateHandler) +return +var $form=this.$el.closest('form'),data={scopeName:scopeName,options:this.scopeValues[scopeName]} +$.oc.stripeLoadIndicator.show() +$form.request(this.options.updateHandler,{data:data}).always(function(){$.oc.stripeLoadIndicator.hide()})} +FilterWidget.prototype.checkboxToggle=function(scopeName,isChecked){if(!this.options.updateHandler) +return +var $form=this.$el.closest('form'),data={scopeName:scopeName,value:isChecked} +$.oc.stripeLoadIndicator.show() +$form.request(this.options.updateHandler,{data:data}).always(function(){$.oc.stripeLoadIndicator.hide()})} +var old=$.fn.filterWidget +$.fn.filterWidget=function(option){var args=arguments,result +this.each(function(){var $this=$(this) +var data=$this.data('oc.filterwidget') +var options=$.extend({},FilterWidget.DEFAULTS,$this.data(),typeof option=='object'&&option) +if(!data)$this.data('oc.filterwidget',(data=new FilterWidget(this,options))) +if(typeof option=='string')result=data[option].call($this) +if(typeof result!='undefined')return false}) +return result?result:this} +$.fn.filterWidget.Constructor=FilterWidget +$.fn.filterWidget.noConflict=function(){$.fn.filterWidget=old +return this} +$(document).render(function(){$('[data-control="filterwidget"]').filterWidget();})}(window.jQuery);(function(factory){if(typeof define==='function'&&define.amd){define(['jquery'],factory);}else if(typeof exports==='object'){factory(require('jquery'));}else{factory(jQuery);}}(function(jQuery){var S2=(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd){var S2=jQuery.fn.select2.amd;} var S2;(function(){if(!S2||!S2.requirejs){if(!S2){S2={};}else{require=S2;} var requirejs,require,define;(function(undef){var main,req,makeMap,handlers,defined={},waiting={},config={},defining={},hasOwn=Object.prototype.hasOwnProperty,aps=[].slice,jsSuffixRegExp=/\.js$/;function hasProp(obj,prop){return hasOwn.call(obj,prop);} function normalize(name,baseName){var nameParts,nameSegment,mapValue,foundMap,lastIndex,foundI,foundStarMap,starI,i,j,part,baseParts=baseName&&baseName.split("/"),map=config.map,starMap=(map&&map['*'])||{};if(name&&name.charAt(0)==="."){if(baseName){baseParts=baseParts.slice(0,baseParts.length-1);name=name.split('/');lastIndex=name.length-1;if(config.nodeIdCompat&&jsSuffixRegExp.test(name[lastIndex])){name[lastIndex]=name[lastIndex].replace(jsSuffixRegExp,'');} @@ -846,929 +1278,6 @@ $element.one('dispose-control',function(){if($element.data('select2')){$element. if($element.hasClass('select-no-search')){extraOptions.minimumResultsForSearch=Infinity} $element.select2($.extend({},selectOptions,extraOptions))})}) $(document).on('disable','select.custom-select',function(event,status){$(this).select2('enable',!status)}) -$(document).on('focus','select.custom-select',function(event){setTimeout($.proxy(function(){$(this).select2('focus')},this),10)})})(jQuery);+function($){"use strict";var Base=$.oc.foundation.base,BaseProto=Base.prototype -if($.oc===undefined) -$.oc={} -$.oc.inspector={editors:{},propertyCounter:0} -var Inspector=function(element,options){this.options=options -this.$el=$(element) -this.title=false -this.description=false -Base.call(this)} -Inspector.prototype=Object.create(BaseProto) -Inspector.prototype.constructor=Inspector -Inspector.prototype.loadConfiguration=function(onSuccess){var configString=this.$el.data('inspector-config') -if(configString!==undefined){this.parseConfiguration(configString) -if(onSuccess!==undefined) -onSuccess();}else{var $form=$(this.selector).closest('form'),data=this.$el.data(),self=this -$.oc.stripeLoadIndicator.show() -var request=$form.request('onGetInspectorConfiguration',{data:data}).done(function(data){self.parseConfiguration(data.configuration.properties) -if(data.configuration.title!==undefined) -self.title=data.configuration.title -if(data.configuration.description!==undefined) -self.description=data.configuration.description -$.oc.stripeLoadIndicator.hide() -if(onSuccess!==undefined) -onSuccess();}).always(function(){$.oc.stripeLoadIndicator.hide()})}} -Inspector.prototype.parseConfiguration=function(jsonString){if(jsonString===undefined) -throw new Error('The Inspector cannot be initialized because the Inspector configuration '+'attribute is not defined on the inspectable element.');if(!$.isArray(jsonString)&&!$.isPlainObject(jsonString)){try{this.config=$.parseJSON(jsonString)}catch(err){throw new Error('Error parsing the Inspector field configuration. '+err)}}else -this.config=jsonString -this.propertyValuesField=$('input[data-inspector-values]',this.$el)} -Inspector.prototype.getPopoverTemplate=function(){return' \ -
      \ -

      {{title}}

      \ - {{#description}} \ -

      {{description}}

      \ - {{/description}} \ - \ -
      \ -
      \ - \ - {{#properties}} \ - \ - \ - {{#editor}}{{/editor}} \ - \ - {{/properties}} \ -
      \ - {{#expandControl}}{{/expandControl}} \ - {{title}} \ - {{#info}}{{/info}} \ -
      \ - \ - '} -Inspector.prototype.init=function(){if(!this.config||this.config.length==0) -return -this.editors=[] -this.initProperties() -this.$el.data('oc.inspectorVisible',true) -var e=$.Event('showing.oc.inspector') -this.$el.trigger(e,[{callback:this.proxy(this.displayPopover)}]) -if(e.isDefaultPrevented()) -return -if(!e.isPropagationStopped()) -this.displayPopover()} -Inspector.prototype.displayPopover=function(){var fieldsConfig=this.preprocessConfig(),renderEditorBound=this.proxy(this.renderEditor),groupExpandedBound=this.proxy(this.groupExpanded),data={title:this.title?this.title:this.$el.data('inspector-title'),description:this.description?this.description:this.$el.data('inspector-description'),properties:fieldsConfig.properties,editor:function(){return function(text,render){if(this.itemType=='property') -return renderEditorBound(this,render)}},info:function(){return function(text,render){if(this.description!==undefined&&this.description!=null) -return render('',this)}},propFormat:function(){return function(text,render){return'prop-'+render(text).replace('.','-')}},colspan:function(){return function(text,render){return this.itemType=='group'?'colspan="2"':null}},tableClass:function(){return function(text,render){return fieldsConfig.hasGroups?'has-groups':null}},cellClass:function(){return function(text,render){var result=this.itemType+((this.itemType=='property'&&this.groupIndex!==undefined)?' grouped':'') -if(this.itemType=='property'&&this.groupIndex!==undefined) -result+=groupExpandedBound(this.group)?' expanded':' collapsed' -if(this.itemType=='property'&&!this.showExternalParam) -result+=' no-external-parameter' -return result}},expandControl:function(){return function(text,render){if(this.itemType=='group'){this.itemStatus=groupExpandedBound(this.title)?'expanded':'' -return render('
      Expand/collapse',this)}}},dataGroupIndex:function(){return function(text,render){return this.groupIndex!==undefined&&this.itemType=='property'?render('data-group-index={{groupIndex}}',this):''}}} -var offset=this.$el.data('inspector-offset') -if(offset===undefined) -offset=15 -var offsetX=this.$el.data('inspector-offset-x'),offsetY=this.$el.data('inspector-offset-y') -var placement=this.$el.data('inspector-placement') -if(placement===undefined) -placement='bottom' -var fallbackPlacement=this.$el.data('inspector-fallback-placement') -if(fallbackPlacement===undefined) -fallbackPlacement='bottom' -this.$el.ocPopover({content:Mustache.render(this.getPopoverTemplate(),data),highlightModalTarget:true,modal:true,placement:placement,fallbackPlacement:fallbackPlacement,containerClass:'control-inspector',container:this.$el.data('inspector-container'),offset:offset,offsetX:offsetX,offsetY:offsetY,width:400}) -this.$el.on('hiding.oc.popover',this.proxy(this.onBeforeHide)) -this.$el.on('hide.oc.popover',this.proxy(this.cleanup)) -this.$el.addClass('inspector-open') -$(this.$el.data('oc.popover').$container).on('keydown',this.proxy(this.onPopoverKeyDown)) -if(this.editors.length>0){if(this.editors[0].focus!==undefined) -this.editors[0].focus()} -if(this.$el.closest('[data-inspector-external-parameters]').length>0) -this.initExternalParameterEditor(this.$el.data('oc.popover').$container) -for(var i=0,len=this.editors.length;i
    • '),$editor=$('
      \ -
      \ - \ - \ - \ - \ -
      \ -
      ') -$editorContainer.append($td.children()) -$editorContainer.append($editor) -$td.append($editorContainer) -var $editorLink=$('a',$editor) -$editorLink.click(function(){return self.toggleExternalParameterEditor($(this))}).attr('title','Click to enter the external parameter name to load the property value from').tooltip({'container':'body',delay:500}) -var $input=$editor.find('input'),propertyValue=self.propertyValues[property] -$input.on('focus',function(){var $field=$(this) -$('td',$field.closest('table')).removeClass('active') -$field.closest('td').addClass('active')}) -$input.on('change',function(){self.markPropertyChanged(property,true)}) -var matches=[] -if(propertyValue){if(matches=propertyValue.match(/^\{\{([^\}]+)\}\}$/)){var value=$.trim(matches[1]) -if(value.length>0){self.showExternalParameterEditor($editorContainer,$editor,$editorLink,$td,true) -$editor.find('input').val(value) -self.writeProperty(property,null,true)}}}}})} -Inspector.prototype.showExternalParameterEditor=function($container,$editor,$editorLink,$cell,noAnimation){var position=$editor.position() -$('input',$editor).focus() -if(!noAnimation){$editor.css({'left':position.left+'px','right':0})}else{$editor.css('right',0)} -setTimeout(function(){$editor.css('left',0) -$cell.scrollTop(0)},0) -$container.addClass('editor-visible') -$editorLink.attr('data-original-title','Click to enter the property value') -this.toggleCellEditorVisibility($cell,false) -$editor.find('input').attr('tabindex',0)} -Inspector.prototype.toggleExternalParameterEditor=function($editorLink){var $container=$editorLink.closest('.external-param-editor-container'),$editor=$('.external-editor',$container),$cell=$editorLink.closest('td'),self=this -$editorLink.tooltip('hide') -if(!$container.hasClass('editor-visible')){self.showExternalParameterEditor($container,$editor,$editorLink,$cell)}else{var left=$container.width() -$editor.css('left',left+'px') -setTimeout(function(){$editor.css({'left':'auto','right':'30px'}) -$container.removeClass('editor-visible') -$container.closest('td').removeClass('active') -var property=$container.closest('tr').data('property'),propertyEditor=self.findEditor(property) -if(propertyEditor&&propertyEditor.onHideExternalParameterEditor!==undefined) -propertyEditor.onHideExternalParameterEditor()},200) -$editorLink.attr('data-original-title','Click to enter the external parameter name to load the property value from') -$editor.find('input').attr('tabindex',-1) -self.toggleCellEditorVisibility($cell,true)} -return false} -Inspector.prototype.toggleCellEditorVisibility=function($cell,show){var $container=$('.external-param-editor-container',$cell) -$container.children().each(function(){var $el=$(this) -if($el.hasClass('external-editor')) -return -if(show) -$el.removeClass('hide') -else{var height=$cell.data('inspector-cell-height') -if(!height){height=$cell.height() -$cell.data('inspector-cell-height',height)} -$container.css('height',height+'px') -$el.addClass('hide')}})} -Inspector.prototype.preprocessConfig=function(){var fields=[],result={hasGroups:false,properties:[]},groupIndex=0 -function findGroup(title){var groups=$.grep(fields,function(item){return item.itemType!==undefined&&item.itemType=='group'&&item.title==title}) -if(groups.length>0) -return groups[0] -return null} -$.each(this.config,function(){this.itemType='property' -if(this.group===undefined) -fields.push(this) -else{var group=findGroup(this.group) -if(!group){group={itemType:'group',title:this.group,properties:[],groupIndex:groupIndex} -groupIndex++ -fields.push(group)} -this.groupIndex=group.groupIndex -group.properties.push(this)}}) -$.each(fields,function(){result.properties.push(this) -if(this.itemType=='group'){result.hasGroups=true -$.each(this.properties,function(){result.properties.push(this)}) -delete this.properties}}) -return result} -Inspector.prototype.toggleGroup=function(link,$container){var $link=$(link),groupIndex=$link.data('group-index'),propertyRows=$('tr[data-group-index='+groupIndex+']',$container),duration=Math.round(100/propertyRows.length),collapse=true,statuses=this.loadGroupExpandedStatuses(),title=$('span.title-element',$link.closest('tr')).attr('title') -if($link.hasClass('expanded')){$link.removeClass('expanded') -statuses[title]=false}else{$link.addClass('expanded') -collapse=false -statuses[title]=true} -propertyRows.each(function(index){var self=$(this) -setTimeout(function(){self.toggleClass('collapsed',collapse) -self.toggleClass('expanded',!collapse)},index*duration)}) -this.writeGroupExpandedStatuses(statuses)} -Inspector.prototype.loadGroupExpandedStatuses=function(){var statuses=this.$el.data('inspector-group-statuses') -return statuses!==undefined?JSON.parse(statuses):{}} -Inspector.prototype.writeGroupExpandedStatuses=function(statuses){this.$el.data('inspector-group-statuses',JSON.stringify(statuses))} -Inspector.prototype.groupExpanded=function(title){var statuses=this.loadGroupExpandedStatuses() -if(statuses[title]!==undefined) -return statuses[title] -return false} -Inspector.prototype.normalizePropertyCode=function(code){var lowerCaseCode=code.toLowerCase() -for(var index in this.config){var propertyInfo=this.config[index] -if(propertyInfo.property.toLowerCase()==lowerCaseCode) -return propertyInfo.property} -return code} -Inspector.prototype.initProperties=function(){if(!this.propertyValuesField.length){var properties={},attributes=this.$el.get(0).attributes -for(var i=0,len=attributes.length;i',data)} -InspectorEditorString.prototype.validate=function(){var val=$.trim($(this.selector).val()) -if(this.fieldDef.required&&val.length===0) -return this.fieldDef.validationMessage||'Required fields were left blank.' -if(this.fieldDef.validationPattern===undefined) -return -var re=new RegExp(this.fieldDef.validationPattern,'m') -if(!val.match(re)) -return this.fieldDef.validationMessage} -InspectorEditorString.prototype.focus=function(){$(this.selector).focus() -$(this.selector).closest('td').scrollLeft(0)} -$.oc.inspector.editors.inspectorEditorString=InspectorEditorString;var InspectorEditorCheckbox=function(editorId,inspector,fieldDef){this.inspector=inspector -this.fieldDef=fieldDef -this.editorId=editorId -this.selector='#'+this.editorId+' input' -Base.call(this) -$(document).on('change',this.selector,this.proxy(this.applyValue))} -InspectorEditorCheckbox.prototype=Object.create(BaseProto) -InspectorEditorCheckbox.prototype.constructor=InspectorEditorCheckbox -InspectorEditorCheckbox.prototype.dispose=function(){$(document).off('change',this.selector,this.proxy(this.applyValue)) -this.inspector=null -this.fieldDef=null -this.editorId=null -this.selector=null -BaseProto.dispose.call(this)} -InspectorEditorCheckbox.prototype.applyValue=function(){this.inspector.writeProperty(this.fieldDef.property,$(this.selector).get(0).checked?1:0)} -InspectorEditorCheckbox.prototype.renderEditor=function(){var self=this,data={id:this.editorId,cbId:this.editorId+'-cb',title:this.fieldDef.title} -return Mustache.render(this.getTemplate(),data)} -InspectorEditorCheckbox.prototype.init=function(){var isChecked=this.inspector.readProperty(this.fieldDef.property,true) -if(isChecked===undefined){if(this.fieldDef.default!==undefined){isChecked=this.normalizeCheckedValue(this.fieldDef.default)}}else{isChecked=this.normalizeCheckedValue(isChecked)} -$(this.selector).prop('checked',isChecked)} -InspectorEditorCheckbox.prototype.normalizeCheckedValue=function(value){if(value=='0'||value=='false') -return false -return value} -InspectorEditorCheckbox.prototype.focus=function(){$(this.selector).closest('div').focus()} -InspectorEditorCheckbox.prototype.getTemplate=function(){return' \ - \ -
      \ - \ - \ -
      \ - \ - ';} -$.oc.inspector.editors.inspectorEditorCheckbox=InspectorEditorCheckbox;var InspectorEditorDropdown=function(editorId,inspector,fieldDef){this.inspector=inspector -this.fieldDef=fieldDef -this.editorId=editorId -this.selector='#'+this.editorId+' select' -this.dynamicOptions=this.fieldDef.options?false:true -this.initialization=false -Base.call(this) -$(document).on('change',this.selector,this.proxy(this.applyValue))} -InspectorEditorDropdown.prototype=Object.create(BaseProto) -InspectorEditorDropdown.prototype.constructor=InspectorEditorDropdown -InspectorEditorDropdown.prototype.dispose=function(){$(document).off('change',this.selector,this.proxy(this.applyValue)) -var $element=$(this.selector) -if($element.data('select2')!=null){$element.select2('close') -$element.select2('destroy')} -this.inspector=null -this.fieldDef=null -this.editorId=null -this.selector=null -BaseProto.dispose.call(this)} -InspectorEditorDropdown.prototype.applyValue=function(){this.inspector.writeProperty(this.fieldDef.property,$(this.selector).val(),this.initialization)} -InspectorEditorDropdown.prototype.renderEditor=function(){var -self=this,data={id:this.editorId,value:$.trim(this.inspector.readProperty(this.fieldDef.property)),selectId:this.editorId+'-select',defaultOption:function(){return function(text,render){if(self.fieldDef.placeholder==undefined) -return'' -if(!Modernizr.touch) -return''}}} -if(this.fieldDef.options){var options=[] -if(this.fieldDef.placeholder!==undefined&&Modernizr.touch) -options.push({value:null,title:this.fieldDef.placeholder}) -$.each(this.fieldDef.options,function(value,title){options.push({value:value,title:title})}) -data.options=options} -return Mustache.render(this.getTemplate(),data)} -InspectorEditorDropdown.prototype.getTemplate=function(){return' \ - \ - \ - \ - ';} -InspectorEditorDropdown.prototype.init=function(){var value=this.inspector.readProperty(this.fieldDef.property,true) -if(value===undefined) -value=this.inspector.getDefaultValue(this.fieldDef.property) -$(this.selector).val(value) -if(!Modernizr.touch){var options={dropdownCssClass:'ocInspectorDropdown'} -if(this.fieldDef.placeholder!==undefined) -options.placeholder=this.fieldDef.placeholder -$(this.selector).select2(options)} -if(this.dynamicOptions){if(!Modernizr.touch){this.indicatorContainer=$('.select2-container',$(this.selector).closest('td')) -this.indicatorContainer.addClass('loading-indicator-container').addClass('size-small')} -this.loadOptions(true)} -if(this.fieldDef.depends) -this.inspector.$el.on('propertyChanged.oc.Inspector',$.proxy(this.onDependencyChanged,this))} -InspectorEditorDropdown.prototype.onDependencyChanged=function(ev,property){if($.inArray(property,this.fieldDef.depends)===-1) -return -var self=this,dependencyValues=this.getDependencyValues() -if(this.prevDependencyValues===undefined||this.prevDependencyValues!=dependencyValues) -this.loadOptions()} -InspectorEditorDropdown.prototype.saveDependencyValues=function(){this.prevDependencyValues=this.getDependencyValues()} -InspectorEditorDropdown.prototype.getDependencyValues=function(){var dependencyValues='',self=this -$.each(this.fieldDef.depends,function(index,masterProperty){dependencyValues+=masterProperty+':'+self.inspector.readProperty(masterProperty)+'-'}) -return dependencyValues} -InspectorEditorDropdown.prototype.showLoadingIndicator=function(){if(!Modernizr.touch) -this.indicatorContainer.loadIndicator()} -InspectorEditorDropdown.prototype.hideLoadingIndicator=function(){if(!Modernizr.touch) -this.indicatorContainer.loadIndicator('hide')} -InspectorEditorDropdown.prototype.loadOptions=function(initialization){var $form=$(this.selector).closest('form'),data=this.inspector.propertyValues,$select=$(this.selector),currentValue=this.inspector.readProperty(this.fieldDef.property,true),self=this -if(currentValue===undefined) -currentValue=this.inspector.getDefaultValue(this.fieldDef.property) -for(var index in this.inspector.config){var propertyInfo=this.inspector.config[index] -if(propertyInfo.itemType=='property'){if(data[propertyInfo.property]===undefined) -data[propertyInfo.property]=this.inspector.getDefaultValue(propertyInfo.property)}} -if(this.fieldDef.depends) -this.saveDependencyValues() -data.inspectorProperty=this.fieldDef.property -data.inspectorClassName=this.inspector.options.inspectorClass -this.showLoadingIndicator() -$form.request('onInspectableGetOptions',{data:data,success:function(data){$('option',$select).remove() -if(self.fieldDef.placeholder!==undefined) -$select.append($('')) -if(data.options) -$.each(data.options,function(key,obj){$select.append($('').attr('value',obj.value).text(obj.title))}) -var hasOption=$('option[value="'+currentValue+'"]',$select).length>0 -if(hasOption) -$select.val(currentValue) -else -$('option:first-child',$select).attr("selected","selected");self.initialization=initialization -$select.trigger('change') -self.initialization=false -self.hideLoadingIndicator()},error:function(jqXHR,textStatus,errorThrown){alert(jqXHR.responseText.length?jqXHR.responseText:jqXHR.statusText) -self.hideLoadingIndicator()}})} -InspectorEditorDropdown.prototype.onHideExternalParameterEditor=function(){this.loadOptions(false)} -$.oc.inspector.editors.inspectorEditorDropdown=InspectorEditorDropdown;function initInspector($element){var inspector=$element.data('oc.inspector') -if(inspector===undefined){inspector=new Inspector($element.get(0),$element.data()) -inspector.loadConfiguration(function(){inspector.init()}) -$element.data('oc.inspector',inspector)}} -$.fn.inspector=function(option){return this.each(function(){initInspector($(this))})} -$(document).on('click','[data-inspectable]',function(){var $this=$(this) -if($this.data('oc.inspectorVisible')) -return false -initInspector($this) -return false})}(window.jQuery);(function($){$(document).on('keydown','div.custom-checkbox',function(e){if(e.keyCode==32) -e.preventDefault()}) -$(document).on('keyup','div.custom-checkbox',function(e){if(e.keyCode==32){var $cb=$('input',this) -if($cb.data('oc-space-timestamp')==e.timeStamp) -return -$cb.get(0).checked=!$cb.get(0).checked -$cb.data('oc-space-timestamp',e.timeStamp) -$cb.trigger('change') -return false}})})(jQuery);+function($){'use strict';var backdrop='.dropdown-backdrop' -var toggle='[data-toggle=dropdown]' -var Dropdown=function(element){$(element).on('click.bs.dropdown',this.toggle)} -Dropdown.prototype.toggle=function(e){var $this=$(this) -if($this.is('.disabled, :disabled'))return -var $parent=getParent($this) -var isActive=$parent.hasClass('open') -clearMenus() -if(!isActive){if('ontouchstart'in document.documentElement&&!$parent.closest('.navbar-nav').length){$('