PageSourceSearch

https://samnanstore.com/wp-content/plugins/saudi-riyal-symbol-for-…/assets/js/gulf-currencies.js?ver=2.1

js samnanstore.com collected 2026-09-24 11:02:07 UTC 3,097 bytes, 131 lines download raw bytes

1/**
2 * Gulf Currencies Symbol Fix for WooCommerce.
3 *
4 * Adds 'gulf-currency' class to the direct parent element of Gulf currency symbols
5 * to enable proper font rendering.
6 */
7( function() {
8	'use strict';
9
10	// Determine class based on context
11	const isAdmin = document.body.classList.contains( 'wp-admin' );
12	const currencyClass = isAdmin ? 'gulf-currency-dashboard' : 'gulf-currency';
13
14	// Build symbols array from localized data or fallbacks (SAR=U+20C1, AED=U+E001, OMR=U+E900)
15	const symbols = ( typeof nsrwcGulfCurrencies !== 'undefined' && nsrwcGulfCurrencies.symbols )
16		? Object.values( nsrwcGulfCurrencies.symbols )
17		: [ '\u20C1', '\uE001', '\uE900' ];
18
19	// Pre-compiled regex for O(1) symbol detection
20	const symbolRegex = new RegExp( '[' + symbols.join( '' ) + ']' );
21
22	// Track processed elements to avoid duplicate work
23	const processed = new WeakSet();
24
25	// Debounce state
26	let pending = [];
27	let rafId = null;
28
29	/**
30	 * Mark element with currency class.
31	 */
32	function markElement( el ) {
33		if ( el && el.classList && ! processed.has( el ) ) {
34			el.classList.add( currencyClass );
35			processed.add( el );
36		}
37	}
38
39	/**
40	 * Process a text node - mark its parent if it contains a symbol.
41	 */
42	function processTextNode( node ) {
43		if ( node.nodeValue && symbolRegex.test( node.nodeValue ) ) {
44			markElement( node.parentElement );
45		}
46	}
47
48	/**
49	 * Scan all text nodes in a container.
50	 */
51	function scanContainer( root ) {
52		const walker = document.createTreeWalker( root, NodeFilter.SHOW_TEXT );
53		let node;
54		while ( ( node = walker.nextNode() ) ) {
55			processTextNode( node );
56		}
57	}
58
59	/**
60	 * Process pending nodes in batched animation frame.
61	 */
62	function flushPending() {
63		rafId = null;
64		const nodes = pending;
65		pending = [];
66
67		for ( let i = 0, len = nodes.length; i < len; i++ ) {
68			const node = nodes[ i ];
69			if ( node.nodeType === 3 ) {
70				processTextNode( node );
71			} else if ( node.nodeType === 1 && node.isConnected ) {
72				scanContainer( node );
73			}
74		}
75	}
76
77	/**
78	 * Schedule pending nodes processing.
79	 */
80	function schedulePending() {
81		if ( ! rafId ) {
82			rafId = requestAnimationFrame( flushPending );
83		}
84	}
85
86	/**
87	 * MutationObserver callback.
88	 */
89	function onMutation( mutations ) {
90		for ( let i = 0, len = mutations.length; i < len; i++ ) {
91			const m = mutations[ i ];
92
93			// Collect added nodes
94			const added = m.addedNodes;
95			for ( let j = 0, jLen = added.length; j < jLen; j++ ) {
96				pending.push( added[ j ] );
97			}
98
99			// Handle character data changes immediately
100			if ( m.type === 'characterData' ) {
101				processTextNode( m.target );
102			}
103		}
104
105		if ( pending.length ) {
106			schedulePending();
107		}
108	}
109
110	// Create observer
111	const observer = new MutationObserver( onMutation );
112
113	/**
114	 * Initialize scanning and observing.
115	 */
116	function init() {
117		scanContainer( document.body );
118		observer.observe( document.body, {
119			childList: true,
120			subtree: true,
121			characterData: true
122		} );
123	}
124
125	// Run when ready
126	if ( document.readyState === 'loading' ) {
127		document.addEventListener( 'DOMContentLoaded', init );
128	} else {
129		init();
130	}
131} )();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.