happy-dom 9.18.3 → 9.19.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.

Potentially problematic release.


This version of happy-dom might be problematic. Click here for more details.

Files changed (131) hide show
  1. package/README.md +15 -1
  2. package/lib/css/CSSParser.d.ts.map +1 -1
  3. package/lib/css/CSSParser.js +16 -6
  4. package/lib/css/CSSParser.js.map +1 -1
  5. package/lib/css/declaration/AbstractCSSStyleDeclaration.d.ts +2 -2
  6. package/lib/css/declaration/AbstractCSSStyleDeclaration.d.ts.map +1 -1
  7. package/lib/css/declaration/AbstractCSSStyleDeclaration.js +2 -2
  8. package/lib/css/declaration/AbstractCSSStyleDeclaration.js.map +1 -1
  9. package/lib/css/declaration/css-parser/CSSStyleDeclarationCSSParser.d.ts.map +1 -0
  10. package/lib/css/declaration/css-parser/CSSStyleDeclarationCSSParser.js.map +1 -0
  11. package/lib/css/declaration/{utilities → element-style}/CSSStyleDeclarationElementStyle.d.ts +14 -3
  12. package/lib/css/declaration/element-style/CSSStyleDeclarationElementStyle.d.ts.map +1 -0
  13. package/lib/css/declaration/{utilities → element-style}/CSSStyleDeclarationElementStyle.js +102 -84
  14. package/lib/css/declaration/element-style/CSSStyleDeclarationElementStyle.js.map +1 -0
  15. package/lib/css/declaration/element-style/config/CSSStyleDeclarationElementDefaultCSS.d.ts.map +1 -0
  16. package/lib/css/declaration/{utilities → element-style/config}/CSSStyleDeclarationElementDefaultCSS.js +1 -1
  17. package/lib/css/declaration/element-style/config/CSSStyleDeclarationElementDefaultCSS.js.map +1 -0
  18. package/lib/css/declaration/element-style/config/CSSStyleDeclarationElementInheritedProperties.d.ts.map +1 -0
  19. package/lib/css/declaration/element-style/config/CSSStyleDeclarationElementInheritedProperties.js.map +1 -0
  20. package/lib/css/declaration/element-style/config/CSSStyleDeclarationElementMeasurementProperties.d.ts +3 -0
  21. package/lib/css/declaration/element-style/config/CSSStyleDeclarationElementMeasurementProperties.d.ts.map +1 -0
  22. package/lib/css/declaration/element-style/config/CSSStyleDeclarationElementMeasurementProperties.js +44 -0
  23. package/lib/css/declaration/element-style/config/CSSStyleDeclarationElementMeasurementProperties.js.map +1 -0
  24. package/lib/css/declaration/measurement-converter/CSSMeasurementConverter.d.ts +32 -0
  25. package/lib/css/declaration/measurement-converter/CSSMeasurementConverter.d.ts.map +1 -0
  26. package/lib/css/declaration/measurement-converter/CSSMeasurementConverter.js +70 -0
  27. package/lib/css/declaration/measurement-converter/CSSMeasurementConverter.js.map +1 -0
  28. package/lib/css/declaration/{utilities → property-manager}/CSSStyleDeclarationPropertyGetParser.d.ts +9 -0
  29. package/lib/css/declaration/property-manager/CSSStyleDeclarationPropertyGetParser.d.ts.map +1 -0
  30. package/lib/css/declaration/{utilities → property-manager}/CSSStyleDeclarationPropertyGetParser.js +38 -0
  31. package/lib/css/declaration/property-manager/CSSStyleDeclarationPropertyGetParser.js.map +1 -0
  32. package/lib/css/declaration/{utilities → property-manager}/CSSStyleDeclarationPropertyManager.d.ts +1 -1
  33. package/lib/css/declaration/property-manager/CSSStyleDeclarationPropertyManager.d.ts.map +1 -0
  34. package/lib/css/declaration/{utilities → property-manager}/CSSStyleDeclarationPropertyManager.js +32 -1
  35. package/lib/css/declaration/property-manager/CSSStyleDeclarationPropertyManager.js.map +1 -0
  36. package/lib/css/declaration/{utilities → property-manager}/CSSStyleDeclarationPropertySetParser.d.ts +90 -0
  37. package/lib/css/declaration/property-manager/CSSStyleDeclarationPropertySetParser.d.ts.map +1 -0
  38. package/lib/css/declaration/{utilities → property-manager}/CSSStyleDeclarationPropertySetParser.js +171 -25
  39. package/lib/css/declaration/property-manager/CSSStyleDeclarationPropertySetParser.js.map +1 -0
  40. package/lib/css/declaration/property-manager/CSSStyleDeclarationValueParser.d.ts.map +1 -0
  41. package/lib/css/declaration/{utilities → property-manager}/CSSStyleDeclarationValueParser.js +1 -1
  42. package/lib/css/declaration/property-manager/CSSStyleDeclarationValueParser.js.map +1 -0
  43. package/lib/css/declaration/property-manager/ICSSStyleDeclarationPropertyValue.d.ts +5 -0
  44. package/lib/css/declaration/property-manager/ICSSStyleDeclarationPropertyValue.d.ts.map +1 -0
  45. package/lib/css/declaration/property-manager/ICSSStyleDeclarationPropertyValue.js.map +1 -0
  46. package/lib/match-media/IMediaQueryRange.d.ts +12 -0
  47. package/lib/match-media/IMediaQueryRange.d.ts.map +1 -0
  48. package/lib/match-media/IMediaQueryRange.js +3 -0
  49. package/lib/match-media/IMediaQueryRange.js.map +1 -0
  50. package/lib/match-media/IMediaQueryRule.d.ts +5 -0
  51. package/lib/match-media/IMediaQueryRule.d.ts.map +1 -0
  52. package/lib/match-media/IMediaQueryRule.js +3 -0
  53. package/lib/match-media/IMediaQueryRule.js.map +1 -0
  54. package/lib/match-media/MediaQueryItem.d.ts +77 -0
  55. package/lib/match-media/MediaQueryItem.d.ts.map +1 -0
  56. package/lib/match-media/MediaQueryItem.js +283 -0
  57. package/lib/match-media/MediaQueryItem.js.map +1 -0
  58. package/lib/match-media/MediaQueryList.d.ts +18 -4
  59. package/lib/match-media/MediaQueryList.d.ts.map +1 -1
  60. package/lib/match-media/MediaQueryList.js +37 -21
  61. package/lib/match-media/MediaQueryList.js.map +1 -1
  62. package/lib/match-media/MediaQueryParser.d.ts +22 -0
  63. package/lib/match-media/MediaQueryParser.d.ts.map +1 -0
  64. package/lib/match-media/MediaQueryParser.js +112 -0
  65. package/lib/match-media/MediaQueryParser.js.map +1 -0
  66. package/lib/match-media/MediaQueryTypeEnum.d.ts +7 -0
  67. package/lib/match-media/MediaQueryTypeEnum.d.ts.map +1 -0
  68. package/lib/match-media/MediaQueryTypeEnum.js +10 -0
  69. package/lib/match-media/MediaQueryTypeEnum.js.map +1 -0
  70. package/lib/nodes/element/Element.d.ts +2 -0
  71. package/lib/nodes/element/Element.d.ts.map +1 -1
  72. package/lib/nodes/element/Element.js +1 -0
  73. package/lib/nodes/element/Element.js.map +1 -1
  74. package/lib/window/IHappyDOMOptions.d.ts +4 -0
  75. package/lib/window/IHappyDOMOptions.d.ts.map +1 -1
  76. package/lib/window/IHappyDOMSettings.d.ts +4 -0
  77. package/lib/window/IHappyDOMSettings.d.ts.map +1 -1
  78. package/lib/window/Window.d.ts +4 -0
  79. package/lib/window/Window.d.ts.map +1 -1
  80. package/lib/window/Window.js +16 -4
  81. package/lib/window/Window.js.map +1 -1
  82. package/package.json +1 -1
  83. package/src/css/CSSParser.ts +21 -6
  84. package/src/css/declaration/AbstractCSSStyleDeclaration.ts +2 -2
  85. package/src/css/declaration/{utilities → element-style}/CSSStyleDeclarationElementStyle.ts +117 -94
  86. package/src/css/declaration/{utilities → element-style/config}/CSSStyleDeclarationElementDefaultCSS.ts +1 -1
  87. package/src/css/declaration/element-style/config/CSSStyleDeclarationElementMeasurementProperties.ts +41 -0
  88. package/src/css/declaration/measurement-converter/CSSMeasurementConverter.ts +81 -0
  89. package/src/css/declaration/{utilities → property-manager}/CSSStyleDeclarationPropertyGetParser.ts +51 -0
  90. package/src/css/declaration/{utilities → property-manager}/CSSStyleDeclarationPropertyManager.ts +34 -2
  91. package/src/css/declaration/{utilities → property-manager}/CSSStyleDeclarationPropertySetParser.ts +235 -20
  92. package/src/css/declaration/{utilities → property-manager}/CSSStyleDeclarationValueParser.ts +2 -1
  93. package/src/css/declaration/{utilities → property-manager}/ICSSStyleDeclarationPropertyValue.ts +2 -2
  94. package/src/match-media/IMediaQueryRange.ts +5 -0
  95. package/src/match-media/IMediaQueryRule.ts +4 -0
  96. package/src/match-media/MediaQueryItem.ts +336 -0
  97. package/src/match-media/MediaQueryList.ts +43 -20
  98. package/src/match-media/MediaQueryParser.ts +113 -0
  99. package/src/match-media/MediaQueryTypeEnum.ts +7 -0
  100. package/src/nodes/element/Element.ts +2 -0
  101. package/src/window/IHappyDOMOptions.ts +4 -0
  102. package/src/window/IHappyDOMSettings.ts +4 -0
  103. package/src/window/Window.ts +16 -4
  104. package/lib/css/declaration/utilities/CSSStyleDeclarationCSSParser.d.ts.map +0 -1
  105. package/lib/css/declaration/utilities/CSSStyleDeclarationCSSParser.js.map +0 -1
  106. package/lib/css/declaration/utilities/CSSStyleDeclarationElementDefaultCSS.d.ts.map +0 -1
  107. package/lib/css/declaration/utilities/CSSStyleDeclarationElementDefaultCSS.js.map +0 -1
  108. package/lib/css/declaration/utilities/CSSStyleDeclarationElementInheritedProperties.d.ts.map +0 -1
  109. package/lib/css/declaration/utilities/CSSStyleDeclarationElementInheritedProperties.js.map +0 -1
  110. package/lib/css/declaration/utilities/CSSStyleDeclarationElementStyle.d.ts.map +0 -1
  111. package/lib/css/declaration/utilities/CSSStyleDeclarationElementStyle.js.map +0 -1
  112. package/lib/css/declaration/utilities/CSSStyleDeclarationPropertyGetParser.d.ts.map +0 -1
  113. package/lib/css/declaration/utilities/CSSStyleDeclarationPropertyGetParser.js.map +0 -1
  114. package/lib/css/declaration/utilities/CSSStyleDeclarationPropertyManager.d.ts.map +0 -1
  115. package/lib/css/declaration/utilities/CSSStyleDeclarationPropertyManager.js.map +0 -1
  116. package/lib/css/declaration/utilities/CSSStyleDeclarationPropertySetParser.d.ts.map +0 -1
  117. package/lib/css/declaration/utilities/CSSStyleDeclarationPropertySetParser.js.map +0 -1
  118. package/lib/css/declaration/utilities/CSSStyleDeclarationValueParser.d.ts.map +0 -1
  119. package/lib/css/declaration/utilities/CSSStyleDeclarationValueParser.js.map +0 -1
  120. package/lib/css/declaration/utilities/ICSSStyleDeclarationPropertyValue.d.ts +0 -5
  121. package/lib/css/declaration/utilities/ICSSStyleDeclarationPropertyValue.d.ts.map +0 -1
  122. package/lib/css/declaration/utilities/ICSSStyleDeclarationPropertyValue.js.map +0 -1
  123. /package/lib/css/declaration/{utilities → css-parser}/CSSStyleDeclarationCSSParser.d.ts +0 -0
  124. /package/lib/css/declaration/{utilities → css-parser}/CSSStyleDeclarationCSSParser.js +0 -0
  125. /package/lib/css/declaration/{utilities → element-style/config}/CSSStyleDeclarationElementDefaultCSS.d.ts +0 -0
  126. /package/lib/css/declaration/{utilities → element-style/config}/CSSStyleDeclarationElementInheritedProperties.d.ts +0 -0
  127. /package/lib/css/declaration/{utilities → element-style/config}/CSSStyleDeclarationElementInheritedProperties.js +0 -0
  128. /package/lib/css/declaration/{utilities → property-manager}/CSSStyleDeclarationValueParser.d.ts +0 -0
  129. /package/lib/css/declaration/{utilities → property-manager}/ICSSStyleDeclarationPropertyValue.js +0 -0
  130. /package/src/css/declaration/{utilities → css-parser}/CSSStyleDeclarationCSSParser.ts +0 -0
  131. /package/src/css/declaration/{utilities → element-style/config}/CSSStyleDeclarationElementInheritedProperties.ts +0 -0
