diff --git a/app/code/Magento/Catalog/Model/Observer.php b/app/code/Magento/Catalog/Model/Observer.php index dac92e427e266bdd07f63eb1e3ce3c5edf18c7dc..39e72883f68add9d3672497199eb7c744480a7db 100644 --- a/app/code/Magento/Catalog/Model/Observer.php +++ b/app/code/Magento/Catalog/Model/Observer.php @@ -5,6 +5,9 @@ */ namespace Magento\Catalog\Model; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class Observer { /** @@ -62,16 +65,23 @@ class Observer protected $_productResourceFactory; /** - * @param \Magento\Catalog\Model\Resource\Category $categoryResource - * @param \Magento\Catalog\Model\Resource\Product $catalogProduct + * @var \Magento\Framework\Registry + */ + protected $_registry; + + /** + * @param \Magento\Framework\Registry $registry + * @param Resource\Category $categoryResource + * @param Resource\Product $catalogProduct * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Catalog\Model\Layer\Resolver $layerResolver + * @param Layer\Resolver $layerResolver * @param \Magento\Catalog\Helper\Category $catalogCategory * @param \Magento\Catalog\Helper\Data $catalogData * @param Indexer\Category\Flat\State $categoryFlatState - * @param \Magento\Catalog\Model\Resource\ProductFactory $productResourceFactory + * @param Resource\ProductFactory $productResourceFactory */ public function __construct( + \Magento\Framework\Registry $registry, \Magento\Catalog\Model\Resource\Category $categoryResource, \Magento\Catalog\Model\Resource\Product $catalogProduct, \Magento\Store\Model\StoreManagerInterface $storeManager, @@ -81,6 +91,7 @@ class Observer \Magento\Catalog\Model\Indexer\Category\Flat\State $categoryFlatState, \Magento\Catalog\Model\Resource\ProductFactory $productResourceFactory ) { + $this->_registry = $registry; $this->_categoryResource = $categoryResource; $this->_catalogProduct = $catalogProduct; $this->_storeManager = $storeManager; @@ -137,11 +148,20 @@ class Observer $block->addIdentity(\Magento\Catalog\Model\Category::CACHE_TAG . '_' . $category->getId()); $tree = $parentCategoryNode->getTree(); + + $isActiveCategory = false; + /** @var \Magento\Catalog\Model\Category $currentCategory */ + $currentCategory = $this->_registry->registry('current_category'); + if ($currentCategory && $currentCategory->getId() == $category->getId()) { + $isActiveCategory = true; + } + $categoryData = [ 'name' => $category->getName(), 'id' => $nodeId, 'url' => $this->_catalogCategory->getCategoryUrl($category), - 'is_active' => $this->_isActiveMenuCategory($category), + 'has_active' => $this->hasActive($category), + 'is_active' => $isActiveCategory ]; $categoryNode = new \Magento\Framework\Data\Tree\Node($categoryData, 'id', $tree, $parentCategoryNode); $parentCategoryNode->addChild($categoryNode); @@ -162,7 +182,7 @@ class Observer * @param \Magento\Framework\Data\Tree\Node $category * @return bool */ - protected function _isActiveMenuCategory($category) + protected function hasActive($category) { if (!$this->_catalogLayer) { return false; diff --git a/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable.phtml b/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable.phtml index db3a01d67c3cf61a3b8469d5b995c2dbd79b0810..b09be18c66169f4c3d0e1242cdd2585609a50499 100644 --- a/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable.phtml +++ b/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable.phtml @@ -26,7 +26,7 @@ require([ var uploaderTemplate = '<div class="no-display" id="[[idName]]-template">' + '<div id="<%- data.id %>" class="file-row file-row-narrow">' + '<span class="file-info">' + - '<span class="file-info-name"><%- data.name %></span>' + + '<span class="file-info-name"><%= data.name %></span>' + ' ' + '<span class="file-info-size">(<%- data.size %>)</span>' + '</span>' + @@ -41,7 +41,7 @@ var uploaderTemplate = '<div class="no-display" id="[[idName]]-template">' + '</div>'; var fileListTemplate = '<span class="file-info">' + - '<span class="file-info-name"><%- data.name %></span>' + + '<span class="file-info-name"><%= data.name %></span>' + ' ' + '<span class="file-info-size">(<%- data.size %>)</span>' + '</span>'; diff --git a/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/links.phtml b/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/links.phtml index bf2b72140ba8a082faa3e7824016fe7310ce724b..c7db53b3b85d63a7a0a6568f3efe26dea28270e1 100644 --- a/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/links.phtml +++ b/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/links.phtml @@ -15,58 +15,61 @@ ?> <?php $_product = $block->getProduct()?> <?php $block->getConfigJson() ?> -<div class="form-inline"> - <div class="field"> - <label class="label" for="name"><span><?php echo __('Title')?></span></label> - <div class="control"> - <input type="text" class="input-text" id="downloadable_links_title" name="product[links_title]" value="<?php echo $block->getLinksTitle() ?>" <?php echo($_product->getStoreId() && $block->getUsedDefault()) ? 'disabled="disabled"' : '' ?>> - <?php if ($_product->getStoreId()): ?> - <input id="link_title_default" type="checkbox" name="use_default[]" value="links_title" onclick="toggleValueElements(this, this.parentNode.parentNode)" <?php echo $block->getUsedDefault() ? 'checked="checked"' : '' ?> /> - <label class="normal" for="link_title_default"><?php echo __('Use Default Value'); ?></label> - <?php endif; ?> - </div> - <div class="field-service"> - <?php echo !$block->isSingleStoreMode() ? __('[STORE VIEW]') : ''; ?> +<div class="admin__scope"> + <fieldset class="admin__fieldset downloadable-form"> + + <div class="admin__field" <?php echo !$block->isSingleStoreMode() ? ' data-config-scope="' . __('[STORE VIEW]') . '"' : ''; ?>> + <label class="admin__field-label" for="downloadable_links_title"><span><?php echo __('Title')?></span></label> + <div class="admin__field-control"> + <input type="text" class="admin__control-text" id="downloadable_links_title" name="product[links_title]" value="<?php echo $block->getLinksTitle() ?>" <?php echo($_product->getStoreId() && $block->getUsedDefault()) ? 'disabled="disabled"' : '' ?>> + <?php if ($_product->getStoreId()): ?> + <div class="admin__field admin__field-option"> + <input id="link_title_default" class="admin__control-checkbox" type="checkbox" name="use_default[]" value="links_title" onclick="toggleValueElements(this, this.parentNode.parentNode)" <?php echo $block->getUsedDefault() ? 'checked="checked"' : '' ?> /> + <label class="admin__field-label" for="link_title_default"><span><?php echo __('Use Default Value'); ?></span></label> + </div> + <?php endif; ?> + </div> </div> - </div> - <div class="field"> - <label class="label" for="name"><span><?php echo __('Links can be purchased separately')?></span></label> - <div class="control"> - <?php echo $block->getPurchasedSeparatelySelect()?> + <div class="admin__field" <?php echo !$block->isSingleStoreMode() ? ' data-config-scope="' . __('[GLOBAL]') . '"' : ''; ?>> + <label class="admin__field-label" for="downloadable_link_purchase_type"><span><?php echo __('Links can be purchased separately')?></span></label> + <div class="admin__field-control"> + <?php echo $block->getPurchasedSeparatelySelect()?> + </div> </div> - <div class="field-service"> - <?php echo !$block->isSingleStoreMode() ? __('[GLOBAL]') : ''; ?> + <div class="admin__field admin__field-wide"> + <div class="admin__field-control"> + <div class="admin__control-table-wrapper"> + <table cellspacing="0" class="admin__control-table"> + <thead> + <tr> + <th class="col-title _required"><span><?php echo __('Title') ?></span></th> + <?php if ($block->getCanReadPrice() !== false) : ?> + <th class="col-price"><span><?php echo __('Price') ?></span></th> + <?php endif; ?> + <th class="col-limit"><span><?php echo __('Max. Downloads') ?></span></th> + <th class="col-option"><span><?php echo __('Shareable') ?></span></th> + <th class="col-sample"><span><?php echo __('Sample') ?></span></th> + <th class="col-file"><span><?php echo __('File') ?></span></th> + <th class="col-sort"><span><?php echo __('Sort Order') ?></span></th> + <th class="col-actions"> </th> + </tr> + </thead> + <tfoot> + <tr> + <td class="col-actions-add" colspan="8"><?php echo $block->getAddButtonHtml() ?></td> + </tr> + </tfoot> + <tbody id="link_items_body"> + </tbody> + </table> + </div> + <div class="admin__field-note"> + <span><?php echo __('Alphanumeric, dash and underscore characters are recommended for filenames. Improper characters are replaced with \'_\'.')?></span> + </div> + </div> </div> - </div> - - <table cellspacing="0" class="data-table"> - <thead> - <tr> - <th><?php echo __('Title')?> <span class="required">*</span></th> - <?php if ($block->getCanReadPrice() !== false) : ?> - <th><?php echo __('Price')?></th> - <?php endif; ?> - <th><?php echo __('Max. Downloads')?></th> - <th><?php echo __('Shareable')?></th> - <th><?php echo __('Sample')?></th> - <th><?php echo __('File')?></th> - <th><?php echo __('Sort Order')?></th> - <th class="col-delete"> </th> - </tr> - </thead> - <tfoot> - <tr> - <td colspan="8" class="col-actions-add"><?php echo $block->getAddButtonHtml()?></td> - </tr> - </tfoot> - <tbody id="link_items_body"> - </tbody> - </table> - -<div><small><?php echo __('Alphanumeric, dash and underscore characters are recommended for filenames. Improper characters are replaced with \'_\'.')?></small></div> - - + </fieldset> </div> <script> require([ @@ -79,15 +82,15 @@ require([ ], function(jQuery, registry, mageTemplate){ registry.get('downloadable', function (Downloadable) { var linkTemplate = '<tr>'+ - '<td>'+ + '<td class="col-title">'+ '<input type="hidden" class="__delete__" name="downloadable[link][<%- data.id %>][is_delete]" value="" />'+ '<input type="hidden" name="downloadable[link][<%- data.id %>][link_id]" value="<%- data.link_id %>" />'+ - '<input type="text" class="required-entry input-text" name="downloadable[link][<%- data.id %>][title]" value="<%- data.title %>" />'+ + '<input type="text" class="required-entry input-text admin__control-text" name="downloadable[link][<%- data.id %>][title]" value="<%- data.title %>" />'+ '<?php echo $_product->getStoreId() ? '<input type="checkbox" id="downloadable_link_<%- data.id %>_title" name="downloadable[link][<%- data.id %>][use_default_title]" value="1" /><label class="normal" for="downloadable_link_<%- data.id %>_title">Use Default Value</label>' : '' ?>'+ '</td>'+ <?php if ($block->getCanReadPrice() !== false) : ?> - '<td class="input-price">'+ - '<input type="text" id="downloadable_link_<%- data.id %>_price_value" class="input-text validate-number link-prices<?php if ($block->getCanEditPrice() === false) : ?> disabled<?php endif; ?>" name="downloadable[link][<%- data.id %>][price]" value="<%- data.price %>"<?php if ($block->getCanEditPrice() === false) : ?> disabled="disabled"<?php endif; ?> /> ' + + '<td class="input-price col-price">'+ + '<input type="text" id="downloadable_link_<%- data.id %>_price_value" class="input-text admin__control-text validate-number link-prices<?php if ($block->getCanEditPrice() === false) : ?> disabled<?php endif; ?>" name="downloadable[link][<%- data.id %>][price]" value="<%- data.price %>"<?php if ($block->getCanEditPrice() === false) : ?> disabled="disabled"<?php endif; ?> /> ' + '<label>[<?php echo $block->getBaseCurrencyCode($_product->getStoreId()) ?>]</label>' + <?php if ($_product->getStoreId() && $block->getIsPriceWebsiteScope()) : ?> '<br /><input type="checkbox" id="downloadable_link_<%- data.id %>_price" name="downloadable[link][<%- data.id %>][use_default_price]" value="1"<?php if ($block->getCanEditPrice() === false) : ?> disabled="disabled"<?php endif; ?> /> <label for="downloadable_link_<%- data.id %>_price">Use Default Value</label>' + @@ -99,16 +102,16 @@ require([ '<input type="hidden" id="downloadable_link_<%- data.id %>_price" name="downloadable[link][<%- data.id %>][use_default_price]" value="1" />' + <?php endif; ?> <?php endif; ?> - '<td><input type="text" id="downloadable_link_<%- data.id %>_downloads" name="downloadable[link][<%- data.id %>][number_of_downloads]" class="input-text downloads" value="<%- data.number_of_downloads %>" />'+ + '<td class="col-limit"><input type="text" id="downloadable_link_<%- data.id %>_downloads" name="downloadable[link][<%- data.id %>][number_of_downloads]" class="input-text admin__control-text downloads" value="<%- data.number_of_downloads %>" />'+ '<p><input type="checkbox" class="checkbox" id="downloadable_link_<%- data.id %>_is_unlimited" name="downloadable[link][<%- data.id %>][is_unlimited]" value="1" <%- data.is_unlimited %> /> <label for="downloadable_link_<%- data.id %>_is_unlimited">Unlimited</label></p></td>'+ - '<td>'+ + '<td class="col-share">'+ '<select id="downloadable_link _<%- data.id %>_shareable" name="downloadable[link][<%- data.id %>][is_shareable]">'+ '<option value="1">Yes</option>'+ '<option value="0">No</option>'+ '<option value="2" selected="selected">Use config</option>'+ '</select>'+ '</td>'+ - '<td>'+ + '<td class="col-file">'+ '<div class="files">'+ '<div class="row">'+ '<label for="downloadable_link_<%- data.id %>_sample_file_type"><input type="radio" class="radio" id="downloadable_link_<%- data.id %>_sample_file_type" name="downloadable[link][<%- data.id %>][sample][type]" value="file"<%- data.sample_file_checked %> /> File:</label>'+ @@ -127,14 +130,14 @@ require([ '</div>'+ '</div>'+ '<div class="row">'+ - '<label for="downloadable_link_<%- data.id %>_sample_url_type"><input type="radio" class="radio" id="downloadable_link_<%- data.id %>_sample_url_type" name="downloadable[link][<%- data.id %>][sample][type]" value="url"<%- data.sample_url_checked %> /> URL:</label><input type="text" class="input-text validate-downloadable-url validate-url" name="downloadable[link][<%- data.id %>][sample][url]" value="<%- data.sample_url %>" />'+ + '<label for="downloadable_link_<%- data.id %>_sample_url_type"><input type="radio" class="radio" id="downloadable_link_<%- data.id %>_sample_url_type" name="downloadable[link][<%- data.id %>][sample][type]" value="url"<%- data.sample_url_checked %> /> URL:</label><input type="text" class="input-text admin__control-text validate-downloadable-url validate-url" name="downloadable[link][<%- data.id %>][sample][url]" value="<%- data.sample_url %>" />'+ '</div>'+ '<div>'+ '<span id="downloadable_link_<%- data.id %>_sample_container"></span>'+ '</div>'+ '</div>'+ '</td>'+ - '<td>'+ + '<td class="col-file">'+ '<div class="files">'+ '<div class="row">'+ '<label for="downloadable_link_<%- data.id %>_file_type"><input type="radio" class="radio validate-one-required-by-name" id="downloadable_link_<%- data.id %>_file_type" name="downloadable[link][<%- data.id %>][type]" value="file"<%- data.file_checked %> /> File:</label>'+ @@ -153,16 +156,16 @@ require([ '</div>'+ '</div>'+ '<div class="row">'+ - '<label for="downloadable_link_<%- data.id %>_url_type"><input type="radio" class="radio validate-one-required-by-name" id="downloadable_link_<%- data.id %>_url_type" name="downloadable[link][<%- data.id %>][type]" value="url"<%- data.url_checked %> /> URL:</label><input type="text" class="validate-downloadable-url validate-url input-text" name="downloadable[link][<%- data.id %>][link_url]" value="<%- data.link_url %>" />'+ + '<label for="downloadable_link_<%- data.id %>_url_type"><input type="radio" class="radio validate-one-required-by-name" id="downloadable_link_<%- data.id %>_url_type" name="downloadable[link][<%- data.id %>][type]" value="url"<%- data.url_checked %> /> URL:</label><input type="text" class="validate-downloadable-url validate-url input-text admin__control-text" name="downloadable[link][<%- data.id %>][link_url]" value="<%- data.link_url %>" />'+ '</div>'+ '<div>'+ '<span id="downloadable_link_<%- data.id %>_link_container"></span>'+ '</div>'+ '</div>'+ '</td>'+ - '<td><input type="text" name="downloadable[link][<%- data.id %>][sort_order]" value="<%- data.sort_order %>" class="input-text sort" /></td>'+ - '<td class="col-delete">'+ - '<button id="downloadable_link_<%- data.id %>_delete_button" type="button" class="action- scalable delete delete-link-item"><span><span><span><?php echo __('Delete'); ?></span></span></span></button>'+ + '<td class="col-sort"><input type="text" name="downloadable[link][<%- data.id %>][sort_order]" value="<%- data.sort_order %>" class="input-text admin__control-text sort" /></td>'+ + '<td class="col-action">'+ + '<button id="downloadable_link_<%- data.id %>_delete_button" type="button" class="action-remove"><span><?php echo __('Delete'); ?></span></button>'+ '</td>'+ '</tr>'; @@ -309,7 +312,7 @@ require([ } }, bindRemoveButtons : function(){ - var buttons = $$('tbody#link_items_body .delete-link-item'); + var buttons = $$('tbody#link_items_body .action-remove'); for(var i=0;i<buttons.length;i++){ if(!$(buttons[i]).binded && !$(buttons[i]).hasClassName('disabled')){ $(buttons[i]).binded = true; @@ -351,7 +354,7 @@ require([ if ($(id + ' .progressbar-container').length) { $(id + ' .progressbar-container').parent().remove(); } - + fileSize = typeof file.size == "undefined" ? $.mage.__('We could not detect a size.') : byteConvert(file.size); diff --git a/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/samples.phtml b/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/samples.phtml index 525009f591747a531c55553aeb251e81cad8d6b4..85b099dd18a06cddb89a558f594cf399b3d4b7f3 100644 --- a/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/samples.phtml +++ b/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/samples.phtml @@ -15,40 +15,47 @@ $_product = $block->getProduct(); $block->getConfigJson(); ?> -<div class="form-inline"> - <div class="field"> - <label class="label" for="name"><span><?php echo __('Title')?></span></label> - <div class="control"> - <input type="text" class="input-text" name="product[samples_title]" value="<?php echo $block->getSamplesTitle() ?>" <?php echo($_product->getStoreId() && $block->getUsedDefault()) ? 'disabled="disabled"' : '' ?>> - <?php if ($_product->getStoreId()): ?> - <input id="sample_title_default" type="checkbox" name="use_default[]" value="samples_title" onclick="toggleValueElements(this, this.parentNode.parentNode)" <?php echo $block->getUsedDefault() ? 'checked="checked"' : '' ?> /> - <label class="normal" for="sample_title_default">Use Default Value</label> - <?php endif; ?> +<div class="admin__scope"> + <fieldset class="admin__fieldset downloadable-form"> + <div class="admin__field"<?php echo !$block->isSingleStoreMode() ? ' data-config-scope="' . __('[STORE VIEW]') . '"' : ''; ?>> + <label class="admin__field-label" for="downloadable_samples_title"><span><?php echo __('Title')?></span></label> + <div class="admin__field-control"> + <input type="text" class="admin__control-text" id="downloadable_samples_title" name="product[samples_title]" value="<?php echo $block->getSamplesTitle() ?>" <?php echo($_product->getStoreId() && $block->getUsedDefault()) ? 'disabled="disabled"' : '' ?>> + <?php if ($_product->getStoreId()): ?> + <div class="admin__field admin__field-option"> + <input id="sample_title_default" class="admin__control-checkbox" type="checkbox" name="use_default[]" value="samples_title" onclick="toggleValueElements(this, this.parentNode.parentNode)" <?php echo $block->getUsedDefault() ? 'checked="checked"' : '' ?> /> + <label class="admin__field-label" for="sample_title_default"><span>Use Default Value</span></label> + </div> + <?php endif; ?> + </div> </div> - <div class="field-service"> - <?php echo !$block->isSingleStoreMode() ? __('[STORE VIEW]') : ''; ?> + <div class="admin__field admin__field-wide"> + <div class="admin__field-control"> + <div class="admin__control-table-wrapper"> + <table cellspacing="0" class="admin__control-table"> + <thead> + <tr> + <th class="_required col-title"><span><?php echo __('Title') ?></span></th> + <th class="col-file"><span><?php echo __('File') ?></span></th> + <th class="col-sort"><span><?php echo __('Sort Order') ?></span></th> + <th class="col-actions"> </th> + </tr> + </thead> + <tfoot> + <tr> + <td colspan="4" class="col-actions"><?php echo $block->getAddButtonHtml() ?></td> + </tr> + </tfoot> + <tbody id="sample_items_body"> + </tbody> + </table> + </div> + <div class="admin__field-note"> + <span><?php echo __('Alphanumeric, dash and underscore characters are recommended for filenames. Improper characters are replaced with \'_\'.')?></span> + </div> + </div> </div> - </div> - - <table cellspacing="0" class="data-table"> - <thead> - <tr> - <th><?php echo __('Title') ?> <span class="required">*</span></th> - <th><?php echo __('File') ?></th> - <th><?php echo __('Sort Order') ?></th> - <th class="col-delete"> </th> - </tr> - </thead> - <tfoot> - <tr> - <td colspan="4" class="col-actions-add"><?php echo $block->getAddButtonHtml() ?></td> - </tr> - </tfoot> - <tbody id="sample_items_body"> - </tbody> - </table> - - <div><small><?php echo __('Alphanumeric, dash and underscore characters are recommended for filenames. Improper characters are replaced with \'_\'.')?></small></div> + </fieldset> </div> <script> require([ @@ -60,13 +67,13 @@ require([ ], function (jQuery, registry, mageTemplate) { registry.get('downloadable', function (Downloadable) { var sampleTemplate = '<tr>'+ - '<td>'+ + '<td class="col-title">'+ '<input type="hidden" class="__delete__" name="downloadable[sample][<%- data.id %>][is_delete]" value="" />'+ '<input type="hidden" name="downloadable[sample][<%- data.id %>][sample_id]" value="<%- data.sample_id %>" />'+ - '<input type="text" class="required-entry input-text" name="downloadable[sample][<%- data.id %>][title]" value="<%- data.title %>" />'+ + '<input type="text" class="required-entry input-text admin__control-text" name="downloadable[sample][<%- data.id %>][title]" value="<%- data.title %>" />'+ '<?php echo $_product->getStoreId() ? '<br /><input type="checkbox" id="downloadable_sample_<%- data.id %>_title" name="downloadable[sample][<%- data.id %>][use_default_title]" value="1" /><label class="normal" for="downloadable_sample_<%- data.id %>_title">Use Default Value</label>' : '' ?>'+ '</td>'+ - '<td>'+ + '<td class="col-file">'+ '<div class="files-wide">'+ '<div class="row">'+ '<label for="downloadable_sample_<%- data.id %>_file_type"><input type="radio" class="radio validate-one-required-by-name" id="downloadable_sample_<%- data.id %>_file_type" name="downloadable[sample][<%- data.id %>][type]" value="file"<%- data.file_checked %> /> File:</label>'+ @@ -87,7 +94,7 @@ require([ '</div>'+ '</div>'+ '<div class="row">'+ - '<label for="downloadable_sample_<%- data.id %>_url_type"><input type="radio" class="radio validate-one-required-by-name" id="downloadable_sample_<%- data.id %>_url_type" name="downloadable[sample][<%- data.id %>][type]" value="url"<%- data.url_checked %> /> URL:</label> <input type="text" class="validate-downloadable-url validate-url input-text" name="downloadable[sample][<%- data.id %>][sample_url]" value="<%- data.sample_url %>" />'+ + '<label for="downloadable_sample_<%- data.id %>_url_type"><input type="radio" class="radio validate-one-required-by-name" id="downloadable_sample_<%- data.id %>_url_type" name="downloadable[sample][<%- data.id %>][type]" value="url"<%- data.url_checked %> /> URL:</label> <input type="text" class="validate-downloadable-url validate-url input-text admin__control-text" name="downloadable[sample][<%- data.id %>][sample_url]" value="<%- data.sample_url %>" />'+ '</div>'+ '<div>'+ '<span id="downloadable_sample_<%- data.id %>_container"></span>'+ @@ -95,9 +102,9 @@ require([ '</div>'+ '</td>'+ - '<td><input type="text" name="downloadable[sample][<%- data.id %>][sort_order]" value="<%- data.sort_order %>" class="input-text sort" /></td>'+ - '<td class="col-delete">'+ - '<button type="button" class="action- scalable delete icon-btn delete-sample-item"><span>Delete</span></button>'+ + '<td class="col-sort"><input type="text" name="downloadable[sample][<%- data.id %>][sort_order]" value="<%- data.sort_order %>" class="input-text sort admin__control-text" /></td>'+ + '<td class="col-actions">'+ + '<button type="button" class="action-remove"><span>Delete</span></button>'+ '</td>'+ '</tr>'; sampleItems = { @@ -178,7 +185,7 @@ require([ } }, bindRemoveButtons: function() { - var buttons = $$('tbody#sample_items_body .delete-sample-item'); + var buttons = $$('tbody#sample_items_body .action-remove'); for(var i=0;i<buttons.length;i++){ if(!$(buttons[i]).binded){ $(buttons[i]).binded = true; diff --git a/app/code/Magento/Theme/Block/Html/Topmenu.php b/app/code/Magento/Theme/Block/Html/Topmenu.php index 5bd175abffc813c4117778c4420df3d3a509c452..177418d892ed452d2864c4327e4a837a62ba7b07 100644 --- a/app/code/Magento/Theme/Block/Html/Topmenu.php +++ b/app/code/Magento/Theme/Block/Html/Topmenu.php @@ -7,6 +7,9 @@ namespace Magento\Theme\Block\Html; use Magento\Framework\View\Block\IdentityInterface; use Magento\Framework\View\Element\Template; +use Magento\Framework\Data\TreeFactory; +use Magento\Framework\Data\Tree\Node; +use Magento\Framework\Data\Tree\NodeFactory; /** * Html page top menu block @@ -28,13 +31,32 @@ class Topmenu extends Template implements IdentityInterface protected $_menu; /** - * Init top menu tree structure + * Core registry * - * @return void + * @var Registry */ - public function _construct() - { - $this->_menu = new \Magento\Framework\Data\Tree\Node([], 'root', new \Magento\Framework\Data\Tree()); + protected $registry; + + /** + * @param Template\Context $context + * @param NodeFactory $nodeFactory + * @param TreeFactory $treeFactory + * @param array $data + */ + public function __construct( + Template\Context $context, + NodeFactory $nodeFactory, + TreeFactory $treeFactory, + array $data = [] + ) { + parent::__construct($context, $data); + $this->_menu = $nodeFactory->create( + [ + 'data' => [], + 'idField' => 'root', + 'tree' => $treeFactory->create() + ] + ); } /** @@ -272,6 +294,8 @@ class Topmenu extends Template implements IdentityInterface if ($item->getIsActive()) { $classes[] = 'active'; + } elseif ($item->getHasActive()) { + $classes[] = 'has-active'; } if ($item->getIsLast()) { diff --git a/app/code/Magento/Theme/Test/Unit/Block/Html/TopmenuTest.php b/app/code/Magento/Theme/Test/Unit/Block/Html/TopmenuTest.php new file mode 100644 index 0000000000000000000000000000000000000000..ab2afb8ef4ea906040c419e4e04522f28013c09d --- /dev/null +++ b/app/code/Magento/Theme/Test/Unit/Block/Html/TopmenuTest.php @@ -0,0 +1,141 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Theme\Test\Unit\Block\Html; + +use Magento\Theme\Block\Html\Topmenu; +use Magento\Framework\Registry; +use Magento\Framework\View\Element\Template\Context; +use Magento\Framework\Data\TreeFactory; +use Magento\Framework\Data\Tree\NodeFactory; + +class TopmenuTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Registry|\PHPUnit_Framework_MockObject_MockObject + */ + protected $registry; + + /** + * @var Context|\PHPUnit_Framework_MockObject_MockObject + */ + protected $context; + + /** + * @var NodeFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $nodeFactory; + + /** + * @var TreeFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $treeFactory; + + /** + * @var \Magento\Catalog\Model\Category|\PHPUnit_Framework_MockObject_MockObject + */ + protected $category; + + // @codingStandardsIgnoreStart + + /** @var string */ + protected $htmlWithoutCategory = <<<HTML +<li class="level0 nav-1 first"><a href="http://magento2/category-0.html" ><span></span></a></li><li class="level0 nav-2"><a href="http://magento2/category-1.html" ><span></span></a></li><li class="level0 nav-3"><a href="http://magento2/category-2.html" ><span></span></a></li><li class="level0 nav-4"><a href="http://magento2/category-3.html" ><span></span></a></li><li class="level0 nav-5"><a href="http://magento2/category-4.html" ><span></span></a></li><li class="level0 nav-6"><a href="http://magento2/category-5.html" ><span></span></a></li><li class="level0 nav-7"><a href="http://magento2/category-6.html" ><span></span></a></li><li class="level0 nav-8"><a href="http://magento2/category-7.html" ><span></span></a></li><li class="level0 nav-9"><a href="http://magento2/category-8.html" ><span></span></a></li><li class="level0 nav-10 last"><a href="http://magento2/category-9.html" ><span></span></a></li> +HTML; + + /** @var string */ + protected $htmlWithCategory = <<<HTML +<li class="level0 nav-1 first active"><a href="http://magento2/category-0.html" ><span></span></a></li><li class="level0 nav-2"><a href="http://magento2/category-1.html" ><span></span></a></li><li class="level0 nav-3"><a href="http://magento2/category-2.html" ><span></span></a></li><li class="level0 nav-4"><a href="http://magento2/category-3.html" ><span></span></a></li><li class="level0 nav-5"><a href="http://magento2/category-4.html" ><span></span></a></li><li class="level0 nav-6"><a href="http://magento2/category-5.html" ><span></span></a></li><li class="level0 nav-7"><a href="http://magento2/category-6.html" ><span></span></a></li><li class="level0 nav-8"><a href="http://magento2/category-7.html" ><span></span></a></li><li class="level0 nav-9"><a href="http://magento2/category-8.html" ><span></span></a></li><li class="level0 nav-10 last"><a href="http://magento2/category-9.html" ><span></span></a></li> +HTML; + + // @codingStandardsIgnoreEnd + + public function setUp() + { + $isCurrentItem = $this->getName() == 'testGetHtmlWithSelectedCategory' ? true : false; + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + + $this->context = $objectManager->getObject('Magento\Framework\View\Element\Template\Context'); + + $this->nodeFactory = $this->getMock('Magento\Framework\Data\Tree\NodeFactory', [], [], '', false); + $this->treeFactory = $this->getMock('Magento\Framework\Data\TreeFactory', [], [], '', false); + + $tree = $this->getMock('Magento\Framework\Data\Tree', [], [], '', false); + + $container = $this->getMock('Magento\Catalog\Model\Resource\Category\Tree', [], [], '', false); + + $children = $this->getMock( + 'Magento\Framework\Data\Tree\Node\Collection', + ['count'], + ['container' => $container] + ); + + for ($i = 0; $i < 10; $i++) { + $id = "category-node-$i"; + $categoryNode = $this->getMock('Magento\Framework\Data\Tree\Node', ['getId', 'hasChildren'], [], '', false); + $categoryNode + ->expects($this->once()) + ->method('getId') + ->willReturn($id); + $categoryNode + ->expects($this->atLeastOnce()) + ->method('hasChildren') + ->willReturn(false); + $categoryNode->setData( + [ + 'name' => "Category $i", + 'id' => $id, + 'url' => "http://magento2/category-$i.html", + 'is_active' => $i == 0 ? $isCurrentItem : false, + 'is_current_item' => $i == 0 ? $isCurrentItem : false, + + ] + ); + $children->add($categoryNode); + } + + $children + ->expects($this->once()) + ->method('count') + ->willReturn(10); + + $node = $this->getMock('Magento\Framework\Data\Tree\Node', ['getChildren'], [], '', false); + $node + ->expects($this->once()) + ->method('getChildren') + ->willReturn($children); + $node + ->expects($this->any()) + ->method('__call') + ->with('getLevel', []) + ->willReturn(null); + + $this->nodeFactory + ->expects($this->once()) + ->method('create') + ->willReturn($node); + + $this->treeFactory + ->expects($this->once()) + ->method('create') + ->willReturn($tree); + } + + protected function getTopmenu() + { + return new Topmenu($this->context, $this->nodeFactory, $this->treeFactory); + } + + public function testGetHtmlWithoutSelectedCategory() + { + $this->assertEquals($this->htmlWithoutCategory, $this->getTopmenu()->getHtml()); + } + + public function testGetHtmlWithSelectedCategory() + { + $this->assertEquals($this->htmlWithCategory, $this->getTopmenu()->getHtml()); + } +} diff --git a/app/design/adminhtml/Magento/backend/Magento_Downloadable/web/css/source/_module.less b/app/design/adminhtml/Magento/backend/Magento_Downloadable/web/css/source/_module.less new file mode 100644 index 0000000000000000000000000000000000000000..af531ff02ac2067b0fc1d51bab40c460070df5a3 --- /dev/null +++ b/app/design/adminhtml/Magento/backend/Magento_Downloadable/web/css/source/_module.less @@ -0,0 +1,81 @@ +// /** +// * Copyright © 2015 Magento. All rights reserved. +// * See COPYING.txt for license details. +// */ + +// +// Variables +// _____________________________________________ + +// @todo ui - rebuilt with common classes for table control and file upload ui component + +// +// File uploads dynamic control +// --------------------------------------------- + +.downloadable-form { + .col-price, + .col-limit, + .col-share, + .col-sort { + width: 1%; + } + .col-action { + width: 1px; + } + td { + &.col-limit { + white-space: nowrap; + } + } + .admin__control-table { + .admin__control-text { + margin-bottom: .5rem; + min-width: 6rem; + } + } + .files, + .files-wide { + .row { + margin: .7rem 0; + > .admin__control-text { + margin-top: .7rem; + } + } + .uploader { + margin: .5rem 0; + } + .fileinput-button { + color: @link__color; + cursor: pointer; + display: inline-block; + float: none; + margin: .5rem 0; + text-decoration: none; + &:hover { + color: @link__hover__color; + text-decoration: underline; + } + } + + } + .action-remove { + .button-reset(); + .icon-font( + @icon-delete__content, + @icons-admin__font-name, + @_icon-font-size: 1.8rem, + @_icon-font-line-height: 16px, + @_icon-font-text-hide: true, + @_icon-font-position: after, + @_icon-font-color: @color-brown-darkie + ); + margin-top: .5rem; + } +} + +@-moz-document url-prefix() { // Firefox fieldset overflow bug fix + .downloadable-form { + display: table-column; + } +} diff --git a/app/design/adminhtml/Magento/backend/web/css/override.less b/app/design/adminhtml/Magento/backend/web/css/override.less index 1b6b674ec910a5e84f7ef66f0e1b05e4fae9768b..173fee2cef2b7c89dbb57e20e388ee32706d9451 100644 --- a/app/design/adminhtml/Magento/backend/web/css/override.less +++ b/app/design/adminhtml/Magento/backend/web/css/override.less @@ -328,7 +328,7 @@ nav ol { .admin__control-file:active + .admin__control-file-label:before, .admin__control-file:focus + .admin__control-file-label:before, .admin__control-textarea:focus, -.admin__control-addon [class*='admin__control-']:focus + label:before { +.admin__control-addon [class*='admin__control-']:focus + [class*='admin__addon-']:before { border-color: #007bdb; box-shadow: none; outline: 0; @@ -345,6 +345,7 @@ nav ol { opacity: .5; cursor: not-allowed; } +.admin__fieldset > .admin__field.admin__field-wide[class] > .admin__field-control, .address-item-edit-content .admin__field[class] > .admin__field-control, .page-layout-admin-login .admin__field[class] > .admin__field-control { float: none; @@ -352,6 +353,7 @@ nav ol { text-align: left; width: auto; } +.admin__fieldset > .admin__field.admin__field-wide[class]:not(.admin__field-option) > .admin__field-label, .address-item-edit-content .admin__field[class]:not(.admin__field-option) > .admin__field-label, .page-layout-admin-login .admin__field[class]:not(.admin__field-option) > .admin__field-label { text-align: left; @@ -361,20 +363,58 @@ nav ol { margin-bottom: 0.86rem; margin-top: -0.14rem; } +.admin__fieldset > .admin__field.admin__field-wide[class]:not(.admin__field-option) > .admin__field-label:before, .address-item-edit-content .admin__field[class]:not(.admin__field-option) > .admin__field-label:before, .page-layout-admin-login .admin__field[class]:not(.admin__field-option) > .admin__field-label:before { display: none; } +.admin__fieldset > .admin__field.admin__field-wide[class]:not(.admin__field-option)._required > .admin__field-label span, .address-item-edit-content .admin__field[class]:not(.admin__field-option)._required > .admin__field-label span, .page-layout-admin-login .admin__field[class]:not(.admin__field-option)._required > .admin__field-label span { padding-left: 1.5rem; } +.admin__fieldset > .admin__field.admin__field-wide[class]:not(.admin__field-option)._required > .admin__field-label span:after, .address-item-edit-content .admin__field[class]:not(.admin__field-option)._required > .admin__field-label span:after, .page-layout-admin-login .admin__field[class]:not(.admin__field-option)._required > .admin__field-label span:after { left: 0; margin-left: 30px; top: .2rem; } +.admin__control-table-wrapper { + max-width: 100%; + overflow-x: auto; + overflow-y: hidden; +} +.admin__control-table { + width: 100%; +} +.admin__control-table thead { + background: none; +} +.admin__control-table td, +.admin__control-table th { + background: #efefef; + border: 0; + border-bottom: 1px solid #ffffff; + padding: 1.3rem 2.5rem 1.3rem 0; + text-align: left; +} +.admin__control-table td:first-child, +.admin__control-table th:first-child { + padding-left: 1.5rem; +} +.admin__control-table th { + border: 0; + vertical-align: bottom; + color: #303030; + font-size: 1.4rem; + font-weight: 600; + padding-bottom: 0; +} +.admin__control-table th._required span:after { + color: #eb5202; + content: '*'; +} .admin__control-text { line-height: 3.3rem; width: 100%; @@ -684,9 +724,11 @@ option:empty { color: #808080; content: attr(data-config-scope); display: inline-block; - position: absolute; + font-size: 1.2rem; left: ~" calc( (100%) * 0.7777777777777778 - 30px )"; + line-height: 3.2rem; margin-left: 60px; + position: absolute; width: ~" calc( (100%) * 0.2222222222222222 - 30px )"; } .admin__field-control .admin__field[data-config-scope]:nth-child(n+2):before { @@ -3241,6 +3283,10 @@ fieldset[disabled] .admin__control-text + .ui-datepicker-trigger { font-size: 1.7rem; transition: color 0.1s linear; } +.admin__menu .submenu-close:hover { + cursor: pointer; + text-decoration: none; +} .admin__menu .submenu-close:hover:before { color: #ffffff; } @@ -4277,6 +4323,108 @@ fieldset[disabled] .admin__control-text + .ui-datepicker-trigger { font-size: 2.4rem; font-weight: 600; } +.downloadable-form .col-price, +.downloadable-form .col-limit, +.downloadable-form .col-share, +.downloadable-form .col-sort { + width: 1%; +} +.downloadable-form .col-action { + width: 1px; +} +.downloadable-form td.col-limit { + white-space: nowrap; +} +.downloadable-form .admin__control-table .admin__control-text { + margin-bottom: .5rem; + min-width: 6rem; +} +.downloadable-form .files .row, +.downloadable-form .files-wide .row { + margin: .7rem 0; +} +.downloadable-form .files .row > .admin__control-text, +.downloadable-form .files-wide .row > .admin__control-text { + margin-top: .7rem; +} +.downloadable-form .files .uploader, +.downloadable-form .files-wide .uploader { + margin: .5rem 0; +} +.downloadable-form .files .fileinput-button, +.downloadable-form .files-wide .fileinput-button { + color: #007bdb; + cursor: pointer; + display: inline-block; + float: none; + margin: .5rem 0; + text-decoration: none; +} +.downloadable-form .files .fileinput-button:hover, +.downloadable-form .files-wide .fileinput-button:hover { + color: #007bdb; + text-decoration: underline; +} +.downloadable-form .action-remove { + background-image: none; + background: none; + border: 0; + margin: 0; + padding: 0; + -moz-box-sizing: content-box; + box-shadow: none; + text-shadow: none; + line-height: inherit; + font-weight: 400; + display: inline-block; + text-decoration: none; + margin-top: .5rem; +} +.downloadable-form .action-remove:focus, +.downloadable-form .action-remove:active { + background: none; + border: none; +} +.downloadable-form .action-remove:hover { + background: none; + border: none; +} +.downloadable-form .action-remove.disabled, +.downloadable-form .action-remove[disabled], +fieldset[disabled] .downloadable-form .action-remove { + cursor: not-allowed; + pointer-events: none; + opacity: 0.5; +} +.downloadable-form .action-remove > span { + border: 0; + clip: rect(0, 0, 0, 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} +.downloadable-form .action-remove:after { + font-family: 'Admin Icons'; + content: '\e630'; + font-size: 1.8rem; + line-height: 16px; + color: #41362f; + overflow: hidden; + speak: none; + font-weight: normal; + -webkit-font-smoothing: antialiased; + display: inline-block; + vertical-align: middle; + text-align: center; +} +@-moz-document url-prefix() { + .downloadable-form { + display: table-column; + } +} .admin__section-nav { padding-bottom: 51px; } diff --git a/app/design/adminhtml/Magento/backend/web/css/source/forms/_control-table.less b/app/design/adminhtml/Magento/backend/web/css/source/forms/_control-table.less new file mode 100644 index 0000000000000000000000000000000000000000..50386e2ae44e46440fdb7fe4023e2efa3572e50b --- /dev/null +++ b/app/design/adminhtml/Magento/backend/web/css/source/forms/_control-table.less @@ -0,0 +1,54 @@ +// /** +// * Copyright © 2015 Magento. All rights reserved. +// * See COPYING.txt for license details. +// */ + +// +// Variables +// _____________________________________________ + +// @todo ui - rebuilt dynamic table control + +// +// Table control +// --------------------------------------------- + +.admin__control-table-wrapper { + max-width: 100%; + overflow-x: auto; + overflow-y: hidden; +} + +.admin__control-table { + width: 100%; + thead { + background: none; + } + td, + th { + background: @color-white-dark-smoke; + border: 0; + border-bottom: 1px solid @color-white; + padding: 1.3rem 2.5rem 1.3rem 0; + text-align: left; + &:first-child { + padding-left: 1.5rem; + } + } + th { + border: 0; + vertical-align: bottom; + color: @color-very-dark-gray-black; + font-size: @font-size__base; + font-weight: @font-weight__semibold; + padding-bottom: 0; + &._required { + span { + &:after { + color: @field-label__required__color; + content: '*'; + } + } + } + } +} diff --git a/app/design/adminhtml/Magento/backend/web/css/source/forms/_controls.less b/app/design/adminhtml/Magento/backend/web/css/source/forms/_controls.less index 987d5f6f39f406ed9f1b5aa1c89be49566bf78b8..8618dc7b82dbffb6800f314e4f65687a91f1bd9b 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/forms/_controls.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/forms/_controls.less @@ -4,6 +4,7 @@ // */ @import (reference) '_extends.less'; +@import '_control-table.less'; // // Variables @@ -288,7 +289,7 @@ option:empty { &[disabled] + [class*='admin__addon-']:before { &:extend(.__form-control-styles[disabled]); } - &:focus + label:before { + &:focus + [class*='admin__addon-']:before { &:extend(.__form-control-styles:focus); } } diff --git a/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less b/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less index d1a4f148c350ea82dece47f8ad6055f22dfb1bf2..c7218ab8e50904e566c03b6c9591e617c6a5da3f 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less @@ -39,6 +39,9 @@ padding: 0; #mix-grid .row(); + &.admin__field-wide { + .extend__field-rows(); + } > .admin__field-control { #mix-grid .column(4,9); } @@ -138,9 +141,11 @@ color: @field-scope__color; content: attr(data-config-scope); display: inline-block; - position: absolute; + font-size: @font-size__s; left: @_length; + line-height: 3.2rem; margin-left: 2 * @temp_gutter; + position: absolute; & { #mix-grid .return_length(2,9); diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/_module.less index d4eee51f4323b613c79ad681dc0c5f1f7dd3ef86..9fd0cc27f492effdb869f17edc22b2f513cbf3de 100644 --- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/_module.less +++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/_module.less @@ -153,6 +153,9 @@ .fieldset > .field > .label { font-weight: @font-weight__regular; } + .product-item-name { + margin: 0; + } } .data.table:extend(.abs-product-options-list all) { diff --git a/dev/tools/grunt/configs/watch.js b/dev/tools/grunt/configs/watch.js index f1a117ac8edb4dc079841f83c74edbb9c03f5b7f..ffe0fcc097e5216278f9c12f81455b7d63001ce9 100644 --- a/dev/tools/grunt/configs/watch.js +++ b/dev/tools/grunt/configs/watch.js @@ -25,6 +25,12 @@ var watchOptions = { "files": "<%= path.less.setup %>/**/*.less", "tasks": "less:setup" }, + "reload": { + "files": "<%= path.pub %>/**/*.css", + "options": { + livereload: true + } + }, "backendMigration": { "files": [ "<%= combo.autopath(\"backend\",\"pub\") %>/css/styles.css" diff --git a/lib/internal/Magento/Framework/Data/Tree/NodeFactory.php b/lib/internal/Magento/Framework/Data/Tree/NodeFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..0fa561adbd7aa9f6f0bf7fe1720d47f85b9a5c40 --- /dev/null +++ b/lib/internal/Magento/Framework/Data/Tree/NodeFactory.php @@ -0,0 +1,54 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Framework\Data\Tree; + +use Magento\Framework\ObjectManagerInterface; + +/** + * Factory class for @see \Magento\Framework\Data\Tree\Node + */ +class NodeFactory +{ + /** + * Object Manager instance + * + * @var ObjectManagerInterface + */ + protected $objectManager; + + /** + * Instance name to create + * + * @var string + */ + protected $instanceName; + + /** + * Factory constructor + * + * @param ObjectManagerInterface $objectManager + * @param string $instanceName + */ + public function __construct( + ObjectManagerInterface $objectManager, + $instanceName = '\Magento\Framework\Data\Tree\Node' + ) { + $this->objectManager = $objectManager; + $this->instanceName = $instanceName; + } + + /** + * Create class instance with specified parameters + * + * @param array $data + * @return \Magento\Framework\Data\Tree\Node + */ + public function create(array $data = []) + { + return $this->objectManager->create($this->instanceName, $data); + } +} diff --git a/lib/internal/Magento/Framework/Data/TreeFactory.php b/lib/internal/Magento/Framework/Data/TreeFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..ad3a41304b09fd8472a590d639df80984188807e --- /dev/null +++ b/lib/internal/Magento/Framework/Data/TreeFactory.php @@ -0,0 +1,54 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Framework\Data; + +use Magento\Framework\ObjectManagerInterface; + +/** + * Factory class for @see \Magento\Framework\Data\Tree + */ +class TreeFactory +{ + /** + * Object Manager instance + * + * @var ObjectManagerInterface + */ + protected $objectManager = null; + + /** + * Instance name to create + * + * @var string + */ + protected $instanceName = null; + + /** + * Factory constructor + * + * @param ObjectManagerInterface $objectManager + * @param string $instanceName + */ + public function __construct( + ObjectManagerInterface $objectManager, + $instanceName = '\Magento\Framework\Data\Tree' + ) { + $this->objectManager = $objectManager; + $this->instanceName = $instanceName; + } + + /** + * Create class instance with specified parameters + * + * @param array $data + * @return \Magento\Framework\Data\Tree + */ + public function create(array $data = []) + { + return $this->objectManager->create($this->instanceName, $data); + } +} diff --git a/lib/web/css/source/lib/_navigation.less b/lib/web/css/source/lib/_navigation.less index d56bd79f32c59e9ef806be17b8acaddd2d013288..6cf85b4ba0474fb65c4b07309445e12d85a5263f 100644 --- a/lib/web/css/source/lib/_navigation.less +++ b/lib/web/css/source/lib/_navigation.less @@ -8,6 +8,7 @@ // _____________________________________________ .main-navigation( + @_nav__indent-side: 15px, @_nav-background-color: @navigation__background, @_nav-border: @navigation__border, @_nav-level0-font-size: @navigation-level0-item__font-size, @@ -23,16 +24,21 @@ @_nav-level0-item-text-decoration: @navigation-level0-item__text-decoration, @_nav-level0-item-background-color-active: @navigation-level0-item__active__background, - @_nav-level0-item-border-active: @navigation-level0-item__active__border, + @_nav-level0-item__active__border-color: @navigation-level0-item__active__border-color, + @_nav-level0-item__active__border-style: @navigation-level0-item__active__border-style, + @_nav-level0-item__active__border-width: @navigation-level0-item__active__border-width, @_nav-level0-item-color-active: @navigation-level0-item__active__color, @_nav-level0-item-text-decoration-active: @navigation-level0-item__active__text-decoration, @_submenu-background-color: @submenu__background, @_submenu-border: @submenu__border, - @_submenu-padding: @submenu__padding, @_submenu-font-size: @submenu__font-size, @_submenu-font-weight: @submenu__font-weight, - @_submenu-item-padding: @submenu-item__padding, + @_submenu-line-height: @submenu-item__line-height, + @_submenu-item__padding-top: @submenu__padding-top, + @_submenu-item__padding-right: @submenu__padding-right, + @_submenu-item__padding-bottom: @submenu__padding-bottom, + @_submenu-item__padding-left: @submenu__padding-left, @_submenu-item-background-color: @submenu-item__background, @_submenu-item-border: @submenu-item__border, @@ -40,7 +46,10 @@ @_submenu-item-text-decoration: @submenu-item__text-decoration, @_submenu-item-background-color-active: @submenu-item__active__background, - @_submenu-item-border-active: @submenu-item__active__border, + @_submenu-item__active__border: @submenu-item__active__border, + @_submenu-item__active__border-color: @submenu-item__active__border-color, + @_submenu-item__active__border-style: @submenu-item__active__border-style, + @_submenu-item__active__border-width: @submenu-item__active__border-width, @_submenu-item-color-active: @submenu-item__active__color, @_submenu-item-text-decoration-active: @submenu-item__active__text-decoration ) { @@ -52,6 +61,16 @@ margin: 0; padding: 0; } + li { + margin: 0; + } + a { + display: block; + .css(padding-top, @_submenu-item__padding-top); + .css(padding-right, @_submenu-item__padding-right); + .css(padding-bottom, @_submenu-item__padding-bottom); + .css(padding-left, @_submenu-item__padding-left); + } a, a:hover { .css(color, @_nav-level0-item-color); @@ -60,22 +79,47 @@ .level0 { .font-size(@_nav-level0-font-size); .css(border-top, @_nav-level0-item-border); - margin: 0; > .level-top { .css(background, @_nav-level0-item-background-color); .css(font-weight, @_nav-level0-font-weight); .css(line-height, @_nav-level0-item-line-height); .css(padding, @_nav-level0-item-padding); .css(text-transform, @_nav-level0-text-transform); - display: block; word-break: break-all; } - &.active > a { - .css(background, @_nav-level0-item-background-color-active); - .css(border, @_nav-level0-item-border-active); - .css(color, @_nav-level0-item-color-active); - .css(text-decoration, @_nav-level0-item-text-decoration-active); + &.active { + .all-category { + .ui-state-focus { + .css(background, @_nav-level0-item-background-color-active); + .css(border-color, @_nav-level0-item__active__border-color); + .css(border-style, @_nav-level0-item__active__border-style); + .css(border-width, @_nav-level0-item__active__border-width); + .css(color, @_nav-level0-item-color-active); + .css(padding-left, @_nav__indent-side - @_submenu-item__active__border); + .css(text-decoration, @_nav-level0-item-text-decoration-active); + display: inline-block; + } + } + } + > .level1 { + font-weight: @font-weight__semibold; } + &.active, + &.has-active { // ToDo UI: remove "has_active" here, when mobile navigation default open state is implemented + > a:not(.ui-state-active) { + .css(background, @_nav-level0-item-background-color-active); + .css(border-color, @_nav-level0-item__active__border-color); + .css(border-style, @_nav-level0-item__active__border-style); + .css(border-width, @_nav-level0-item__active__border-width); + .css(color, @_nav-level0-item-color-active); + .css(text-decoration, @_nav-level0-item-text-decoration-active); + span:not(.ui-menu-icon) { + margin-left: -@_submenu-item__active__border; + } + } + } + } + li.level0 { &:last-child { .css(border-bottom, @_nav-level0-item-border); } @@ -89,25 +133,33 @@ .css(border, @_submenu-border); .css(font-size, @_submenu-font-size); .css(font-weight, @_submenu-font-weight); + .css(line-height, @_submenu-line-height); + left: auto !important; overflow-x: hidden; + padding: 0; position: relative; - transition: left .3s ease-out 0; top: auto !important; - left: auto !important; - padding: 10px 20px; - > ul { + transition: left .3s ease-out; + > li { + > a { + padding-left: @_nav__indent-side; + } + &:last-child { + margin-bottom: 0; + } + } + ul { display: block; - .css(padding, @_submenu-padding); + .css(padding-left, @_submenu-item__padding-left); > li { margin: 0; a { .css(background, @_submenu-item-background-color); .css(border, @_submenu-item-border); .css(color, @_submenu-item-color); - .css(text-decoration, @_submenu-item-text-decoration); display: block; line-height: normal; - .css(padding, @_submenu-item-padding); + .css(text-decoration, @_submenu-item-text-decoration); } } } @@ -116,11 +168,23 @@ top: 0 !important; padding-right: 0; } - .active > a { - .css(background, @_submenu-item-background-color-active); - .css(border, @_submenu-item-border-active); - .css(color, @_submenu-item-color-active); - .css(text-decoration, @_submenu-item-text-decoration-active); + .active { + > a { + .css(background, @_submenu-item-background-color-active); + .css(border-color, @_submenu-item__active__border-color); + .css(border-style, @_submenu-item__active__border-style); + .css(border-width, @_submenu-item__active__border-width); + .css(color, @_submenu-item-color-active); + .css(padding-left, @_nav__indent-side - @_submenu-item__active__border); + .css(text-decoration, @_submenu-item-text-decoration-active); + } + } + .level1 { + &.active { + > a { + padding-left: @_nav__indent-side - @_submenu-item__active__border; + } + } } } } @@ -152,7 +216,9 @@ @_nav-level0-item-text-decoration-hover: @navigation-desktop-level0-item__hover__text-decoration, @_nav-level0-item-background-color-active: @navigation-desktop-level0-item__active__background, - @_nav-level0-item-border-active: @navigation-desktop-level0-item__active__border, + @_nav-level0-item__active__border-color: @navigation-desktop-level0-item__active__border-color, + @_nav-level0-item__active__border-style: @navigation-desktop-level0-item__active__border-style, + @_nav-level0-item__active__border-width: @navigation-desktop-level0-item__active__border-width, @_nav-level0-item-color-active: @navigation-desktop-level0-item__active__color, @_nav-level0-item-text-decoration-active: @navigation-desktop-level0-item__active__text-decoration, @@ -182,7 +248,9 @@ @_submenu-item-text-decoration-hover: @submenu-desktop-item__hover__text-decoration, @_submenu-item-background-color-active: @submenu-desktop-item__active__background, - @_submenu-item-border-active: @submenu-desktop-item__active__border, + @_submenu-item__active__border-color: @submenu-desktop-item__active__border-color, + @_submenu-item__active__border-style: @submenu-desktop-item__active__border-style, + @_submenu-item__active__border-width: @submenu-desktop-item__active__border-width, @_submenu-item-color-active: @submenu-desktop-item__active__color, @_submenu-item-text-decoration-active: @submenu-desktop-item__active__text-decoration ) { @@ -237,12 +305,16 @@ .css(text-decoration, @_nav-level0-item-text-decoration-hover); } } - &.active { + &.active, + &.has-active { > .level-top { .css(background, @_nav-level0-item-background-color-active); - .css(border, @_nav-level0-item-border-active); + .css(border-color, @_nav-level0-item__active__border-color); + .css(border-style, @_nav-level0-item__active__border-style); + .css(border-width, @_nav-level0-item__active__border-width); .css(color, @_nav-level0-item-color-active); .css(text-decoration, @_nav-level0-item-text-decoration-active); + display: inline-block; } } &.parent:hover > .submenu { @@ -288,7 +360,9 @@ } .active > a { .css(background, @_submenu-item-background-color-active); - .css(border, @_submenu-item-border-active); + .css(border-color, @_submenu-item__active__border-color); + .css(border-style, @_submenu-item__active__border-style); + .css(border-width, @_submenu-item__active__border-width); .css(color, @_submenu-item-color-active); .css(text-decoration, @_submenu-item-text-decoration-active); } @@ -365,7 +439,7 @@ .css(margin-top, -@_size); > ul { .css(margin-top, @_size); - &:before{ + &:before { .css(color, @_bg); content: ''; display: block; @@ -382,7 +456,7 @@ .css(margin-top, -@_size); > ul { .css(margin-top, @_size); - &:before{ + &:before { .css(color, @_border); content: ''; display: block; diff --git a/lib/web/css/source/lib/variables/_colors.less b/lib/web/css/source/lib/variables/_colors.less index 603a465151215b6ad4b766484de0edba7c25479f..95374e5802e6db799efd9467872db5928d19fbec 100644 --- a/lib/web/css/source/lib/variables/_colors.less +++ b/lib/web/css/source/lib/variables/_colors.less @@ -33,6 +33,7 @@ @color-gray94: #f0f0f0; @color-gray95: #f2f2f2; @color-white-smoke: #f5f5f5; +@color-white-dark-smoke: #efefef; @color-white-fog: #f8f8f8; @color-gray-light0: #f6f6f6; diff --git a/lib/web/css/source/lib/variables/_navigation.less b/lib/web/css/source/lib/variables/_navigation.less index eb1840348a47677eabd5fd15fb314e0bb2e8c766..73d1ad71cb3e4e69fe9f26a6553e8cae1e77bab8 100644 --- a/lib/web/css/source/lib/variables/_navigation.less +++ b/lib/web/css/source/lib/variables/_navigation.less @@ -14,7 +14,7 @@ @navigation-level0-item__font-weight: @font-weight__bold; @navigation-level0-item__line-height: false; @navigation-level0-item__margin: 0; -@navigation-level0-item__padding: 8px @indent__xl 8px @indent__base; +@navigation-level0-item__padding: 8px @indent__xl 8px 15px; @navigation-level0-item__text-transform: uppercase; @navigation-level0-item__background: ''; @@ -23,24 +23,32 @@ @navigation-level0-item__text-decoration: none; @navigation-level0-item__active__background: ''; -@navigation-level0-item__active__border: ''; +@navigation-level0-item__active__border-color: @color-orange-red1; +@navigation-level0-item__active__border-style: solid; +@navigation-level0-item__active__border-width: 0 0 0 8px; @navigation-level0-item__active__color: ''; @navigation-level0-item__active__text-decoration: ''; @submenu__background: ''; @submenu__border: ''; -@submenu__padding: 0 0 0 @indent__base; +@submenu__padding-top: @indent__s; +@submenu__padding-right: 0; +@submenu__padding-bottom: @indent__s; +@submenu__padding-left: 15px; @submenu__font-size: ''; @submenu__font-weight: @font-weight__regular; +@submenu-item__line-height: 1.3; -@submenu-item__padding: 8px 0; @submenu-item__background: ''; @submenu-item__border: ''; @submenu-item__color: @color-gray34; @submenu-item__text-decoration: ''; @submenu-item__active__background: ''; -@submenu-item__active__border: ''; +@submenu-item__active__border: 8px; +@submenu-item__active__border-color: @color-orange-red1; +@submenu-item__active__border-style: solid; +@submenu-item__active__border-width: 0 0 0 @submenu-item__active__border; @submenu-item__active__color: ''; @submenu-item__active__text-decoration: ''; @@ -68,7 +76,9 @@ @navigation-desktop-level0-item__hover__text-decoration: @navigation-desktop-level0-item__text-decoration; @navigation-desktop-level0-item__active__background: ''; -@navigation-desktop-level0-item__active__border: ''; +@navigation-desktop-level0-item__active__border-color: @color-orange-red1; +@navigation-desktop-level0-item__active__border-style: solid; +@navigation-desktop-level0-item__active__border-width: 0 0 3px; @navigation-desktop-level0-item__active__color: @navigation-desktop-level0-item__hover__color; @navigation-desktop-level0-item__active__text-decoration: @navigation-desktop-level0-item__text-decoration; @@ -98,6 +108,8 @@ @submenu-desktop-item__hover__text-decoration: @navigation-desktop-level0-item__text-decoration; @submenu-desktop-item__active__background: ''; -@submenu-desktop-item__active__border: ''; +@submenu-desktop-item__active__border-color: @color-orange-red1; +@submenu-desktop-item__active__border-style: solid; +@submenu-desktop-item__active__border-width: 0 0 0 3px; @submenu-desktop-item__active__color: ''; @submenu-desktop-item__active__text-decoration: '';