@rio-cloud/rio-uikit 1.13.1 → 1.13.2
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/.DS_Store +0 -0
- package/components/button/Button.d.ts +2 -0
- package/components/button/Button.js +1 -0
- package/lib/es/components/button/Button.d.ts +2 -0
- package/lib/es/components/button/Button.js +1 -0
- package/lib/es/utils/hidePiiData.js +35 -13
- package/lib/es/utils/init/initPiiObserver.js +1 -1
- package/lib/es/version.json +1 -1
- package/package.json +1 -1
- package/utils/hidePiiData.js +35 -13
- package/utils/init/initPiiObserver.js +1 -1
- package/version.json +1 -1
package/.DS_Store
CHANGED
|
Binary file
|
|
@@ -2,6 +2,7 @@ import React, { type ForwardRefExoticComponent, type HTMLProps, type PropsWithCh
|
|
|
2
2
|
import type { ObjectValues } from '../../utils/ObjectValues';
|
|
3
3
|
export declare const STYLES_MAP: {
|
|
4
4
|
readonly DEFAULT: "default";
|
|
5
|
+
readonly UNSTYLED: "unstyled";
|
|
5
6
|
readonly PRIMARY: "primary";
|
|
6
7
|
readonly SECONDARY: "secondary";
|
|
7
8
|
readonly INFO: "info";
|
|
@@ -125,6 +126,7 @@ export type ButtonProps = Omit<HTMLProps<HTMLButtonElement>, 'type' | 'onClick'>
|
|
|
125
126
|
type Props = PropsWithChildren<ButtonProps>;
|
|
126
127
|
type ButtonType = ForwardRefExoticComponent<Props & RefAttributes<HTMLButtonElement>> & {
|
|
127
128
|
DEFAULT: 'default';
|
|
129
|
+
UNSTYLED: 'unstyled';
|
|
128
130
|
PRIMARY: 'primary';
|
|
129
131
|
SECONDARY: 'secondary';
|
|
130
132
|
INFO: 'info';
|
|
@@ -2,6 +2,7 @@ import React, { type ForwardRefExoticComponent, type HTMLProps, type PropsWithCh
|
|
|
2
2
|
import type { ObjectValues } from '../../utils/ObjectValues';
|
|
3
3
|
export declare const STYLES_MAP: {
|
|
4
4
|
readonly DEFAULT: "default";
|
|
5
|
+
readonly UNSTYLED: "unstyled";
|
|
5
6
|
readonly PRIMARY: "primary";
|
|
6
7
|
readonly SECONDARY: "secondary";
|
|
7
8
|
readonly INFO: "info";
|
|
@@ -125,6 +126,7 @@ export type ButtonProps = Omit<HTMLProps<HTMLButtonElement>, 'type' | 'onClick'>
|
|
|
125
126
|
type Props = PropsWithChildren<ButtonProps>;
|
|
126
127
|
type ButtonType = ForwardRefExoticComponent<Props & RefAttributes<HTMLButtonElement>> & {
|
|
127
128
|
DEFAULT: 'default';
|
|
129
|
+
UNSTYLED: 'unstyled';
|
|
128
130
|
PRIMARY: 'primary';
|
|
129
131
|
SECONDARY: 'secondary';
|
|
130
132
|
INFO: 'info';
|
|
@@ -10,6 +10,7 @@ const buttonEffect_1 = require("../../utils/buttonEffect");
|
|
|
10
10
|
const useMergeRefs_1 = tslib_1.__importDefault(require("../../hooks/useMergeRefs"));
|
|
11
11
|
exports.STYLES_MAP = {
|
|
12
12
|
DEFAULT: 'default',
|
|
13
|
+
UNSTYLED: 'unstyled',
|
|
13
14
|
PRIMARY: 'primary',
|
|
14
15
|
SECONDARY: 'secondary',
|
|
15
16
|
INFO: 'info',
|
|
@@ -30,6 +30,9 @@
|
|
|
30
30
|
*/
|
|
31
31
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
32
|
exports.hidePiiData = exports.shufflePii = exports.shuffleText = void 0;
|
|
33
|
+
const ATTR_DATA_PII = 'data-pii';
|
|
34
|
+
const ATTR_ORIGINAL_PII = 'data-original-pii';
|
|
35
|
+
const ATTR_OBFUSCATED_PII = 'data-obfuscated-pii';
|
|
33
36
|
/**
|
|
34
37
|
* In place Fisher Yates shuffle.
|
|
35
38
|
* Randomizes the order of the given array using `Math.random()`.
|
|
@@ -306,26 +309,26 @@ const hidePiiData = (target, forceResult) => {
|
|
|
306
309
|
const elements = target instanceof Element ? [target] : Array.from(target);
|
|
307
310
|
for (const el of elements) {
|
|
308
311
|
// Mark the element as processed so other parts of the app can detect its state
|
|
309
|
-
el.setAttribute(
|
|
312
|
+
el.setAttribute(ATTR_DATA_PII, 'hidden');
|
|
310
313
|
const beforeText = (el.textContent || '').trim();
|
|
311
314
|
// If the selected element is an <input>, shuffle its value instead of text nodes
|
|
312
315
|
if (el.matches?.('input') || el.tagName === 'INPUT') {
|
|
313
316
|
const input = el;
|
|
314
317
|
const val = input.value || '';
|
|
315
318
|
if (typeof forceResult === 'string' && forceResult.length > 0) {
|
|
316
|
-
el.setAttribute(
|
|
319
|
+
el.setAttribute(ATTR_ORIGINAL_PII, val);
|
|
317
320
|
input.value = forceResult;
|
|
318
|
-
el.setAttribute(
|
|
321
|
+
el.setAttribute(ATTR_OBFUSCATED_PII, input.value);
|
|
319
322
|
continue;
|
|
320
323
|
}
|
|
321
|
-
el.setAttribute(
|
|
324
|
+
el.setAttribute(ATTR_ORIGINAL_PII, val);
|
|
322
325
|
const trimmed = val.trim();
|
|
323
326
|
if (trimmed.length > 0) {
|
|
324
327
|
const shuffled = (0, exports.shufflePii)(val);
|
|
325
328
|
if (shuffled !== val) {
|
|
326
329
|
input.value = shuffled;
|
|
327
330
|
}
|
|
328
|
-
el.setAttribute(
|
|
331
|
+
el.setAttribute(ATTR_OBFUSCATED_PII, input.value);
|
|
329
332
|
}
|
|
330
333
|
continue; // skip text-node processing for inputs
|
|
331
334
|
}
|
|
@@ -365,10 +368,10 @@ const hidePiiData = (target, forceResult) => {
|
|
|
365
368
|
};
|
|
366
369
|
if (typeof forceResult === 'string' && forceResult.length > 0) {
|
|
367
370
|
if (beforeText) {
|
|
368
|
-
el.setAttribute(
|
|
371
|
+
el.setAttribute(ATTR_ORIGINAL_PII, beforeText);
|
|
369
372
|
}
|
|
370
373
|
applyForcedText(el, forceResult);
|
|
371
|
-
el.setAttribute(
|
|
374
|
+
el.setAttribute(ATTR_OBFUSCATED_PII, (el.textContent || '').trim());
|
|
372
375
|
continue;
|
|
373
376
|
}
|
|
374
377
|
let anyTextChanged = false;
|
|
@@ -377,20 +380,39 @@ const hidePiiData = (target, forceResult) => {
|
|
|
377
380
|
let node = walker.nextNode();
|
|
378
381
|
while (node) {
|
|
379
382
|
const txtNode = node;
|
|
380
|
-
const original = txtNode.
|
|
381
|
-
|
|
383
|
+
const original = String(txtNode.textContent || '');
|
|
384
|
+
// Whitespace fix 1/2: If the text node contains only whitespace, remove it entirely
|
|
385
|
+
if (/^\s*$/.test(original)) {
|
|
386
|
+
const nextNode = walker.nextNode();
|
|
387
|
+
txtNode.remove();
|
|
388
|
+
node = nextNode;
|
|
389
|
+
continue;
|
|
390
|
+
}
|
|
391
|
+
// Normalize all whitespace in non-empty text nodes to a single space
|
|
392
|
+
const normalized = original.replace(/\s+/g, ' ');
|
|
393
|
+
const trimmed = normalized.trim();
|
|
382
394
|
if (trimmed.length > 0) {
|
|
383
|
-
const shuffled = (0, exports.shufflePii)(
|
|
384
|
-
if (shuffled !==
|
|
385
|
-
txtNode.
|
|
395
|
+
const shuffled = (0, exports.shufflePii)(normalized);
|
|
396
|
+
if (shuffled !== normalized) {
|
|
397
|
+
txtNode.textContent = shuffled;
|
|
386
398
|
anyTextChanged = true;
|
|
387
399
|
}
|
|
388
400
|
}
|
|
389
401
|
node = walker.nextNode();
|
|
390
402
|
}
|
|
403
|
+
// Whitespace fix 2/2: Restore spacing between adjacent text nodes
|
|
404
|
+
const directTextNodes = Array.from(el.childNodes).filter(n => n.nodeType === Node.TEXT_NODE);
|
|
405
|
+
for (let i = 0; i < directTextNodes.length - 1; i++) {
|
|
406
|
+
const current = directTextNodes[i];
|
|
407
|
+
const next = directTextNodes[i + 1];
|
|
408
|
+
if (current.textContent?.trim() && next.textContent?.trim()) {
|
|
409
|
+
const spacer = document.createTextNode(' ');
|
|
410
|
+
current.parentNode?.insertBefore(spacer, next);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
391
413
|
const currentText = (el.textContent || '').trim();
|
|
392
414
|
if (anyTextChanged && currentText) {
|
|
393
|
-
el.setAttribute(
|
|
415
|
+
el.setAttribute(ATTR_OBFUSCATED_PII, currentText);
|
|
394
416
|
if (beforeText) {
|
|
395
417
|
el.setAttribute('data-original-pii', beforeText);
|
|
396
418
|
}
|
|
@@ -108,7 +108,7 @@ const initPiiObserver = () => {
|
|
|
108
108
|
ensureHiddenConsistent(node);
|
|
109
109
|
const descendants = node.querySelectorAll(SELECTOR_PII_OBFUSCATED + SELECTOR_PII_ORIGINAL);
|
|
110
110
|
for (const descendant of descendants) {
|
|
111
|
-
console.log('data-original-pii:', descendant.getAttribute(ATTR_ORIGINAL_PII));
|
|
111
|
+
// console.log('data-original-pii:', descendant.getAttribute(ATTR_ORIGINAL_PII));
|
|
112
112
|
ensureHiddenConsistent(descendant);
|
|
113
113
|
}
|
|
114
114
|
}
|
package/lib/es/version.json
CHANGED
package/package.json
CHANGED
package/utils/hidePiiData.js
CHANGED
|
@@ -27,6 +27,9 @@
|
|
|
27
27
|
* - `data-pii="hidden"` is written to elements that have already been processed to help external code introspect state.
|
|
28
28
|
* - `data-hide-pii="shuffle"` on `<html>` is used by an external observer to decide when to call `hidePiiData`.
|
|
29
29
|
*/
|
|
30
|
+
const ATTR_DATA_PII = 'data-pii';
|
|
31
|
+
const ATTR_ORIGINAL_PII = 'data-original-pii';
|
|
32
|
+
const ATTR_OBFUSCATED_PII = 'data-obfuscated-pii';
|
|
30
33
|
/**
|
|
31
34
|
* In place Fisher Yates shuffle.
|
|
32
35
|
* Randomizes the order of the given array using `Math.random()`.
|
|
@@ -301,26 +304,26 @@ export const hidePiiData = (target, forceResult) => {
|
|
|
301
304
|
const elements = target instanceof Element ? [target] : Array.from(target);
|
|
302
305
|
for (const el of elements) {
|
|
303
306
|
// Mark the element as processed so other parts of the app can detect its state
|
|
304
|
-
el.setAttribute(
|
|
307
|
+
el.setAttribute(ATTR_DATA_PII, 'hidden');
|
|
305
308
|
const beforeText = (el.textContent || '').trim();
|
|
306
309
|
// If the selected element is an <input>, shuffle its value instead of text nodes
|
|
307
310
|
if (el.matches?.('input') || el.tagName === 'INPUT') {
|
|
308
311
|
const input = el;
|
|
309
312
|
const val = input.value || '';
|
|
310
313
|
if (typeof forceResult === 'string' && forceResult.length > 0) {
|
|
311
|
-
el.setAttribute(
|
|
314
|
+
el.setAttribute(ATTR_ORIGINAL_PII, val);
|
|
312
315
|
input.value = forceResult;
|
|
313
|
-
el.setAttribute(
|
|
316
|
+
el.setAttribute(ATTR_OBFUSCATED_PII, input.value);
|
|
314
317
|
continue;
|
|
315
318
|
}
|
|
316
|
-
el.setAttribute(
|
|
319
|
+
el.setAttribute(ATTR_ORIGINAL_PII, val);
|
|
317
320
|
const trimmed = val.trim();
|
|
318
321
|
if (trimmed.length > 0) {
|
|
319
322
|
const shuffled = shufflePii(val);
|
|
320
323
|
if (shuffled !== val) {
|
|
321
324
|
input.value = shuffled;
|
|
322
325
|
}
|
|
323
|
-
el.setAttribute(
|
|
326
|
+
el.setAttribute(ATTR_OBFUSCATED_PII, input.value);
|
|
324
327
|
}
|
|
325
328
|
continue; // skip text-node processing for inputs
|
|
326
329
|
}
|
|
@@ -360,10 +363,10 @@ export const hidePiiData = (target, forceResult) => {
|
|
|
360
363
|
};
|
|
361
364
|
if (typeof forceResult === 'string' && forceResult.length > 0) {
|
|
362
365
|
if (beforeText) {
|
|
363
|
-
el.setAttribute(
|
|
366
|
+
el.setAttribute(ATTR_ORIGINAL_PII, beforeText);
|
|
364
367
|
}
|
|
365
368
|
applyForcedText(el, forceResult);
|
|
366
|
-
el.setAttribute(
|
|
369
|
+
el.setAttribute(ATTR_OBFUSCATED_PII, (el.textContent || '').trim());
|
|
367
370
|
continue;
|
|
368
371
|
}
|
|
369
372
|
let anyTextChanged = false;
|
|
@@ -372,20 +375,39 @@ export const hidePiiData = (target, forceResult) => {
|
|
|
372
375
|
let node = walker.nextNode();
|
|
373
376
|
while (node) {
|
|
374
377
|
const txtNode = node;
|
|
375
|
-
const original = txtNode.
|
|
376
|
-
|
|
378
|
+
const original = String(txtNode.textContent || '');
|
|
379
|
+
// Whitespace fix 1/2: If the text node contains only whitespace, remove it entirely
|
|
380
|
+
if (/^\s*$/.test(original)) {
|
|
381
|
+
const nextNode = walker.nextNode();
|
|
382
|
+
txtNode.remove();
|
|
383
|
+
node = nextNode;
|
|
384
|
+
continue;
|
|
385
|
+
}
|
|
386
|
+
// Normalize all whitespace in non-empty text nodes to a single space
|
|
387
|
+
const normalized = original.replace(/\s+/g, ' ');
|
|
388
|
+
const trimmed = normalized.trim();
|
|
377
389
|
if (trimmed.length > 0) {
|
|
378
|
-
const shuffled = shufflePii(
|
|
379
|
-
if (shuffled !==
|
|
380
|
-
txtNode.
|
|
390
|
+
const shuffled = shufflePii(normalized);
|
|
391
|
+
if (shuffled !== normalized) {
|
|
392
|
+
txtNode.textContent = shuffled;
|
|
381
393
|
anyTextChanged = true;
|
|
382
394
|
}
|
|
383
395
|
}
|
|
384
396
|
node = walker.nextNode();
|
|
385
397
|
}
|
|
398
|
+
// Whitespace fix 2/2: Restore spacing between adjacent text nodes
|
|
399
|
+
const directTextNodes = Array.from(el.childNodes).filter(n => n.nodeType === Node.TEXT_NODE);
|
|
400
|
+
for (let i = 0; i < directTextNodes.length - 1; i++) {
|
|
401
|
+
const current = directTextNodes[i];
|
|
402
|
+
const next = directTextNodes[i + 1];
|
|
403
|
+
if (current.textContent?.trim() && next.textContent?.trim()) {
|
|
404
|
+
const spacer = document.createTextNode(' ');
|
|
405
|
+
current.parentNode?.insertBefore(spacer, next);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
386
408
|
const currentText = (el.textContent || '').trim();
|
|
387
409
|
if (anyTextChanged && currentText) {
|
|
388
|
-
el.setAttribute(
|
|
410
|
+
el.setAttribute(ATTR_OBFUSCATED_PII, currentText);
|
|
389
411
|
if (beforeText) {
|
|
390
412
|
el.setAttribute('data-original-pii', beforeText);
|
|
391
413
|
}
|
|
@@ -105,7 +105,7 @@ export const initPiiObserver = () => {
|
|
|
105
105
|
ensureHiddenConsistent(node);
|
|
106
106
|
const descendants = node.querySelectorAll(SELECTOR_PII_OBFUSCATED + SELECTOR_PII_ORIGINAL);
|
|
107
107
|
for (const descendant of descendants) {
|
|
108
|
-
console.log('data-original-pii:', descendant.getAttribute(ATTR_ORIGINAL_PII));
|
|
108
|
+
// console.log('data-original-pii:', descendant.getAttribute(ATTR_ORIGINAL_PII));
|
|
109
109
|
ensureHiddenConsistent(descendant);
|
|
110
110
|
}
|
|
111
111
|
}
|
package/version.json
CHANGED