@@ -3,18 +3,22 @@ import IElement from '../../../nodes/element/IElement';
3
3
  import IDocument from '../../../nodes/document/IDocument';
4
4
  import IHTMLStyleElement from '../../../nodes/html-style-element/IHTMLStyleElement';
5
5
  import INodeList from '../../../nodes/node/INodeList';
6
- import CSSStyleDeclarationPropertyManager from './CSSStyleDeclarationPropertyManager';
6
+ import CSSStyleDeclarationPropertyManager from '../property-manager/CSSStyleDeclarationPropertyManager';
7
7
  import NodeTypeEnum from '../../../nodes/node/NodeTypeEnum';
8
8
  import CSSRuleTypeEnum from '../../CSSRuleTypeEnum';
9
9
  import CSSMediaRule from '../../rules/CSSMediaRule';
10
10
  import CSSRule from '../../CSSRule';
11
11
  import CSSStyleRule from '../../rules/CSSStyleRule';
12
- import CSSStyleDeclarationElementDefaultCSS from './CSSStyleDeclarationElementDefaultCSS';
13
- import CSSStyleDeclarationElementInheritedProperties from './CSSStyleDeclarationElementInheritedProperties';
14
- import CSSStyleDeclarationCSSParser from './CSSStyleDeclarationCSSParser';
12
+ import CSSStyleDeclarationElementDefaultCSS from './config/CSSStyleDeclarationElementDefaultCSS';
13
+ import CSSStyleDeclarationElementInheritedProperties from './config/CSSStyleDeclarationElementInheritedProperties';
14
+ import CSSStyleDeclarationElementMeasurementProperties from './config/CSSStyleDeclarationElementMeasurementProperties';
15
+ import CSSStyleDeclarationCSSParser from '../css-parser/CSSStyleDeclarationCSSParser';
15
16
  import QuerySelector from '../../../query-selector/QuerySelector';
