This commit is contained in:
arnaucode
2017-02-03 08:56:51 +01:00
parent c4b7414770
commit 112745d6fa
1585 changed files with 450241 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
{
"name": "angular-material-tooltip",
"version": "1.1.2-master-a9ba340",
"dependencies": {
"angular-material-core": "1.1.2-master-a9ba340",
"angular-material-panel": "1.1.2-master-a9ba340"
}
}

View File

@@ -0,0 +1,9 @@
/*!
* Angular Material Design
* https://github.com/angular/material
* @license MIT
* v1.1.3
*/
.md-panel.md-tooltip.md-THEME_NAME-theme {
color: '{{background-700-contrast}}';
background-color: '{{background-700}}'; }

View File

@@ -0,0 +1,6 @@
/*!
* Angular Material Design
* https://github.com/angular/material
* @license MIT
* v1.1.2-master-a9ba340
*/.md-panel.md-tooltip.md-THEME_NAME-theme{color:"{{background-700-contrast}}";background-color:"{{background-700}}"}

View File

@@ -0,0 +1,67 @@
/*!
* Angular Material Design
* https://github.com/angular/material
* @license MIT
* v1.1.3
*/
.md-tooltip {
pointer-events: none;
border-radius: 4px;
overflow: hidden;
opacity: 0;
font-weight: 500;
font-size: 14px;
white-space: nowrap;
text-overflow: ellipsis;
height: 32px;
line-height: 32px;
padding-right: 16px;
padding-left: 16px; }
.md-tooltip.md-origin-top {
-webkit-transform-origin: center bottom;
transform-origin: center bottom;
margin-top: -24px; }
.md-tooltip.md-origin-right {
-webkit-transform-origin: left center;
transform-origin: left center;
margin-left: 24px; }
.md-tooltip.md-origin-bottom {
-webkit-transform-origin: center top;
transform-origin: center top;
margin-top: 24px; }
.md-tooltip.md-origin-left {
-webkit-transform-origin: right center;
transform-origin: right center;
margin-left: -24px; }
@media (min-width: 960px) {
.md-tooltip {
font-size: 10px;
height: 22px;
line-height: 22px;
padding-right: 8px;
padding-left: 8px; }
.md-tooltip.md-origin-top {
margin-top: -14px; }
.md-tooltip.md-origin-right {
margin-left: 14px; }
.md-tooltip.md-origin-bottom {
margin-top: 14px; }
.md-tooltip.md-origin-left {
margin-left: -14px; } }
.md-tooltip.md-show-add {
-webkit-transform: scale(0);
transform: scale(0); }
.md-tooltip.md-show {
-webkit-transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
-webkit-transform: scale(1);
transform: scale(1);
opacity: 0.9; }
.md-tooltip.md-hide {
-webkit-transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2);
transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2);
-webkit-transition-duration: .1s;
transition-duration: .1s;
-webkit-transform: scale(0);
transform: scale(0);
opacity: 0; }

View File

