testaro 18.2.0 → 18.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/aslint/utils/aria.test.ts +12 -0
- package/aslint/utils/aria.ts +120 -0
- package/aslint/utils/async.test.ts +25 -0
- package/aslint/utils/async.ts +22 -0
- package/aslint/utils/common.test.ts +239 -0
- package/aslint/utils/common.ts +168 -0
- package/aslint/utils/console.test.ts +85 -0
- package/aslint/utils/console.ts +89 -0
- package/aslint/utils/css.test.ts +153 -0
- package/aslint/utils/css.ts +191 -0
- package/aslint/utils/dom.test.ts +627 -0
- package/aslint/utils/dom.ts +1051 -0
- package/aslint/utils/env.test.ts +14 -0
- package/aslint/utils/env.ts +8 -0
- package/aslint/utils/func.test.ts +160 -0
- package/aslint/utils/func.ts +70 -0
- package/aslint/utils/global.test.ts +12 -0
- package/aslint/utils/global.ts +25 -0
- package/aslint/utils/object.test.ts +524 -0
- package/aslint/utils/object.ts +278 -0
- package/aslint/utils/report.test.ts +56 -0
- package/aslint/utils/report.ts +36 -0
- package/aslint/utils/text.test.ts +270 -0
- package/aslint/utils/text.ts +165 -0
- package/aslint/utils/time.test.ts +43 -0
- package/aslint/utils/time.ts +33 -0
- package/package.json +1 -1
- package/procs/getSource.js +35 -0
- package/testaro/dupAtt.js +86 -108
- package/testaro/headEl.js +83 -0
- package/testaro/hrRisk.js +67 -0
- package/tests/testaro.js +2 -0
- package/validation/tests/jobs/headEl.json +67 -0
- package/validation/tests/jobs/hrRisk.json +134 -0
- package/validation/tests/targets/headEl/index.html +16 -0
- package/validation/tests/targets/hrRisk/index.html +18 -0
- /package/aslint/app/rules/aslint/{aria-role-dialog → redundant/aria-role-dialog}/aria-role-dialog.documentation.md +0 -0
- /package/aslint/app/rules/aslint/{aria-role-dialog → redundant/aria-role-dialog}/aria-role-dialog.test.ts +0 -0
- /package/aslint/app/rules/aslint/{aria-role-dialog → redundant/aria-role-dialog}/aria-role-dialog.ts +0 -0
- /package/aslint/app/rules/aslint/{capital-letters-words → redundant/capital-letters-words}/capital-letters-words.documentation.md +0 -0
- /package/aslint/app/rules/aslint/{capital-letters-words → redundant/capital-letters-words}/capital-letters-words.test.ts +0 -0
- /package/aslint/app/rules/aslint/{capital-letters-words → redundant/capital-letters-words}/capital-letters-words.ts +0 -0
- /package/aslint/app/rules/aslint/{contentinfo-landmark-only-one → redundant/contentinfo-landmark-only-one}/contentinfo-landmark-only-one.documentation.md +0 -0
- /package/aslint/app/rules/aslint/{contentinfo-landmark-only-one → redundant/contentinfo-landmark-only-one}/contentinfo-landmark-only-one.test.ts +0 -0
- /package/aslint/app/rules/aslint/{contentinfo-landmark-only-one → redundant/contentinfo-landmark-only-one}/contentinfo-landmark-only-one.ts +0 -0
- /package/aslint/app/rules/aslint/{empty-title-attribute → redundant/empty-title-attribute}/empty-title-attribute.documentation.md +0 -0
- /package/aslint/app/rules/aslint/{empty-title-attribute → redundant/empty-title-attribute}/empty-title-attribute.test.ts +0 -0
- /package/aslint/app/rules/aslint/{empty-title-attribute → redundant/empty-title-attribute}/empty-title-attribute.ts +0 -0
- /package/aslint/app/rules/aslint/{flash-content → redundant/flash-content}/flash-content.documentation.md +0 -0
- /package/aslint/app/rules/aslint/{flash-content → redundant/flash-content}/flash-content.test.ts +0 -0
- /package/aslint/app/rules/aslint/{flash-content → redundant/flash-content}/flash-content.ts +0 -0
- /package/aslint/app/rules/aslint/{font-style-italic → redundant/font-style-italic}/font-style-italic.documentation.md +0 -0
- /package/aslint/app/rules/aslint/{font-style-italic → redundant/font-style-italic}/font-style-italic.test.ts +0 -0
- /package/aslint/app/rules/aslint/{font-style-italic → redundant/font-style-italic}/font-style-italic.ts +0 -0
- /package/aslint/app/rules/aslint/{h1-must-be → redundant/h1-must-be}/h1-must-be.documentation.md +0 -0
- /package/aslint/app/rules/aslint/{h1-must-be → redundant/h1-must-be}/h1-must-be.test.ts +0 -0
- /package/aslint/app/rules/aslint/{h1-must-be → redundant/h1-must-be}/h1-must-be.ts +0 -0
- /package/aslint/app/rules/aslint/{aria-hidden-false → unimportant/aria-hidden-false}/aria-hidden-false.test.ts +0 -0
- /package/aslint/app/rules/aslint/{aria-hidden-false → unimportant/aria-hidden-false}/aria-hidden-false.ts +0 -0
- /package/aslint/app/rules/aslint/{aria-hidden-false → unimportant/aria-hidden-false}/aria-hidden.documentation.md +0 -0
- /package/aslint/app/rules/aslint/{content-editable-missing-attributes → unimportant/content-editable-missing-attributes}/content-editable-missing-attributes.docmentation.md +0 -0
- /package/aslint/app/rules/aslint/{content-editable-missing-attributes → unimportant/content-editable-missing-attributes}/content-editable-missing-attributes.test.ts +0 -0
- /package/aslint/app/rules/aslint/{content-editable-missing-attributes → unimportant/content-editable-missing-attributes}/content-editable-missing-attributes.ts +0 -0
- /package/aslint/app/rules/aslint/{elements-not-allowed-in-head → used/elements-not-allowed-in-head}/elements-not-allowed-in-head.documentation.md +0 -0
- /package/aslint/app/rules/aslint/{elements-not-allowed-in-head → used/elements-not-allowed-in-head}/elements-not-allowed-in-head.test.ts +0 -0
- /package/aslint/app/rules/aslint/{elements-not-allowed-in-head → used/elements-not-allowed-in-head}/elements-not-allowed-in-head.ts +0 -0
- /package/aslint/app/rules/aslint/{headings-sibling-unique → used/headings-sibling-unique}/headings-sibling-unique.documentation.md +0 -0
- /package/aslint/app/rules/aslint/{headings-sibling-unique → used/headings-sibling-unique}/headings-sibling-unique.test.ts +0 -0
- /package/aslint/app/rules/aslint/{headings-sibling-unique → used/headings-sibling-unique}/headings-sibling-unique.ts +0 -0
- /package/aslint/app/rules/aslint/{horizontal-rule → used/horizontal-rule}/horizontal-rule.documentation.md +0 -0
- /package/aslint/app/rules/aslint/{horizontal-rule → used/horizontal-rule}/horizontal-rule.test.ts +0 -0
- /package/aslint/app/rules/aslint/{horizontal-rule → used/horizontal-rule}/horizontal-rule.ts +0 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Global } from './global';
|
|
2
|
+
|
|
3
|
+
export class Console {
|
|
4
|
+
|
|
5
|
+
public static init(globalContext?: any): any {
|
|
6
|
+
const globalAny: any = globalContext || Global.context;
|
|
7
|
+
const consoleCountData: any = {};
|
|
8
|
+
const methods: string[] = ['assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', 'msIsIndependentlyComposed', 'profile', 'profileEnd', 'select', 'time', 'timeEnd', 'trace', 'warn'];
|
|
9
|
+
const config: any = {
|
|
10
|
+
trace: true
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const noop = (): boolean => {
|
|
14
|
+
return false;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
if (typeof globalAny.console === 'undefined') {
|
|
18
|
+
globalAny.console = {};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
globalAny.console.config = config;
|
|
22
|
+
|
|
23
|
+
if (typeof globalAny.console.count === 'undefined') {
|
|
24
|
+
globalAny.console.count = function countCalls(...args: any): any {
|
|
25
|
+
const _arguments = Array.from(args);
|
|
26
|
+
const str = String(_arguments[0]);
|
|
27
|
+
|
|
28
|
+
if (typeof consoleCountData[str] === 'number') {
|
|
29
|
+
consoleCountData[str] += 1;
|
|
30
|
+
} else {
|
|
31
|
+
consoleCountData[str] = 1;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
_arguments.shift();
|
|
35
|
+
_arguments.unshift(`${str}: ${consoleCountData[str]}`);
|
|
36
|
+
|
|
37
|
+
globalAny.console.log(globalAny.console, ..._arguments);
|
|
38
|
+
|
|
39
|
+
return consoleCountData;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (typeof globalAny.console.countReset === 'undefined') {
|
|
44
|
+
globalAny.console.countReset = function(str: string): any {
|
|
45
|
+
const title: string = String(str);
|
|
46
|
+
|
|
47
|
+
consoleCountData[title] = 0;
|
|
48
|
+
|
|
49
|
+
return consoleCountData;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
for (let i: number = 0; i < methods.length; i += 1) {
|
|
54
|
+
if (typeof globalAny.console[methods[i]] === 'undefined') {
|
|
55
|
+
globalAny.console[methods[i]] = noop;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Wrap original console method
|
|
61
|
+
* @param {object} consoleMethod - console method
|
|
62
|
+
* @param {string} methodName - console method name
|
|
63
|
+
*/
|
|
64
|
+
|
|
65
|
+
const wrapper = (methodName: string): void => {
|
|
66
|
+
const originalMethod: any = globalAny.console[methodName];
|
|
67
|
+
|
|
68
|
+
const consoleFn = (args: any): void => {
|
|
69
|
+
if (globalAny.console.config[methodName]) {
|
|
70
|
+
originalMethod.apply(globalAny.console, ...args);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
consoleFn.originalMethod = false;
|
|
75
|
+
|
|
76
|
+
globalAny.console[methodName] = consoleFn;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// Wrapping original console methods
|
|
80
|
+
const processConfig = (key: any): void => {
|
|
81
|
+
wrapper(key);
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
Object.keys(globalAny.console.config).forEach(processConfig);
|
|
85
|
+
|
|
86
|
+
return globalAny.console;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { Css } from './css';
|
|
2
|
+
|
|
3
|
+
describe('Utils', () => {
|
|
4
|
+
|
|
5
|
+
describe('Css', () => {
|
|
6
|
+
|
|
7
|
+
describe('#isLargeText', () => {
|
|
8
|
+
|
|
9
|
+
it('should indicate that text is large when font size is 14pt and font weight is bold', () => {
|
|
10
|
+
const el = document.createElement('div');
|
|
11
|
+
|
|
12
|
+
el.style.cssText = 'font-size: 14pt; font-weight: bold;';
|
|
13
|
+
document.body.appendChild(el);
|
|
14
|
+
|
|
15
|
+
const isLargeText = Css.isLargeText(el);
|
|
16
|
+
|
|
17
|
+
expect(isLargeText).toBeTruthy();
|
|
18
|
+
|
|
19
|
+
el.parentNode.removeChild(el);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should indicate that text is not large when font size is 14pt and font weight less than bold', () => {
|
|
23
|
+
const el = document.createElement('div');
|
|
24
|
+
|
|
25
|
+
el.style.cssText = 'font-size: 14pt; font-weight: normal;';
|
|
26
|
+
document.body.appendChild(el);
|
|
27
|
+
|
|
28
|
+
const isLargeText = Css.isLargeText(el);
|
|
29
|
+
|
|
30
|
+
expect(isLargeText).toBeFalsy();
|
|
31
|
+
|
|
32
|
+
el.parentNode.removeChild(el);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should indicate that text is large when font size is 18pt', () => {
|
|
36
|
+
const el = document.createElement('div');
|
|
37
|
+
|
|
38
|
+
el.style.cssText = 'font-size: 18pt;';
|
|
39
|
+
document.body.appendChild(el);
|
|
40
|
+
|
|
41
|
+
const isLargeText = Css.isLargeText(el);
|
|
42
|
+
|
|
43
|
+
expect(isLargeText).toBeTruthy();
|
|
44
|
+
|
|
45
|
+
el.parentNode.removeChild(el);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe('#getComputedStyle', () => {
|
|
51
|
+
|
|
52
|
+
it('should return style object for specified element', () => {
|
|
53
|
+
const el = document.createElement('div');
|
|
54
|
+
|
|
55
|
+
el.style.cssText = 'position: absolute';
|
|
56
|
+
document.body.appendChild(el);
|
|
57
|
+
|
|
58
|
+
const style = Css.getComputedStyle(el);
|
|
59
|
+
|
|
60
|
+
expect(style.position).toBe('absolute');
|
|
61
|
+
|
|
62
|
+
el.parentNode.removeChild(el);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
describe('#getStyle', () => {
|
|
68
|
+
|
|
69
|
+
it('should return style value for specified element and css rule', () => {
|
|
70
|
+
const el = document.createElement('div');
|
|
71
|
+
|
|
72
|
+
el.style.cssText = 'position: absolute';
|
|
73
|
+
document.body.appendChild(el);
|
|
74
|
+
|
|
75
|
+
const style = Css.getStyle(el, 'position');
|
|
76
|
+
|
|
77
|
+
expect(style).toBe('absolute');
|
|
78
|
+
el.parentNode.removeChild(el);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// TODO: maybe it's worth to check why PhantomJS and JSDOM don't return pseudo-element property value
|
|
82
|
+
if ((/PhantomJS/).test(window.navigator.userAgent) === false && (/jsdom/).test(window.navigator.userAgent) === false) {
|
|
83
|
+
|
|
84
|
+
it('should return pseudo-element and it\'s value for specified element', () => {
|
|
85
|
+
const el = document.createElement('div'),
|
|
86
|
+
cssString = 'div:after { content: "test" }',
|
|
87
|
+
head = document.head || document.getElementsByTagName('head')[0],
|
|
88
|
+
style = document.createElement('style');
|
|
89
|
+
|
|
90
|
+
style.appendChild(document.createTextNode(cssString));
|
|
91
|
+
|
|
92
|
+
head.appendChild(style);
|
|
93
|
+
document.body.appendChild(el);
|
|
94
|
+
|
|
95
|
+
const cssStyleDeclaration = Css.getStyle(el, 'content', ':after');
|
|
96
|
+
|
|
97
|
+
expect(cssStyleDeclaration).toBe('"test"');
|
|
98
|
+
|
|
99
|
+
el.parentNode.removeChild(el);
|
|
100
|
+
style.parentNode.removeChild(style);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
describe('#getActualDPI', () => {
|
|
108
|
+
|
|
109
|
+
it('should return default DPI as per testing environment', () => {
|
|
110
|
+
expect(Css.getActualDPI()).toBe(96);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
describe('#getElementBackgroundImage', () => {
|
|
116
|
+
let element: HTMLElement = null;
|
|
117
|
+
|
|
118
|
+
beforeEach(() => {
|
|
119
|
+
element = document.createElement('div');
|
|
120
|
+
document.body.appendChild(element);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
afterEach(() => {
|
|
124
|
+
element.parentNode.removeChild(element);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('should return null if theres no background image', () => {
|
|
128
|
+
expect(Css.getElementBackgroundImage(element)).toEqual(null);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('should return background image of the element', () => {
|
|
132
|
+
const imageUrl = '/abc123.jpeg';
|
|
133
|
+
|
|
134
|
+
element.style.cssText = `background-image: url("${imageUrl}");`;
|
|
135
|
+
|
|
136
|
+
expect(Css.getElementBackgroundImage(element)).toContain(imageUrl);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('should return background image of a parent element', () => {
|
|
140
|
+
const imageUrl = '/abc1234.jpeg';
|
|
141
|
+
|
|
142
|
+
element.innerHTML = '<div><div id="testElement"></div></div>';
|
|
143
|
+
element.style.cssText = `background-image: url("${imageUrl}");`;
|
|
144
|
+
|
|
145
|
+
const testElement: HTMLElement = element.querySelector('#testElement');
|
|
146
|
+
|
|
147
|
+
expect(Css.getElementBackgroundImage(testElement, true)).toContain(imageUrl);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
});
|
|
153
|
+
});
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { TinyColor } from '@ctrl/tinycolor';
|
|
2
|
+
|
|
3
|
+
import { Env } from './env';
|
|
4
|
+
import { Async } from './async';
|
|
5
|
+
import { CommonUtility } from './common';
|
|
6
|
+
import { ObjectUtility } from './object';
|
|
7
|
+
|
|
8
|
+
export class Css {
|
|
9
|
+
private static cachedDPI: number | null = null;
|
|
10
|
+
private static get floatStyle(): string {
|
|
11
|
+
return typeof document.documentElement.style.cssFloat === 'string' ? 'cssFloat' : 'styleFloat';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
constructor() { }
|
|
15
|
+
|
|
16
|
+
public static getComputedStyle(element: Element, pseudoElt?: string): CSSStyleDeclaration | null {
|
|
17
|
+
if (ObjectUtility.isHtmlElement(element)) {
|
|
18
|
+
return document && document.defaultView && document.defaultView.getComputedStyle(element, pseudoElt || null);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Note: regarding z-index - if browser is applying the z-index on a static element then the "auto" value is a correct value.
|
|
25
|
+
public static getStyle(element: Element, styleProp: string, pseudoElt?: string): string | null {
|
|
26
|
+
const isHtmlElement: boolean = ObjectUtility.isHtmlElement(element);
|
|
27
|
+
|
|
28
|
+
if (isHtmlElement === false) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (ObjectUtility.isHostMethod(window, 'getComputedStyle')) {
|
|
33
|
+
return window.getComputedStyle(element, pseudoElt || null).getPropertyValue(styleProp);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (ObjectUtility.isRealObjectProperty(document, 'defaultView')) {
|
|
37
|
+
return document && document.defaultView && document.defaultView.getComputedStyle(element, pseudoElt || null).getPropertyValue(styleProp);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public static setStyle(element: HTMLElement, style: string, value: string): void {
|
|
44
|
+
let styleProp: string = style;
|
|
45
|
+
|
|
46
|
+
if (styleProp === 'float') {
|
|
47
|
+
styleProp = Css.floatStyle;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
element.style.setProperty(styleProp, value);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public static getSize(element: Element): ClientRect | DOMRect {
|
|
54
|
+
return element.getBoundingClientRect();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
public static getBackgroundColor(element: Element): TinyColor | null {
|
|
58
|
+
let node: Element = element;
|
|
59
|
+
const backgroundStyle: string | null = Css.getStyle(node, 'background-color');
|
|
60
|
+
|
|
61
|
+
if (backgroundStyle === null) {
|
|
62
|
+
console.warn('[Css.getBackgroundColor] CSS style background color is not available for element', element);
|
|
63
|
+
|
|
64
|
+
return new TinyColor('transparent');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
let color: TinyColor = new TinyColor(backgroundStyle);
|
|
68
|
+
|
|
69
|
+
if (color.toName() !== 'transparent') {
|
|
70
|
+
return color;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
while (CommonUtility.isHtmlDocument(node) === false) {
|
|
74
|
+
const backgroundColorStyle: string | null = Css.getStyle(node, 'background-color');
|
|
75
|
+
|
|
76
|
+
color = typeof backgroundColorStyle === 'string' ? new TinyColor(backgroundColorStyle) : new TinyColor('transparent');
|
|
77
|
+
|
|
78
|
+
if (color.toName() !== 'transparent') {
|
|
79
|
+
return color;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
node = node.parentNode as Element;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (CommonUtility.isHtmlDocument(node)) {
|
|
86
|
+
color = new TinyColor('transparent');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return color;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
public static getElementBackgroundImage(element: Element, includeParents: boolean = false): string | null {
|
|
93
|
+
const elementStyles: CSSStyleDeclaration | null = Css.getComputedStyle(element);
|
|
94
|
+
|
|
95
|
+
if (elementStyles === null) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (typeof elementStyles.backgroundImage !== 'string' || ['', 'none'].includes(elementStyles.backgroundImage.trim()) === false) {
|
|
100
|
+
return elementStyles.backgroundImage;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (includeParents) {
|
|
104
|
+
let currentElement: Element | null = element.parentElement;
|
|
105
|
+
|
|
106
|
+
while (currentElement !== null) {
|
|
107
|
+
const styles: CSSStyleDeclaration | null = Css.getComputedStyle(currentElement);
|
|
108
|
+
|
|
109
|
+
if (styles) {
|
|
110
|
+
if (typeof styles.backgroundImage !== 'string' || ['', 'none'].includes(styles.backgroundImage.trim()) === false) {
|
|
111
|
+
return styles.backgroundImage;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
currentElement = currentElement.parentElement;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
public static getActualDPI(): number {
|
|
123
|
+
if (Env.isTest) {
|
|
124
|
+
return 96;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (typeof this.cachedDPI === 'number') {
|
|
128
|
+
return this.cachedDPI;
|
|
129
|
+
}
|
|
130
|
+
const dpiTestElement: HTMLDivElement = document.createElement('div');
|
|
131
|
+
|
|
132
|
+
dpiTestElement.style.position = 'fixed';
|
|
133
|
+
dpiTestElement.style.top = '-999999px';
|
|
134
|
+
dpiTestElement.style.left = '-999999px';
|
|
135
|
+
dpiTestElement.style.width = '1in';
|
|
136
|
+
dpiTestElement.style.height = '1in';
|
|
137
|
+
|
|
138
|
+
document.body.appendChild(dpiTestElement);
|
|
139
|
+
|
|
140
|
+
const elementWidthStyle: string | null = Css.getStyle(dpiTestElement, 'width');
|
|
141
|
+
const elementHeightStyle: string | null = Css.getStyle(dpiTestElement, 'height');
|
|
142
|
+
|
|
143
|
+
if (elementWidthStyle === null || elementHeightStyle === null) {
|
|
144
|
+
this.cachedDPI = 0;
|
|
145
|
+
} else {
|
|
146
|
+
this.cachedDPI = (parseInt(elementWidthStyle, 10) + parseInt(elementHeightStyle, 10)) / 2;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
dpiTestElement.remove();
|
|
151
|
+
|
|
152
|
+
const clearCachedDPI: () => void = (): void => {
|
|
153
|
+
this.cachedDPI = null;
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
Async.run(clearCachedDPI, this, 1000);
|
|
157
|
+
|
|
158
|
+
return this.cachedDPI;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
public static covertPtToPx(val: string | number, considerDPI: boolean = false): number {
|
|
162
|
+
const dpi: number = considerDPI ? this.getActualDPI() : 96;
|
|
163
|
+
|
|
164
|
+
return typeof val === 'number' || val.endsWith('px') === false ? Math.round((parseInt(val.toString(), 10) * dpi) / 72) : parseInt(val.toString(), 10);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
public static covertPxToPt(val: string | number, considerDPI: boolean = false): number {
|
|
168
|
+
const dpi: number = (considerDPI ? this.getActualDPI() : 96);
|
|
169
|
+
|
|
170
|
+
return typeof val === 'number' || val.endsWith('pt') === false ? Math.round((parseInt(val.toString(), 10) * 72) / dpi) : parseInt(val.toString(), 10);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
public static isLargeText(element: Element): boolean {
|
|
174
|
+
const elementFontSize: string | null = Css.getStyle(element, 'font-size');
|
|
175
|
+
|
|
176
|
+
if (elementFontSize === null) {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const elementFontWeight: string | null = Css.getStyle(element, 'font-weight');
|
|
181
|
+
const fontSizePt: number = Css.covertPxToPt(elementFontSize, true);
|
|
182
|
+
const isFontBold: boolean = elementFontWeight !== null && (elementFontWeight === 'bold' || parseInt(elementFontWeight, 10) >= 700);
|
|
183
|
+
|
|
184
|
+
return isFontBold && fontSizePt >= 14 || fontSizePt >= 18;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
public static isCssTextTransformUsed(element: HTMLElement): boolean {
|
|
188
|
+
return Css.getStyle(element, 'text-transform') === 'uppercase' || typeof element.style === 'object' && element.style.textTransform.toLowerCase() === 'uppercase';
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
}
|