Project import generated by Copybara.
GitOrigin-RevId: 63746295f1a5ab5a619056791995793d65529e62
diff --git a/node_modules/mdl-ext/es/collapsible/collapsible.js b/node_modules/mdl-ext/es/collapsible/collapsible.js
new file mode 100644
index 0000000..80c2db0
--- /dev/null
+++ b/node_modules/mdl-ext/es/collapsible/collapsible.js
@@ -0,0 +1,481 @@
+'use strict';
+
+var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
+
+var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
+
+var _createClass2 = require('babel-runtime/helpers/createClass');
+
+var _createClass3 = _interopRequireDefault(_createClass2);
+
+var _constants = require('../utils/constants');
+
+var _stringUtils = require('../utils/string-utils');
+
+var _domUtils = require('../utils/dom-utils');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var JS_COLLAPSIBLE = 'mdlext-js-collapsible'; /**
+ * @license
+ * Copyright 2016-2017 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This code is built with Google Material Design Lite,
+ * which is Licensed under the Apache License, Version 2.0
+ */
+
+/**
+ * A collapsible is a component to mark expandable and collapsible regions.
+ * The component use the aria-expanded state to indicate whether regions of
+ * the content are collapsible, and to expose whether a region is currently
+ * expanded or collapsed.
+ * @see https://www.w3.org/WAI/GL/wiki/Using_the_WAI-ARIA_aria-expanded_state_to_mark_expandable_and_collapsible_regions
+ */
+
+var COLLAPSIBLE_CONTROL_CLASS = 'mdlext-collapsible';
+var COLLAPSIBLE_GROUP_CLASS = 'mdlext-collapsible-group';
+var COLLAPSIBLE_REGION_CLASS = 'mdlext-collapsible-region';
+
+/**
+ * The collapsible component
+ */
+
+var Collapsible = function () {
+
+ /**
+ * @constructor
+ * @param {HTMLElement} element The element that this component is connected to.
+ */
+ function Collapsible(element) {
+ var _this = this;
+
+ (0, _classCallCheck3.default)(this, Collapsible);
+ this.element_ = null;
+ this.controlElement_ = null;
+
+ this.keyDownHandler = function (event) {
+ if (event.keyCode === _constants.VK_ENTER || event.keyCode === _constants.VK_SPACE) {
+ event.preventDefault();
+
+ // Trigger click
+ (event.target || _this.controlElement).dispatchEvent(new MouseEvent('click', {
+ bubbles: true,
+ cancelable: true,
+ view: window
+ }));
+ }
+ };
+
+ this.clickHandler = function (event) {
+ if (!_this.isDisabled) {
+ if (event.target !== _this.controlElement) {
+ // Do not toggle if a focusable element inside the control element triggered the event
+ var p = (0, _domUtils.getParentElements)(event.target, _this.controlElement);
+ p.push(event.target);
+ if (p.find(function (el) {
+ return (0, _domUtils.isFocusable)(el);
+ })) {
+ return;
+ }
+ }
+ _this.toggle();
+ }
+ };
+
+ this.element_ = element;
+ this.init();
+ }
+
+ (0, _createClass3.default)(Collapsible, [{
+ key: 'collapse',
+ value: function collapse() {
+ if (!this.isDisabled && this.isExpanded) {
+ if (this.dispatchToggleEvent('collapse')) {
+ this.controlElement.setAttribute('aria-expanded', 'false');
+ var regions = this.regionElements.slice(0);
+ for (var i = regions.length - 1; i >= 0; --i) {
+ regions[i].setAttribute('hidden', '');
+ }
+ }
+ }
+ }
+ }, {
+ key: 'expand',
+ value: function expand() {
+ if (!this.isDisabled && !this.isExpanded) {
+ if (this.dispatchToggleEvent('expand')) {
+ this.controlElement.setAttribute('aria-expanded', 'true');
+ this.regionElements.forEach(function (region) {
+ return region.removeAttribute('hidden');
+ });
+ }
+ }
+ }
+ }, {
+ key: 'toggle',
+ value: function toggle() {
+ if (this.isExpanded) {
+ this.collapse();
+ } else {
+ this.expand();
+ }
+ }
+ }, {
+ key: 'dispatchToggleEvent',
+ value: function dispatchToggleEvent(action) {
+ return this.element.dispatchEvent(new CustomEvent('toggle', {
+ bubbles: true,
+ cancelable: true,
+ detail: {
+ action: action
+ }
+ }));
+ }
+ }, {
+ key: 'disableToggle',
+ value: function disableToggle() {
+ this.controlElement.setAttribute('aria-disabled', true);
+ }
+ }, {
+ key: 'enableToggle',
+ value: function enableToggle() {
+ this.controlElement.removeAttribute('aria-disabled');
+ }
+ }, {
+ key: 'addRegionId',
+ value: function addRegionId(regionId) {
+ var ids = this.regionIds;
+ if (!ids.find(function (id) {
+ return regionId === id;
+ })) {
+ ids.push(regionId);
+ this.controlElement.setAttribute('aria-controls', ids.join(' '));
+ }
+ }
+ }, {
+ key: 'addRegionElement',
+ value: function addRegionElement(region) {
+ if (!(region.classList.contains(COLLAPSIBLE_GROUP_CLASS) || region.classList.contains(COLLAPSIBLE_REGION_CLASS))) {
+ region.classList.add(COLLAPSIBLE_GROUP_CLASS);
+ }
+
+ if (!region.hasAttribute('role')) {
+ var role = region.classList.contains(COLLAPSIBLE_GROUP_CLASS) ? 'group' : 'region';
+ region.setAttribute('role', role);
+ }
+
+ if (!region.hasAttribute('id')) {
+ region.id = region.getAttribute('role') + '-' + (0, _stringUtils.randomString)();
+ }
+
+ if (this.isExpanded) {
+ region.removeAttribute('hidden');
+ } else {
+ region.setAttribute('hidden', '');
+ }
+ this.addRegionId(region.id);
+ }
+ }, {
+ key: 'removeRegionElement',
+ value: function removeRegionElement(region) {
+ if (region && region.id) {
+ var ids = this.regionIds.filter(function (id) {
+ return id === region.id;
+ });
+ this.controlElement.setAttribute('aria-controls', ids.join(' '));
+ }
+ }
+ }, {
+ key: 'removeListeners',
+ value: function removeListeners() {
+ this.controlElement.removeEventListener('keydown', this.keyDownHandler);
+ this.controlElement.removeEventListener('click', this.clickHandler);
+ }
+ }, {
+ key: 'init',
+ value: function init() {
+ var _this2 = this;
+
+ var initControl = function initControl() {
+ // Find the button element
+ _this2.controlElement_ = _this2.element.querySelector('.' + COLLAPSIBLE_CONTROL_CLASS) || _this2.element;
+
+ // Add "aria-expanded" attribute if not present
+ if (!_this2.controlElement.hasAttribute('aria-expanded')) {
+ _this2.controlElement.setAttribute('aria-expanded', 'false');
+ }
+
+ // Add role=button if control != <button>
+ if (_this2.controlElement.nodeName.toLowerCase() !== 'button') {
+ _this2.controlElement.setAttribute('role', 'button');
+ }
+
+ // Add tabindex
+ if (!(0, _domUtils.isFocusable)(_this2.controlElement) && !_this2.controlElement.hasAttribute('tabindex')) {
+ _this2.controlElement.setAttribute('tabindex', '0');
+ }
+ };
+
+ var initRegions = function initRegions() {
+ var regions = [];
+ if (!_this2.controlElement.hasAttribute('aria-controls')) {
+ // Add siblings as collapsible region(s)
+ var r = _this2.element.nextElementSibling;
+ while (r) {
+ if (r.classList.contains(COLLAPSIBLE_GROUP_CLASS) || r.classList.contains(COLLAPSIBLE_REGION_CLASS)) {
+ regions.push(r);
+ } else if (r.classList.contains(JS_COLLAPSIBLE)) {
+ // A new collapsible component
+ break;
+ }
+ r = r.nextElementSibling;
+ }
+ } else {
+ regions = _this2.regionElements;
+ }
+ regions.forEach(function (region) {
+ return _this2.addRegionElement(region);
+ });
+ };
+
+ var addListeners = function addListeners() {
+ _this2.controlElement.addEventListener('keydown', _this2.keyDownHandler);
+ _this2.controlElement.addEventListener('click', _this2.clickHandler);
+ };
+
+ initControl();
+ initRegions();
+ this.removeListeners();
+ addListeners();
+ }
+ }, {
+ key: 'downgrade',
+ value: function downgrade() {
+ this.removeListeners();
+ }
+ }, {
+ key: 'element',
+ get: function get() {
+ return this.element_;
+ }
+ }, {
+ key: 'controlElement',
+ get: function get() {
+ return this.controlElement_;
+ }
+ }, {
+ key: 'isDisabled',
+ get: function get() {
+ return this.controlElement.hasAttribute('disabled') && this.controlElement.getAttribute('disabled').toLowerCase() !== 'false' || this.controlElement.hasAttribute('aria-disabled') && this.controlElement.getAttribute('aria-disabled').toLowerCase() !== 'false';
+ }
+ }, {
+ key: 'isExpanded',
+ get: function get() {
+ return this.controlElement.hasAttribute('aria-expanded') && this.controlElement.getAttribute('aria-expanded').toLowerCase() === 'true';
+ }
+ }, {
+ key: 'regionIds',
+ get: function get() {
+ return this.controlElement.hasAttribute('aria-controls') ? this.controlElement.getAttribute('aria-controls').split(' ') : [];
+ }
+ }, {
+ key: 'regionElements',
+ get: function get() {
+ return this.regionIds.map(function (id) {
+ return document.querySelector('#' + id);
+ }).filter(function (el) {
+ return el != null;
+ });
+ }
+ }]);
+ return Collapsible;
+}();
+
+(function () {
+ 'use strict';
+
+ /**
+ * @constructor
+ * @param {HTMLElement} element The element that will be upgraded.
+ */
+
+ var MaterialExtCollapsible = function MaterialExtCollapsible(element) {
+ this.element_ = element;
+ this.collapsible = null;
+
+ // Initialize instance.
+ this.init();
+ };
+ window['MaterialExtCollapsible'] = MaterialExtCollapsible;
+
+ /**
+ * Initialize component
+ */
+ MaterialExtCollapsible.prototype.init = function () {
+ if (this.element_) {
+ this.collapsible = new Collapsible(this.element_);
+ this.element_.classList.add(_constants.IS_UPGRADED);
+
+ // Listen to 'mdl-componentdowngraded' event
+ this.element_.addEventListener('mdl-componentdowngraded', this.mdlDowngrade_.bind(this));
+ }
+ };
+
+ /*
+ * Downgrade component
+ * E.g remove listeners and clean up resources
+ */
+ MaterialExtCollapsible.prototype.mdlDowngrade_ = function () {
+ this.collapsible.downgrade();
+ };
+
+ // Public methods.
+
+ /**
+ * Get control element.
+ * @return {HTMLElement} element The element that controls the collapsible region.
+ * @public
+ */
+ MaterialExtCollapsible.prototype.getControlElement = function () {
+ return this.collapsible.controlElement;
+ };
+ MaterialExtCollapsible.prototype['getControlElement'] = MaterialExtCollapsible.prototype.getControlElement;
+
+ /**
+ * Get region elements controlled by this collapsible
+ * @returns {Array<HTMLElement>} the collapsible region elements
+ * @public
+ */
+ MaterialExtCollapsible.prototype.getRegionElements = function () {
+ return this.collapsible.regionElements;
+ };
+ MaterialExtCollapsible.prototype['getRegionElements'] = MaterialExtCollapsible.prototype.getRegionElements;
+
+ /**
+ * Add region elements.
+ * @param {Array<HTMLElement>} elements The element that will be upgraded.
+ * @return {void}
+ * @public
+ */
+ MaterialExtCollapsible.prototype.addRegionElements = function () {
+ var _this3 = this;
+
+ for (var _len = arguments.length, elements = Array(_len), _key = 0; _key < _len; _key++) {
+ elements[_key] = arguments[_key];
+ }
+
+ elements.forEach(function (element) {
+ return _this3.collapsible.addRegionElement(element);
+ });
+ };
+ MaterialExtCollapsible.prototype['addRegionElements'] = MaterialExtCollapsible.prototype.addRegionElements;
+
+ /**
+ * Remove collapsible region(s) from component.
+ * Note: This operation does not delete the element from the DOM tree.
+ * @param {Array<HTMLElement>} elements The element that will be upgraded.
+ * @public
+ */
+ MaterialExtCollapsible.prototype.removeRegionElements = function () {
+ var _this4 = this;
+
+ for (var _len2 = arguments.length, elements = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
+ elements[_key2] = arguments[_key2];
+ }
+
+ elements.forEach(function (element) {
+ return _this4.collapsible.removeRegionElement(element);
+ });
+ };
+ MaterialExtCollapsible.prototype['removeRegionElements'] = MaterialExtCollapsible.prototype.removeRegionElements;
+
+ /**
+ * Expand collapsible region(s)
+ * @return {void}
+ * @public
+ */
+ MaterialExtCollapsible.prototype.expand = function () {
+ this.collapsible.expand();
+ };
+ MaterialExtCollapsible.prototype['expand'] = MaterialExtCollapsible.prototype.expand;
+
+ /**
+ * Collapse collapsible region(s)
+ * @return {void}
+ * @public
+ */
+ MaterialExtCollapsible.prototype.collapse = function () {
+ this.collapsible.collapse();
+ };
+ MaterialExtCollapsible.prototype['collapse'] = MaterialExtCollapsible.prototype.collapse;
+
+ /**
+ * Toggle collapsible region(s)
+ * @return {void}
+ * @public
+ */
+ MaterialExtCollapsible.prototype.toggle = function () {
+ this.collapsible.toggle();
+ };
+ MaterialExtCollapsible.prototype['toggle'] = MaterialExtCollapsible.prototype.toggle;
+
+ /**
+ * Check whether component has aria-expanded state true
+ * @return {Boolean} true if aria-expanded="true", otherwise false
+ */
+ MaterialExtCollapsible.prototype.isExpanded = function () {
+ return this.collapsible.isExpanded;
+ };
+ MaterialExtCollapsible.prototype['isExpanded'] = MaterialExtCollapsible.prototype.isExpanded;
+
+ /**
+ * Check whether component has aria-disabled state set to true
+ * @return {Boolean} true if aria-disabled="true", otherwise false
+ */
+ MaterialExtCollapsible.prototype.isDisabled = function () {
+ return this.collapsible.isDisabled;
+ };
+ MaterialExtCollapsible.prototype['isDisabled'] = MaterialExtCollapsible.prototype.isDisabled;
+
+ /**
+ * Disables toggling of collapsible region(s)
+ * @return {void}
+ * @public
+ */
+ MaterialExtCollapsible.prototype.disableToggle = function () {
+ this.collapsible.disableToggle();
+ };
+ MaterialExtCollapsible.prototype['disableToggle'] = MaterialExtCollapsible.prototype.disableToggle;
+
+ /**
+ * Enables toggling of collapsible region(s)
+ * @return {void}
+ * @public
+ */
+ MaterialExtCollapsible.prototype.enableToggle = function () {
+ this.collapsible.enableToggle();
+ };
+ MaterialExtCollapsible.prototype['enableToggle'] = MaterialExtCollapsible.prototype.enableToggle;
+
+ // The component registers itself. It can assume componentHandler is available
+ // in the global scope.
+ /* eslint no-undef: 0 */
+ componentHandler.register({
+ constructor: MaterialExtCollapsible,
+ classAsString: 'MaterialExtCollapsible',
+ cssClass: JS_COLLAPSIBLE,
+ widget: true
+ });
+})();
\ No newline at end of file