Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

fix(layouts): register Layout directives for xs, gt-xs, xl #6037

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
200 changes: 85 additions & 115 deletions src/core/services/layout/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
var ALIGNMENT_MAIN_AXIS= [ "", "start", "center", "end", "stretch", "space-around", "space-between" ];
var ALIGNMENT_CROSS_AXIS= [ "", "start", "center", "end", "stretch" ];


var config = {
/**
* Enable directive attribute-to-class conversions
Expand All @@ -31,7 +30,11 @@
breakpoints: []
};

registerLayoutAPI( angular.module('material.core.layout', ['ng']) );

/**
* registerLayoutAPI()
*
* The original ngMaterial Layout solution used attribute selectors and CSS.
*
* ```html
Expand All @@ -40,12 +43,12 @@
*
* ```css
* [layout] {
* box-sizing: border-box;
* display:flex;
* }
* box-sizing: border-box;
* display:flex;
* }
* [layout=column] {
* flex-direction : column
* }
* flex-direction : column
* }
* ```
*
* Use of attribute selectors creates significant performance impacts in some
Expand All @@ -61,117 +64,83 @@
*
* ```css
* .layout {
* box-sizing: border-box;
* display:flex;
* }
* box-sizing: border-box;
* display:flex;
* }
* .layout-column {
* flex-direction : column
* }
* flex-direction : column
* }
* ```
*/
angular.module('material.core.layout', ['ng'])

.directive('mdLayoutCss', disableLayoutDirective )

.directive('layout', attributeWithObserve('layout'))
.directive('layoutSm', attributeWithObserve('layout-sm'))
.directive('layoutGtSm', attributeWithObserve('layout-gt-sm'))
.directive('layoutMd', attributeWithObserve('layout-md'))
.directive('layoutGtMd', attributeWithObserve('layout-gt-md'))
.directive('layoutLg', attributeWithObserve('layout-lg'))
.directive('layoutGtLg', attributeWithObserve('layout-gt-lg'))

.directive('flex', attributeWithObserve('flex'))
.directive('flexSm', attributeWithObserve('flex-sm'))
.directive('flexGtSm', attributeWithObserve('flex-gt-sm'))
.directive('flexMd', attributeWithObserve('flex-md'))
.directive('flexGtMd', attributeWithObserve('flex-gt-md'))
.directive('flexLg', attributeWithObserve('flex-lg'))
.directive('flexGtLg', attributeWithObserve('flex-gt-lg'))

.directive('flexOrder', attributeWithObserve('flex-order'))
.directive('flexOrderSm', attributeWithObserve('flex-order-sm'))
.directive('flexOrderGtSm', attributeWithObserve('flex-order-gt-sm'))
.directive('flexOrderMd', attributeWithObserve('flex-order-md'))
.directive('flexOrderGtMd', attributeWithObserve('flex-order-gt-md'))
.directive('flexOrderLg', attributeWithObserve('flex-order-lg'))
.directive('flexOrderGtLg', attributeWithObserve('flex-order-gt-lg'))

.directive('flexOffset', attributeWithObserve('flex-offset'))
.directive('flexOffsetSm', attributeWithObserve('flex-offset-sm'))
.directive('flexOffsetGtSm', attributeWithObserve('flex-offset-gt-sm'))
.directive('flexOffsetMd', attributeWithObserve('flex-offset-md'))
.directive('flexOffsetGtMd', attributeWithObserve('flex-offset-gt-md'))
.directive('flexOffsetLg', attributeWithObserve('flex-offset-lg'))
.directive('flexOffsetGtLg', attributeWithObserve('flex-offset-gt-lg'))

.directive('layoutAlign', attributeWithObserve('layout-align'))
.directive('layoutAlignSm', attributeWithObserve('layout-align-sm'))
.directive('layoutAlignGtSm', attributeWithObserve('layout-align-gt-sm'))
.directive('layoutAlignMd', attributeWithObserve('layout-align-md'))
.directive('layoutAlignGtMd', attributeWithObserve('layout-align-gt-md'))
.directive('layoutAlignLg', attributeWithObserve('layout-align-lg'))
.directive('layoutAlignGtLg', attributeWithObserve('layout-align-gt-lg'))

// Attribute directives with no value(s)

.directive('hide', attributeWithoutValue('hide'))
.directive('hideSm', attributeWithoutValue('hide-sm'))
.directive('hideGtSm', attributeWithoutValue('hide-gt-sm'))
.directive('hideMd', attributeWithoutValue('hide-md'))
.directive('hideGtMd', attributeWithoutValue('hide-gt-md'))
.directive('hideLg', attributeWithoutValue('hide-lg'))
.directive('hideGtLg', attributeWithoutValue('hide-gt-lg'))
.directive('show', attributeWithoutValue('show'))
.directive('showSm', attributeWithoutValue('show-sm'))
.directive('showGtSm', attributeWithoutValue('show-gt-sm'))
.directive('showMd', attributeWithoutValue('show-md'))
.directive('showGtMd', attributeWithoutValue('show-gt-md'))
.directive('showLg', attributeWithoutValue('show-lg'))
.directive('showGtLg', attributeWithoutValue('show-gt-lg'))

// Attribute directives with no value(s) and NO breakpoints

.directive('layoutPadding', attributeWithoutValue('layout-padding'))
.directive('layoutPaddingSm', attributeWithoutValue('layout-padding-sm'))
.directive('layoutPaddingGtSm', attributeWithoutValue('layout-padding-gt-sm'))
.directive('layoutPaddingMd', attributeWithoutValue('layout-padding-md'))
.directive('layoutPaddingGtMd', attributeWithoutValue('layout-padding-gt-md'))
.directive('layoutPaddingLg', attributeWithoutValue('layout-padding-lg'))
.directive('layoutPaddingGtLg', attributeWithoutValue('layout-padding-gt-lg'))

.directive('layoutMargin', attributeWithoutValue('layout-margin'))
.directive('layoutMarginSm', attributeWithoutValue('layout-margin-sm'))
.directive('layoutMarginGtSm', attributeWithoutValue('layout-margin-gt-sm'))
.directive('layoutMarginMd', attributeWithoutValue('layout-margin-md'))
.directive('layoutMarginGtMd', attributeWithoutValue('layout-margin-gt-md'))
.directive('layoutMarginLg', attributeWithoutValue('layout-margin-lg'))
.directive('layoutMarginGtLg', attributeWithoutValue('layout-margin-gt-lg'))

.directive('layoutWrap', attributeWithoutValue('layout-wrap'))
.directive('layoutNoWrap', attributeWithoutValue('layout-no-wrap'))
.directive('layoutFill', attributeWithoutValue('layout-fill'))

// !! Deprecated attributes: use the `-lt` (aka less-than) notations

.directive('layoutLtMd', warnAttrNotSupported('layout-lt-md', true))
.directive('layoutLtLg', warnAttrNotSupported('layout-lt-lg', true))
.directive('flexLtMd', warnAttrNotSupported('flex-lt-md', true))
.directive('flexLtLg', warnAttrNotSupported('flex-lt-lg', true))

.directive('layoutAlignLtMd', warnAttrNotSupported('layout-align-lt-md'))
.directive('layoutAlignLtLg', warnAttrNotSupported('layout-align-lt-lg'))
.directive('flexOrderLtMd', warnAttrNotSupported('flex-order-lt-md'))
.directive('flexOrderLtLg', warnAttrNotSupported('flex-order-lt-lg'))
.directive('offsetLtMd', warnAttrNotSupported('flex-offset-lt-md'))
.directive('offsetLtLg', warnAttrNotSupported('flex-offset-lt-lg'))

.directive('hideLtMd', warnAttrNotSupported('hide-lt-md'))
.directive('hideLtLg', warnAttrNotSupported('hide-lt-lg'))
.directive('showLtMd', warnAttrNotSupported('show-lt-md'))
.directive('showLtLg', warnAttrNotSupported('show-lt-lg'))

.directive('ngCloak', buildCloakInterceptor('ng-cloak'));
function registerLayoutAPI(module){
var PREFIX_REGEXP = /^((?:x|data)[\:\-_])/i;
var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;

// NOTE: these are also defined in constants::MEDIA_PRIORITY and constants::MEDIA
var BREAKPOINTS = [ "", "xs", "gt-xs", "sm", "gt-sm", "md", "gt-md", "lg", "gt-lg", "xl" ];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that I think about it, how much of a performance impact does adding all of these directives have? This currently registers 90 directives just in this loop (or 109 total).

var API_WITH_VALUES = [ "layout", "flex", "flex-order", "flex-offset", "layout-align" ];
var API_NO_VALUES = [ "show", "hide", "layout-padding", "layout-margin" ];


// Build directive registration functions for the standard Layout API... for all breakpoints.
angular.forEach(BREAKPOINTS, function(mqb) {

// Attribute directives with expected, observable value(s)
angular.forEach( API_WITH_VALUES, function(name){
var fullName = mqb ? name + "-" + mqb : name;
module.directive( directiveNormalize(fullName), attributeWithObserve(fullName));
});

// Attribute directives with no expected value(s)
angular.forEach( API_NO_VALUES, function(name){
var fullName = mqb ? name + "-" + mqb : name;
module.directive( directiveNormalize(fullName), attributeWithoutValue(fullName));
});

});

// Register other, special directive functions for the Layout features:
module
.directive('mdLayoutCss' , disableLayoutDirective )
.directive('ngCloak' , buildCloakInterceptor('ng-cloak'))

.directive('layoutWrap' , attributeWithoutValue('layout-wrap'))
.directive('layoutNoWrap' , attributeWithoutValue('layout-no-wrap'))
.directive('layoutFill' , attributeWithoutValue('layout-fill'))

// !! Deprecated attributes: use the `-lt` (aka less-than) notations

.directive('layoutLtMd' , warnAttrNotSupported('layout-lt-md', true))
.directive('layoutLtLg' , warnAttrNotSupported('layout-lt-lg', true))
.directive('flexLtMd' , warnAttrNotSupported('flex-lt-md', true))
.directive('flexLtLg' , warnAttrNotSupported('flex-lt-lg', true))

.directive('layoutAlignLtMd', warnAttrNotSupported('layout-align-lt-md'))
.directive('layoutAlignLtLg', warnAttrNotSupported('layout-align-lt-lg'))
.directive('flexOrderLtMd' , warnAttrNotSupported('flex-order-lt-md'))
.directive('flexOrderLtLg' , warnAttrNotSupported('flex-order-lt-lg'))
.directive('offsetLtMd' , warnAttrNotSupported('flex-offset-lt-md'))
.directive('offsetLtLg' , warnAttrNotSupported('flex-offset-lt-lg'))

.directive('hideLtMd' , warnAttrNotSupported('hide-lt-md'))
.directive('hideLtLg' , warnAttrNotSupported('hide-lt-lg'))
.directive('showLtMd' , warnAttrNotSupported('show-lt-md'))
.directive('showLtLg' , warnAttrNotSupported('show-lt-lg'));

/**
* Converts snake_case to camelCase.
* Also there is special case for Moz prefix starting with upper case letter.
* @param name Name to normalize
*/
function directiveNormalize(name) {
return name
.replace(PREFIX_REGEXP, '')
.replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) {
return offset ? letter.toUpperCase() : letter;
});
}

}

/**
* Special directive that will disable ALL Layout conversions of layout
Expand Down Expand Up @@ -464,7 +433,7 @@
cross: "stretch"
};

var values = (value || "").replace(WHITESPACE, "-").split("-");
var values = (value || "").toLowerCase().trim().replace(WHITESPACE, "-").split("-");
if ( values.length == 3 ) {
values = [ values[0]+"-"+values[1],values[2] ];
}
Expand All @@ -478,4 +447,5 @@
return axis;
}


})();
2 changes: 1 addition & 1 deletion src/core/services/layout/layout.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
describe('layout directives', function() {
var suffixes = ['sm', 'gt-sm', 'md', 'gt-md', 'lg', 'gt-lg'],
var suffixes = ['xs', 'gt-xs', 'sm', 'gt-sm', 'md', 'gt-md', 'lg', 'gt-lg', 'xl'],
$mdUtil, $compile, pageScope;

beforeEach(module('material.core', 'material.core.layout'));
Expand Down