Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build: replace gulp-autoprefixer #3563

Merged
merged 3 commits into from
Mar 17, 2017
Merged
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"@types/node": "^7.0.5",
"@types/run-sequence": "^0.0.28",
"@types/rx": "2.5.33",
"autoprefixer": "^6.7.6",
"axe-core": "^2.1.7",
"axe-webdriverjs": "^0.5.0",
"conventional-changelog": "^1.1.0",
Expand All @@ -62,7 +63,6 @@
"glob": "^7.1.1",
"google-cloud": "^0.48.0",
"gulp": "^3.9.1",
"gulp-autoprefixer": "^3.1.1",
"gulp-better-rollup": "^1.0.2",
"gulp-clean": "^0.3.2",
"gulp-clean-css": "^3.0.3",
Expand Down
3 changes: 1 addition & 2 deletions src/demo-app/ripple/ripple-demo.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
text-align: center;
transition: all 200ms linear;
width: 200px;
user-select: none;

&.demo-ripple-disabled {
color: rgba(32, 32, 32, 0.4);
Expand All @@ -32,4 +31,4 @@
.demo-ripple-checkbox-option {
margin: 10px 0;
}
}
}
3 changes: 2 additions & 1 deletion src/lib/button-toggle/button-toggle.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@import '../core/a11y/a11y';
@import '../core/style/elevation';
@import '../core/style/vendor-prefixes';
@import '../core/style/layout-common';

$mat-button-toggle-padding: 0 16px !default;
Expand Down Expand Up @@ -44,11 +45,11 @@ $mat-button-toggle-border-radius: 2px !default;
}

.mat-button-toggle-label-content {
@include user-select(none);
display: inline-block;
line-height: $mat-button-toggle-line-height;
padding: $mat-button-toggle-padding;
cursor: pointer;
user-select: none;
}

