diff --git a/app/code/Magento/AdminNotification/view/adminhtml/templates/notification/window.phtml b/app/code/Magento/AdminNotification/view/adminhtml/templates/notification/window.phtml index 9695c2c407073..260c7f9be9684 100644 --- a/app/code/Magento/AdminNotification/view/adminhtml/templates/notification/window.phtml +++ b/app/code/Magento/AdminNotification/view/adminhtml/templates/notification/window.phtml @@ -12,20 +12,18 @@ * @see \Magento\AdminNotification\Block\Window */ ?> -
- -
+ \ No newline at end of file diff --git a/app/code/Magento/Backend/view/adminhtml/web/template/dynamic-rows/grid.html b/app/code/Magento/Backend/view/adminhtml/web/template/dynamic-rows/grid.html index eb96fbd9ab994..aec1ec41522da 100644 --- a/app/code/Magento/Backend/view/adminhtml/web/template/dynamic-rows/grid.html +++ b/app/code/Magento/Backend/view/adminhtml/web/template/dynamic-rows/grid.html @@ -46,7 +46,7 @@ -
- + 'product_form.product_form.' . self::CODE_BUNDLE_DATA . '.' . self::CODE_BUNDLE_OPTIONS, - 'actionName' => 'addChild', + 'actionName' => 'processingAddChild', ] ], ], @@ -272,7 +272,6 @@ protected function getBundleOptions() 'template' => 'ui/dynamic-rows/templates/collapsible', 'label' => '', 'additionalClasses' => 'admin__field-wide', - 'itemTemplate' => 'record', 'collapsibleHeader' => true, 'columnsHeader' => false, 'deleteProperty' => false, @@ -324,18 +323,23 @@ protected function getBundleOptions() 'additionalClasses' => 'admin__field-wide', 'component' => 'Magento_Ui/js/dynamic-rows/dynamic-rows-grid', 'template' => 'ui/dynamic-rows/templates/default', - 'renderDefaultRecord' => true, 'columnsHeader' => false, 'columnsHeaderAfterRender' => true, - 'recordTemplate' => 'record', 'provider' => 'product_form.product_form_data_source', 'dataProvider' => '${ $.dataScope }' . '.bundle_button_proxy', + 'identificationDRProperty' => 'product_id', + 'identificationProperty' => 'product_id', 'map' => [ - 'id' => 'entity_id', 'product_id' => 'entity_id', 'name' => 'name', 'sku' => 'sku', 'price' => 'price', + 'delete' => '', + 'selection_can_change_qty' => '', + 'selection_id' => '', + 'selection_price_type' => '', + 'selection_price_value' => '', + 'selection_qty' => '', ], 'links' => [ 'insertData' => '${ $.provider }:${ $.dataProvider }' diff --git a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php index b2ea891b41a03..82eba7f655e1a 100644 --- a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php +++ b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php @@ -124,6 +124,7 @@ public function modifyData(array $data) 'selection_can_change_qty' => $productLink->getCanChangeQuantity(), 'selection_qty_is_integer' => (bool)$integerQty, 'position' => $productLink->getPosition(), + 'delete' => '', ]; } $data[$modelId][BundlePanel::CODE_BUNDLE_OPTIONS][BundlePanel::CODE_BUNDLE_OPTIONS][] = [ diff --git a/app/code/Magento/Catalog/Block/Product/View/Options/Type/Date.php b/app/code/Magento/Catalog/Block/Product/View/Options/Type/Date.php index ea391090c89e5..cf4b807147106 100644 --- a/app/code/Magento/Catalog/Block/Product/View/Options/Type/Date.php +++ b/app/code/Magento/Catalog/Block/Product/View/Options/Type/Date.php @@ -200,8 +200,11 @@ protected function _getHtmlSelect($name, $value = null) } $extraParams .= ' data-role="calendar-dropdown" data-calendar-role="' . $name . '"'; $extraParams .= ' data-selector="' . $select->getName() . '"'; - $select->setExtraParams($extraParams); + if ($this->getOption()->getIsRequire()) { + $extraParams .= ' data-validate=\'{"datetime-validation": true}\''; + } + $select->setExtraParams($extraParams); if ($value === null) { $value = $this->getProduct()->getPreconfiguredValues()->getData( 'options/' . $option->getId() . '/' . $name diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php index 391855ad74f1e..34df989a292df 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php @@ -320,7 +320,7 @@ protected function getHeaderContainerConfig($sortOrder) 'actions' => [ [ 'targetName' => 'ns = ${ $.ns }, index = ' . static::GRID_OPTIONS_NAME, - 'actionName' => 'addChild', + 'actionName' => 'processingAddChild', ] ] ] diff --git a/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js b/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js index 00d3e7c5b70b7..28bcd7011ab8f 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js @@ -3,7 +3,7 @@ * See COPYING.txt for license details. */ define([ - "jquery", + "Magento_Ui/js/lib/view/utils/async", "jquery/ui", "mage/translate", "prototype", @@ -45,16 +45,18 @@ define([ var self = this; this._initWindowElements(); - this.dialog = jQuery('#product_composite_configure').modal({ - title: jQuery.mage.__('Configure Product'), - type: 'slide', - buttons: [{ - text: jQuery.mage.__('OK'), - 'class': 'action-primary', - click: function () { - self.onConfirmBtn(); - } - }] + jQuery.async('#product_composite_configure',function (el) { + self.dialog = jQuery(el).modal({ + title: jQuery.mage.__('Configure Product'), + type: 'slide', + buttons: [{ + text: jQuery.mage.__('OK'), + 'class': 'action-primary', + click: function () { + self.onConfirmBtn(); + } + }] + }); }); }, diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/view/options/type/date.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/view/options/type/date.phtml index e082fa71ca5c3..f3067c352f281 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/view/options/type/date.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/view/options/type/date.phtml @@ -27,7 +27,7 @@ getType() == \Magento\Catalog\Model\Product\Option::OPTION_TYPE_DATE_TIME || $_option->getType() == \Magento\Catalog\Model\Product\Option::OPTION_TYPE_TIME): ?> - getTimeHtml() ?> + getTimeHtml() ?> getIsRequire()): ?> diff --git a/app/code/Magento/Catalog/view/frontend/web/product/view/validation.js b/app/code/Magento/Catalog/view/frontend/web/product/view/validation.js index a7a87f70989de..0fe8494c3bc96 100644 --- a/app/code/Magento/Catalog/view/frontend/web/product/view/validation.js +++ b/app/code/Magento/Catalog/view/frontend/web/product/view/validation.js @@ -5,26 +5,40 @@ (function (factory) { if (typeof define === 'function' && define.amd) { define([ - "jquery", - "jquery/ui", - "mage/validation/validation" + 'jquery', + 'jquery/ui', + 'mage/validation/validation' ], factory); } else { factory(jQuery); } }(function ($) { - "use strict"; + 'use strict'; - $.widget("mage.validation", $.mage.validation, { + $.widget('mage.validation', $.mage.validation, { options: { radioCheckboxClosest: 'ul, ol', errorPlacement: function (error, element) { + var messageBox, + dataValidate; + + if ($(element).hasClass('datetime-picker')) { + element = $(element).parent(); + + if (element.parent().find('[generated=true].mage-error').length) { + return; + } + } + if (element.attr('data-errors-message-box')) { - var messageBox = $(element.attr('data-errors-message-box')); + messageBox = $(element.attr('data-errors-message-box')); messageBox.html(error); + return; } - var dataValidate = element.attr('data-validate'); + + dataValidate = element.attr('data-validate'); + if (dataValidate && dataValidate.indexOf('validate-one-checkbox-required-by-name') > 0) { error.appendTo('#links-advice-container'); } else if (element.is(':radio, :checkbox')) { @@ -35,6 +49,7 @@ }, highlight: function (element, errorClass) { var dataValidate = $(element).attr('data-validate'); + if (dataValidate && dataValidate.indexOf('validate-required-datetime') > 0) { $(element).parent().find('.datetime-picker').each(function() { $(this).removeClass(errorClass); @@ -50,6 +65,7 @@ }, unhighlight: function (element, errorClass) { var dataValidate = $(element).attr('data-validate'); + if (dataValidate && dataValidate.indexOf('validate-required-datetime') > 0) { $(element).parent().find('.datetime-picker').removeClass(errorClass); } else if ($(element).is(':radio, :checkbox')) { diff --git a/app/code/Magento/Customer/Block/Widget/Dob.php b/app/code/Magento/Customer/Block/Widget/Dob.php index eac450a98ef1f..641825d1e6515 100644 --- a/app/code/Magento/Customer/Block/Widget/Dob.php +++ b/app/code/Magento/Customer/Block/Widget/Dob.php @@ -175,6 +175,7 @@ public function getLabel() public function getFieldHtml() { $this->dateElement->setData([ + 'extra_params' => $this->isRequired() ? 'data-validate="{required:true}"' : '', 'name' => $this->getHtmlId(), 'id' => $this->getHtmlId(), 'class' => $this->getHtmlClass(), diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/create/js.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/create/js.phtml index d6b592a6a2acd..3ae582d8f0157 100644 --- a/app/code/Magento/Sales/view/adminhtml/templates/order/create/js.phtml +++ b/app/code/Magento/Sales/view/adminhtml/templates/order/create/js.phtml @@ -10,20 +10,19 @@ require([ "prototype", "Magento_Sales/order/create/form", - "Magento_Catalog/catalog/product/composite/configure" + "Magento_Catalog/catalog/product/composite/configure", + "domReady!" ], function(){ order.sidebarHide(); - Event.observe(window, 'load', function() { - if (window.productConfigure) { - productConfigure.addListType('product_to_add', { - urlFetch: 'getUrl('sales/order_create/configureProductToAdd') ?>' - }); - productConfigure.addListType('quote_items', { - urlFetch: 'getUrl('sales/order_create/configureQuoteItems') ?>' - }); - } - }); + if (window.productConfigure) { + productConfigure.addListType('product_to_add', { + urlFetch: 'getUrl('sales/order_create/configureProductToAdd') ?>' + }); + productConfigure.addListType('quote_items', { + urlFetch: 'getUrl('sales/order_create/configureQuoteItems') ?>' + }); + } }); diff --git a/app/code/Magento/Sales/view/adminhtml/ui_component/sales_order_grid.xml b/app/code/Magento/Sales/view/adminhtml/ui_component/sales_order_grid.xml index 2107fb6e29122..e0a5471b1e45e 100644 --- a/app/code/Magento/Sales/view/adminhtml/ui_component/sales_order_grid.xml +++ b/app/code/Magento/Sales/view/adminhtml/ui_component/sales_order_grid.xml @@ -186,6 +186,7 @@ Magento_Ui/js/grid/columns/date date Purchase Date + MMM dd, YYYY, H:MM:SS A diff --git a/app/code/Magento/Swatches/view/adminhtml/layout/catalog_product_attribute_edit.xml b/app/code/Magento/Swatches/view/adminhtml/layout/catalog_product_attribute_edit.xml index ffb951b9296ec..ccedd36d6be36 100644 --- a/app/code/Magento/Swatches/view/adminhtml/layout/catalog_product_attribute_edit.xml +++ b/app/code/Magento/Swatches/view/adminhtml/layout/catalog_product_attribute_edit.xml @@ -9,7 +9,6 @@ - diff --git a/app/code/Magento/Swatches/view/adminhtml/layout/catalog_product_attribute_edit_popup.xml b/app/code/Magento/Swatches/view/adminhtml/layout/catalog_product_attribute_edit_popup.xml index 2eaacd9f8f7c5..3e420e0818af1 100755 --- a/app/code/Magento/Swatches/view/adminhtml/layout/catalog_product_attribute_edit_popup.xml +++ b/app/code/Magento/Swatches/view/adminhtml/layout/catalog_product_attribute_edit_popup.xml @@ -9,7 +9,6 @@ - diff --git a/app/code/Magento/Swatches/view/adminhtml/layout/catalog_product_form.xml b/app/code/Magento/Swatches/view/adminhtml/layout/catalog_product_form.xml index b3aef114026cb..76405c547344c 100644 --- a/app/code/Magento/Swatches/view/adminhtml/layout/catalog_product_form.xml +++ b/app/code/Magento/Swatches/view/adminhtml/layout/catalog_product_form.xml @@ -9,6 +9,5 @@ - diff --git a/app/code/Magento/Swatches/view/adminhtml/web/js/form/element/swatch-visual.js b/app/code/Magento/Swatches/view/adminhtml/web/js/form/element/swatch-visual.js index 1bd1facbcd6d0..165a8cf8e1eda 100644 --- a/app/code/Magento/Swatches/view/adminhtml/web/js/form/element/swatch-visual.js +++ b/app/code/Magento/Swatches/view/adminhtml/web/js/form/element/swatch-visual.js @@ -12,6 +12,7 @@ define([ 'uiRegistry', 'prototype', 'Magento_Ui/js/form/element/abstract', + 'jquery/colorpicker/js/colorpicker', 'jquery/ui' ], function (_, jQuery, mageTemplate, rg, prototype, Abstract) { 'use strict'; diff --git a/app/code/Magento/Swatches/view/adminhtml/web/js/visual.js b/app/code/Magento/Swatches/view/adminhtml/web/js/visual.js index eb39a08b404b4..98beda718cbe8 100644 --- a/app/code/Magento/Swatches/view/adminhtml/web/js/visual.js +++ b/app/code/Magento/Swatches/view/adminhtml/web/js/visual.js @@ -9,6 +9,7 @@ define([ 'jquery', 'mage/template', 'uiRegistry', + 'jquery/colorpicker/js/colorpicker', 'prototype', 'jquery/ui' ], function (jQuery, mageTemplate, rg) { diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dnd.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dnd.js index 5bf6580df1615..8695345e59cce 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dnd.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dnd.js @@ -49,14 +49,12 @@ define([ return Element.extend({ defaults: { - rootSelector: '${ $.recordsProvider }:div.admin__field', - tableClass: 'table.admin__dynamic-rows', - tableSelector: '${ $.rootSelector } -> ${ $.tableClass }', separatorsClass: { top: '_dragover-top', bottom: '_dragover-bottom' }, step: 'auto', + tableClass: 'table.admin__dynamic-rows', recordsCache: [], draggableElement: {}, draggableElementClass: '_dragged', @@ -73,14 +71,12 @@ define([ initialize: function () { _.bindAll( this, - 'initTable', 'mousemoveHandler', 'mouseupHandler' ); this._super() .body = $('body'); - $.async(this.tableSelector, this.initTable); return this; }, @@ -100,18 +96,6 @@ define([ return this; }, - /** - * Initialize table - * - * @param {Object} table - table element - */ - initTable: function (table) { - if (!this.table) { - this.table = $(table); - this.tableWrapper = this.table.parent(); - } - }, - /** * Init listens to start drag * @@ -135,8 +119,10 @@ define([ */ mousedownHandler: function (data, elem, event) { var recordNode = this.getRecordNode(elem), - originRecord = $(elem).parents('tr'), - drEl = this.draggableElement; + originRecord = $(elem).parents('tr').eq(0), + drEl = this.draggableElement, + $table = $(elem).parents('table').eq(0), + $tableWrapper = $table.parent(); $(recordNode).addClass(this.draggableElementClass); $(originRecord).addClass(this.draggableElementClass); @@ -146,10 +132,10 @@ define([ drEl.instanceCtx = this.getRecord(originRecord[0]); drEl.eventMousedownY = isTouchDevice ? event.originalEvent.touches[0].pageY : event.pageY; drEl.minYpos = - this.table.offset().top - originRecord.offset().top + - this.table.outerHeight() - this.table.find('tbody').outerHeight(); - drEl.maxYpos = drEl.minYpos + this.table.find('tbody').outerHeight() - originRecord.outerHeight(); - this.tableWrapper.append(recordNode); + $table.offset().top - originRecord.offset().top + + $table.outerHeight() - $table.find('tbody').outerHeight(); + drEl.maxYpos = drEl.minYpos + $table.find('tbody').outerHeight() - originRecord.outerHeight(); + $tableWrapper.append(recordNode); if (isTouchDevice) { this.body.bind('touchmove', this.mousemoveHandler); @@ -173,7 +159,7 @@ define([ processingPositionY = positionY + 'px', processingMaxYpos = depEl.maxYpos + 'px', processingMinYpos = depEl.minYpos + 'px', - depElement = this.getDepElement(depEl.instance, positionY); + depElement = this.getDepElement(depEl.instance, positionY, depEl.originRow); event.stopPropagation(); event.preventDefault(); @@ -234,7 +220,7 @@ define([ * @param {Object} dragData - data draggable element */ setPosition: function (depElem, depElementCtx, dragData) { - var depElemPosition = parseInt(depElementCtx.position, 10); + var depElemPosition = ~~depElementCtx.position; if (dragData.depElement.insert === 'after') { dragData.instanceCtx.position = depElemPosition + 1; @@ -249,14 +235,17 @@ define([ * @param {Object} curInstance - current element instance * @param {Number} position */ - - getDepElement: function (curInstance, position) { + getDepElement: function (curInstance, position, row) { var tableSelector = this.tableClass + ' tr', - recordsCollection = this.table.find('tbody > tr').filter(function (index, elem) { - return !$(elem).parents(tableSelector).length; - }), - curInstancePositionTop = $(curInstance).position().top, - curInstancePositionBottom = curInstancePositionTop + $(curInstance).height(); + $table = $(row).parents('table').eq(0), + $curInstance = $(curInstance), + recordsCollection = $table.find('table').length ? + $table.find('tbody > tr').filter(function (index, elem) { + return !$(elem).parents(tableSelector).length; + }) : + $table.find('tbody > tr'), + curInstancePositionTop = $curInstance.position().top, + curInstancePositionBottom = curInstancePositionTop + $curInstance.height(); if (position < 0) { return this._getDepElement(recordsCollection, 'before', curInstancePositionTop); @@ -313,7 +302,7 @@ define([ * @param {Object} data - current element data */ _setDefaultPosition: function (elem, data) { - var originRecord = $(elem).parents('tr'), + var originRecord = $(elem).parents('tr').eq(0), position = originRecord.position(); ++position.top; @@ -337,7 +326,7 @@ define([ * @returns {Object} instance data. */ processingStyles: function (data, elem) { - var table = this.table, + var table = $(elem).parents('table').eq(0), columns = table.find('th'), recordColumns = $(data).find('td'); @@ -380,10 +369,12 @@ define([ * @returns {Object} draggable record instance */ getRecordNode: function (record) { - var table = this.table[0].cloneNode(true); + var $record = $(record), + table = $record.parents('table')[0].cloneNode(true), + $table = $(table); - $(table).find('tr').remove(); - $(table).append($(record).parents('tr')[0].cloneNode(true)); + $table.find('tr').remove(); + $table.append($record.parents('tr')[0].cloneNode(true)); return table; }, @@ -395,7 +386,10 @@ define([ * @returns {Object} draggable record context */ getRecord: function (elem) { - return this.recordsCache()[getContext(elem).$index]; + var ctx = getContext(elem), + index = _.isFunction(ctx.$index) ? ctx.$index() : ctx.$index; + + return this.recordsCache()[index]; } }); diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js index 42219a0083aac..9e541c2a9b94f 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js @@ -16,8 +16,10 @@ define([ map: null, cacheGridData: [], deleteProperty: false, + positionProvider: 'position', dataLength: 0, identificationProperty: 'id', + identificationDRProperty: 'id', listens: { 'insertData': 'processingInsertData', 'recordData': 'initElements setToInsertData' @@ -63,7 +65,7 @@ define([ */ initChildren: function () { this.getChildItems().each(function (data, index) { - this.processingAddChild(data, this.startIndex + index, data.id); + this.processingAddChild(data, this.startIndex + index, data[this.identificationDRProperty]); }, this); return this; @@ -83,7 +85,7 @@ define([ if (newData.length) { if (this.insertData().length) { - this.processingAddChild(newData[0], data.length - 1, newData[0].id); + this.processingAddChild(newData[0], data.length - 1, newData[0][this.identificationProperty]); } } @@ -98,11 +100,12 @@ define([ * @param {String|Number} recordId */ deleteRecord: function (index, recordId) { - var data = this.getElementData(this.insertData(), recordId); + var data = this.getElementData(this.insertData(), recordId), + prop = this.map[this.identificationDRProperty]; this._super(); this.insertData(_.reject(this.source.get(this.dataProvider), function (recordData) { - return parseInt(recordData[this.map.id], 10) === parseInt(data[this.map.id], 10); + return ~~recordData[prop] === ~~data[prop]; }, this)); }, @@ -119,9 +122,15 @@ define([ var obj = {}, result; - property ? obj[property] = index : obj[this.map.id] = index; + property ? obj[property] = index : obj[this.map[this.identificationDRProperty]] = index; result = _.findWhere(array, obj); - !result ? property ? obj[property] = index.toString() : obj[this.map.id] = index.toString() : false; + + if (!result) { + property ? + obj[property] = index.toString() : + obj[this.map[this.identificationDRProperty]] = index.toString(); + } + result = _.findWhere(array, obj); return result; @@ -151,13 +160,14 @@ define([ * @returns {Array} changed data */ getNewData: function (data) { - var changes = []; + var changes = [], + tmpObj = {}; if (data.length !== this.relatedData) { data.each(function (obj) { - if (!_.findWhere(this.relatedData, { - id: obj.id - })) { + tmpObj[this.identificationDRProperty] = obj[this.identificationDRProperty]; + + if (!_.findWhere(this.relatedData, tmpObj)) { changes.push(obj); } }, this); @@ -172,14 +182,23 @@ define([ * @param {Array} data */ processingInsertData: function (data) { - var changes; + var changes, + obj = {}; changes = this._checkGridData(data); this.cacheGridData = data; - changes.each(function (changedObject) { - this.mappingValue(changedObject); - }, this); + if (changes.length) { + obj[this.identificationDRProperty] = changes[0][this.map[this.identificationProperty]]; + + if (_.findWhere(this.recordData(), obj)) { + return false; + } + + changes.each(function (changedObject) { + this.mappingValue(changedObject); + }, this); + } }, /** @@ -188,16 +207,21 @@ define([ * @param {Array} data */ mappingValue: function (data) { - var obj = {}; + var obj = {}, + tmpObj = {}; _.each(this.map, function (prop, index) { - obj[index] = data[prop]; + obj[index] = !_.isUndefined(data[prop]) ? data[prop] : ''; }, this); - if (_.findWhere(this.recordData(), { - id: obj.id - })) { + tmpObj[this.identificationDRProperty] = obj[this.identificationDRProperty]; + + if (!obj.hasOwnProperty(this.positionProvider)) { + this.setMaxPosition(); + obj[this.positionProvider] = this.maxPosition; + } + if (_.findWhere(this.recordData(), tmpObj)) { return false; } @@ -218,7 +242,7 @@ define([ obj = {}; max.each(function (record, index) { - obj[this.map.id] = record[this.map.id]; + obj[this.map[this.identificationDRProperty]] = record[this.map[this.identificationDRProperty]]; if (!_.where(this.cacheGridData, obj).length) { changes.push(data[index]); diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index ab358e1197888..e8a73adf8526b 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -68,7 +68,7 @@ define([ dnd: '${ $.dndConfig.name }' }, pages: 1, - pageSize: 5, + pageSize: 20, relatedData: [], currentPage: 1, startIndex: 0 @@ -227,6 +227,13 @@ define([ sorted, updatedCollection; + if (this.elems().filter(function (el) { + return el.position; + }).length !== this.getChildItems().length) { + + return false; + } + if (!elem.containers.length) { registry.get(elem.name, function () { that.sort(position, elem); @@ -236,12 +243,10 @@ define([ } sorted = this.elems().sort(function (propOne, propTwo) { - return parseInt(propOne.position, 10) - parseInt(propTwo.position, 10); + return ~~propOne.position - ~~propTwo.position; }); updatedCollection = this.updatePosition(sorted, position, elem.name); - - this.elems([]); this.elems(updatedCollection); }, @@ -277,7 +282,7 @@ define([ * @returns {Array} data */ getChildItems: function () { - this.startIndex = (parseInt(this.currentPage(), 10) - 1) * this.pageSize; + this.startIndex = (~~this.currentPage() - 1) * this.pageSize; return this.relatedData.slice(this.startIndex, this.startIndex + this.pageSize); }, @@ -303,7 +308,7 @@ define([ this.clear(); this.pages(this.pages() + 1); this.currentPage(this.pages()); - } else if (parseInt(this.currentPage(), 10) !== this.pages()) { + } else if (~~this.currentPage() !== this.pages()) { this.currentPage(this.pages()); } @@ -319,7 +324,7 @@ define([ processingDeleteRecord: function (index, recordId) { this.deleteRecord(index, recordId); - if (this.getChildItems().length <= 0) { + if (this.getChildItems().length <= 0 && this.pages() !== 1) { this.pages(this.pages() - 1); this.currentPage(this.pages()); } @@ -335,11 +340,11 @@ define([ return false; } - if (parseInt(page, 10) > this.pages()) { + if (~~page > this.pages()) { this.currentPage(this.pages()); return false; - } else if (parseInt(page, 10) < 1) { + } else if (~~page < 1) { this.currentPage(1); return false; @@ -392,9 +397,9 @@ define([ */ updatePosition: function (collection, position, elemName) { var curPos, - parsePosition = parseInt(position, 10), + parsePosition = ~~position, result = _.filter(collection, function (record) { - return parseInt(record.position, 10) === parsePosition; + return ~~record.position === parsePosition; }); if (result[1]) { @@ -416,7 +421,7 @@ define([ pos; this.elems.each(function (record) { - pos = parseInt(record.position, 10); + pos = ~~record.position; pos > max ? max = pos : false; }); @@ -430,7 +435,7 @@ define([ removeMaxPosition: function () { this.maxPosition = 0; this.elems.each(function (record) { - this.maxPosition < record.position ? this.maxPosition = parseInt(record.position, 10) : false; + this.maxPosition < record.position ? this.maxPosition = ~~record.position : false; }, this); }, @@ -455,20 +460,28 @@ define([ deleteRecord: function (index, recordId) { var recordInstance, lastRecord, - recordsData; + recordsData, + childs; if (this.deleteProperty) { recordInstance = _.find(this.elems(), function (elem) { return elem.index === index; }); recordInstance.destroy(); + this.elems([]); + this._updateCollection(); this.removeMaxPosition(); this.recordData()[recordInstance.index][this.deleteProperty] = this.deleteValue; this.recordData.valueHasMutated(); + childs = this.getChildItems(); + + if (childs.length > this.elems().length) { + this.addChild(false, childs[childs.length - 1][this.identificationProperty], false); + } } else { this.update = true; - if (parseInt(this.currentPage(), 10) === this.pages()) { + if (~~this.currentPage() === this.pages()) { lastRecord = _.findWhere(this.elems(), { index: this.startIndex + this.getChildItems().length - 1 @@ -486,7 +499,7 @@ define([ this.update = false; } - if (this.pages() < parseInt(this.currentPage(), 10)) { + if (this.pages() < ~~this.currentPage()) { this.currentPage(this.pages()); } @@ -503,7 +516,7 @@ define([ prop = prop || this.identificationProperty; return _.reject(this.getChildItems(), function (recordData) { - return parseInt(recordData[prop], 10) === parseInt(id, 10); + return ~~recordData[prop] === ~~id; }, this); }, @@ -512,7 +525,7 @@ define([ */ _sort: function () { this.elems(this.elems().sort(function (propOne, propTwo) { - return parseInt(propOne.position, 10) - parseInt(propTwo.position, 10); + return ~~propOne.position - ~~propTwo.position; })); }, @@ -543,6 +556,15 @@ define([ this.setMaxPosition(); } + elems.forEach(function (record) { + _.where(record.elems(), + { + formElement: 'select' + }).forEach(function (elem) { + elem.value(undefined); + }); + }); + path = this.dataScope + '.' + this.index + '.' + (this.startIndex + idx); this.source.set(path, rec); }, this); @@ -564,9 +586,7 @@ define([ * @returns {Object} Chainable. */ clear: function () { - this.elems.each(function (elem) { - elem.destroy(); - }, this); + this.destroyChildren(); return this; }, diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/record.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/record.js index e8325721434dc..305de77d47dd8 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/record.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/record.js @@ -71,7 +71,7 @@ define([ * @param {Number} position - element position */ initPosition: function (position) { - var pos = parseInt(position, 10); + var pos = ~~position; this.parentComponent().setMaxPosition(pos, this); @@ -89,11 +89,15 @@ define([ }); if (!elem) { - return false; + return; } this.childVisibleListener(elem); - !elem.visibleListener ? elem.on('visible', this.childVisibleListener.bind(this, elem)) : false; + + if (!elem.visibleListener) { + elem.on('visible', this.childVisibleListener.bind(this, elem)); + } + elem.visibleListener = true; }, @@ -225,7 +229,7 @@ define([ * @param {Boolean} state */ setDisabledColumn: function (index, state) { - index = parseInt(index, 10); + index = ~~index; this.elems()[index].disabled(state); } }); diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js b/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js index caa848c24f8cd..c400fcac43a9a 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js +++ b/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js @@ -119,11 +119,13 @@ define([ /** * Is being invoked on children validation error. * Sets error property to one incoming. + * + * @param {String} message - error message. */ - onChildrenError: function () { + onChildrenError: function (message) { var hasErrors = this.elems.some('error'); - this.error(hasErrors); + this.error(hasErrors || message); }, /** diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js index 5c90177c1f8a7..7c2bbc65cbd9b 100755 --- a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js @@ -385,6 +385,7 @@ define([ isValid = this.disabled() || !this.visible() || result.passed; this.error(message); + this.bubble('error', message); //TODO: Implement proper result propagation for form if (!isValid) { diff --git a/app/code/Magento/Ui/view/base/web/js/grid/toolbar.js b/app/code/Magento/Ui/view/base/web/js/grid/toolbar.js index 7a785feebb27d..692176ab2a43a 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/toolbar.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/toolbar.js @@ -7,8 +7,9 @@ define([ 'underscore', 'Magento_Ui/js/lib/view/utils/async', 'Magento_Ui/js/lib/view/utils/raf', + 'rjsResolver', 'uiCollection' -], function (_, $, raf, Collection) { +], function (_, $, raf, resolver, Collection) { 'use strict'; var transformProp; @@ -195,6 +196,7 @@ define([ */ setNode: function (key, node) { var nodes = this._requiredNodes, + promise = this._domPromise, defined; this[key] = node; @@ -204,7 +206,7 @@ define([ }, this); if (defined) { - this._domPromise.resolve(); + resolver(promise.resolve, promise); } }, diff --git a/app/code/Magento/Ui/view/base/web/js/lib/core/collection.js b/app/code/Magento/Ui/view/base/web/js/lib/core/collection.js index d96bbe9d0e42c..49133721369c8 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/core/collection.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/core/collection.js @@ -109,21 +109,37 @@ define([ * Removes specified child from collection. * * @param {(Object|String)} elem - Child or index of a child to be removed. + * @param {Boolean} skipUpdate - skip collection update when element to be destroyed. + * * @returns {Collection} Chainable. */ - removeChild: function (elem) { + removeChild: function (elem, skipUpdate) { if (_.isString(elem)) { elem = this.getChild(elem); } if (elem) { utils.remove(this._elems, elem); - this._updateCollection(); + + if (!skipUpdate) { + this._updateCollection(); + } } return this; }, + /** + * Destroys collection children with its' elements. + */ + destroyChildren: function () { + this.elems.each(function (elem) { + elem.destroy(true); + }); + + this._updateCollection(); + }, + /** * Clear data. Call method "clear" * in child components diff --git a/app/code/Magento/Ui/view/base/web/js/lib/core/element/element.js b/app/code/Magento/Ui/view/base/web/js/lib/core/element/element.js index 2876594fe3810..0b2ce22c03c42 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/core/element/element.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/core/element/element.js @@ -503,10 +503,11 @@ define([ /** * Destroys current instance along with all of its' children. + * @param {Boolean} skipUpdate - skip collection update when element to be destroyed. */ - destroy: function () { + destroy: function (skipUpdate) { this._dropHandlers() - ._clearRefs(); + ._clearRefs(skipUpdate); }, /** @@ -531,14 +532,15 @@ define([ * Removes all references to current instance and * calls 'destroy' method on all of its' children. * @private + * @param {Boolean} skipUpdate - skip collection update when element to be destroyed. * * @returns {Element} Chainable. */ - _clearRefs: function () { + _clearRefs: function (skipUpdate) { registry.remove(this.name); this.containers.forEach(function (parent) { - parent.removeChild(this); + parent.removeChild(this, skipUpdate); }, this); return this; diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/bind-html.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/bind-html.js index cbfa18b556aa3..14474d240130d 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/bind-html.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/bind-html.js @@ -39,7 +39,7 @@ define([ function applyComponents(el, ctx) { ko.utils.arrayForEach(el.childNodes, ko.cleanNode); ko.applyBindingsToDescendants(ctx, el); - mage.apply(el); + mage.apply(); } ko.bindingHandlers.bindHtml = { diff --git a/app/code/Magento/Ui/view/base/web/js/lib/registry/registry.js b/app/code/Magento/Ui/view/base/web/js/lib/registry/registry.js index 728f4bab1987a..034eae9c67b33 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/registry/registry.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/registry/registry.js @@ -173,7 +173,7 @@ define([ requests: [] }; - this._updateRequests = _.debounce(this._updateRequests.bind(this), 50); + this._updateRequests = _.debounce(this._updateRequests.bind(this), 10); privateData.set(this, data); } diff --git a/app/code/Magento/Ui/view/base/web/js/lib/view/utils/dom-observer.js b/app/code/Magento/Ui/view/base/web/js/lib/view/utils/dom-observer.js index db6735c7857bc..9329422d2f26b 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/view/utils/dom-observer.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/view/utils/dom-observer.js @@ -5,7 +5,8 @@ define([ 'jquery', 'underscore', - 'MutationObserver' + 'MutationObserver', + 'domReady!' ], function ($, _) { 'use strict'; diff --git a/app/code/Magento/Ui/view/base/web/js/modal/modal-component.js b/app/code/Magento/Ui/view/base/web/js/modal/modal-component.js index c2b2d1c32505a..949db7f83707e 100644 --- a/app/code/Magento/Ui/view/base/web/js/modal/modal-component.js +++ b/app/code/Magento/Ui/view/base/web/js/modal/modal-component.js @@ -107,7 +107,7 @@ define([ * Init toolbar section so other components will be able to place something in it */ initToolbarSection: function () { - this.set('toolbarSection', this.modal.data('modal').modal.find('header').get(0)); + this.set('toolbarSection', this.modal.data('mage-modal').modal.find('header').get(0)); }, /** diff --git a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html index 5dab5c390e8de..84a4114254830 100644 --- a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html +++ b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html @@ -10,6 +10,14 @@
+
+
+ + + + +
+
diff --git a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html index 7ea3ed6dc72af..b69c6b0de652a 100644 --- a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html +++ b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html @@ -39,14 +39,14 @@ class="col-draggable" template="name: dndConfig.template, data: dnd"/> - - + + diff --git a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/grid.html b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/grid.html index a405c36707b74..13f1bed36d297 100644 --- a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/grid.html +++ b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/grid.html @@ -56,7 +56,7 @@ class="data-grid-draggable-row-cell" template="name: dndConfig.template, data: dnd"/> - +
- -
+ +
- + Lib::mage/list.js Lib::mage/loader.js Lib::mage/menu.js - Lib::mage/popup-window.js Lib::mage/redirect-url.js Lib::mage/sticky.js Lib::mage/terms.js @@ -49,6 +48,9 @@ Lib::mage/validation/validation.js Lib::mage/adminhtml/varienLoader.js Lib::mage/adminhtml/tools.js + Lib::mage/gallery/gallery.js + Lib::mage/requirejs/mixins.js + Lib::mage/requirejs/static.js Lib::jquery/jquery.min.js Lib::jquery/jquery.parsequery.js Lib::jquery/jquery.mobile.custom.js @@ -56,14 +58,18 @@ Lib::jquery/jquery-ui.min.js Lib::matchMedia.js Lib::requirejs/require.js + Lib::requirejs/text.js Lib::date-format-normalizer.js Lib::varien/js.js Lib::css Lib::lib Lib::prototype Lib::scriptaculous + Lib::extjs + Lib::less + Lib::fotorama + Lib::magnifier Lib::tiny_mce - Lib::mage/requirejs Lib::tiny_mce/classes Lib::tiny_mce/langs Lib::tiny_mce/plugins diff --git a/app/design/frontend/Magento/blank/etc/view.xml b/app/design/frontend/Magento/blank/etc/view.xml index 90dc921d7674f..3a92ad0a67410 100644 --- a/app/design/frontend/Magento/blank/etc/view.xml +++ b/app/design/frontend/Magento/blank/etc/view.xml @@ -250,21 +250,40 @@ 1MB + Lib::jquery/jquery.min.js Lib::jquery/jquery-ui-1.9.2.js Lib::jquery/jquery.ba-hashchange.min.js Lib::jquery/jquery.details.js Lib::jquery/jquery.details.min.js Lib::jquery/jquery.hoverIntent.js - Lib::jquery/jquery.min.js + Lib::jquery/colorpicker/js/colorpicker.js + Lib::requirejs/require.js + Lib::requirejs/text.js + Lib::date-format-normalizer.js + Lib::legacy-build.min.js Lib::mage/captcha.js Lib::mage/dropdown_old.js Lib::mage/list.js Lib::mage/loader_old.js Lib::mage/webapi.js - Lib::moment.js - Lib::requirejs/require.js - Lib::date-format-normalizer.js - Lib::legacy-build.min.js + Lib::mage/zoom.js + Lib::mage/translate-inline-vde.js + Lib::mage/requirejs/mixins.js + Lib::mage/requirejs/static.js + Magento_Customer::js/zxcvbn.js + Magento_Catalog::js/zoom.js + Magento_Ui::js/lib/step-wizard.js + Magento_Ui::js/form/element/ui-select.js + Magento_Ui::js/form/element/file-uploader.js + Magento_Ui::js/form/components/insert.js + Magento_Ui::js/form/components/insert-listing.js + Magento_Ui::js/timeline + Magento_Ui::js/grid + Magento_Ui::js/dynamic-rows + Magento_Ui::templates/timeline + Magento_Ui::templates/grid + Magento_Ui::templates/dynamic-rows + Magento_Swagger::swagger-ui Lib::modernizr Lib::tiny_mce Lib::varien @@ -276,9 +295,8 @@ Lib::extjs Lib::prototype Lib::scriptaculous - Lib::mage/requirejs + Lib::less Lib::mage/adminhtml Lib::mage/backend - Magento_Swagger::swagger-ui diff --git a/app/design/frontend/Magento/blank/web/css/source/_forms.less b/app/design/frontend/Magento/blank/web/css/source/_forms.less index bd9a878570801..743ac3d869b8c 100644 --- a/app/design/frontend/Magento/blank/web/css/source/_forms.less +++ b/app/design/frontend/Magento/blank/web/css/source/_forms.less @@ -107,7 +107,7 @@ } .hasDatepicker { - + .ui-datepicker-trigger { + ~ .ui-datepicker-trigger { .lib-button-reset(); .lib-icon-font( @_icon-font-content: @icon-calendar, diff --git a/app/design/frontend/Magento/luma/etc/view.xml b/app/design/frontend/Magento/luma/etc/view.xml index 41d513f3bb894..e0fc864e00084 100644 --- a/app/design/frontend/Magento/luma/etc/view.xml +++ b/app/design/frontend/Magento/luma/etc/view.xml @@ -263,21 +263,40 @@ 1MB + Lib::jquery/jquery.min.js Lib::jquery/jquery-ui-1.9.2.js Lib::jquery/jquery.ba-hashchange.min.js Lib::jquery/jquery.details.js Lib::jquery/jquery.details.min.js Lib::jquery/jquery.hoverIntent.js - Lib::jquery/jquery.min.js + Lib::jquery/colorpicker/js/colorpicker.js + Lib::requirejs/require.js + Lib::requirejs/text.js + Lib::date-format-normalizer.js + Lib::legacy-build.min.js Lib::mage/captcha.js Lib::mage/dropdown_old.js Lib::mage/list.js Lib::mage/loader_old.js Lib::mage/webapi.js - Lib::moment.js - Lib::requirejs/require.js - Lib::date-format-normalizer.js - Lib::legacy-build.min.js + Lib::mage/zoom.js + Lib::mage/translate-inline-vde.js + Lib::mage/requirejs/mixins.js + Lib::mage/requirejs/static.js + Magento_Customer::js/zxcvbn.js + Magento_Catalog::js/zoom.js + Magento_Ui::js/lib/step-wizard.js + Magento_Ui::js/form/element/ui-select.js + Magento_Ui::js/form/element/file-uploader.js + Magento_Ui::js/form/components/insert.js + Magento_Ui::js/form/components/insert-listing.js + Magento_Ui::js/timeline + Magento_Ui::js/grid + Magento_Ui::js/dynamic-rows + Magento_Ui::templates/timeline + Magento_Ui::templates/grid + Magento_Ui::templates/dynamic-rows + Magento_Swagger::swagger-ui Lib::modernizr Lib::tiny_mce Lib::varien @@ -289,9 +308,8 @@ Lib::extjs Lib::prototype Lib::scriptaculous - Lib::mage/requirejs + Lib::less Lib::mage/adminhtml Lib::mage/backend - Magento_Swagger::swagger-ui diff --git a/app/design/frontend/Magento/luma/web/css/source/_forms.less b/app/design/frontend/Magento/luma/web/css/source/_forms.less index 76f4fe6982c61..d762203438efb 100644 --- a/app/design/frontend/Magento/luma/web/css/source/_forms.less +++ b/app/design/frontend/Magento/luma/web/css/source/_forms.less @@ -130,7 +130,7 @@ } .hasDatepicker { - + .ui-datepicker-trigger { + ~ .ui-datepicker-trigger { .lib-button-reset(); .lib-icon-font( @_icon-font-content: @icon-calendar, diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/calendar/calendar-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/calendar/calendar-test.js index c2b0f1652717d..a8ce39c9d5205 100644 --- a/dev/tests/js/JsTestDriver/testsuite/mage/calendar/calendar-test.js +++ b/dev/tests/js/JsTestDriver/testsuite/mage/calendar/calendar-test.js @@ -77,9 +77,8 @@ CalendarTest.prototype.testDateTimeMapping = function() { assertEquals('mm/d/yy', calendar.calendar('option', 'dateFormat')); assertEquals('h:mm TT', calendar.calendar('option', 'timeFormat')); calendar.calendar('destroy'); - calendar.calendar({dateFormat: 'MMMM/EEEE/yyyy', timeFormat: 'HH:mm'}); + calendar.calendar({dateFormat: 'MMMM/EEEE/yyyy'}); assertEquals('MM/DD/yy', calendar.calendar('option', 'dateFormat')); - assertEquals('hh:mm', calendar.calendar('option', 'timeFormat')); calendar.calendar('destroy'); }; CalendarTest.prototype.testDestroy = function() { diff --git a/lib/web/jquery/colorpicker/js/colorpicker.js b/lib/web/jquery/colorpicker/js/colorpicker.js index 5f83972e00cb5..60bae011c28f9 100644 --- a/lib/web/jquery/colorpicker/js/colorpicker.js +++ b/lib/web/jquery/colorpicker/js/colorpicker.js @@ -7,7 +7,7 @@ * */ -require([ +define([ "jquery", ], function ($) { var ColorPicker = function () { diff --git a/lib/web/mage/apply/main.js b/lib/web/mage/apply/main.js index 6f56722fc4157..7625b59bc1861 100644 --- a/lib/web/mage/apply/main.js +++ b/lib/web/mage/apply/main.js @@ -56,14 +56,12 @@ define([ /** * Initializes components assigned to HTML elements via [data-mage-init]. * - * @param {HTMLElement} context - Element of context to search * @example Sample 'data-mage-init' declaration. * data-mage-init='{"path/to/component": {"foo": "bar"}}' */ - apply: function (context) { - var el = _.isElement(context) ? context : document, - virtuals = processScripts(el), - nodes = el.querySelectorAll(nodeSelector); + apply: function () { + var virtuals = processScripts(), + nodes = document.querySelectorAll(nodeSelector); _.toArray(nodes) .map(getData) diff --git a/lib/web/mage/apply/scripts.js b/lib/web/mage/apply/scripts.js index 655db231e1de1..7f059a45ae5cd 100644 --- a/lib/web/mage/apply/scripts.js +++ b/lib/web/mage/apply/scripts.js @@ -91,7 +91,6 @@ define([ * to a 'data-mage-init' attribute of an elemennt found by provided selector. * Note: All found script nodes will be removed from DOM. * - * @param {HTMLElement} context - Element of context to search * @returns {Array} An array of components not assigned to the specific element. * * @example Sample declaration. @@ -110,9 +109,8 @@ define([ * } * } */ - return function (context) { - var el = _.isElement(context) ? context : document, - nodes = el.querySelectorAll(scriptSelector); + return function () { + var nodes = document.querySelectorAll(scriptSelector); _.toArray(nodes) .map(getNodeData) diff --git a/lib/web/mage/calendar.js b/lib/web/mage/calendar.js index 971c0668c2f93..9c79849e23b08 100644 --- a/lib/web/mage/calendar.js +++ b/lib/web/mage/calendar.js @@ -395,8 +395,9 @@ }, time: { 'a': 'TT', - 'HH': 'hh', - 'H': 'h' + 'H': 'h', + 'MM': 'mm', + 'SS': 'ss' } }, diff --git a/lib/web/mage/requirejs/mixins.js b/lib/web/mage/requirejs/mixins.js index 4059d206ba3cd..c9494cffa4117 100644 --- a/lib/web/mage/requirejs/mixins.js +++ b/lib/web/mage/requirejs/mixins.js @@ -7,6 +7,8 @@ define('mixins', [ ], function (module) { 'use strict'; + var rjsMixins; + /** * Checks if specified string contains * a plugin spacer '!' substring. @@ -88,7 +90,7 @@ define('mixins', [ return target; } - return { + rjsMixins = { /** * Loads specified module along with its' mixins. @@ -113,17 +115,11 @@ define('mixins', [ */ getMixins: function (path) { var config = module.config() || {}, - mixins = config[path] || {}, - result = [], - mixin; - - for (mixin in mixins) { - if (mixins.hasOwnProperty(mixin) && mixins[mixin] !== false) { - result.push(mixin); - } - } + mixins = config[path] || {}; - return result; + return Object.keys(mixins).filter(function (mixin) { + return mixins[mixin] !== false; + }); }, /** @@ -137,28 +133,39 @@ define('mixins', [ }, /** - * Modifies items of a 'names' array adding to them - * a 'mixins!' plugin prefix if it's necessary. + * Modifies provided names perpending to them + * the 'mixins!' plugin prefix if it's necessary. * - * @param {Array} names - An array of names, paths or aliases. + * @param {(Array|String)} names - Module names, paths or aliases. * @param {Object} context - Current requirejs context. + * @returns {Array|String} */ processNames: function (names, context) { - var config = context.config, - index = names.length, - path, - name; - - while (index--) { - name = names[index]; - path = getPath(name, config); - - if (!hasPlugin(name) && (isRelative(name) || this.hasMixins(path))) { - names[index] = addPlugin(name); + var config = context.config; + + /** + * Prepends 'mixin' plugin to a single name. + * + * @param {String} name + * @returns {String} + */ + function processName(name) { + var path = getPath(name, config); + + if (!hasPlugin(name) && (isRelative(name) || rjsMixins.hasMixins(path))) { + return addPlugin(name); } + + return name; } + + return typeof names !== 'string' ? + names.map(processName) : + processName(names); } }; + + return rjsMixins; }); require([ @@ -166,14 +173,20 @@ require([ ], function (mixins) { 'use strict'; - var origRequire = window.require, + var originalRequire = window.require, originalDefine = window.define, - commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg, - cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g, - contexts = origRequire.s.contexts, + contexts = originalRequire.s.contexts, defContextName = '_', hasOwn = Object.prototype.hasOwnProperty, - key; + getLastInQueue; + + getLastInQueue = + '(function () {' + + 'var queue = globalDefQueue,' + + 'item = queue[queue.length - 1];' + + '' + + 'return item;' + + '})();'; /** * Returns property of an object if @@ -191,9 +204,9 @@ require([ * Overrides global 'require' method adding to it dependencies modfication. */ window.require = function (deps, callback, errback, optional) { - var context, - config, - contextName = defContextName; + var contextName = defContextName, + context, + config; if (!Array.isArray(deps) && typeof deps !== 'string') { config = deps; @@ -221,7 +234,7 @@ require([ context.configure(config); } - mixins.processNames(deps, context); + deps = mixins.processNames(deps, context); return context.require(deps, callback, errback); }; @@ -229,66 +242,32 @@ require([ /** * Overrides global 'define' method adding to it dependencies modfication. */ - window.define = function (name, deps, callback) { - var context = getOwn(contexts, defContextName), - args; - - if (typeof name !== 'string') { - callback = deps; - deps = name; - name = null; + window.define = function (name, deps, callback) { // eslint-disable-line no-unused-vars + var context = getOwn(contexts, defContextName), + result = originalDefine.apply(this, arguments), + queueItem = require.exec(getLastInQueue), + lastDeps = queueItem && queueItem[1]; + + if (Array.isArray(lastDeps)) { + queueItem[1] = mixins.processNames(lastDeps, context); } - if (!Array.isArray(deps)) { - callback = deps; - deps = null; - } - - if (!deps && typeof callback === 'function') { - deps = []; - - if (callback.length) { - callback - .toString() - .replace(commentRegExp, '') - .replace(cjsRequireRegExp, function (match, dep) { - deps.push(dep); - }); - - deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps); - } - } - - if (Array.isArray(deps)) { - mixins.processNames(deps, context); - } - - args = [name, deps, callback]; - - if (!name) { - args.shift(0); - } - - originalDefine.apply(null, args); + return result; }; /** * Copy properties of original 'require' method. */ - for (key in origRequire) { - if (origRequire.hasOwnProperty(key)) { - require[key] = origRequire[key]; - } - } + Object.keys(originalRequire).forEach(function (key) { + require[key] = originalRequire[key]; + }); /** * Copy properties of original 'define' method. */ - for (key in originalDefine) { - if (originalDefine.hasOwnProperty(key)) { - define[key] = originalDefine[key]; - } - } + Object.keys(originalDefine).forEach(function (key) { + define[key] = originalDefine[key]; + }); window.requirejs = window.require; }); diff --git a/lib/web/mage/requirejs/resolver.js b/lib/web/mage/requirejs/resolver.js index 21ac625e60ae2..b82837e1d75dd 100644 --- a/lib/web/mage/requirejs/resolver.js +++ b/lib/web/mage/requirejs/resolver.js @@ -12,7 +12,7 @@ define([ execCb = context.execCb, registry = context.registry, callbacks = [], - retries = 3, + retries = 10, updateDelay = 1, ready, update; diff --git a/lib/web/mage/validation.js b/lib/web/mage/validation.js index 12ed14ef05de0..26cd61df45c80 100644 --- a/lib/web/mage/validation.js +++ b/lib/web/mage/validation.js @@ -1297,6 +1297,19 @@ }, 'Please enter a valid number.' ], + 'datetime-validation': [ + function (value, element) { + var isValid = true; + + if ($(element).val().length === 0) { + isValid = false; + $(element).addClass('mage-error'); + } + + return isValid; + }, + 'This is required field' + ], 'required-text-swatch-entry': [ tableSingleValidation, 'Admin is a required field in the each row.'