Project import generated by Copybara.
GitOrigin-RevId: 63746295f1a5ab5a619056791995793d65529e62
diff --git a/node_modules/mdl-ext/es/lightboard/lightboard.js b/node_modules/mdl-ext/es/lightboard/lightboard.js
new file mode 100644
index 0000000..03ceed8
--- /dev/null
+++ b/node_modules/mdl-ext/es/lightboard/lightboard.js
@@ -0,0 +1,316 @@
+'use strict';
+
+var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
+
+var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
+
+var _constants = require('../utils/constants');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var MDL_RIPPLE_CONTAINER = 'mdlext-lightboard__slide__ripple-container'; /**
+ * @license
+ * Copyright 2016 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 lightboard is a translucent surface illuminated from behind, used for situations
+ * where a shape laid upon the surface needs to be seen with high contrast. In the "old days" of photography
+ * photograpers used a lightboard to get a quick view of their slides. The goal is to create a responsive lightbox
+ * design, based on flex layout, similar to what is used in Adobe LightRoom to browse images.
+ */
+
+(function () {
+ 'use strict';
+
+ //const LIGHTBOARD = 'mdlext-lightboard';
+
+ var LIGHTBOARD_ROLE = 'grid';
+ var SLIDE = 'mdlext-lightboard__slide';
+ var SLIDE_ROLE = 'gridcell';
+ var SLIDE_TABSTOP = 'mdlext-lightboard__slide__frame';
+ /**
+ * @constructor
+ * @param {Element} element The element that will be upgraded.
+ */
+ var MaterialExtLightboard = function MaterialExtLightboard(element) {
+ // Stores the element.
+ this.element_ = element;
+
+ // Initialize instance.
+ this.init();
+ };
+ window['MaterialExtLightboard'] = MaterialExtLightboard;
+
+ // Helpers
+ var getSlide = function getSlide(element) {
+ return element ? element.closest('.' + SLIDE) : null;
+ };
+
+ // Private methods.
+
+ /**
+ * Select a slide, i.e. set aria-selected="true"
+ * @param element
+ * @private
+ */
+ MaterialExtLightboard.prototype.selectSlide_ = function (element) {
+ var slide = getSlide(element);
+ if (slide && !slide.hasAttribute('aria-selected')) {
+ [].concat((0, _toConsumableArray3.default)(this.element_.querySelectorAll('.' + SLIDE + '[aria-selected="true"]'))).forEach(function (selectedSlide) {
+ return selectedSlide.removeAttribute('aria-selected');
+ });
+
+ slide.setAttribute('aria-selected', 'true');
+ }
+ };
+
+ /**
+ * Dispatch select event
+ * @param {Element} slide The slide that caused the event
+ * @private
+ */
+ MaterialExtLightboard.prototype.dispatchSelectEvent_ = function (slide) {
+ this.element_.dispatchEvent(new CustomEvent('select', {
+ bubbles: true,
+ cancelable: true,
+ detail: { source: slide }
+ }));
+ };
+
+ /**
+ * Handles custom command event, 'first', 'next', 'prev', 'last', 'select' or upgrade
+ * @param event. A custom event
+ * @private
+ */
+ MaterialExtLightboard.prototype.commandHandler_ = function (event) {
+ event.preventDefault();
+ event.stopPropagation();
+
+ if (event && event.detail) {
+ this.command(event.detail);
+ }
+ };
+
+ // Public methods
+
+ /**
+ * Initialize lightboard slides
+ * @public
+ */
+ MaterialExtLightboard.prototype.upgradeSlides = function () {
+
+ var addRipple = function addRipple(slide) {
+ // Use slide frame as ripple container
+ if (!slide.querySelector('.' + MDL_RIPPLE_CONTAINER)) {
+ var a = slide.querySelector('.' + SLIDE_TABSTOP);
+ if (a) {
+ var rippleContainer = a;
+ rippleContainer.classList.add(MDL_RIPPLE_CONTAINER);
+ rippleContainer.classList.add(_constants.MDL_RIPPLE_EFFECT);
+ var ripple = document.createElement('span');
+ ripple.classList.add(_constants.MDL_RIPPLE);
+ rippleContainer.appendChild(ripple);
+ componentHandler.upgradeElement(rippleContainer, _constants.MDL_RIPPLE_COMPONENT);
+ }
+ }
+ };
+
+ var hasRippleEffect = this.element_.classList.contains(_constants.MDL_RIPPLE_EFFECT);
+
+ [].concat((0, _toConsumableArray3.default)(this.element_.querySelectorAll('.' + SLIDE))).forEach(function (slide) {
+
+ slide.setAttribute('role', SLIDE_ROLE);
+
+ if (!slide.querySelector('a')) {
+ slide.setAttribute('tabindex', '0');
+ }
+ if (hasRippleEffect) {
+ addRipple(slide);
+ }
+ });
+ };
+ MaterialExtLightboard.prototype['upgradeSlides'] = MaterialExtLightboard.prototype.upgradeSlides;
+
+ /**
+ * Execute command
+ * @param detail
+ * @public
+ */
+ MaterialExtLightboard.prototype.command = function (detail) {
+ var _this = this;
+
+ var firstSlide = function firstSlide() {
+ return _this.element_.querySelector('.' + SLIDE + ':first-child');
+ };
+
+ var lastSlide = function lastSlide() {
+ return _this.element_.querySelector('.' + SLIDE + ':last-child');
+ };
+
+ var nextSlide = function nextSlide() {
+ var slide = _this.element_.querySelector('.' + SLIDE + '[aria-selected="true"]').nextElementSibling;
+ return slide ? slide : firstSlide();
+ };
+
+ var prevSlide = function prevSlide() {
+ var slide = _this.element_.querySelector('.' + SLIDE + '[aria-selected="true"]').previousElementSibling;
+ return slide ? slide : lastSlide();
+ };
+
+ if (detail && detail.action) {
+ var action = detail.action,
+ target = detail.target;
+
+
+ var slide = void 0;
+ switch (action.toLowerCase()) {
+ case 'select':
+ slide = getSlide(target);
+ this.dispatchSelectEvent_(slide);
+ break;
+ case 'first':
+ slide = firstSlide();
+ break;
+ case 'next':
+ slide = nextSlide();
+ break;
+ case 'prev':
+ slide = prevSlide();
+ break;
+ case 'last':
+ slide = lastSlide();
+ break;
+ case 'upgrade':
+ this.upgradeSlides();
+ break;
+ default:
+ throw new Error('Unknown action "' + action + '". Action must be one of "first", "next", "prev", "last", "select" or "upgrade"');
+ }
+
+ if (slide) {
+ var a = slide.querySelector('a');
+ if (a) {
+ a.focus();
+ } else {
+ slide.focus();
+ }
+
+ // Workaround for JSDom testing:
+ // In JsDom 'element.focus()' does not trigger any focus event
+ if (!slide.hasAttribute('aria-selected')) {
+ this.selectSlide_(slide);
+ }
+ }
+ }
+ };
+ MaterialExtLightboard.prototype['command'] = MaterialExtLightboard.prototype.command;
+
+ /**
+ * Initialize component
+ */
+ MaterialExtLightboard.prototype.init = function () {
+ var _this2 = this;
+
+ var keydownHandler = function keydownHandler(event) {
+
+ if (event.target !== _this2.element_) {
+ var action = void 0;
+ var target = void 0;
+ switch (event.keyCode) {
+ case _constants.VK_HOME:
+ action = 'first';
+ break;
+ case _constants.VK_END:
+ action = 'last';
+ break;
+ case _constants.VK_ARROW_UP:
+ case _constants.VK_ARROW_LEFT:
+ action = 'prev';
+ break;
+ case _constants.VK_ARROW_DOWN:
+ case _constants.VK_ARROW_RIGHT:
+ action = 'next';
+ break;
+ case _constants.VK_ENTER:
+ case _constants.VK_SPACE:
+ action = 'select';
+ target = event.target;
+ break;
+ }
+ if (action) {
+ event.preventDefault();
+ event.stopPropagation();
+ _this2.command({ action: action, target: target });
+ }
+ }
+ };
+
+ var clickHandler = function clickHandler(event) {
+ event.preventDefault();
+ event.stopPropagation();
+
+ if (event.target !== _this2.element_) {
+ _this2.command({ action: 'select', target: event.target });
+ }
+ };
+
+ var focusHandler = function focusHandler(event) {
+ event.preventDefault();
+ event.stopPropagation();
+
+ if (event.target !== _this2.element_) {
+ _this2.selectSlide_(event.target);
+ }
+ };
+
+ if (this.element_) {
+ this.element_.setAttribute('role', LIGHTBOARD_ROLE);
+
+ if (this.element_.classList.contains(_constants.MDL_RIPPLE_EFFECT)) {
+ this.element_.classList.add(_constants.MDL_RIPPLE_EFFECT_IGNORE_EVENTS);
+ }
+
+ // Remove listeners, just in case ...
+ this.element_.removeEventListener('command', this.commandHandler_);
+ this.element_.removeEventListener('keydown', keydownHandler);
+ this.element_.removeEventListener('click', clickHandler);
+ this.element_.removeEventListener('focus', focusHandler);
+
+ this.element_.addEventListener('command', this.commandHandler_.bind(this), false);
+ this.element_.addEventListener('keydown', keydownHandler, true);
+ this.element_.addEventListener('click', clickHandler, true);
+ this.element_.addEventListener('focus', focusHandler, true);
+
+ this.upgradeSlides();
+
+ this.element_.classList.add(_constants.IS_UPGRADED);
+ }
+ };
+
+ // The component registers itself. It can assume componentHandler is available
+ // in the global scope.
+ /* eslint no-undef: 0 */
+ /* jshint undef:false */
+ componentHandler.register({
+ constructor: MaterialExtLightboard,
+ classAsString: 'MaterialExtLightboard',
+ cssClass: 'mdlext-js-lightboard',
+ widget: true
+ });
+})();
\ No newline at end of file