.mat-button-toggle-label-content > * {
Expand Down
3 changes: 2 additions & 1 deletion src/lib/core/option/_option.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@import '../style/menu-common';
@import '../style/vendor-prefixes';
@import '../a11y/a11y';

/**
Expand All @@ -13,8 +14,8 @@
outline: none;

&[aria-disabled='true'] {
@include user-select(none);
cursor: default;
user-select: none;
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/lib/core/style/_button-common.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
@import './vendor-prefixes';

// Mixin overriding default button styles like the gray background, the border, and the outline.
@mixin mat-button-reset {
@include user-select(none);
cursor: pointer;
user-select: none;
outline: none;
border: none;
}
31 changes: 31 additions & 0 deletions src/lib/core/style/_vendor-prefixes.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* stylelint-disable material/no-prefixes */
@mixin user-select($value) {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}

@mixin input-placeholder {
&::placeholder {
@content;
}

&::-moz-placeholder {
@content;
}

&::-webkit-input-placeholder {
@content;
}

&:-ms-input-placeholder {
@content;
}
}

@mixin cursor-grab {
cursor: -webkit-grab;
cursor: grab;
}
/* stylelint-enable */
12 changes: 2 additions & 10 deletions src/lib/input/input-container.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@import '../core/style/variables';
@import '../core/style/vendor-prefixes';
@import '../core/style/form-common';


Expand Down Expand Up @@ -109,16 +110,7 @@ $mat-input-underline-disabled-background-image:
// Note that we can't use something like visibility: hidden or
// display: none, because IE ends up preventing the user from
// focusing the input altogether.
&::placeholder {
color: transparent;
}
&::-moz-placeholder {
color: transparent;
}
&::-webkit-input-placeholder {
color: transparent;
}
&:-ms-input-placeholder {
@include input-placeholder {
color: transparent;
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/lib/select/select.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
@import '../core/style/list-common';
@import '../core/style/form-common';
@import '../core/style/variables';
@import '../core/style/vendor-prefixes';
@import '../core/a11y/a11y';

$mat-select-trigger-height: 30px !default;
Expand All @@ -28,8 +29,8 @@ $mat-select-trigger-font-size: 16px !default;
font-size: $mat-select-trigger-font-size;

[aria-disabled='true'] & {
@include user-select(none);
cursor: default;
user-select: none;
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/lib/slide-toggle/slide-toggle.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
@import '../core/style/variables';
@import '../core/ripple/ripple';
@import '../core/style/elevation';
@import '../core/style/vendor-prefixes';
@import '../core/a11y/a11y';

$mat-slide-toggle-thumb-size: 20px !default;
Expand All @@ -25,7 +26,7 @@ $mat-slide-toggle-bar-track-width: $mat-slide-toggle-bar-width - $mat-slide-togg

// Disable user selection to ensure that dragging is smooth without grabbing
// some elements accidentally.
user-select: none;
@include user-select(none);

outline: none;

Expand Down Expand Up @@ -100,7 +101,7 @@ $mat-slide-toggle-bar-track-width: $mat-slide-toggle-bar-width - $mat-slide-togg
transition: $swift-linear;
transition-property: transform;

cursor: grab;
@include cursor-grab;

// Once the thumb container is being dragged around, we remove the transition duration to
// make the drag feeling fast and not delayed.
Expand Down
4 changes: 4 additions & 0 deletions stylelint-config.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
{
"plugins": [
"./tools/stylelint/no-prefixes/no-prefixes.js"
],
"rules": {
"material/no-prefixes": [["last 2 versions", "not ie <= 10", "not ie_mob <= 10"]],
"color-hex-case": "lower",
"color-no-invalid-hex": true,

Expand Down
9 changes: 0 additions & 9 deletions tools/gulp/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,6 @@ export const DIST_COMPONENTS_ROOT = join(DIST_ROOT, '@angular/material');

export const COVERAGE_RESULT_FILE = join(DIST_ROOT, 'coverage', 'coverage-summary.json');

export const SASS_AUTOPREFIXER_OPTIONS = {
browsers: [
'last 2 versions',
'not ie <= 10',
'not ie_mob <= 10',
],
cascade: false,
};

export const HTML_MINIFIER_OPTIONS = {
collapseWhitespace: true,
removeComments: true,
Expand Down
4 changes: 1 addition & 3 deletions tools/gulp/util/task_helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as child_process from 'child_process';
import * as fs from 'fs';
import * as gulp from 'gulp';
import * as path from 'path';
import {NPM_VENDOR_FILES, PROJECT_ROOT, DIST_ROOT, SASS_AUTOPREFIXER_OPTIONS} from '../constants';
import {NPM_VENDOR_FILES, PROJECT_ROOT, DIST_ROOT} from '../constants';


/** Those imports lack typings. */
Expand All @@ -11,7 +11,6 @@ const gulpMerge = require('merge2');
const gulpRunSequence = require('run-sequence');
const gulpSass = require('gulp-sass');
const gulpSourcemaps = require('gulp-sourcemaps');
const gulpAutoprefixer = require('gulp-autoprefixer');
const gulpConnect = require('gulp-connect');
const resolveBin = require('resolve-bin');

Expand Down Expand Up @@ -44,7 +43,6 @@ export function sassBuildTask(dest: string, root: string) {
return gulp.src(_globify(root, '**/*.scss'))
.pipe(gulpSourcemaps.init())
.pipe(gulpSass().on('error', gulpSass.logError))
.pipe(gulpAutoprefixer(SASS_AUTOPREFIXER_OPTIONS))
.pipe(gulpSourcemaps.write('.'))
.pipe(gulp.dest(dest));
};
Expand Down
61 changes: 61 additions & 0 deletions tools/stylelint/no-prefixes/needs-prefix.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
const autoprefixer = require('autoprefixer');
const Browsers = require('autoprefixer/lib/browsers');
const Prefixes = require('autoprefixer/lib/prefixes');

/**
* Utility to be used when checking whether a CSS declaration needs to be prefixed. Based on
* Stylelint's `no-vendor-prefix` rule, but instead of checking whether a rule has a prefix,
* we check whether it needs one.
* Reference https://github.com/stylelint/stylelint/blob/master/lib/utils/isAutoprefixable.js
*/
module.exports = class NeedsPrefix {
constructor(browsers) {
this._prefixes = new Prefixes(
autoprefixer.data.prefixes,
new Browsers(autoprefixer.data.browsers, browsers)
);
}

/** Checks whether an @-rule needs to be prefixed. */
atRule(identifier) {
return this._prefixes.add[`@${identifier.toLowerCase()}`];
}

/** Checks whether a selector needs to be prefixed. */
selector(identifier) {
return this._prefixes.add.selectors.some(selectorObj => {
return identifier.toLowerCase() === selectorObj.name;
});
}

/** Checks whether a media query value needs to be prefixed. */
mediaFeature(identifier) {
return identifier.toLowerCase().indexOf('device-pixel-ratio') > -1;
}

/** Checks whether a property needs to be prefixed. */
property(identifier) {
// `fill` is an edge case since it was part of a proposal that got renamed to `stretch`.
// see: https://www.w3.org/TR/css-sizing-3/#changes
if (!identifier || identifier === 'fill') return false;

const needsPrefix = autoprefixer.data.prefixes[identifier.toLowerCase()];
const browsersThatNeedPrefix = needsPrefix ? needsPrefix.browsers : null;

return !!browsersThatNeedPrefix && !!this._prefixes.browsers.selected.find(browser => {
return browsersThatNeedPrefix.indexOf(browser) > -1;
});
}

/** Checks whether a CSS property value needs to be prefixed. */
value(prop, value) {
if (!prop || !value) return false;

const possiblePrefixableValues = this._prefixes.add[prop.toLowerCase()] &&
this._prefixes.add[prop.toLowerCase()].values;

return !!possiblePrefixableValues && possiblePrefixableValues.some(valueObj => {
return value.toLowerCase() === valueObj.name;
});
}
};
88 changes: 88 additions & 0 deletions tools/stylelint/no-prefixes/no-prefixes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
const stylelint = require('stylelint');
const NeedsPrefix = require('./needs-prefix');
const parseSelector = require('stylelint/lib/utils/parseSelector');

const ruleName = 'material/no-prefixes';
const messages = stylelint.utils.ruleMessages(ruleName, {
property: property => `Unprefixed property "${property}".`,
value: (property, value) => `Unprefixed value in "${property}: ${value}".`,
atRule: name => `Unprefixed @rule "${name}".`,
mediaFeature: value => `Unprefixed media feature "${value}".`,
selector: selector => `Unprefixed selector "${selector}".`
});

/**
* Stylelint plugin that warns for unprefixed CSS.
*/
const plugin = stylelint.createPlugin(ruleName, browsers => {
return (root, result) => {
if (!stylelint.utils.validateOptions(result, ruleName, {})) return;

const needsPrefix = new NeedsPrefix(browsers);

// Check all of the `property: value` pairs.
root.walkDecls(decl => {
if (needsPrefix.property(decl.prop)) {
stylelint.utils.report({
result,
ruleName,
message: messages.property(decl.prop),
node: decl,
index: (decl.raws.before || '').length
});
} else if (needsPrefix.value(decl.prop, decl.value)) {
stylelint.utils.report({
result,
ruleName,
message: messages.value(decl.prop, decl.value),
node: decl,
index: (decl.raws.before || '').length
});
}
});

// Check all of the @-rules and their values.
root.walkAtRules(rule => {
if (needsPrefix.atRule(rule.name)) {
stylelint.utils.report({
result,
ruleName,
message: messages.atRule(rule.name),
node: rule
});
} else if (needsPrefix.mediaFeature(rule.params)) {
stylelint.utils.report({
result,
ruleName,
message: messages.mediaFeature(rule.name),
node: rule
});
}
});

// Walk the rules and check if the selector needs prefixes.
root.walkRules(rule => {
// Silence warnings for SASS selectors. Stylelint does this in their own rules as well:
// https://github.com/stylelint/stylelint/blob/master/lib/utils/isStandardSyntaxSelector.js
parseSelector(rule.selector, { warn: () => {} }, rule, selectorTree => {
selectorTree.walkPseudos(pseudoNode => {
if (needsPrefix.selector(pseudoNode.value)) {
stylelint.utils.report({
result,
ruleName,
message: messages.selector(pseudoNode.value),
node: rule,
index: (rule.raws.before || '').length + pseudoNode.sourceIndex,
});
}
});
});
});

};
});


plugin.ruleName = ruleName;
plugin.messages = messages;
module.exports = plugin;