PageSourceSearch

https://business.fallbrookchamberofcommerce.org/GZContent/PublicWidgets/Partners.js

js fallbrookchamberofcommerce.org collected 2026-10-02 07:25:44 UTC 13,906 bytes, 327 lines download raw bytes

1(function (document) {
2    /**
3     * A storage interface that uses sessionStorage when available and falls back to an in-memory object.
4    */
5    class StorageAdapter {
6        constructor(namespace) {
7            this._namespace = namespace || 'app';
8            this._useSessionStorage = this._isSessionStorageAvailable();
9            this._memoryCache = {};
10        }
11
12        /**
13         * Tests if sessionStorage is available and functional.
14         * @returns {boolean} True if sessionStorage is available.
15         */
16        _isSessionStorageAvailable() {
17            try {
18                var testKey = '__storage_test__';
19                sessionStorage.setItem(testKey, testKey);
20                sessionStorage.removeItem(testKey);
21                return true;
22            } catch (e) {
23                return false;
24            }
25        }
26
27        /**
28         * Gets the full key with namespace prefix.
29         * @param {string} key - The key to namespace.
30         * @returns {string} The namespaced key.
31         */
32        _getNamespacedKey(key) {
33            return this._namespace + ':' + key;
34        }
35
36        /**
37         * Gets a value from storage.
38         * @param {string} key - The key to retrieve.
39         * @returns {*} The stored value, or null if not found.
40         */
41        getItem(key) {
42            var namespacedKey = this._getNamespacedKey(key);
43
44            if (this._useSessionStorage) {
45                try {
46                    var value = sessionStorage.getItem(namespacedKey);
47                    return value ? JSON.parse(value) : null;
48                } catch (e) {
49                    // Fall back to memory cache if sessionStorage fails
50                    return this._memoryCache[namespacedKey] || null;
51                }
52            }
53
54            return this._memoryCache[namespacedKey] || null;
55        }
56
57        /**
58         * Sets a value in storage.
59         * @param {string} key - The key to set.
60         * @param {*} value - The value to store.
61         */
62        setItem(key, value) {
63            var namespacedKey = this._getNamespacedKey(key);
64
65            if (this._useSessionStorage) {
66                try {
67                    sessionStorage.setItem(namespacedKey, JSON.stringify(value));
68                    return;
69                } catch (e) {
70                    // Fall back to memory cache if sessionStorage fails
71                    this._memoryCache[namespacedKey] = value;
72                }
73            } else {
74                this._memoryCache[namespacedKey] = value;
75            }
76        }
77
78        /**
79         * Removes a value from storage.
80         * @param {string} key - The key to remove.
81         */
82        removeItem(key) {
83            var namespacedKey = this._getNamespacedKey(key);
84
85            if (this._useSessionStorage) {
86                try {
87                    sessionStorage.removeItem(namespacedKey);
88                } catch (e) {
89                    // Continue to remove from memory cache
90                }
91            }
92
93            delete this._memoryCache[namespacedKey];
94        }
95
96        /**
97         * Clears all items in the namespace.
98         */
99        clear() {
100            if (this._useSessionStorage) {
101                try {
102                    var keysToRemove = [];
103                    for (var i = 0; i < sessionStorage.length; i++) {
104                        var key = sessionStorage.key(i);
105                        if (key && key.indexOf(this._namespace + ':') === 0) {
106                            keysToRemove.push(key);
107                        }
108                    }
109                    keysToRemove.forEach(function (key) {
110                        sessionStorage.removeItem(key);
111                    });
112                } catch (e) {
113                    // Continue to clear memory cache
114                }
115            }
116
117            // Clear memory cache
118            var prefix = this._namespace + ':';
119            Object.keys(this._memoryCache).forEach(function (key) {
120                if (key.indexOf(prefix) === 0) {
121                    delete this._memoryCache[key];
122                }
123            });
124        }
125
126        /**
127         * Checks if a key exists in storage.
128         * @param {string} key - The key to check.
129         * @returns {boolean} True if the key exists.
130         */
131        hasItem(key) {
132            return this.getItem(key) !== null;
133        }
134    }
135
136    var countAllImpressions = false;
137    var cache = new StorageAdapter('mni-partners-viewed');
138    var pendingEvents = []; // Queue for events before gza loads
139
140    (function () {
141        var l = getScriptTagData();
142        var url = '//' + l.domain + '/api/widget/analytics';
143        getData(url, function (data) {
144            if ((data || {}).Enabled) {
145                countAllImpressions = data.CountAllImpressions;
146                (function (b, d, a, c) { b.getElementById(d) || (c = b.getElementsByTagName(a)[0], a = b.createElement(a), a.type = "text/javascript", a.async = !0, a.src = '//' + l.domain + "/GZContent/analytics/gza.js", c.parentNode.insertBefore(a, c)) })(document, "mni-analytics-script", "script");
147            }
148        });
149    })();
150
151    var queueVarName = '_mnipartq';
152
153    function getPartnerKey(props) {
154        return props.tenant + '-' + props.id + '-' + props.location;
155    }
156    function hasKey(props) {
157        // if we are not counting all impressions,
158        return !countAllImpressions
159            // only check for the key if this is a view action, as clicks should always be counted
160            && props.action === 'view'
161            // check the session storage/memory cache for the key to determine if this impression has already been counted
162            && cache.hasItem(getPartnerKey(props));
163    }
164    function setKey(props) {
165        // if we are not counting all impressions
166        if (!countAllImpressions
167            // and this is a view action,
168            && props.action === 'view') {
169            // set the key in session storage / memory cache so that subsequent impressions with the same tenant, partner, and location will not be counted
170            cache.setItem(getPartnerKey(props), true);
171        }
172    }
173
174    function getScriptTagData() {
175        var scripts = document.getElementsByTagName('script');
176
177        for (var i = 0; i < scripts.length; i++) {
178            var script = scripts[i],
179                match = script.src.match(/^((https?:)?\/\/([^/]+))\/.+\/publicwidgets\/partners\.(min\.)?js/i);
180
181            if (match) {
182                return {
183                    protocol: match[2] || window.location.protocol,
184                    origin: match[1] || window.location.origin,
185                    domain: match[3] || window.location.host
186                };
187            }
188        }
189        return {
190            protocol: window.location.protocol,
191            origin: window.location.origin,
192            domain: window.location.host
193        };
194    }
195    function parseUrl(param) {
196        return (!!param.push) ? param.join(',') : param;
197    }
198    function getUrl(params, valid) {
199        var l = getScriptTagData();
200        var v = valid ? valid.reduce(function (o, k) { o[k] = true; return o; }, {}) : null;
201        var args = Object.keys(params)
202            .filter(function (k) { return !v || !!v[k] })
203            .map(function (k) { return k + '=' + parseUrl(params[k]) });
204
205        return '//' + l.domain + '/api/widget/partners' + (args.length ? "?" + args.join('&') : "");
206    }
207    function createXHR() {
208        if (window.XMLHttpRequest)
209            try { return new XMLHttpRequest(); } catch (e) { }
210
211        if (window.ActiveXObject) {
212            try { return new ActiveXObject("MSXML2.XMLHTTP"); } catch (e) { }
213            try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { }
214        }
215    }
216    function getData(url, callback) {
217        var xhr = createXHR();
218        xhr.open('GET', url, true);
219        //xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
220        xhr.setRequestHeader('Accept', 'application/json, text/javascript, */*');
221        xhr.onreadystatechange = function () {
222            if (this.readyState == 4 && this.status == 200)
223                callback(JSON.parse(this.responseText));
224        };
225        xhr.send();
226    }
227
228    function send(props) {
229        var analytics = (window.gza || function () { })();
230        pendingEvents.push(props);
231        if (analytics) {
232            pendingEvents.forEach(function (p) {
233                if (!hasKey(p)) {
234                    analytics.track('Partner', p);
235                    setKey(p);
236                }
237            });
238            pendingEvents = [];
239        }
240    }
241    var widgets = window[queueVarName].reduce(function (o, k) {
242        var params = k[0].split('.');
243        var id = params[0];
244        var arg = params[1];
245        if (!o[id]) o[id] = {};
246        if (!o[id].loaded) o[id][arg] = k[1];
247        return o;
248    }, {});
249
250    Object.keys(widgets).forEach(function (k) { Init(k, widgets[k]); });
251
252    var render = function (id, params, items, format) {
253        var width = (items[0] || {}).Width;
254        var height = (items[0] || {}).Height;
255        return '<div class="mni-partners-widget transition-' + (params['animation'] ? "fade" : "flash") + '">' +
256            //'<div class="edge"></div>' +
257            '<div class="mni-partners-container">' +
258            '<ul class="partners">' +
259            items.reduce(function (o, k) { return o + format(k) }, '') +
260            '</ul>' +
261            '</div>' +
262            '</div>' +
263            '<style> #' + id + ' .mni-partners-widget { text-align: center; } #' + id + ' .mni-partners-container { ' + (width ? ('max-width:' + width + 'px;width:100%;') : '') + (height ? ('height:' + height + 'px;') : '') + ' display: inline-block; } #' + id + ' .mni-partners-widget .partners { margin: 0px; padding: 0px; position: relative; } #' + id + ' .mni-partners-widget .partner { position: absolute; } #' + id + ' .mni-partners-widget.transition-fade .partner { -webkit-transition: opacity 1s ease; -moz-transition: opacity 1s ease; -ms-transition: opacity 1s ease; -o-transition: opacity 1s ease; transition: opacity 1s ease; opacity: 0; height: 0; overflow: hidden; } #' + id + ' .mni-partners-widget.transition-fade .partner.mn-active { opacity: 1; height: auto; } #' + id + ' .mni-partners-widget.transition-flash .partner { display:none; } #' + id + ' .mni-partners-widget.transition-flash .partner.mn-active { display:block; }</style>';
264    };
265    function Init(id, params) {
266        var format = function (item) {
267            return '<li class="partner" ' +
268                'data-partner-id="' + (item.AdvertisementId || 0) + '" ' +
269                'data-partner-slug="' + (item.AdvertisementSlug || 0) + '" ' +
270                'data-location-id="' + (item.AdvertisementPlacementId || 0) + '" ' +
271                'data-location-slug="' + (item.LocationSlug || 0) + '" ' +
272                'data-tenant-id="' + (item.TenantKey || 0) + '">' +
273                '<a href="' + item.URL + '" target="' + item.Target + '" >' +
274                '<image src="' + item.Image + '" alt="' + item.ImageShortDescription + '"/>' +
275                '</a>' +
276                '</li>';
277        }
278        var id = params['create'];
279        getData(getUrl(params, ['type', 'max', 'v', 'pageId', 'position', 'categoryItemId', 'parentCategoryId']), function (items) {
280            document.getElementById(id).innerHTML = render(id, params, items, format);
281
282            var partners = document.querySelectorAll('#' + id + ' .partner');
283            if (partners.length) {
284                for (const partner of partners) {
285                    partner.addEventListener('click', function () {
286                        send({
287                            action: 'click',
288                            id: this.dataset.partnerId,
289                            idSlug: this.dataset.partnerSlug,
290                            location: this.dataset.locationId,
291                            locationSlug: this.dataset.locationSlug,
292                            tenant: this.dataset.tenantId
293                        });
294                    });
295                }
296
297                var all = partners.length;
298                var current = all - 2;
299                var timeout = null;
300                var delay = params['delay'] || 5;
301                function changeImg(b) {
302                    var currentPartner = partners[(all - ((Math.abs(b ? --current : ++current) % all) + 1))];
303                    var triggerAnalytics = !currentPartner.classList.contains('mn-active');
304                    partners.forEach(function (p) { p.classList.remove('mn-active'); });
305                    currentPartner.classList.add('mn-active');
306
307                    if (triggerAnalytics) {
308                        send({
309                            action: 'view',
310                            id: currentPartner.dataset.partnerId,
311                            idSlug: currentPartner.dataset.partnerSlug,
312                            location: currentPartner.dataset.locationId,
313                            locationSlug: currentPartner.dataset.locationSlug,
314                            tenant: currentPartner.dataset.tenantId
315                        });
316                    }
317                }
318                function dChangeImg(b) {
319                    if (timeout) clearInterval(timeout);
320                    timeout = setInterval(changeImg, (delay * 1000));
321                    changeImg(b);
322                }
323                dChangeImg();
324            }
325        });
326    }
327})(window.document)

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.