Carga
Carga
This commit is contained in:
@@ -0,0 +1,226 @@
|
||||
/* *
|
||||
*
|
||||
* (c) 2009-2021 Øystein Moseng
|
||||
*
|
||||
* Proxy elements are used to shadow SVG elements in HTML for assistive
|
||||
* technology, such as screen readers or voice input software.
|
||||
*
|
||||
* The ProxyElement class represents such an element, and deals with
|
||||
* overlay positioning and mirroring events for the target.
|
||||
*
|
||||
* License: www.highcharts.com/license
|
||||
*
|
||||
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
||||
*
|
||||
* */
|
||||
'use strict';
|
||||
import H from '../Core/Globals.js';
|
||||
var doc = H.doc;
|
||||
import U from '../Core/Utilities.js';
|
||||
var attr = U.attr, css = U.css, merge = U.merge;
|
||||
import EventProvider from './Utils/EventProvider.js';
|
||||
import ChartUtilities from './Utils/ChartUtilities.js';
|
||||
var fireEventOnWrappedOrUnwrappedElement = ChartUtilities.fireEventOnWrappedOrUnwrappedElement;
|
||||
import HTMLUtilities from './Utils/HTMLUtilities.js';
|
||||
var cloneMouseEvent = HTMLUtilities.cloneMouseEvent, cloneTouchEvent = HTMLUtilities.cloneTouchEvent, getFakeMouseEvent = HTMLUtilities.getFakeMouseEvent, removeElement = HTMLUtilities.removeElement;
|
||||
/* *
|
||||
*
|
||||
* Class
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Represents a proxy element that overlays a target and relays events
|
||||
* to its target.
|
||||
*
|
||||
* @private
|
||||
* @class
|
||||
*/
|
||||
var ProxyElement = /** @class */ (function () {
|
||||
/* *
|
||||
*
|
||||
* Constructor
|
||||
*
|
||||
* */
|
||||
function ProxyElement(chart, target, groupType, attributes) {
|
||||
this.chart = chart;
|
||||
this.target = target;
|
||||
this.groupType = groupType;
|
||||
var isListItem = groupType === 'ul';
|
||||
this.eventProvider = new EventProvider();
|
||||
var wrapperEl = isListItem ? doc.createElement('li') : null;
|
||||
var btnEl = this.buttonElement = doc.createElement('button');
|
||||
if (!chart.styledMode) {
|
||||
this.hideButtonVisually(btnEl);
|
||||
}
|
||||
if (wrapperEl) {
|
||||
if (isListItem && !chart.styledMode) {
|
||||
wrapperEl.style.listStyle = 'none';
|
||||
}
|
||||
wrapperEl.appendChild(btnEl);
|
||||
this.element = wrapperEl;
|
||||
}
|
||||
else {
|
||||
this.element = btnEl;
|
||||
}
|
||||
this.updateTarget(target, attributes);
|
||||
}
|
||||
/* *
|
||||
*
|
||||
* Functions
|
||||
*
|
||||
* */
|
||||
/* eslint-disable valid-jsdoc */
|
||||
/**
|
||||
* Fake a click event on the target.
|
||||
*/
|
||||
ProxyElement.prototype.click = function () {
|
||||
var pos = this.getTargetPosition();
|
||||
pos.x += pos.width / 2;
|
||||
pos.y += pos.height / 2;
|
||||
var fakeEventObject = getFakeMouseEvent('click', pos);
|
||||
fireEventOnWrappedOrUnwrappedElement(this.target.click, fakeEventObject);
|
||||
};
|
||||
/**
|
||||
* Update the target to be proxied. The position and events are updated to
|
||||
* match the new target.
|
||||
* @param target The new target definition
|
||||
* @param attributes New HTML attributes to apply to the button. Set an
|
||||
* attribute to null to remove.
|
||||
*/
|
||||
ProxyElement.prototype.updateTarget = function (target, attributes) {
|
||||
this.target = target;
|
||||
this.updateCSSClassName();
|
||||
var attrs = attributes || {};
|
||||
Object.keys(attrs).forEach(function (a) {
|
||||
if (attrs[a] === null) {
|
||||
delete attrs[a];
|
||||
}
|
||||
});
|
||||
attr(this.buttonElement, merge({
|
||||
'aria-label': this.getTargetAttr(target.click, 'aria-label')
|
||||
}, attrs));
|
||||
this.eventProvider.removeAddedEvents();
|
||||
this.addProxyEventsToButton(this.buttonElement, target.click);
|
||||
this.refreshPosition();
|
||||
};
|
||||
/**
|
||||
* Refresh the position of the proxy element to match the current target
|
||||
*/
|
||||
ProxyElement.prototype.refreshPosition = function () {
|
||||
var bBox = this.getTargetPosition();
|
||||
css(this.buttonElement, {
|
||||
width: (bBox.width || 1) + 'px',
|
||||
height: (bBox.height || 1) + 'px',
|
||||
left: (Math.round(bBox.x) || 0) + 'px',
|
||||
top: (Math.round(bBox.y) || 0) + 'px'
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Remove button from DOM, and clear events.
|
||||
*/
|
||||
ProxyElement.prototype.remove = function () {
|
||||
this.eventProvider.removeAddedEvents();
|
||||
removeElement(this.element);
|
||||
};
|
||||
// -------------------------- private ------------------------------------
|
||||
/**
|
||||
* Update the CSS class name to match target
|
||||
*/
|
||||
ProxyElement.prototype.updateCSSClassName = function () {
|
||||
var stringHasNoTooltip = function (s) { return (s.indexOf('highcharts-no-tooltip') > -1); };
|
||||
var legend = this.chart.legend;
|
||||
var groupDiv = legend.group && legend.group.div;
|
||||
var noTooltipOnGroup = stringHasNoTooltip(groupDiv && groupDiv.className || '');
|
||||
var targetClassName = this.getTargetAttr(this.target.click, 'class') || '';
|
||||
var noTooltipOnTarget = stringHasNoTooltip(targetClassName);
|
||||
this.buttonElement.className = noTooltipOnGroup || noTooltipOnTarget ?
|
||||
'highcharts-a11y-proxy-button highcharts-no-tooltip' :
|
||||
'highcharts-a11y-proxy-button';
|
||||
};
|
||||
/**
|
||||
* Mirror events for a proxy button to a target
|
||||
*/
|
||||
ProxyElement.prototype.addProxyEventsToButton = function (button, target) {
|
||||
var _this = this;
|
||||
[
|
||||
'click', 'touchstart', 'touchend', 'touchcancel', 'touchmove',
|
||||
'mouseover', 'mouseenter', 'mouseleave', 'mouseout'
|
||||
].forEach(function (evtType) {
|
||||
var isTouchEvent = evtType.indexOf('touch') === 0;
|
||||
_this.eventProvider.addEvent(button, evtType, function (e) {
|
||||
var clonedEvent = isTouchEvent ?
|
||||
cloneTouchEvent(e) :
|
||||
cloneMouseEvent(e);
|
||||
if (target) {
|
||||
fireEventOnWrappedOrUnwrappedElement(target, clonedEvent);
|
||||
}
|
||||
e.stopPropagation();
|
||||
// #9682, #15318: Touch scrolling didnt work when touching
|
||||
// proxy
|
||||
if (!isTouchEvent) {
|
||||
e.preventDefault();
|
||||
}
|
||||
}, { passive: false });
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Set visually hidden style on a proxy button
|
||||
*/
|
||||
ProxyElement.prototype.hideButtonVisually = function (button) {
|
||||
css(button, {
|
||||
borderWidth: 0,
|
||||
backgroundColor: 'transparent',
|
||||
cursor: 'pointer',
|
||||
outline: 'none',
|
||||
opacity: 0.001,
|
||||
filter: 'alpha(opacity=1)',
|
||||
zIndex: 999,
|
||||
overflow: 'hidden',
|
||||
padding: 0,
|
||||
margin: 0,
|
||||
display: 'block',
|
||||
position: 'absolute',
|
||||
'-ms-filter': 'progid:DXImageTransform.Microsoft.Alpha(Opacity=1)'
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Get the position relative to chart container for the target
|
||||
*/
|
||||
ProxyElement.prototype.getTargetPosition = function () {
|
||||
var clickTarget = this.target.click;
|
||||
// We accept both DOM elements and wrapped elements as click targets.
|
||||
var clickTargetElement = clickTarget.element ?
|
||||
clickTarget.element :
|
||||
clickTarget;
|
||||
var posElement = this.target.visual || clickTargetElement;
|
||||
var chartDiv = this.chart.renderTo;
|
||||
if (chartDiv && posElement && posElement.getBoundingClientRect) {
|
||||
var rectEl = posElement.getBoundingClientRect(), chartPos = this.chart.pointer.getChartPosition();
|
||||
return {
|
||||
x: (rectEl.left - chartPos.left) / chartPos.scaleX,
|
||||
y: (rectEl.top - chartPos.top) / chartPos.scaleY,
|
||||
width: rectEl.right / chartPos.scaleX -
|
||||
rectEl.left / chartPos.scaleX,
|
||||
height: rectEl.bottom / chartPos.scaleY -
|
||||
rectEl.top / chartPos.scaleY
|
||||
};
|
||||
}
|
||||
return { x: 0, y: 0, width: 1, height: 1 };
|
||||
};
|
||||
/**
|
||||
* Get an attribute value of a target
|
||||
*/
|
||||
ProxyElement.prototype.getTargetAttr = function (target, key) {
|
||||
if (target.element) {
|
||||
return target.element.getAttribute(key);
|
||||
}
|
||||
return target.getAttribute(key);
|
||||
};
|
||||
return ProxyElement;
|
||||
}());
|
||||
/* *
|
||||
*
|
||||
* Default Export
|
||||
*
|
||||
* */
|
||||
export default ProxyElement;
|
||||
Reference in New Issue
Block a user