@atlassian/aui
Version:
Atlassian User Interface Framework
348 lines (293 loc) • 12.4 kB
JavaScript
(function (global, factory) {
if (typeof define === "function" && define.amd) {
define(['module', 'exports', './jquery', './internal/alignment', './internal/amdify', './internal/attributes', './internal/enforcer', './internal/globalize', './layer', './internal/skate', './internal/state'], factory);
} else if (typeof exports !== "undefined") {
factory(module, exports, require('./jquery'), require('./internal/alignment'), require('./internal/amdify'), require('./internal/attributes'), require('./internal/enforcer'), require('./internal/globalize'), require('./layer'), require('./internal/skate'), require('./internal/state'));
} else {
var mod = {
exports: {}
};
factory(mod, mod.exports, global.jquery, global.alignment, global.amdify, global.attributes, global.enforcer, global.globalize, global.layer, global.skate, global.state);
global.inlineDialog2 = mod.exports;
}
})(this, function (module, exports, _jquery, _alignment, _amdify, _attributes, _enforcer, _globalize, _layer, _skate, _state) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _jquery2 = _interopRequireDefault(_jquery);
var _alignment2 = _interopRequireDefault(_alignment);
var _amdify2 = _interopRequireDefault(_amdify);
var _attributes2 = _interopRequireDefault(_attributes);
var _enforcer2 = _interopRequireDefault(_enforcer);
var _globalize2 = _interopRequireDefault(_globalize);
var _layer2 = _interopRequireDefault(_layer);
var _skate2 = _interopRequireDefault(_skate);
var _state2 = _interopRequireDefault(_state);
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
var DEFAULT_HOVEROUT_DELAY = 1000;
function getTrigger(element) {
return document.querySelector('[aria-controls="' + element.id + '"]');
}
function doIfTrigger(element, callback) {
var trigger = getTrigger(element);
if (trigger) {
callback(trigger);
}
}
function initAlignment(element, trigger) {
if (!element._auiAlignment) {
element._auiAlignment = new _alignment2.default(element, trigger);
}
}
function enableAlignment(element, trigger) {
initAlignment(element, trigger);
element._auiAlignment.enable();
}
function disableAlignment(element, trigger) {
initAlignment(element, trigger);
element._auiAlignment.disable();
}
function handleMessage(element, message) {
var messageTypeMap = {
toggle: ['click'],
hover: ['mouseenter', 'mouseleave', 'focus', 'blur']
};
var messageList = messageTypeMap[element.respondsTo];
if (messageList && messageList.indexOf(message.type) > -1) {
messageHandler[message.type](element, message);
}
}
var messageHandler = {
click: function click(element) {
if (element.open) {
if (!(0, _layer2.default)(element).isPersistent()) {
element.open = false;
}
} else {
element.open = true;
}
},
mouseenter: function mouseenter(element) {
if (!element.open) {
element.open = true;
}
if (element._clearMouseleaveTimeout) {
element._clearMouseleaveTimeout();
}
},
mouseleave: function mouseleave(element) {
if ((0, _layer2.default)(element).isPersistent() || !element.open) {
return;
}
if (element._clearMouseleaveTimeout) {
element._clearMouseleaveTimeout();
}
var timeout = setTimeout(function () {
if (!(0, _state2.default)(element).get('mouse-inside')) {
element.open = false;
}
}, DEFAULT_HOVEROUT_DELAY);
element._clearMouseleaveTimeout = function () {
clearTimeout(timeout);
element._clearMouseleaveTimeout = null;
};
},
focus: function focus(element) {
if (!element.open) {
element.open = true;
}
},
blur: function blur(element) {
if (!(0, _layer2.default)(element).isPersistent() && element.open) {
element.open = false;
}
}
};
function onMouseEnter(e) {
var element = e.target;
(0, _state2.default)(element).set('mouse-inside', true);
element.message({
type: 'mouseenter'
});
}
function onMouseLeave(e) {
var element = e.target;
(0, _state2.default)(element).set('mouse-inside', false);
element.message({
type: 'mouseleave'
});
}
function rebindMouseEvents(el) {
(0, _state2.default)(el).set('mouse-inside', undefined);
el.removeEventListener('mouseenter', onMouseEnter);
el.removeEventListener('mouseleave', onMouseLeave);
if (el.respondsTo === 'hover') {
(0, _state2.default)(el).set('mouse-inside', false);
el.addEventListener('mouseenter', onMouseEnter);
el.addEventListener('mouseleave', onMouseLeave);
}
}
function showInlineDialog(el) {
(0, _layer2.default)(el).show();
if ((0, _layer2.default)(el).isVisible()) {
doIfTrigger(el, function (trigger) {
enableAlignment(el, trigger);
trigger.setAttribute('aria-expanded', 'true');
});
} else {
el.open = false;
}
}
function hideInlineDialog(el) {
(0, _layer2.default)(el).hide();
if (!(0, _layer2.default)(el).isVisible()) {
doIfTrigger(el, function (trigger) {
disableAlignment(el, trigger);
trigger.setAttribute('aria-expanded', 'false');
});
} else {
el.open = true;
}
}
function reflectOpenness(el) {
var isInitalizing = !el.hasAttribute('aria-hidden');
var shouldBeOpen = el.hasAttribute('open');
if (isInitalizing || el.open !== shouldBeOpen) {
if (shouldBeOpen) {
(0, _state2.default)(el).set('is-processing-show', true);
showInlineDialog(el);
(0, _state2.default)(el).set('is-processing-show', false);
} else {
hideInlineDialog(el);
}
}
}
var RESPONDS_TO_ATTRIBUTE_ENUM = {
attribute: 'responds-to',
values: ['toggle', 'hover'],
missingDefault: 'toggle',
invalidDefault: 'toggle'
};
var inlineDialog = (0, _skate2.default)('aui-inline-dialog', {
prototype: {
/**
* Returns whether the inline dialog is open.
*/
get open() {
return (0, _layer2.default)(this).isVisible();
},
/**
* Opens or closes the inline dialog, returning whether the dialog is
* open or closed as a result (since event handlers can prevent either
* action).
*
* You should check the value of open after setting this
* value since the before show/hide events may have prevented it.
*/
set open(value) {
// TODO AUI-3726 Revisit double calls to canceled event handlers.
// Explicitly calling reflectOpenness(…) in this setter means
// that in native we'll get two sync calls to reflectOpenness(…)
// and in polyfill one sync (here) and one async (attr change
// handler). The latter of the two calls, for both cases, will
// usually be a noop (except when show/hide events are cancelled).
_attributes2.default.setBooleanAttribute(this, 'open', value);
reflectOpenness(this);
},
get persistent() {
return this.hasAttribute('persistent');
},
set persistent(value) {
_attributes2.default.setBooleanAttribute(this, 'persistent', value);
},
get respondsTo() {
var attr = RESPONDS_TO_ATTRIBUTE_ENUM.attribute;
return _attributes2.default.computeEnumValue(RESPONDS_TO_ATTRIBUTE_ENUM, this.getAttribute(attr));
},
set respondsTo(value) {
var oldComputedValue = this.respondsTo;
_attributes2.default.setEnumAttribute(this, RESPONDS_TO_ATTRIBUTE_ENUM, value);
if (oldComputedValue !== this.respondsTo) {
rebindMouseEvents(this);
}
},
/**
* Handles the receiving of a message from another component.
*
* @param {Object} msg The message to act on.
*
* @returns {HTMLElement}
*/
message: function message(msg) {
handleMessage(this, msg);
return this;
}
},
created: function created(element) {
(0, _state2.default)(element).set('is-processing-show', false);
doIfTrigger(element, function (trigger) {
trigger.setAttribute('aria-expanded', element.open);
trigger.setAttribute('aria-haspopup', 'true');
});
},
attributes: {
'aria-hidden': function ariaHidden(element, change) {
if (change.newValue === 'true') {
var trigger = getTrigger(element);
if (trigger) {
trigger.setAttribute('aria-expanded', 'false');
}
}
// Whenever layer manager hides us, we need to sync the open attribute.
_attributes2.default.setBooleanAttribute(element, 'open', change.newValue === 'false');
},
open: function open(element) {
// skate runs the created callback for attributes before the
// element is attached to the DOM, so guard against that.
if (document.body.contains(element)) {
reflectOpenness(element);
}
},
'responds-to': function respondsTo(element, change) {
var oldComputedValue = _attributes2.default.computeEnumValue(RESPONDS_TO_ATTRIBUTE_ENUM, change.oldValue);
var newComputedValue = _attributes2.default.computeEnumValue(RESPONDS_TO_ATTRIBUTE_ENUM, change.newValue);
if (oldComputedValue !== newComputedValue) {
rebindMouseEvents(element);
}
}
},
attached: function attached(element) {
(0, _enforcer2.default)(element).attributeExists('id');
if (element.hasAttribute('open')) {
// show() can cause the element to be reattached (to the <body>),
// so guard against a nested show() call that blows up the layer
// manager (since it sees us pushing the same element twice).
if (!(0, _state2.default)(element).get('is-processing-show')) {
reflectOpenness(element);
}
} else {
reflectOpenness(element);
}
rebindMouseEvents(element);
},
detached: function detached(element) {
if (element._auiAlignment) {
element._auiAlignment.destroy();
}
},
template: function template(element) {
var elem = (0, _jquery2.default)('<div class="aui-inline-dialog-contents"></div>').append(element.childNodes);
(0, _jquery2.default)(element).addClass('aui-layer').html(elem);
}
});
(0, _amdify2.default)('aui/inline-dialog2', inlineDialog);
(0, _globalize2.default)('InlineDialog2', inlineDialog);
exports.default = inlineDialog;
module.exports = exports['default'];
});
//# sourceMappingURL=inline-dialog2.js.map