@@ -0,0 +1,480 @@
/*!
* Angular Material Design
* https://github.com/angular/material
* @license MIT
* v1.1.3
*/
(function( window, angular, undefined ){
"use strict";
/**
* @ngdoc module
* @name material.components.tooltip
*/
MdTooltipDirective['$inject'] = ["$timeout", "$window", "$$rAF", "$document", "$interpolate", "$mdUtil", "$mdPanel", "$$mdTooltipRegistry"];
angular
.module('material.components.tooltip', [
'material.core',
'material.components.panel'
])
.directive('mdTooltip', MdTooltipDirective)
.service('$$mdTooltipRegistry', MdTooltipRegistry);
/**
* @ngdoc directive
* @name mdTooltip
* @module material.components.tooltip
* @description
* Tooltips are used to describe elements that are interactive and primarily
* graphical (not textual).
*
* Place a `<md-tooltip>` as a child of the element it describes.
*
* A tooltip will activate when the user hovers over, focuses, or touches the
* parent element.
*
* @usage
* <hljs lang="html">
* <md-button class="md-fab md-accent" aria-label="Play">
* <md-tooltip>Play Music</md-tooltip>
* <md-icon md-svg-src="img/icons/ic_play_arrow_24px.svg"></md-icon>
* </md-button>
* </hljs>
*
* @param {number=} md-z-index The visual level that the tooltip will appear
* in comparison with the rest of the elements of the application.
* @param {expression=} md-visible Boolean bound to whether the tooltip is
* currently visible.
* @param {number=} md-delay How many milliseconds to wait to show the tooltip
* after the user hovers over, focuses, or touches the parent element.
* Defaults to 0ms on non-touch devices and 75ms on touch.
* @param {boolean=} md-autohide If present or provided with a boolean value,
* the tooltip will hide on mouse leave, regardless of focus.
* @param {string=} md-direction The direction that the tooltip is shown,
* relative to the parent element. Supports top, right, bottom, and left.
* Defaults to bottom.
*/
function MdTooltipDirective($timeout, $window, $$rAF, $document, $interpolate,
$mdUtil, $mdPanel, $$mdTooltipRegistry) {
var ENTER_EVENTS = 'focus touchstart mouseenter';
var LEAVE_EVENTS = 'blur touchcancel mouseleave';
var TOOLTIP_DEFAULT_Z_INDEX = 100;
var TOOLTIP_DEFAULT_SHOW_DELAY = 0;
var TOOLTIP_DEFAULT_DIRECTION = 'bottom';
var TOOLTIP_DIRECTIONS = {
top: { x: $mdPanel.xPosition.CENTER, y: $mdPanel.yPosition.ABOVE },
right: { x: $mdPanel.xPosition.OFFSET_END, y: $mdPanel.yPosition.CENTER },
bottom: { x: $mdPanel.xPosition.CENTER, y: $mdPanel.yPosition.BELOW },
left: { x: $mdPanel.xPosition.OFFSET_START, y: $mdPanel.yPosition.CENTER }
};
return {
restrict: 'E',
priority: 210, // Before ngAria
scope: {
mdZIndex: '=?mdZIndex',
mdDelay: '=?mdDelay',
mdVisible: '=?mdVisible',
mdAutohide: '=?mdAutohide',
mdDirection: '@?mdDirection' // Do not expect expressions.
},
link: linkFunc
};
function linkFunc(scope, element, attr) {
// Set constants.
var parent = $mdUtil.getParentWithPointerEvents(element);
var debouncedOnResize = $$rAF.throttle(updatePosition);
var mouseActive = false;
var origin, position, panelPosition, panelRef, autohide, showTimeout,
elementFocusedOnWindowBlur = null;
// Set defaults
setDefaults();
// Set parent aria-label.
addAriaLabel();
// Remove the element from its current DOM position.
element.detach();
updatePosition();
bindEvents();
configureWatchers();
function setDefaults() {
scope.mdZIndex = scope.mdZIndex || TOOLTIP_DEFAULT_Z_INDEX;
scope.mdDelay = scope.mdDelay || TOOLTIP_DEFAULT_SHOW_DELAY;
if (!TOOLTIP_DIRECTIONS[scope.mdDirection]) {
scope.mdDirection = TOOLTIP_DEFAULT_DIRECTION;
}
}
function addAriaLabel(override) {
if (override || !parent.attr('aria-label')) {
// Only interpolate the text from the HTML element because otherwise the custom text
// could be interpolated twice and cause XSS violations.
var interpolatedText = override || $interpolate(element.text().trim())(scope.$parent);
parent.attr('aria-label', interpolatedText);
}
}
function updatePosition() {
setDefaults();
// If the panel has already been created, remove the current origin
// class from the panel element.
if (panelRef && panelRef.panelEl) {
panelRef.panelEl.removeClass(origin);
}
// Set the panel element origin class based off of the current
// mdDirection.
origin = 'md-origin-' + scope.mdDirection;
// Create the position of the panel based off of the mdDirection.
position = TOOLTIP_DIRECTIONS[scope.mdDirection];
// Using the newly created position object, use the MdPanel
// panelPosition API to build the panel's position.
panelPosition = $mdPanel.newPanelPosition()
.relativeTo(parent)
.addPanelPosition(position.x, position.y);
// If the panel has already been created, add the new origin class to
// the panel element and update it's position with the panelPosition.
if (panelRef && panelRef.panelEl) {
panelRef.panelEl.addClass(origin);
panelRef.updatePosition(panelPosition);
}
}
function bindEvents() {
// Add a mutationObserver where there is support for it and the need
// for it in the form of viable host(parent[0]).
if (parent[0] && 'MutationObserver' in $window) {
// Use a mutationObserver to tackle #2602.
var attributeObserver = new MutationObserver(function(mutations) {
if (isDisabledMutation(mutations)) {
$mdUtil.nextTick(function() {
setVisible(false);
});
}
});
attributeObserver.observe(parent[0], {
attributes: true
});
}
elementFocusedOnWindowBlur = false;
$$mdTooltipRegistry.register('scroll', windowScrollEventHandler, true);
$$mdTooltipRegistry.register('blur', windowBlurEventHandler);
$$mdTooltipRegistry.register('resize', debouncedOnResize);
scope.$on('$destroy', onDestroy);
// To avoid 'synthetic clicks', we listen to mousedown instead of
// 'click'.
parent.on('mousedown', mousedownEventHandler);
parent.on(ENTER_EVENTS, enterEventHandler);
function isDisabledMutation(mutations) {
mutations.some(function(mutation) {
return mutation.attributeName === 'disabled' && parent[0].disabled;
});
return false;
}
function windowScrollEventHandler() {
setVisible(false);
}
function windowBlurEventHandler() {
elementFocusedOnWindowBlur = document.activeElement === parent[0];
}
function enterEventHandler($event) {
// Prevent the tooltip from showing when the window is receiving
// focus.
if ($event.type === 'focus' && elementFocusedOnWindowBlur) {
elementFocusedOnWindowBlur = false;
} else if (!scope.mdVisible) {
parent.on(LEAVE_EVENTS, leaveEventHandler);
setVisible(true);
// If the user is on a touch device, we should bind the tap away
// after the 'touched' in order to prevent the tooltip being
// removed immediately.
if ($event.type === 'touchstart') {
parent.one('touchend', function() {
$mdUtil.nextTick(function() {
$document.one('touchend', leaveEventHandler);
}, false);
});
}
}
}
function leaveEventHandler() {
autohide = scope.hasOwnProperty('mdAutohide') ?
scope.mdAutohide :
attr.hasOwnProperty('mdAutohide');
if (autohide || mouseActive ||
$document[0].activeElement !== parent[0]) {
// When a show timeout is currently in progress, then we have
// to cancel it, otherwise the tooltip will remain showing
// without focus or hover.
if (showTimeout) {
$timeout.cancel(showTimeout);
setVisible.queued = false;
showTimeout = null;
}
parent.off(LEAVE_EVENTS, leaveEventHandler);
parent.triggerHandler('blur');
setVisible(false);
}
mouseActive = false;
}
function mousedownEventHandler() {
mouseActive = true;
}
function onDestroy() {
$$mdTooltipRegistry.deregister('scroll', windowScrollEventHandler, true);
$$mdTooltipRegistry.deregister('blur', windowBlurEventHandler);
$$mdTooltipRegistry.deregister('resize', debouncedOnResize);
parent
.off(ENTER_EVENTS, enterEventHandler)
.off(LEAVE_EVENTS, leaveEventHandler)
.off('mousedown', mousedownEventHandler);
// Trigger the handler in case any of the tooltips are
// still visible.
leaveEventHandler();
attributeObserver && attributeObserver.disconnect();
}
}
function configureWatchers() {
if (element[0] && 'MutationObserver' in $window) {
var attributeObserver = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.attributeName === 'md-visible' &&
!scope.visibleWatcher ) {
scope.visibleWatcher = scope.$watch('mdVisible',
onVisibleChanged);
}
});
});
attributeObserver.observe(element[0], {
attributes: true
});
// Build watcher only if mdVisible is being used.
if (attr.hasOwnProperty('mdVisible')) {
scope.visibleWatcher = scope.$watch('mdVisible',
onVisibleChanged);
}
} else {
// MutationObserver not supported
scope.visibleWatcher = scope.$watch('mdVisible', onVisibleChanged);
}
// Direction watcher
scope.$watch('mdDirection', updatePosition);
// Clean up if the element or parent was removed via jqLite's .remove.
// A couple of notes:
// - In these cases the scope might not have been destroyed, which
// is why we destroy it manually. An example of this can be having
// `md-visible="false"` and adding tooltips while they're
// invisible. If `md-visible` becomes true, at some point, you'd
// usually get a lot of tooltips.
// - We use `.one`, not `.on`, because this only needs to fire once.
// If we were using `.on`, it would get thrown into an infinite
// loop.
// - This kicks off the scope's `$destroy` event which finishes the
// cleanup.
element.one('$destroy', onElementDestroy);
parent.one('$destroy', onElementDestroy);
scope.$on('$destroy', function() {
setVisible(false);
panelRef && panelRef.destroy();
attributeObserver && attributeObserver.disconnect();
element.remove();
});
// Updates the aria-label when the element text changes. This watch
// doesn't need to be set up if the element doesn't have any data
// bindings.
if (element.text().indexOf($interpolate.startSymbol()) > -1) {
scope.$watch(function() {
return element.text().trim();
}, addAriaLabel);
}
function onElementDestroy() {
scope.$destroy();
}
}
function setVisible(value) {
// Break if passed value is already in queue or there is no queue and
// passed value is current in the controller.
if (setVisible.queued && setVisible.value === !!value ||
!setVisible.queued && scope.mdVisible === !!value) {
return;
}
setVisible.value = !!value;
if (!setVisible.queued) {
if (value) {
setVisible.queued = true;
showTimeout = $timeout(function() {
scope.mdVisible = setVisible.value;
setVisible.queued = false;
showTimeout = null;
if (!scope.visibleWatcher) {
onVisibleChanged(scope.mdVisible);
}
}, scope.mdDelay);
} else {
$mdUtil.nextTick(function() {
scope.mdVisible = false;
if (!scope.visibleWatcher) {
onVisibleChanged(false);
}
});
}
}
}
function onVisibleChanged(isVisible) {
isVisible ? showTooltip() : hideTooltip();
}
function showTooltip() {
// Do not show the tooltip if the text is empty.
if (!element[0].textContent.trim()) {
throw new Error('Text for the tooltip has not been provided. ' +
'Please include text within the mdTooltip element.');
}
if (!panelRef) {
var id = 'tooltip-' + $mdUtil.nextUid();
var attachTo = angular.element(document.body);
var panelAnimation = $mdPanel.newPanelAnimation()
.openFrom(parent)
.closeTo(parent)
.withAnimation({
open: 'md-show',
close: 'md-hide'
});
var panelConfig = {
id: id,
attachTo: attachTo,
contentElement: element,
propagateContainerEvents: true,
panelClass: 'md-tooltip ' + origin,
animation: panelAnimation,
position: panelPosition,
zIndex: scope.mdZIndex,
focusOnOpen: false
};
panelRef = $mdPanel.create(panelConfig);
}
panelRef.open().then(function() {
panelRef.panelEl.attr('role', 'tooltip');
});
}
function hideTooltip() {
panelRef && panelRef.close();
}
}
}
/**
* Service that is used to reduce the amount of listeners that are being
* registered on the `window` by the tooltip component. Works by collecting
* the individual event handlers and dispatching them from a global handler.
*
* ngInject
*/
function MdTooltipRegistry() {
var listeners = {};
var ngWindow = angular.element(window);
return {
register: register,
deregister: deregister
};
/**
* Global event handler that dispatches the registered handlers in the
* service.
* @param {!Event} event Event object passed in by the browser
*/
function globalEventHandler(event) {
if (listeners[event.type]) {
listeners[event.type].forEach(function(currentHandler) {
currentHandler.call(this, event);
}, this);
}
}
/**
* Registers a new handler with the service.
* @param {string} type Type of event to be registered.
* @param {!Function} handler Event handler.
* @param {boolean} useCapture Whether to use event capturing.
*/
function register(type, handler, useCapture) {
var handlers = listeners[type] = listeners[type] || [];
if (!handlers.length) {
useCapture ? window.addEventListener(type, globalEventHandler, true) :
ngWindow.on(type, globalEventHandler);
}
if (handlers.indexOf(handler) === -1) {
handlers.push(handler);
}
}
/**
* Removes an event handler from the service.
* @param {string} type Type of event handler.
* @param {!Function} handler The event handler itself.
* @param {boolean} useCapture Whether the event handler used event capturing.
*/
function deregister(type, handler, useCapture) {
var handlers = listeners[type];
var index = handlers ? handlers.indexOf(handler) : -1;
if (index > -1) {
handlers.splice(index, 1);
if (handlers.length === 0) {
useCapture ? window.removeEventListener(type, globalEventHandler, true) :
ngWindow.off(type, globalEventHandler);
}
}
}
}
})(window, window.angular);

