PageSourceSearch

https://www.jbl.com.sg/on/demandware.static/Sites-JB-APAC-NCOM-Sit…/v1790551988158/js/app/001_namespace.js

js jbl.com.sg collected 2026-09-28 06:46:21 UTC 5,423 bytes, 176 lines download raw bytes

1/** @namespace */
2var app = (function (app, $) {
3	//allows the use of $ within this function without conflicting with other JavaScript libraries which are using it (JQuery extension)
4	/******** private functions & vars **********/
5
6	/**
7	 * @private
8	 * @function
9	 * @description Cache dom elements which are being accessed multiple times.<br/>app.ui holds globally available elements.
10	 */
11	function initUiCache() {
12		app.ui = {
13			searchContainer : $(".header-search"),
14			printPage		: $("a.print-page"),
15			reviewsContainer: $("#pwrwritediv"),
16			main			: $("#main"),
17			primary			: $("#primary"),
18			secondary		: $("#secondary"),
19			// elements found in content slots
20			slots : {
21				subscribeEmail : $(".subscribe-email")
22			}
23		};
24	}
25
26	/**
27	 * @private
28	 * @function
29	 * @description Apply dialogify event handler to all elements that match one or more of the specified selectors.
30	 */
31	function initializeEvents() {
32		var controlKeys = ["8", "13", "46", "45", "36", "35", "38", "37", "40", "39"];
33
34		$("body").on("click", ".dialogify, [data-modal], [data-dlg-options], [data-dlg-action]", app.util.setDialogify)
35		.on("keydown", "textarea[data-character-limit]", function(e) {
36			var text = $.trim($(this).val()),
37				charsLimit = $(this).data("character-limit"),
38				charsUsed = text.length;
39
40				if ((charsUsed >= charsLimit) && (controlKeys.indexOf(e.which.toString()) < 0)) {
41					e.preventDefault();
42				}
43		})
44		.on("change keyup mouseup", "textarea[data-character-limit]", function(e) {
45			var text = $.trim($(this).val()),
46				charsLimit = $(this).data("character-limit"),
47				charsUsed = text.length,
48				charsRemain = charsLimit - charsUsed;
49
50			if(charsRemain < 0) {
51				$(this).val( text.slice(0, charsRemain) );
52				charsRemain = 0;
53			}
54
55			$(this).next('div.char-count').find('.char-remain-count').html(charsRemain);
56		});
57
58
59		/**
60		 * initialize search suggestions, pending the value of the site preference(enhancedSearchSuggestions)
61		 * this will either init the legacy(false) or the beta versions(true) of the the search suggest feature.
62		 * */
63		if(app.clientcache.LISTING_SEARCHSUGGEST_LEGACY){
64			app.searchsuggestbeta.init(app.ui.searchContainer, app.resources.SIMPLE_SEARCH);
65		}else{
66			app.searchsuggest.init(app.ui.searchContainer, app.resources.SIMPLE_SEARCH);
67		}
68
69		// print handler
70		app.ui.printPage.on("click", function () { window.print(); return false; });
71
72
73		// add show/hide navigation elements
74		$('.secondary-navigation .toggle').click(function(){
75			$(this).toggleClass('expanded').next('ul').toggle();
76		});
77
78		// add generic toggle functionality
79		$('.toggle').next('.toggle-content').hide();
80		$('.toggle').click(function(){
81			$(this).toggleClass('expanded').next('.toggle-content').toggle();
82		});
83
84		// subscribe email box
85		if (app.ui.slots.subscribeEmail.length > 0)	{
86			app.ui.slots.subscribeEmail.focus(function () {
87				var val = $(this.val());
88				if(val.length > 0 && val !== app.resources.SUBSCRIBE_EMAIL_DEFAULT) {
89					return; // do not animate when contains non-default value
90				}
91
92				$(this).animate({ color: '#999999'}, 500, 'linear', function () {
93					$(this).val('').css('color','#333333');
94				});
95			}).blur(function () {
96				var val = $.trim($(this.val()));
97				if(val.length > 0) {
98					return; // do not animate when contains value
99				}
100
101				$(this).val(app.resources.SUBSCRIBE_EMAIL_DEFAULT)
102					   .css('color','#999999')
103					   .animate({color: '#333333'}, 500, 'linear');
104
105			});
106		}
107	}
108	/**
109	 * @private
110	 * @function
111	 * @description Adds class ('js') to html for css targeting and loads js specific styles.
112	 */
113	function initializeDom() {
114		// add class to html for css targeting
115		$('html').addClass('js');
116		if (app.clientcache.LISTING_INFINITE_SCROLL){
117			$('html').addClass('infinite-scroll');
118		}
119		// load js specific styles
120		app.util.limitCharacters();
121		// really!!! really bad way to solve HAR10-273 issue
122		$('a[href="/content?ContentID=jbl-wireless"]').filter(':not(:has(img))').remove();
123		$('a[href="/portable-speakers/JBL+CHARGE+II+PLUS.html"]').filter(':not(:has(img))').remove();
124	}
125
126
127	/**
128	 * @property {Object} _app "inherits" app object via $.extend() at the end of this seaf (Self-Executing Anonymous Function)
129	 */
130	var _app = {
131		containerId		: "content",
132		ProductCache	: null,  // app.Product object ref to the current/main product
133		ProductDetail	: null,
134		clearDivHtml	: '<div class="clear"></div>',
135		currencyCodes	: app.currencyCodes || {}, // holds currency code/symbol for the site
136
137		/**
138		 * @name init
139		 * @function
140		 * @description Master page initialization routine
141		 */
142		init: function () {
143
144			if (document.cookie.length===0) {
145				$("<div/>").addClass("browser-compatibility-alert").append($("<p/>").addClass("browser-error").html(app.resources.COOKIES_DISABLED)).appendTo("#browser-check");
146			}
147
148
149			// init global cache
150			initUiCache();
151
152			// init global dom elements
153			initializeDom();
154
155			// init global events
156			initializeEvents();
157
158			// init specific global components
159			app.tooltips.init();
160			app.minicart.init();
161			//app.components.init();
162			app.searchplaceholder.init();
163			//app.mulitcurrency.init();
164			app.storefront.init();
165			app.navigation.init();
166
167			// execute page specific initializations
168			var ns = app.page.ns;
169			if (ns && app[ns] && app[ns].init) {
170				app[ns].init();
171			}
172		}
173	};
174
175	return $.extend(app, _app);
176}(window.app = window.app || {}, jQuery));

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.