Skip to content

Commit

Permalink
feat(dom): Create mdc-dom package with Element.matches() ponyfill (
Browse files Browse the repository at this point in the history
…#3515)

Will be used by #3413 and eventually other packages (e.g., for `Element.closest()` ponyfill)

Refs #1104
  • Loading branch information
acdvorak committed Sep 5, 2018
1 parent f3215e6 commit 91d8fe8
Show file tree
Hide file tree
Showing 10 changed files with 176 additions and 1 deletion.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@
"checkbox",
"chips",
"dialog",
"dom",
"drawer",
"elevation",
"fab",
Expand Down Expand Up @@ -218,6 +219,7 @@
"mdc-base",
"mdc-checkbox",
"mdc-chips",
"mdc-dom",
"mdc-drawer",
"mdc-floating-label",
"mdc-form-field",
Expand Down
2 changes: 2 additions & 0 deletions packages/material-components-web/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import * as base from '@material/base/index';
import * as checkbox from '@material/checkbox/index';
import * as chips from '@material/chips/index';
import * as dialog from '@material/dialog/index';
import * as dom from '@material/dom/index';
import * as drawer from '@material/drawer/index';
import * as floatingLabel from '@material/floating-label/index';
import * as formField from '@material/form-field/index';
Expand Down Expand Up @@ -88,6 +89,7 @@ export {
checkbox,
chips,
dialog,
dom,
drawer,
floatingLabel,
formField,
Expand Down
1 change: 1 addition & 0 deletions packages/material-components-web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"@material/checkbox": "^0.39.1",
"@material/chips": "^0.39.1",
"@material/dialog": "^0.39.1",
"@material/dom": "^0.0.0",
"@material/drawer": "^0.39.1",
"@material/elevation": "^0.39.1",
"@material/fab": "^0.39.1",
Expand Down
35 changes: 35 additions & 0 deletions packages/mdc-dom/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<!--docs:
title: "DOM"
layout: detail
section: components
excerpt: "Provides commonly-used utilities for inspecting, traversing, and manipulating the DOM."
path: /catalog/dom/
-->

# DOM

MDC DOM provides commonly-used utilities for inspecting, traversing, and manipulating the DOM.

Most of the time, you shouldn't need to depend on `mdc-dom` directly. It is useful however if you'd like to write custom components that follow MDC Web's pattern and elegantly integrate with the MDC Web ecosystem.

## Installation

```
npm install @material/dom
```

## Basic Usage

```js
import * as ponyfill from '@material/dom/ponyfill';
```

> See [Importing the JS component](../../docs/importing-js.md) for more information on how to import JavaScript.
## Ponyfill Functions

The `ponyfill` module provides the following functions:

Function Signature | Description
--- | ---
`matches(element: Element, selector: string) => boolean` | Returns true if the given element matches the given CSS selector.
26 changes: 26 additions & 0 deletions packages/mdc-dom/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

import * as ponyfill from './ponyfill';

export {ponyfill};
14 changes: 14 additions & 0 deletions packages/mdc-dom/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "@material/dom",
"description": "DOM manipulation utilities for Material Components for the web",
"version": "0.0.0",
"license": "MIT",
"main": "index.js",
"repository": {
"type": "git",
"url": "https://github.com/material-components/material-components-web.git"
},
"publishConfig": {
"access": "public"
}
}
41 changes: 41 additions & 0 deletions packages/mdc-dom/ponyfill.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

/**
* @fileoverview A "ponyfill" is a polyfill that doesn't modify the global prototype chain.
* This makes ponyfills safer than traditional polyfills, especially for libraries like MDC.
*/

/**
* @param {!Element} element
* @param {string} selector
* @return {boolean}
*/
function matches(element, selector) {
const nativeMatches = element.matches
|| element.webkitMatchesSelector
|| element.msMatchesSelector;
return nativeMatches.call(element, selector);
}

export {matches};
10 changes: 9 additions & 1 deletion scripts/check-pkg-for-release.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,14 @@ const MASTER_PKG = require(path.join(process.env.PWD, MASTER_PKG_PATH));
// These few MDC packages work as foundation or utility packages, and are not
// directly included in webpack or the material-component-web module. But they
// are necessary since other MDC packages depend on them.
const CSS_WHITELIST = ['base', 'animation', 'auto-init', 'rtl', 'selection-control'];
const CSS_WHITELIST = [
'base',
'animation',
'auto-init',
'dom',
'rtl',
'selection-control',
];

// List of packages that are intentionally not included in the MCW package's dependencies
const NOT_MCW_DEP = [
Expand All @@ -60,6 +67,7 @@ const NOT_MCW_DEP = [
const NOT_AUTOINIT = [
'auto-init',
'base',
'dom',
'selection-control',
'tab', // Only makes sense in context of tab-bar
'tab-indicator', // Only makes sense in context of tab-bar
Expand Down
1 change: 1 addition & 0 deletions scripts/webpack/js-bundle-factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ class JsBundleFactory {
checkbox: getAbsolutePath('/packages/mdc-checkbox/index.js'),
chips: getAbsolutePath('/packages/mdc-chips/index.js'),
dialog: getAbsolutePath('/packages/mdc-dialog/index.js'),
dom: getAbsolutePath('/packages/mdc-dom/index.js'),
drawer: getAbsolutePath('/packages/mdc-drawer/index.js'),
floatingLabel: getAbsolutePath('/packages/mdc-floating-label/index.js'),
formField: getAbsolutePath('/packages/mdc-form-field/index.js'),
Expand Down
45 changes: 45 additions & 0 deletions test/unit/mdc-dom/ponyfill.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

import {assert} from 'chai';
import bel from 'bel';

import {matches} from '../../../packages/mdc-dom/ponyfill';

suite('MDCDom - ponyfill');

test('#matches returns true when the selector matches the element', () => {
const element = bel`<div class="foo"></div>`;
assert.isTrue(matches(element, '.foo'));
});

test('#matches returns false when the selector does not match the element', () => {
const element = bel`<div class="foo"></div>`;
assert.isFalse(matches(element, '.bar'));
});

test('#matches supports vendor prefixes', () => {
assert.isTrue(matches({matches: () => true}, ''));
assert.isTrue(matches({webkitMatchesSelector: () => true}, ''));
assert.isTrue(matches({msMatchesSelector: () => true}, ''));
});

0 comments on commit 91d8fe8

Please sign in to comment.