@digicole/pdfmake-rtl 1.0.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.
@@ -0,0 +1,485 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * RTL (Right-to-Left) utilities for handling Arabic, Persian (Farsi), and Urdu languages
5
+ */
6
+
7
+ // Unicode ranges for Arabic script (includes Persian and Urdu characters)
8
+ var ARABIC_RANGE = [
9
+ [0x0600, 0x06FF], // Arabic block
10
+ [0x0750, 0x077F], // Arabic Supplement
11
+ [0x08A0, 0x08FF], // Arabic Extended-A
12
+ [0xFB50, 0xFDFF], // Arabic Presentation Forms-A
13
+ [0xFE70, 0xFEFF] // Arabic Presentation Forms-B
14
+ ];
15
+
16
+ // Unicode ranges for Persian (Farsi) specific characters
17
+ var PERSIAN_RANGE = [
18
+ [0x06A9, 0x06AF], // Persian Kaf, Gaf
19
+ [0x06C0, 0x06C3], // Persian Heh, Teh Marbuta variants
20
+ [0x06CC, 0x06CE], // Persian Yeh variants
21
+ [0x06D0, 0x06D5], // Persian Yeh Barree, Arabic-Indic digits
22
+ [0x200C, 0x200D] // Zero Width Non-Joiner, Zero Width Joiner (used in Persian)
23
+ ];
24
+
25
+ // Unicode ranges for Urdu specific characters
26
+ var URDU_RANGE = [
27
+ [0x0679, 0x0679], // Urdu Tteh
28
+ [0x067E, 0x067E], // Urdu Peh
29
+ [0x0686, 0x0686], // Urdu Tcheh
30
+ [0x0688, 0x0688], // Urdu Ddal
31
+ [0x0691, 0x0691], // Urdu Rreh
32
+ [0x0698, 0x0698], // Urdu Jeh
33
+ [0x06A9, 0x06A9], // Urdu Keheh
34
+ [0x06AF, 0x06AF], // Urdu Gaf
35
+ [0x06BA, 0x06BA], // Urdu Noon Ghunna
36
+ [0x06BE, 0x06BE], // Urdu Heh Doachashmee
37
+ [0x06C1, 0x06C1], // Urdu Heh Goal
38
+ [0x06D2, 0x06D2], // Urdu Yeh Barree
39
+ [0x06D3, 0x06D3] // Urdu Yeh Barree with Hamza
40
+ ];
41
+
42
+ // Strong RTL characters (Arabic, Persian, Urdu)
43
+ var RTL_CHARS = /[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF\u200C-\u200D]/;
44
+
45
+ // Strong LTR characters (Latin, etc.)
46
+ var LTR_CHARS = /[A-Za-z\u00C0-\u024F\u1E00-\u1EFF]/;
47
+
48
+ /**
49
+ * Check if a character is in Arabic script (includes Persian and Urdu)
50
+ * @param {string} char - Single character to check
51
+ * @return {boolean} - True if character is Arabic/Persian/Urdu
52
+ */
53
+ function isArabicChar(char) {
54
+ var code = char.charCodeAt(0);
55
+ return ARABIC_RANGE.some(function(range) {
56
+ return code >= range[0] && code <= range[1];
57
+ });
58
+ }
59
+
60
+ /**
61
+ * Check if a character is in Persian (Farsi) script
62
+ * @param {string} char - Single character to check
63
+ * @return {boolean} - True if character is Persian
64
+ */
65
+ function isPersianChar(char) {
66
+ var code = char.charCodeAt(0);
67
+ return PERSIAN_RANGE.some(function(range) {
68
+ return code >= range[0] && code <= range[1];
69
+ }) || isArabicChar(char); // Persian uses Arabic base + extensions
70
+ }
71
+
72
+ /**
73
+ * Check if a character is in Urdu script
74
+ * @param {string} char - Single character to check
75
+ * @return {boolean} - True if character is Urdu
76
+ */
77
+ function isUrduChar(char) {
78
+ var code = char.charCodeAt(0);
79
+ return URDU_RANGE.some(function(range) {
80
+ return code >= range[0] && code <= range[1];
81
+ }) || isArabicChar(char); // Urdu uses Arabic base + extensions
82
+ }
83
+
84
+ /**
85
+ * Check if a character requires RTL rendering
86
+ * @param {string} char - Single character to check
87
+ * @return {boolean} - True if character requires RTL
88
+ */
89
+ function isRTLChar(char) {
90
+ return RTL_CHARS.test(char);
91
+ }
92
+
93
+ /**
94
+ * Check if a character is strongly LTR
95
+ * @param {string} char - Single character to check
96
+ * @return {boolean} - True if character is strongly LTR
97
+ */
98
+ function isLTRChar(char) {
99
+ return LTR_CHARS.test(char);
100
+ }
101
+
102
+ /**
103
+ * Determine the predominant text direction of a string
104
+ * @param {string} text - Text to analyze
105
+ * @return {string} - 'rtl', 'ltr', or 'neutral'
106
+ */
107
+ function getTextDirection(text) {
108
+ if (!text || typeof text !== 'string') {
109
+ return 'neutral';
110
+ }
111
+
112
+ var rtlCount = 0;
113
+ var ltrCount = 0;
114
+
115
+ for (var i = 0; i < text.length; i++) {
116
+ var char = text.charAt(i);
117
+ if (isRTLChar(char)) {
118
+ rtlCount++;
119
+ } else if (isLTRChar(char)) {
120
+ ltrCount++;
121
+ }
122
+ }
123
+
124
+ // If we have any strong directional characters
125
+ if (rtlCount > 0 || ltrCount > 0) {
126
+ if (rtlCount > ltrCount) {
127
+ return 'rtl';
128
+ } else if (ltrCount > rtlCount) {
129
+ return 'ltr';
130
+ } else {
131
+ // Equal counts - slight preference for RTL if both exist
132
+ return rtlCount > 0 ? 'rtl' : 'ltr';
133
+ }
134
+ }
135
+
136
+ return 'neutral';
137
+ }
138
+
139
+ /**
140
+ * Check if text contains any RTL characters
141
+ * @param {string} text - Text to check
142
+ * @return {boolean} - True if text contains RTL characters
143
+ */
144
+ function containsRTL(text) {
145
+ if (!text || typeof text !== 'string') {
146
+ return false;
147
+ }
148
+ return RTL_CHARS.test(text);
149
+ }
150
+
151
+ /**
152
+ * Check if text is primarily Arabic, Persian, or Urdu
153
+ * @param {string} text - Text to check
154
+ * @return {boolean} - True if text is primarily Arabic/Persian/Urdu
155
+ */
156
+ function isArabicText(text) {
157
+ if (!text || typeof text !== 'string') {
158
+ return false;
159
+ }
160
+
161
+ var rtlCount = 0;
162
+ var totalStrongChars = 0;
163
+
164
+ for (var i = 0; i < text.length; i++) {
165
+ var char = text.charAt(i);
166
+ if (isArabicChar(char) || isPersianChar(char) || isUrduChar(char)) {
167
+ rtlCount++;
168
+ totalStrongChars++;
169
+ } else if (isRTLChar(char) || isLTRChar(char)) {
170
+ totalStrongChars++;
171
+ }
172
+ }
173
+
174
+ // If we have any strong characters and RTL represents at least 30%
175
+ // (lowered threshold for mixed text)
176
+ return totalStrongChars > 0 && (rtlCount / totalStrongChars) >= 0.3;
177
+ }
178
+
179
+ /**
180
+ * Process RTL text for proper display
181
+ * For modern PDF libraries, we rely on the underlying engine for BiDi processing
182
+ * We should NOT reverse word order manually - that breaks Arabic text
183
+ * @param {string} text - Text to process
184
+ * @return {string} - Text (unchanged for proper BiDi handling)
185
+ */
186
+ function reverseRTLText(text) {
187
+ if (!text || typeof text !== 'string') {
188
+ return text;
189
+ }
190
+
191
+ // DO NOT reverse Arabic text word order!
192
+ // Arabic text should maintain its natural word order
193
+ // Only the display direction (alignment) should be RTL
194
+ // The PDF engine handles proper BiDi rendering
195
+ return text;
196
+ }
197
+
198
+ /**
199
+ * Apply RTL processing to text if needed
200
+ * @param {string} text - Original text
201
+ * @param {string} direction - Explicit direction override ('rtl', 'ltr', or null)
202
+ * @return {Object} - { text: processedText, isRTL: boolean }
203
+ */
204
+ function processRTLText(text, direction) {
205
+ if (!text || typeof text !== 'string' || getTextDirection(text) !== 'rtl') {
206
+ return { text: text, isRTL: false };
207
+ }
208
+
209
+ var isRTL = false;
210
+
211
+ if (direction === 'rtl') {
212
+ isRTL = true;
213
+ } else if (direction === 'ltr') {
214
+ isRTL = false;
215
+ } else {
216
+ // Auto-detect direction
217
+ var textDir = getTextDirection(text);
218
+ isRTL = textDir === 'rtl';
219
+ }
220
+
221
+ // Keep original text - no word reversal needed
222
+ // The PDF engine handles proper BiDi rendering
223
+ return {
224
+ text: text,
225
+ isRTL: isRTL
226
+ };
227
+ }
228
+
229
+ /**
230
+ * Reverse table row cells for RTL layout
231
+ * @param {Array} row - Table row array
232
+ * @return {Array} - Reversed row array
233
+ */
234
+ function reverseTableRow(row) {
235
+ if (!Array.isArray(row)) {
236
+ return row;
237
+ }
238
+ return row.slice().reverse();
239
+ }
240
+
241
+ /**
242
+ * Process table for RTL layout if supportRTL is enabled
243
+ * @param {Object} tableNode - Table definition object
244
+ * @return {Object} - Processed table node
245
+ */
246
+ function processRTLTable(tableNode) {
247
+ if (!tableNode || !tableNode.supportRTL || !tableNode.table || !tableNode.table.body) {
248
+ return tableNode;
249
+ }
250
+
251
+ // Don't clone the entire object - just modify the table data in place
252
+ // Reverse each row in the table body for RTL layout
253
+ tableNode.table.body = tableNode.table.body.map(function(row) {
254
+ return reverseTableRow(row);
255
+ });
256
+
257
+ // Also reverse the widths array if it exists
258
+ if (tableNode.table.widths && Array.isArray(tableNode.table.widths)) {
259
+ tableNode.table.widths = tableNode.table.widths.slice().reverse();
260
+ }
261
+
262
+ return tableNode;
263
+ }
264
+
265
+ /**
266
+ * Apply automatic RTL detection and formatting to any text element
267
+ * @param {Object|string} element - Text element or string
268
+ * @return {Object} - Enhanced element with RTL properties
269
+ */
270
+ function autoApplyRTL(element) {
271
+ if (!element) return element;
272
+
273
+ // Handle string elements
274
+ if (typeof element === 'string') {
275
+ var direction = getTextDirection(element);
276
+ if (direction === 'rtl') {
277
+ return {
278
+ text: element,
279
+ alignment: 'right',
280
+ font: 'Nillima' // Use Arabic font for RTL text
281
+ };
282
+ }
283
+ return element;
284
+ }
285
+
286
+ // Handle object elements
287
+ if (typeof element === 'object' && element.text) {
288
+ var textDirection = getTextDirection(element.text);
289
+
290
+ if (textDirection === 'rtl') {
291
+ // Auto-apply RTL properties if not already set
292
+ if (!element.alignment) {
293
+ element.alignment = 'right';
294
+ }
295
+ if (!element.font && isArabicText(element.text)) {
296
+ element.font = 'Nillima';
297
+ }
298
+ } else if (textDirection === 'ltr') {
299
+ // Auto-apply LTR properties if not already set
300
+ if (!element.alignment) {
301
+ element.alignment = 'left';
302
+ }
303
+ if (!element.font) {
304
+ element.font = 'Roboto';
305
+ }
306
+ }
307
+ }
308
+
309
+ return element;
310
+ }
311
+
312
+ /**
313
+ * Process list items for RTL support including bullet positioning
314
+ * @param {Array|Object} listItems - ul/ol content
315
+ * @return {Array|Object} - Processed list with RTL support
316
+ */
317
+ function processRTLList(listItems) {
318
+ if (!listItems) return listItems;
319
+
320
+ function processListItem(item) {
321
+ if (typeof item === 'string') {
322
+ var direction = getTextDirection(item);
323
+ if (direction === 'rtl') {
324
+ return {
325
+ text: item,
326
+ alignment: 'right',
327
+ font: 'Nillima',
328
+ markerColor: '#2c5282'
329
+ };
330
+ }
331
+ return item;
332
+ }
333
+
334
+ if (typeof item === 'object') {
335
+ // Process the main text
336
+ if (item.text) {
337
+ var textDirection = getTextDirection(item.text);
338
+ if (textDirection === 'rtl') {
339
+ if (!item.alignment) item.alignment = 'right';
340
+ if (!item.font && isArabicText(item.text)) item.font = 'Nillima';
341
+ if (!item.markerColor) item.markerColor = '#2c5282';
342
+ }
343
+ }
344
+
345
+ // Process nested ul/ol recursively
346
+ if (item.ul) {
347
+ item.ul = processRTLList(item.ul);
348
+ }
349
+ if (item.ol) {
350
+ item.ol = processRTLList(item.ol);
351
+ }
352
+ }
353
+
354
+ return item;
355
+ }
356
+
357
+ if (Array.isArray(listItems)) {
358
+ return listItems.map(processListItem);
359
+ }
360
+
361
+ return processListItem(listItems);
362
+ }
363
+
364
+ /**
365
+ * Process table for automatic RTL detection and layout
366
+ * @param {Object} tableNode - Table definition object
367
+ * @return {Object} - Processed table node
368
+ */
369
+ function processAutoRTLTable(tableNode) {
370
+ if (!tableNode || !tableNode.table || !tableNode.table.body) {
371
+ return tableNode;
372
+ }
373
+
374
+ // Check if table contains RTL content
375
+ var hasRTLContent = false;
376
+ var rtlCellCount = 0;
377
+ var totalCells = 0;
378
+
379
+ tableNode.table.body.forEach(function(row) {
380
+ if (Array.isArray(row)) {
381
+ row.forEach(function(cell) {
382
+ totalCells++;
383
+ var cellText = typeof cell === 'string' ? cell : (cell && cell.text ? cell.text : '');
384
+ if (containsRTL(cellText)) {
385
+ rtlCellCount++;
386
+ }
387
+ });
388
+ }
389
+ });
390
+
391
+ // If more than 30% of cells contain RTL content, treat as RTL table
392
+ hasRTLContent = totalCells > 0 && (rtlCellCount / totalCells) >= 0.3;
393
+
394
+ if (hasRTLContent) {
395
+ // Reverse table columns for RTL layout
396
+ tableNode.table.body = tableNode.table.body.map(function(row) {
397
+ return reverseTableRow(row);
398
+ });
399
+
400
+ // Reverse widths if defined
401
+ if (tableNode.table.widths && Array.isArray(tableNode.table.widths)) {
402
+ tableNode.table.widths = tableNode.table.widths.slice().reverse();
403
+ }
404
+
405
+ // Auto-apply RTL styles to cells
406
+ tableNode.table.body = tableNode.table.body.map(function(row) {
407
+ if (Array.isArray(row)) {
408
+ return row.map(function(cell) {
409
+ return autoApplyRTL(cell);
410
+ });
411
+ }
412
+ return row;
413
+ });
414
+ } else {
415
+ // For non-RTL tables, still auto-apply font and alignment per cell
416
+ tableNode.table.body = tableNode.table.body.map(function(row) {
417
+ if (Array.isArray(row)) {
418
+ return row.map(function(cell) {
419
+ return autoApplyRTL(cell);
420
+ });
421
+ }
422
+ return row;
423
+ });
424
+ }
425
+
426
+ return tableNode;
427
+ }
428
+
429
+ /**
430
+ * Process any document element for automatic RTL detection
431
+ * @param {Object|Array|string} element - Document element
432
+ * @return {Object|Array|string} - Processed element
433
+ */
434
+ function processAutoRTLElement(element) {
435
+ if (!element) return element;
436
+
437
+ // Handle arrays (like content arrays)
438
+ if (Array.isArray(element)) {
439
+ return element.map(processAutoRTLElement);
440
+ }
441
+
442
+ // Handle text elements
443
+ if (typeof element === 'string' || (element && element.text)) {
444
+ element = autoApplyRTL(element);
445
+ }
446
+
447
+ // Handle tables
448
+ if (element && element.table) {
449
+ element = processAutoRTLTable(element);
450
+ }
451
+
452
+ // Handle lists
453
+ if (element && element.ul) {
454
+ element.ul = processRTLList(element.ul);
455
+ }
456
+ if (element && element.ol) {
457
+ element.ol = processRTLList(element.ol);
458
+ }
459
+
460
+ // Handle columns
461
+ if (element && element.columns && Array.isArray(element.columns)) {
462
+ element.columns = element.columns.map(processAutoRTLElement);
463
+ }
464
+
465
+ return element;
466
+ }
467
+
468
+ module.exports = {
469
+ isArabicChar: isArabicChar,
470
+ isPersianChar: isPersianChar,
471
+ isUrduChar: isUrduChar,
472
+ isRTLChar: isRTLChar,
473
+ isLTRChar: isLTRChar,
474
+ getTextDirection: getTextDirection,
475
+ containsRTL: containsRTL,
476
+ isArabicText: isArabicText,
477
+ reverseRTLText: reverseRTLText,
478
+ processRTLText: processRTLText,
479
+ reverseTableRow: reverseTableRow,
480
+ processRTLTable: processRTLTable,
481
+ autoApplyRTL: autoApplyRTL,
482
+ processRTLList: processRTLList,
483
+ processAutoRTLTable: processAutoRTLTable,
484
+ processAutoRTLElement: processAutoRTLElement
485
+ };
@@ -0,0 +1,54 @@
1
+ 'use strict';
2
+
3
+ module.exports = {
4
+ '4A0': [4767.87, 6740.79],
5
+ '2A0': [3370.39, 4767.87],
6
+ A0: [2383.94, 3370.39],
7
+ A1: [1683.78, 2383.94],
8
+ A2: [1190.55, 1683.78],
9
+ A3: [841.89, 1190.55],
10
+ A4: [595.28, 841.89],
11
+ A5: [419.53, 595.28],
12
+ A6: [297.64, 419.53],
13
+ A7: [209.76, 297.64],
14
+ A8: [147.40, 209.76],
15
+ A9: [104.88, 147.40],
16
+ A10: [73.70, 104.88],
17
+ B0: [2834.65, 4008.19],
18
+ B1: [2004.09, 2834.65],
19
+ B2: [1417.32, 2004.09],
20
+ B3: [1000.63, 1417.32],
21
+ B4: [708.66, 1000.63],
22
+ B5: [498.90, 708.66],
23
+ B6: [354.33, 498.90],
24
+ B7: [249.45, 354.33],
25
+ B8: [175.75, 249.45],
26
+ B9: [124.72, 175.75],
27
+ B10: [87.87, 124.72],
28
+ C0: [2599.37, 3676.54],
29
+ C1: [1836.85, 2599.37],
30
+ C2: [1298.27, 1836.85],
31
+ C3: [918.43, 1298.27],
32
+ C4: [649.13, 918.43],
33
+ C5: [459.21, 649.13],
34
+ C6: [323.15, 459.21],
35
+ C7: [229.61, 323.15],
36
+ C8: [161.57, 229.61],
37
+ C9: [113.39, 161.57],
38
+ C10: [79.37, 113.39],
39
+ RA0: [2437.80, 3458.27],
40
+ RA1: [1729.13, 2437.80],
41
+ RA2: [1218.90, 1729.13],
42
+ RA3: [864.57, 1218.90],
43
+ RA4: [609.45, 864.57],
44
+ SRA0: [2551.18, 3628.35],
45
+ SRA1: [1814.17, 2551.18],
46
+ SRA2: [1275.59, 1814.17],
47
+ SRA3: [907.09, 1275.59],
48
+ SRA4: [637.80, 907.09],
49
+ EXECUTIVE: [521.86, 756.00],
50
+ FOLIO: [612.00, 936.00],
51
+ LEGAL: [612.00, 1008.00],
52
+ LETTER: [612.00, 792.00],
53
+ TABLOID: [792.00, 1224.00]
54
+ };
@@ -0,0 +1,138 @@
1
+ 'use strict';
2
+
3
+ var isString = require('./helpers').isString;
4
+ var isArray = require('./helpers').isArray;
5
+ var isUndefined = require('./helpers').isUndefined;
6
+ var isNull = require('./helpers').isNull;
7
+
8
+ /**
9
+ * Creates an instance of StyleContextStack used for style inheritance and style overrides
10
+ *
11
+ * @constructor
12
+ * @this {StyleContextStack}
13
+ * @param {Object} named styles dictionary
14
+ * @param {Object} optional default style definition
15
+ */
16
+ function StyleContextStack(styleDictionary, defaultStyle) {
17
+ this.defaultStyle = defaultStyle || {};
18
+ this.styleDictionary = styleDictionary;
19
+ this.styleOverrides = [];
20
+ }
21
+
22
+ /**
23
+ * Creates cloned version of current stack
24
+ * @return {StyleContextStack} current stack snapshot
25
+ */
26
+ StyleContextStack.prototype.clone = function () {
27
+ var stack = new StyleContextStack(this.styleDictionary, this.defaultStyle);
28
+
29
+ this.styleOverrides.forEach(function (item) {
30
+ stack.styleOverrides.push(item);
31
+ });
32
+
33
+ return stack;
34
+ };
35
+
36
+ /**
37
+ * Pushes style-name or style-overrides-object onto the stack for future evaluation
38
+ *
39
+ * @param {String|Object} styleNameOrOverride style-name (referring to styleDictionary) or
40
+ * a new dictionary defining overriding properties
41
+ */
42
+ StyleContextStack.prototype.push = function (styleNameOrOverride) {
43
+ this.styleOverrides.push(styleNameOrOverride);
44
+ };
45
+
46
+ /**
47
+ * Removes last style-name or style-overrides-object from the stack
48
+ *
49
+ * @param {Number} howMany - optional number of elements to be popped (if not specified,
50
+ * one element will be removed from the stack)
51
+ */
52
+ StyleContextStack.prototype.pop = function (howMany) {
53
+ howMany = howMany || 1;
54
+
55
+ while (howMany-- > 0) {
56
+ this.styleOverrides.pop();
57
+ }
58
+ };
59
+
60
+ /**
61
+ * Creates a set of named styles or/and a style-overrides-object based on the item,
62
+ * pushes those elements onto the stack for future evaluation and returns the number
63
+ * of elements pushed, so they can be easily poped then.
64
+ *
65
+ * @param {Object} item - an object with optional style property and/or style overrides
66
+ * @return the number of items pushed onto the stack
67
+ */
68
+ StyleContextStack.prototype.autopush = function (item) {
69
+ if (isString(item)) {
70
+ return 0;
71
+ }
72
+
73
+ var styleNames = [];
74
+
75
+ if (item.style) {
76
+ if (isArray(item.style)) {
77
+ styleNames = item.style;
78
+ } else {
79
+ styleNames = [item.style];
80
+ }
81
+ }
82
+
83
+ for (var i = 0, l = styleNames.length; i < l; i++) {
84
+ this.push(styleNames[i]);
85
+ }
86
+
87
+ // rather than spend significant time making a styleOverrideObject, just add item
88
+ this.push(item);
89
+ return styleNames.length + 1;
90
+ };
91
+
92
+ /**
93
+ * Automatically pushes elements onto the stack, using autopush based on item,
94
+ * executes callback and then pops elements back. Returns value returned by callback
95
+ *
96
+ * @param {Object} item - an object with optional style property and/or style overrides
97
+ * @param {Function} function to be called between autopush and pop
98
+ * @return {Object} value returned by callback
99
+ */
100
+ StyleContextStack.prototype.auto = function (item, callback) {
101
+ var pushedItems = this.autopush(item);
102
+ var result = callback();
103
+
104
+ if (pushedItems > 0) {
105
+ this.pop(pushedItems);
106
+ }
107
+
108
+ return result;
109
+ };
110
+
111
+ /**
112
+ * Evaluates stack and returns value of a named property
113
+ *
114
+ * @param {String} property - property name
115
+ * @return property value or null if not found
116
+ */
117
+ StyleContextStack.prototype.getProperty = function (property) {
118
+ if (this.styleOverrides) {
119
+ for (var i = this.styleOverrides.length - 1; i >= 0; i--) {
120
+ var item = this.styleOverrides[i];
121
+
122
+ if (isString(item)) {
123
+ // named-style-override
124
+ var style = this.styleDictionary[item];
125
+ if (style && !isUndefined(style[property]) && !isNull(style[property])) {
126
+ return style[property];
127
+ }
128
+ } else if (!isUndefined(item[property]) && !isNull(item[property])) {
129
+ // style-overrides-object
130
+ return item[property];
131
+ }
132
+ }
133
+ }
134
+
135
+ return this.defaultStyle && this.defaultStyle[property];
136
+ };
137
+
138
+ module.exports = StyleContextStack;