17
+ import CSSMeasurementConverter from '../measurement-converter/CSSMeasurementConverter';
18
+ import MediaQueryList from '../../../match-media/MediaQueryList';
16
19
 
17
20
  const CSS_VARIABLE_REGEXP = /var\( *(--[^) ]+)\)/g;
21
+ const CSS_MEASUREMENT_REGEXP = /[0-9.]+(px|rem|em|vw|vh|%|vmin|vmax|cm|mm|in|pt|pc|Q)/g;
18
22
 
19
23
  type IStyleAndElement = {
20
24
  element: IElement | IShadowRoot | IDocument;
@@ -160,98 +164,79 @@ export default class CSSStyleDeclarationElementStyle {
160
164
 
161
165
  // Concatenates all parent element CSS to one string.
162
166
  const targetElement = parentElements[parentElements.length - 1];
163
- let inheritedCSSText = '';
167
+ const propertyManager = new CSSStyleDeclarationPropertyManager();
168
+ const cssVariables: { [k: string]: string } = {};
169
+ let rootFontSize: string | number = 16;
170
+ let parentFontSize: string | number = 16;
164
171
 
165
172
  for (const parentElement of parentElements) {
166
- if (parentElement !== targetElement) {
167
- parentElement.cssTexts.sort((a, b) => a.priorityWeight - b.priorityWeight);
168
-
169
- if (CSSStyleDeclarationElementDefaultCSS[(<IElement>parentElement.element).tagName]) {
170
- inheritedCSSText +=
171
- CSSStyleDeclarationElementDefaultCSS[(<IElement>parentElement.element).tagName];
172
- }
173
+ parentElement.cssTexts.sort((a, b) => a.priorityWeight - b.priorityWeight);
173
174
 
174
- for (const cssText of parentElement.cssTexts) {
175
- inheritedCSSText += cssText.cssText;
176
- }
177
-
178
- if (parentElement.element['_attributes']['style']?.value) {
179
- inheritedCSSText += parentElement.element['_attributes']['style'].value;
180
- }
175
+ let elementCSSText = '';
176
+ if (CSSStyleDeclarationElementDefaultCSS[(<IElement>parentElement.element).tagName]) {
177
+ elementCSSText +=
178
+ CSSStyleDeclarationElementDefaultCSS[(<IElement>parentElement.element).tagName];
181
179
  }
182
- }
183
-
184
- const cssVariables: { [k: string]: string } = {};
185
- const properties = {};
186
- let targetCSSText =
187
- CSSStyleDeclarationElementDefaultCSS[(<IElement>targetElement.element).tagName] || '';
188
-
189
- targetElement.cssTexts.sort((a, b) => a.priorityWeight - b.priorityWeight);
190
-
191
- for (const cssText of targetElement.cssTexts) {
192
- targetCSSText += cssText.cssText;
193
- }
194
180
 
195
- if (targetElement.element['_attributes']['style']?.value) {
196
- targetCSSText += targetElement.element['_attributes']['style'].value;
197
- }
198
-
199
- const combinedCSSText = inheritedCSSText + targetCSSText;
200
-
201
- if (this.cache.propertyManager && this.cache.cssText === combinedCSSText) {
202
- return this.cache.propertyManager;
203
- }
204
-
205
- // Parses the parent element CSS and stores CSS variables and inherited properties.
206
- CSSStyleDeclarationCSSParser.parse(inheritedCSSText, (name, value, important) => {
207
- if (name.startsWith('--')) {
208
- const cssValue = this.getCSSValue(value, cssVariables);
209
- if (cssValue) {
210
- cssVariables[name] = cssValue;
211
- }
212
- return;
181
+ for (const cssText of parentElement.cssTexts) {
182
+ elementCSSText += cssText.cssText;
213
183
  }
214
184
 
215
- if (CSSStyleDeclarationElementInheritedProperties[name]) {
216
- const cssValue = this.getCSSValue(value, cssVariables);
217
- if (cssValue && (!properties[name]?.important || important)) {
218
- properties[name] = {
219
- value: cssValue,
220
- important
221
- };
222
- }
185
+ if (parentElement.element['_attributes']['style']?.value) {
186
+ elementCSSText += parentElement.element['_attributes']['style'].value;
223
187
  }
224
- });
225
-
226
- // Parses the target element CSS.
227
- CSSStyleDeclarationCSSParser.parse(targetCSSText, (name, value, important) => {
228
- if (name.startsWith('--')) {
229
- const cssValue = this.getCSSValue(value, cssVariables);
230
- if (cssValue && (!properties[name]?.important || important)) {
231
- cssVariables[name] = cssValue;
232
- properties[name] = {
233
- value,
234
- important
235
- };
188
+
189
+ CSSStyleDeclarationCSSParser.parse(elementCSSText, (name, value, important) => {
190
+ if (name.startsWith('--')) {
191
+ const cssValue = this.parseCSSVariablesInValue(value, cssVariables);
192
+ if (cssValue) {
193
+ cssVariables[name] = cssValue;
194
+ }
195
+ return;
236
196
  }
237
- } else {
238
- const cssValue = this.getCSSValue(value, cssVariables);
239
- if (cssValue && (!properties[name]?.important || important)) {
240
- properties[name] = {
241
- value: cssValue,
242
- important
243
- };
197
+
198
+ if (
199
+ CSSStyleDeclarationElementInheritedProperties[name] ||
200
+ parentElement === targetElement
201
+ ) {
202
+ const cssValue = this.parseCSSVariablesInValue(value, cssVariables);
203
+ if (cssValue && (!propertyManager.get(name)?.important || important)) {
204
+ propertyManager.set(name, cssValue, important);
205
+ if (name === 'font' || name === 'font-size') {
206
+ const fontSize = propertyManager.properties['font-size'];
207
+ if (fontSize !== null) {
208
+ const parsedValue = this.parseMeasurementsInValue({
209
+ value: fontSize.value,
210
+ rootFontSize,
211
+ parentFontSize,
212
+ parentSize: parentFontSize
213
+ });
214
+ if ((<IElement>parentElement.element).tagName === 'HTML') {
215
+ rootFontSize = parsedValue;
216
+ } else if (parentElement !== targetElement) {
217
+ parentFontSize = parsedValue;
218
+ }
219
+ }
220
+ }
221
+ }
244
222
  }
245
- }
246
- });
223
+ });
224
+ }
247
225
 
248
- const propertyManager = new CSSStyleDeclarationPropertyManager();
226
+ for (const name of CSSStyleDeclarationElementMeasurementProperties) {
227
+ const property = propertyManager.properties[name];
228
+ if (property) {
229
+ property.value = this.parseMeasurementsInValue({
230
+ value: property.value,
231
+ rootFontSize,
232
+ parentFontSize,
249
233
 
250
- for (const name of Object.keys(properties)) {
251
- propertyManager.set(name, properties[name].value, properties[name].important);
234
+ // TODO: Only "font-size" is supported when using percentage values. Add support for other properties.
235
+ parentSize: name === 'font-size' ? parentFontSize : 0
236
+ });
237
+ }
252
238
  }
253
239
 
254
- this.cache.cssText = combinedCSSText;
255
240
  this.cache.propertyManager = propertyManager;
256
241
 
257
242
  return propertyManager;
@@ -274,7 +259,7 @@ export default class CSSStyleDeclarationElementStyle {
274
259
  return;
275
260
  }
276
261
 
277
- const defaultView = options.elements[0].element.ownerDocument.defaultView;
262
+ const ownerWindow = this.element.ownerDocument.defaultView;
278
263
 
279
264
  for (const rule of options.cssRules) {
280
265
  if (rule.type === CSSRuleTypeEnum.styleRule) {
@@ -289,10 +274,6 @@ export default class CSSStyleDeclarationElementStyle {
289
274
  }
290
275
  } else {
291
276
  for (const element of options.elements) {
292
- // Skip @-rules.
293
- if (selectorText.startsWith('@')) {
294
- continue;
295
- }
296
277
  const matchResult = QuerySelector.match(<IElement>element.element, selectorText);
297
278
  if (matchResult) {
298
279
  element.cssTexts.push({
@@ -305,7 +286,12 @@ export default class CSSStyleDeclarationElementStyle {
305
286
  }
306
287
  } else if (
307
288
  rule.type === CSSRuleTypeEnum.mediaRule &&
308
- defaultView.matchMedia((<CSSMediaRule>rule).conditionText).matches
289
+ // TODO: We need to send in a predfined root font size as it will otherwise be calculated using Window.getComputedStyle(), which will cause a never ending loop. Is there another solution?
290
+ new MediaQueryList({
291
+ ownerWindow,
292
+ media: (<CSSMediaRule>rule).conditionText,
293
+ rootFontSize: this.element.tagName === 'HTML' ? 16 : null
294
+ }).matches
309
295
  ) {
310
296
  this.parseCSSRules({
311
297
  elements: options.elements,
@@ -317,23 +303,60 @@ export default class CSSStyleDeclarationElementStyle {
317
303
  }
318
304
 
319
305
  /**
320
- * Returns CSS value.
306
+ * Parses CSS variables in a value.
321
307
  *
322
308
  * @param value Value.
323
309
  * @param cssVariables CSS variables.
324
310
  * @returns CSS value.
325
311
  */
326
- private getCSSValue(value: string, cssVariables: { [k: string]: string }): string {
312
+ private parseCSSVariablesInValue(value: string, cssVariables: { [k: string]: string }): string {
327
313
  const regexp = new RegExp(CSS_VARIABLE_REGEXP);
328
314
  let newValue = value;
329
315
  let match;
316
+
330
317
  while ((match = regexp.exec(value)) !== null) {
331
- const cssVariableValue = cssVariables[match[1]];
332
- if (!cssVariableValue) {
333
- return null;
318
+ newValue = newValue.replace(match[0], cssVariables[match[1]] || '');
319
+ }
320
+
321
+ return newValue;
322
+ }
323
+
324
+ /**
325
+ * Parses measurements in a value.
326
+ *
327
+ * @param options Options.
328
+ * @param options.value Value.
329
+ * @param options.rootFontSize Root font size.
330
+ * @param options.parentFontSize Parent font size.
331
+ * @param [options.parentSize] Parent width.
332
+ * @returns CSS value.
333
+ */
334
+ private parseMeasurementsInValue(options: {
335
+ value: string;
336
+ rootFontSize: string | number;
337
+ parentFontSize: string | number;
338
+ parentSize: string | number;
339
+ }): string {
340
+ const regexp = new RegExp(CSS_MEASUREMENT_REGEXP);
341
+ let newValue = options.value;
342
+ let match;
343
+
344
+ while ((match = regexp.exec(options.value)) !== null) {
345
+ if (match[1] !== 'px') {
346
+ const valueInPixels = CSSMeasurementConverter.toPixels({
347
+ ownerWindow: this.element.ownerDocument.defaultView,
348
+ value: match[0],
349
+ rootFontSize: options.rootFontSize,
350
+ parentFontSize: options.parentFontSize,
351
+ parentSize: options.parentSize
352
+ });
353
+
354
+ if (valueInPixels !== null) {
355
+ newValue = newValue.replace(match[0], valueInPixels + 'px');
356
+ }
334
357
  }
335
- newValue = newValue.replace(match[0], cssVariableValue);
336
358
  }
359
+
337
360
  return newValue;
338
361
  }
339
362
  }
@@ -69,7 +69,7 @@ export default {
69
69
  HEADER: 'display: block;',
70
70
  HGROUP: 'display: block;',
71
71
  HR: 'display: block;',
72
- HTML: 'display: block;direction: ltr;',
72
+ HTML: 'display: block;direction: ltr;font: 16px "Times New Roman";',
73
73
  I: '',
74
74
  IFRAME: '',
75
75
  INS: '',
@@ -0,0 +1,41 @@
1
+ export default [
2
+ 'background-position-x',
3
+ 'background-position-y',
4
+ 'background-size',
5
+ 'border-image-outset',
6
+ 'border-top-width',
7
+ 'border-right-width',
8
+ 'border-bottom-width',
9
+ 'border-left-width',
10
+ 'border-top-left-radius',
11
+ 'border-top-right-radius',
12
+ 'border-bottom-right-radius',
13
+ 'border-bottom-left-radius',
14
+ 'border-image-width',
15
+ 'clip',
16
+ 'font-size',
17
+ 'padding-top',
18
+ 'padding-right',
19
+ 'padding-bottom',
20
+ 'padding-left',
21
+ 'margin-top',
22
+ 'margin-right',
23
+ 'margin-bottom',
24
+ 'margin-left',
25
+ 'width',
26
+ 'height',
27
+ 'min-width',
28
+ 'min-height',
29
+ 'max-width',
30
+ 'max-height',
31
+ 'top',
32
+ 'right',
33
+ 'bottom',
34
+ 'left',
35
+ 'outline-width',
36
+ 'outline-offset',
37
+ 'letter-spacing',
38
+ 'word-spacing',
39
+ 'text-indent',
40
+ 'line-height'
41
+ ];
@@ -0,0 +1,81 @@
1
+ import IWindow from '../../../window/IWindow';
2
+
3
+ /**
4
+ * CSS Measurement Converter.
5
+ */
6
+ export default class CSSMeasurementConverter {
7
+ /**
8
+ * Returns measurement in pixels.
9
+ *
10
+ * @param options Options.
11
+ * @param options.ownerWindow Owner window.
12
+ * @param options.value Measurement (e.g. "10px", "10rem" or "10em").
13
+ * @param options.rootFontSize Root font size in pixels.
14
+ * @param options.parentFontSize Parent font size in pixels.
15
+ * @param [options.parentSize] Parent size in pixels.
16
+ * @returns Measurement in pixels.
17
+ */
18
+ public static toPixels(options: {
19
+ ownerWindow: IWindow;
20
+ value: string;
21
+ rootFontSize: string | number;
22
+ parentFontSize: string | number;
23
+ parentSize?: string | number | null;
24
+ }): number | null {
25
+ const value = parseFloat(options.value);
26
+ const unit = options.value.replace(value.toString(), '');
27
+
28
+ if (isNaN(value)) {
29
+ return null;
30
+ }
31
+
32
+ switch (unit) {
33
+ case 'px':
34
+ return value;
35
+ case 'rem':
36
+ return this.round(value * parseFloat(<string>options.rootFontSize));
37
+ case 'em':
38
+ return this.round(value * parseFloat(<string>options.parentFontSize));
39
+ case 'vw':
40
+ return this.round((value * options.ownerWindow.innerWidth) / 100);
41
+ case 'vh':
42
+ return this.round((value * options.ownerWindow.innerHeight) / 100);
43
+ case '%':
44
+ return options.parentSize !== undefined && options.parentSize !== null
45
+ ? this.round((value * parseFloat(<string>options.parentSize)) / 100)
46
+ : null;
47
+ case 'vmin':
48
+ return this.round(
49
+ (value * Math.min(options.ownerWindow.innerWidth, options.ownerWindow.innerHeight)) / 100
50
+ );
51
+ case 'vmax':
52
+ return (
53
+ (value * Math.max(options.ownerWindow.innerWidth, options.ownerWindow.innerHeight)) / 100
54
+ );
55
+ case 'cm':
56
+ return this.round(value * 37.7812);
57
+ case 'mm':
58
+ return this.round(value * 3.7781);
59
+ case 'in':
60
+ return this.round(value * 96);
61
+ case 'pt':
62
+ return this.round(value * 1.3281);
63
+ case 'pc':
64
+ return this.round(value * 16);
65
+ case 'Q':
66
+ return this.round(value * 0.945);
67
+ default:
68
+ return null;
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Rounds the number with 4 decimals.
74
+ *
75
+ * @param value Value.
76
+ * @returns Rounded value.
77
+ */
78
+ public static round(value: number): number {
79
+ return Math.round(value * 10000) / 10000;
80
+ }
81
+ }
@@ -35,6 +35,57 @@ export default class CSSStyleDeclarationPropertyGetParser {
35
35
  );
36
36
  }
37
37
 
38
+ /**
39
+ * Returns outline.
40
+ *
41
+ * @param properties Properties.
42
+ * @returns Property value
43
+ */
44
+ public static getOutline(properties: {
45
+ [k: string]: ICSSStyleDeclarationPropertyValue;
46
+ }): ICSSStyleDeclarationPropertyValue {
47
+ if (
48
+ !properties['outline-color']?.value ||
49
+ !properties['outline-style']?.value ||
50
+ !properties['outline-width']?.value
51
+ ) {
52
+ return null;
53
+ }
54
+
55
+ const important =
56
+ properties['outline-color'].important &&
57
+ properties['outline-style'].important &&
58
+ properties['outline-width'].important;
59
+
60
+ if (
61
+ CSSStyleDeclarationValueParser.getGlobalExceptInitial(properties['outline-width'].value) &&
62
+ properties['outline-width'].value === properties['outline-style'].value &&
63
+ properties['outline-width'].value === properties['outline-color'].value
64
+ ) {
65
+ return {
66
+ important,
67
+ value: properties['outline-width'].value
68
+ };
69
+ }
70
+
71
+ const values = [];
72
+
73
+ if (!CSSStyleDeclarationValueParser.getInitial(properties['outline-color']?.value)) {
74
+ values.push(properties['outline-color'].value);
75
+ }
76
+ if (!CSSStyleDeclarationValueParser.getInitial(properties['outline-style']?.value)) {
77
+ values.push(properties['outline-style'].value);
78
+ }
79
+ if (!CSSStyleDeclarationValueParser.getInitial(properties['outline-width'].value)) {
80
+ values.push(properties['outline-width'].value);
81
+ }
82
+
83
+ return {
84
+ important,
85
+ value: values.join(' ')
86
+ };
87
+ }
88
+
38
89
  /**
39
90
  * Returns border.
40
91
  *
@@ -2,7 +2,7 @@ import ICSSStyleDeclarationPropertyValue from './ICSSStyleDeclarationPropertyVal
2
2
  import CSSStyleDeclarationPropertySetParser from './CSSStyleDeclarationPropertySetParser';
3
3
  import CSSStyleDeclarationValueParser from './CSSStyleDeclarationValueParser';
4
4
  import CSSStyleDeclarationPropertyGetParser from './CSSStyleDeclarationPropertyGetParser';
5
- import CSSStyleDeclarationCSSParser from './CSSStyleDeclarationCSSParser';
5
+ import CSSStyleDeclarationCSSParser from '../css-parser/CSSStyleDeclarationCSSParser';
6
6
 
7
7
  const TO_STRING_SHORTHAND_PROPERTIES = [
8
8
  ['margin'],
@@ -44,7 +44,7 @@ export default class CSSStyleDeclarationPropertyManager {
44
44
  * @param name Property name.
45
45
  * @returns Property value.
46
46
  */
47
- public get(name: string): ICSSStyleDeclarationPropertyValue {
47
+ public get(name: string): ICSSStyleDeclarationPropertyValue | null {
48
48
  if (this.properties[name]) {
49
49
  return this.properties[name];
50
50
  }
@@ -73,6 +73,8 @@ export default class CSSStyleDeclarationPropertyManager {
73
73
  return CSSStyleDeclarationPropertyGetParser.getBorderRadius(this.properties);
74
74
  case 'border-image':
75
75
  return CSSStyleDeclarationPropertyGetParser.getBorderImage(this.properties);
76
+ case 'outline':
77
+ return CSSStyleDeclarationPropertyGetParser.getOutline(this.properties);
76
78
  case 'background':
77
79
  return CSSStyleDeclarationPropertyGetParser.getBackground(this.properties);
78
80
  case 'background-position':
@@ -186,6 +188,11 @@ export default class CSSStyleDeclarationPropertyManager {
186
188
  delete this.properties['border-bottom-right-radius'];
187
189
  delete this.properties['border-bottom-left-radius'];
188
190
  break;
191
+ case 'outline':
192
+ delete this.properties['outline-color'];
193
+ delete this.properties['outline-style'];
194
+ delete this.properties['outline-width'];
195
+ break;
189
196
  case 'background':
190
197
  delete this.properties['background-color'];
191
198
  delete this.properties['background-image'];
@@ -348,6 +355,24 @@ export default class CSSStyleDeclarationPropertyManager {
348
355
  case 'border-collapse':
349
356
  properties = CSSStyleDeclarationPropertySetParser.getBorderCollapse(value, important);
350
357
  break;
358
+ case 'outline':
359
+ properties = CSSStyleDeclarationPropertySetParser.getOutline(value, important);
360
+ break;
361
+ case 'outline-width':
362
+ properties = CSSStyleDeclarationPropertySetParser.getOutlineWidth(value, important);
363
+ break;
364
+ case 'outline-style':
365
+ properties = CSSStyleDeclarationPropertySetParser.getOutlineStyle(value, important);
366
+ break;
367
+ case 'outline-color':
368
+ properties = CSSStyleDeclarationPropertySetParser.getOutlineColor(value, important);
369
+ break;
370
+ case 'letter-spacing':
371
+ properties = CSSStyleDeclarationPropertySetParser.getLetterSpacing(value, important);
372
+ break;
373
+ case 'word-spacing':
374
+ properties = CSSStyleDeclarationPropertySetParser.getWordSpacing(value, important);
375
+ break;
351
376
  case 'clear':
352
377
  properties = CSSStyleDeclarationPropertySetParser.getClear(value, important);
353
378
  break;
@@ -429,6 +454,9 @@ export default class CSSStyleDeclarationPropertyManager {
429
454
  case 'width':
430
455
  properties = CSSStyleDeclarationPropertySetParser.getWidth(value, important);
431
456
  break;
457
+ case 'height':
458
+ properties = CSSStyleDeclarationPropertySetParser.getHeight(value, important);
459
+ break;
432
460
  case 'top':
433
461
  properties = CSSStyleDeclarationPropertySetParser.getTop(value, important);
434
462
  break;
@@ -462,6 +490,9 @@ export default class CSSStyleDeclarationPropertyManager {
462
490
  case 'line-height':
463
491
  properties = CSSStyleDeclarationPropertySetParser.getLineHeight(value, important);
464
492
  break;
493
+ case 'text-indent':
494
+ properties = CSSStyleDeclarationPropertySetParser.getTextIndent(value, important);
495
+ break;
465
496
  case 'font-family':
466
497
  properties = CSSStyleDeclarationPropertySetParser.getFontFamily(value, important);
467
498
  break;
@@ -477,6 +508,7 @@ export default class CSSStyleDeclarationPropertyManager {
477
508
  case 'visibility':
478
509
  properties = CSSStyleDeclarationPropertySetParser.getVisibility(value, important);
479
510
  break;
511
+
480
512
  default:
481
513
  const trimmedValue = value.trim();
482
514
  if (trimmedValue) {