View File

@@ -0,0 +1,6 @@
/*!
* Angular Material Design
* https://github.com/angular/material
* @license MIT
* v1.1.2-master-a9ba340
*/.md-tooltip{pointer-events:none;border-radius:4px;overflow:hidden;opacity:0;font-weight:500;font-size:14px;white-space:nowrap;text-overflow:ellipsis;height:32px;line-height:32px;padding-right:16px;padding-left:16px}.md-tooltip.md-origin-top{-webkit-transform-origin:center bottom;transform-origin:center bottom;margin-top:-24px}.md-tooltip.md-origin-right{-webkit-transform-origin:left center;transform-origin:left center;margin-left:24px}.md-tooltip.md-origin-bottom{-webkit-transform-origin:center top;transform-origin:center top;margin-top:24px}.md-tooltip.md-origin-left{-webkit-transform-origin:right center;transform-origin:right center;margin-left:-24px}@media (min-width:960px){.md-tooltip{font-size:10px;height:22px;line-height:22px;padding-right:8px;padding-left:8px}.md-tooltip.md-origin-top{margin-top:-14px}.md-tooltip.md-origin-right{margin-left:14px}.md-tooltip.md-origin-bottom{margin-top:14px}.md-tooltip.md-origin-left{margin-left:-14px}}.md-tooltip.md-show-add{-webkit-transform:scale(0);transform:scale(0)}.md-tooltip.md-show{-webkit-transition:all .4s cubic-bezier(.25,.8,.25,1);transition:all .4s cubic-bezier(.25,.8,.25,1);-webkit-transform:scale(1);transform:scale(1);opacity:.9}.md-tooltip.md-hide{-webkit-transition:all .3s cubic-bezier(.55,0,.55,.2);transition:all .3s cubic-bezier(.55,0,.55,.2);-webkit-transition-duration:.1s;transition-duration:.1s;-webkit-transform:scale(0);transform:scale(0);opacity:0}

