accessibility-comms
Version:
add accessibility to your website
229 lines (209 loc) • 7.82 kB
text/typescript
'use strict';
import { ICommon, IDeployedObjects, IFormattedDim, IInjectStyleOptions, IJsonToHtml } from './interfaces/common.interface';
export class Common implements ICommon {
static DEFAULT_PIXEL = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAA1JREFUGFdj+P///38ACfsD/QVDRcoAAAAASUVORK5CYII=';
private body: HTMLBodyElement;
private deployedMap: Map<string, boolean>;
private _isIOS: boolean;
private _canvas: HTMLCanvasElement;
constructor() {
this.body = document.body || (document.querySelector('body') as any);
this.deployedMap = new Map<string, boolean>();
}
isIOS() {
if (typeof this._isIOS === 'boolean')
return this._isIOS;
const isIOS = () => {
var iDevices = [
'iPad Simulator',
'iPhone Simulator',
'iPod Simulator',
'iPad',
'iPhone',
'iPod'
];
if (!!navigator.platform) {
while (iDevices.length) {
if (navigator.platform === iDevices.pop()) { return true; }
}
}
return false;
};
this._isIOS = isIOS();
return this._isIOS;
}
jsonToHtml(obj: IJsonToHtml): HTMLElement {
let elm = document.createElement(obj.type);
for (let i in obj.attrs) {
elm.setAttribute(i, obj.attrs[i]);
}
for (let i in obj.children) {
let newElem = null as any;
if (obj.children[i].type === '#text') {
newElem = document.createTextNode(obj.children[i].text);
}
else
newElem = this.jsonToHtml(obj.children[i]);
if ((newElem && newElem.tagName && newElem.tagName.toLowerCase() !== 'undefined') || newElem.nodeType === 3)
elm.appendChild(newElem);
}
return elm;
}
injectStyle(css: string, innerOptions = {} as IInjectStyleOptions) {
let sheet = document.createElement('style');
sheet.appendChild(document.createTextNode(css));
if (innerOptions.className)
sheet.classList.add(innerOptions.className);
this.body.appendChild(sheet);
return sheet;
}
getFormattedDim(value: string): IFormattedDim {
if (!value) return null;
value = String(value);
let returnBySuffix = function (val: string, suffix: string): IFormattedDim {
return {
size: val.substring(0, val.indexOf(suffix)),
suffix: suffix
};
};
if (value.indexOf('%') > -1)
return returnBySuffix(value, '%');
if (value.indexOf('px') > -1)
return returnBySuffix(value, 'px');
if (value.indexOf('em') > -1)
return returnBySuffix(value, 'em');
if (value.indexOf('rem') > -1)
return returnBySuffix(value, 'rem');
if (value.indexOf('pt') > -1)
return returnBySuffix(value, 'pt');
if (value === 'auto')
return returnBySuffix(value, '');
}
extend(src: any, dest: any) {
for (let i in src) {
if (typeof src[i] === 'object') {
if (dest && dest[i]) {
if (dest[i] instanceof Array)
src[i] = dest[i];
else
src[i] = this.extend(src[i], dest[i]);
}
}
else if (typeof dest === 'object' && typeof dest[i] !== 'undefined') {
src[i] = dest[i];
}
}
return src;
}
injectIconsFont(urls: Array<string>, callback: Function) {
if (urls && urls.length) {
let head = document.getElementsByTagName('head')[0];
let counter = 0;
let hasErrors = false;
let onload = (e: Event) => {
hasErrors = hasErrors || e.type === '';
if (!--counter)
callback(hasErrors);
};
urls.forEach(url => {
let link = document.createElement('link');
link.type = 'text/css';
link.rel = 'stylesheet';
link.href = url;
link.className = `_access-font-icon-${counter++}`;
link.onload = onload;
link.onerror = onload;
this.deployedObjects.set('.' + link.className, true);
head.appendChild(link);
});
}
}
getFixedFont(name: string) {
if (this.isIOS())
return (name as any).replaceAll(' ', '+');
return name;
}
getFixedPseudoFont(name: string) {
if (this.isIOS())
return (name as any).replaceAll('+', ' ');
return name;
}
isFontLoaded(fontFamily?: string, callback?: Function) {
try {
const onReady = () => {
return callback((document as any).fonts.check(`1em ${(fontFamily as any).replaceAll('+', ' ')}`));
// return callback(document.fonts.check(`1em ${fontFamily}`));
};
(document as any).fonts.ready.then(() => {
onReady();
}, () => {
onReady();
});
}
catch (e) {
return callback(true);
}
}
warn(msg: string) {
let prefix = 'Accessibility: ';
if (console.warn)
console.warn(prefix + msg);
else
console.log(prefix + msg);
}
get deployedObjects(): IDeployedObjects {
return {
get: (key: string) => {
return this.deployedMap.get(key);
},
contains: (key: string) => {
return this.deployedMap.has(key);
},
set: (key: string, val: boolean) => {
this.deployedMap.set(key, val);
},
remove: (key: string) => {
this.deployedMap.delete(key);
},
getAll: () => {
return this.deployedMap;
}
};
}
createScreenshot(url: string): Promise<string> {
return new Promise((resolve: Function, reject: Function) => {
if (!this._canvas)
this._canvas = document.createElement('canvas');
const img = new Image();
this._canvas.style.position = 'fixed';
this._canvas.style.top = '0';
this._canvas.style.left = '0';
this._canvas.style.opacity = '0.05';
this._canvas.style.transform = 'scale(0.05)';
img.crossOrigin = 'anonymous';
img.onload = async () => {
document.body.appendChild(this._canvas);
const ctx = this._canvas.getContext('2d');
this._canvas.width = img.naturalWidth;
this._canvas.height = img.naturalHeight;
ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);
// await this.setTimeout(1500);
ctx.drawImage(img, 0, 0);
let res = Common.DEFAULT_PIXEL;
try {
res = this._canvas.toDataURL('image/png');
} catch (e) { }
resolve(res);
this._canvas.remove();
};
img.onerror = () => {
// Return a 1X1 pixels transparent image as a fallback
resolve(Common.DEFAULT_PIXEL);
};
img.src = url;
});
}
getFileExtension(filename: string): string {
return filename.substring(filename.lastIndexOf('.') + 1, filename.length) || filename;
}
}