2019-06-04 12:16:20 -04:00

226 lines
11 KiB
JavaScript

"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var Strings = require("./Strings");
var Platform_1 = require("./common/Platform");
var RenderDebouncer_1 = require("./ui/RenderDebouncer");
var Lifecycle_1 = require("./ui/Lifecycle");
var Lifecycle_2 = require("./common/Lifecycle");
var ScreenDprMonitor_1 = require("./ui/ScreenDprMonitor");
var MAX_ROWS_TO_READ = 20;
var AccessibilityManager = (function (_super) {
__extends(AccessibilityManager, _super);
function AccessibilityManager(_terminal, _dimensions) {
var _this = _super.call(this) || this;
_this._terminal = _terminal;
_this._dimensions = _dimensions;
_this._liveRegionLineCount = 0;
_this._charsToConsume = [];
_this._charsToAnnounce = '';
_this._accessibilityTreeRoot = document.createElement('div');
_this._accessibilityTreeRoot.classList.add('xterm-accessibility');
_this._rowContainer = document.createElement('div');
_this._rowContainer.classList.add('xterm-accessibility-tree');
_this._rowElements = [];
for (var i = 0; i < _this._terminal.rows; i++) {
_this._rowElements[i] = _this._createAccessibilityTreeNode();
_this._rowContainer.appendChild(_this._rowElements[i]);
}
_this._topBoundaryFocusListener = function (e) { return _this._onBoundaryFocus(e, 0); };
_this._bottomBoundaryFocusListener = function (e) { return _this._onBoundaryFocus(e, 1); };
_this._rowElements[0].addEventListener('focus', _this._topBoundaryFocusListener);
_this._rowElements[_this._rowElements.length - 1].addEventListener('focus', _this._bottomBoundaryFocusListener);
_this._refreshRowsDimensions();
_this._accessibilityTreeRoot.appendChild(_this._rowContainer);
_this._renderRowsDebouncer = new RenderDebouncer_1.RenderDebouncer(_this._renderRows.bind(_this));
_this._refreshRows();
_this._liveRegion = document.createElement('div');
_this._liveRegion.classList.add('live-region');
_this._liveRegion.setAttribute('aria-live', 'assertive');
_this._accessibilityTreeRoot.appendChild(_this._liveRegion);
_this._terminal.element.insertAdjacentElement('afterbegin', _this._accessibilityTreeRoot);
_this.register(_this._renderRowsDebouncer);
_this.register(_this._terminal.onResize(function (e) { return _this._onResize(e.rows); }));
_this.register(_this._terminal.onRender(function (e) { return _this._refreshRows(e.start, e.end); }));
_this.register(_this._terminal.onScroll(function () { return _this._refreshRows(); }));
_this.register(_this._terminal.addDisposableListener('a11y.char', function (char) { return _this._onChar(char); }));
_this.register(_this._terminal.onLineFeed(function () { return _this._onChar('\n'); }));
_this.register(_this._terminal.addDisposableListener('a11y.tab', function (spaceCount) { return _this._onTab(spaceCount); }));
_this.register(_this._terminal.onKey(function (e) { return _this._onKey(e.key); }));
_this.register(_this._terminal.addDisposableListener('blur', function () { return _this._clearLiveRegion(); }));
_this._screenDprMonitor = new ScreenDprMonitor_1.ScreenDprMonitor();
_this.register(_this._screenDprMonitor);
_this._screenDprMonitor.setListener(function () { return _this._refreshRowsDimensions(); });
_this.register(Lifecycle_1.addDisposableDomListener(window, 'resize', function () { return _this._refreshRowsDimensions(); }));
return _this;
}
AccessibilityManager.prototype.dispose = function () {
_super.prototype.dispose.call(this);
this._terminal.element.removeChild(this._accessibilityTreeRoot);
this._rowElements.length = 0;
};
AccessibilityManager.prototype._onBoundaryFocus = function (e, position) {
var boundaryElement = e.target;
var beforeBoundaryElement = this._rowElements[position === 0 ? 1 : this._rowElements.length - 2];
var posInSet = boundaryElement.getAttribute('aria-posinset');
var lastRowPos = position === 0 ? '1' : "" + this._terminal.buffer.lines.length;
if (posInSet === lastRowPos) {
return;
}
if (e.relatedTarget !== beforeBoundaryElement) {
return;
}
var topBoundaryElement;
var bottomBoundaryElement;
if (position === 0) {
topBoundaryElement = boundaryElement;
bottomBoundaryElement = this._rowElements.pop();
this._rowContainer.removeChild(bottomBoundaryElement);
}
else {
topBoundaryElement = this._rowElements.shift();
bottomBoundaryElement = boundaryElement;
this._rowContainer.removeChild(topBoundaryElement);
}
topBoundaryElement.removeEventListener('focus', this._topBoundaryFocusListener);
bottomBoundaryElement.removeEventListener('focus', this._bottomBoundaryFocusListener);
if (position === 0) {
var newElement = this._createAccessibilityTreeNode();
this._rowElements.unshift(newElement);
this._rowContainer.insertAdjacentElement('afterbegin', newElement);
}
else {
var newElement = this._createAccessibilityTreeNode();
this._rowElements.push(newElement);
this._rowContainer.appendChild(newElement);
}
this._rowElements[0].addEventListener('focus', this._topBoundaryFocusListener);
this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);
this._terminal.scrollLines(position === 0 ? -1 : 1);
this._rowElements[position === 0 ? 1 : this._rowElements.length - 2].focus();
e.preventDefault();
e.stopImmediatePropagation();
};
AccessibilityManager.prototype._onResize = function (rows) {
this._rowElements[this._rowElements.length - 1].removeEventListener('focus', this._bottomBoundaryFocusListener);
for (var i = this._rowContainer.children.length; i < this._terminal.rows; i++) {
this._rowElements[i] = this._createAccessibilityTreeNode();
this._rowContainer.appendChild(this._rowElements[i]);
}
while (this._rowElements.length > rows) {
this._rowContainer.removeChild(this._rowElements.pop());
}
this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);
this._refreshRowsDimensions();
};
AccessibilityManager.prototype._createAccessibilityTreeNode = function () {
var element = document.createElement('div');
element.setAttribute('role', 'listitem');
element.tabIndex = -1;
this._refreshRowDimensions(element);
return element;
};
AccessibilityManager.prototype._onTab = function (spaceCount) {
for (var i = 0; i < spaceCount; i++) {
this._onChar(' ');
}
};
AccessibilityManager.prototype._onChar = function (char) {
var _this = this;
if (this._liveRegionLineCount < MAX_ROWS_TO_READ + 1) {
if (this._charsToConsume.length > 0) {
var shiftedChar = this._charsToConsume.shift();
if (shiftedChar !== char) {
this._charsToAnnounce += char;
}
}
else {
this._charsToAnnounce += char;
}
if (char === '\n') {
this._liveRegionLineCount++;
if (this._liveRegionLineCount === MAX_ROWS_TO_READ + 1) {
this._liveRegion.textContent += Strings.tooMuchOutput;
}
}
if (Platform_1.isMac) {
if (this._liveRegion.textContent && this._liveRegion.textContent.length > 0 && !this._liveRegion.parentNode) {
setTimeout(function () {
_this._accessibilityTreeRoot.appendChild(_this._liveRegion);
}, 0);
}
}
}
};
AccessibilityManager.prototype._clearLiveRegion = function () {
this._liveRegion.textContent = '';
this._liveRegionLineCount = 0;
if (Platform_1.isMac) {
if (this._liveRegion.parentNode) {
this._accessibilityTreeRoot.removeChild(this._liveRegion);
}
}
};
AccessibilityManager.prototype._onKey = function (keyChar) {
this._clearLiveRegion();
this._charsToConsume.push(keyChar);
};
AccessibilityManager.prototype._refreshRows = function (start, end) {
this._renderRowsDebouncer.refresh(start, end, this._terminal.rows);
};
AccessibilityManager.prototype._renderRows = function (start, end) {
var buffer = this._terminal.buffer;
var setSize = buffer.lines.length.toString();
for (var i = start; i <= end; i++) {
var lineData = buffer.translateBufferLineToString(buffer.ydisp + i, true);
var posInSet = (buffer.ydisp + i + 1).toString();
var element = this._rowElements[i];
if (element) {
element.textContent = lineData.length === 0 ? Strings.blankLine : lineData;
element.setAttribute('aria-posinset', posInSet);
element.setAttribute('aria-setsize', setSize);
}
}
this._announceCharacters();
};
AccessibilityManager.prototype._refreshRowsDimensions = function () {
if (!this._dimensions.actualCellHeight) {
return;
}
if (this._rowElements.length !== this._terminal.rows) {
this._onResize(this._terminal.rows);
}
for (var i = 0; i < this._terminal.rows; i++) {
this._refreshRowDimensions(this._rowElements[i]);
}
};
AccessibilityManager.prototype.setDimensions = function (dimensions) {
this._dimensions = dimensions;
this._refreshRowsDimensions();
};
AccessibilityManager.prototype._refreshRowDimensions = function (element) {
element.style.height = this._dimensions.actualCellHeight + "px";
};
AccessibilityManager.prototype._announceCharacters = function () {
if (this._charsToAnnounce.length === 0) {
return;
}
this._liveRegion.textContent += this._charsToAnnounce;
this._charsToAnnounce = '';
};
return AccessibilityManager;
}(Lifecycle_2.Disposable));
exports.AccessibilityManager = AccessibilityManager;
//# sourceMappingURL=AccessibilityManager.js.map