View File

@@ -0,0 +1,7 @@
/*!
* Angular Material Design
* https://github.com/angular/material
* @license MIT
* v1.1.2-master-a9ba340
*/
!function(e,t,n){"use strict";function i(e,n,i,o,r,d,l,a){function s(s,p,v){function y(){s.mdZIndex=s.mdZIndex||m,s.mdDelay=s.mdDelay||f,b[s.mdDirection]||(s.mdDirection=h)}function E(e){if(e||!R.attr("aria-label")){var t=e||r(p.text().trim())(s.$parent);R.attr("aria-label",t)}}function x(){y(),C&&C.panelEl&&C.panelEl.removeClass(D),D="md-origin-"+s.mdDirection,V=b[s.mdDirection],A=l.newPanelPosition().relativeTo(R).addPanelPosition(V.x,V.y),C&&C.panelEl&&(C.panelEl.addClass(D),C.updatePosition(A))}function $(){function t(e){return e.some(function(e){return"disabled"===e.attributeName&&R[0].disabled}),!1}function i(){P(!1)}function r(){I=document.activeElement===R[0]}function l(e){"focus"===e.type&&I?I=!1:s.mdVisible||(R.on(u,m),P(!0),"touchstart"===e.type&&R.one("touchend",function(){d.nextTick(function(){o.one("touchend",m)},!1)}))}function m(){W=s.hasOwnProperty("mdAutohide")?s.mdAutohide:v.hasOwnProperty("mdAutohide"),(W||F||o[0].activeElement!==R[0])&&(N&&(e.cancel(N),P.queued=!1,N=null),R.off(u,m),R.triggerHandler("blur"),P(!1)),F=!1}function f(){F=!0}function h(){a.deregister("scroll",i,!0),a.deregister("blur",r),a.deregister("resize",q),R.off(c,l).off(u,m).off("mousedown",f),m(),b&&b.disconnect()}if(R[0]&&"MutationObserver"in n){var b=new MutationObserver(function(e){t(e)&&d.nextTick(function(){P(!1)})});b.observe(R[0],{attributes:!0})}I=!1,a.register("scroll",i,!0),a.register("blur",r),a.register("resize",q),s.$on("$destroy",h),R.on("mousedown",f),R.on(c,l)}function w(){function e(){s.$destroy()}if(p[0]&&"MutationObserver"in n){var t=new MutationObserver(function(e){e.forEach(function(e){"md-visible"!==e.attributeName||s.visibleWatcher||(s.visibleWatcher=s.$watch("mdVisible",g))})});t.observe(p[0],{attributes:!0}),v.hasOwnProperty("mdVisible")&&(s.visibleWatcher=s.$watch("mdVisible",g))}else s.visibleWatcher=s.$watch("mdVisible",g);s.$watch("mdDirection",x),p.one("$destroy",e),R.one("$destroy",e),s.$on("$destroy",function(){P(!1),C&&C.destroy(),t&&t.disconnect(),p.remove()}),p.text().indexOf(r.startSymbol())>-1&&s.$watch(function(){return p.text().trim()},E)}function P(t){P.queued&&P.value===!!t||!P.queued&&s.mdVisible===!!t||(P.value=!!t,P.queued||(t?(P.queued=!0,N=e(function(){s.mdVisible=P.value,P.queued=!1,N=null,s.visibleWatcher||g(s.mdVisible)},s.mdDelay)):d.nextTick(function(){s.mdVisible=!1,s.visibleWatcher||g(!1)})))}function g(e){e?T():O()}function T(){if(!p[0].textContent.trim())throw new Error("Text for the tooltip has not been provided. Please include text within the mdTooltip element.");if(!C){var e="tooltip-"+d.nextUid(),n=t.element(document.body),i=l.newPanelAnimation().openFrom(R).closeTo(R).withAnimation({open:"md-show",close:"md-hide"}),o={id:e,attachTo:n,contentElement:p,propagateContainerEvents:!0,panelClass:"md-tooltip "+D,animation:i,position:A,zIndex:s.mdZIndex,focusOnOpen:!1};C=l.create(o)}C.open().then(function(){C.panelEl.attr("role","tooltip")})}function O(){C&&C.close()}var D,V,A,C,W,N,R=d.getParentWithPointerEvents(p),q=i.throttle(x),F=!1,I=null;y(),E(),p.detach(),x(),$(),w()}var c="focus touchstart mouseenter",u="blur touchcancel mouseleave",m=100,f=0,h="bottom",b={top:{x:l.xPosition.CENTER,y:l.yPosition.ABOVE},right:{x:l.xPosition.OFFSET_END,y:l.yPosition.CENTER},bottom:{x:l.xPosition.CENTER,y:l.yPosition.BELOW},left:{x:l.xPosition.OFFSET_START,y:l.yPosition.CENTER}};return{restrict:"E",priority:210,scope:{mdZIndex:"=?mdZIndex",mdDelay:"=?mdDelay",mdVisible:"=?mdVisible",mdAutohide:"=?mdAutohide",mdDirection:"@?mdDirection"},link:s}}function o(){function n(e){r[e.type]&&r[e.type].forEach(function(t){t.call(this,e)},this)}function i(t,i,o){var l=r[t]=r[t]||[];l.length||(o?e.addEventListener(t,n,!0):d.on(t,n)),l.indexOf(i)===-1&&l.push(i)}function o(t,i,o){var l=r[t],a=l?l.indexOf(i):-1;a>-1&&(l.splice(a,1),0===l.length&&(o?e.removeEventListener(t,n,!0):d.off(t,n)))}var r={},d=t.element(e);return{register:i,deregister:o}}i.$inject=["$timeout","$window","$$rAF","$document","$interpolate","$mdUtil","$mdPanel","$$mdTooltipRegistry"],t.module("material.components.tooltip",["material.core","material.components.panel"]).directive("mdTooltip",i).service("$$mdTooltipRegistry",o)}(window,window.angular);