Subversion Repositories munaweb

Rev

Rev 85 | Rev 97 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
//
75 - 2
// Authorization
3
//
87 - 4
var configRuName = 'XxXRuNamexxxxxxxxxxxxxxxxxxxxxxx'; // must have the same length as the actual token
75 - 5
var configAppid = 'XxXAppid';
6
var configDevid = 'XxXDevid';
7
var configCertid = 'XxXCertid';
8
var configDiscogsToken = 'XxXDiscogsToken';
9
var configUSPSUserId = 'XxXUSPSUserId';
10
var configShopifyApiKey = 'XxXShopifyApiKey';
11
var configShopifyPassword = 'XxXShopifyPassword';
12
var configUPSAccessKey = 'XxXUPSAccessKey';
13
var configUPSUsername = 'XxXUPSUsername';
14
var configUPSPassword = 'XxXUPSPassword';
15
 
16
//
2 - 17
// Globals
18
//
19
var configServiceEndpoint = 'https://api.ebay.com/ws/api.dll';
20
var configWarningLevel = "Low";
21
var configSigninUrl = 'https://signin.ebay.com/ws/eBayISAPI.dll';
85 - 22
var configeBayLoginUrl = 'https://www.munatrading.linkpc.net/ebay/ebayLogin.php';
3 - 23
var configOauthTokenUrl = 'https://api.ebay.com/identity/v1/oauth2/token';
2 - 24
var configXmlRequestEntriesPerPage = '100';
25
var configLinkedPayPal = 'paypal@munatrading.com';
85 - 26
var configListingUrl = 'https://www.munatrading.linkpc.net/ebay/listings/';
2 - 27
var configDiscogsBaseUrl = 'https://www.discogs.com';
36 - 28
var configDiscogsApiBaseUrl = 'https://api.discogs.com';
29
var configDiscogsApiUrl = configDiscogsApiBaseUrl + '/database/search';
30
var configDiscogsPriceUrl = configDiscogsApiBaseUrl + '/marketplace/price_suggestions/';
2 - 31
var configDiscogsUserAgent = 'MUNA_Trading/1.0 +http://www.munatrading.com';
85 - 32
var configProxyUrl = 'https://www.munatrading.linkpc.net/proxy.php';
7 - 33
var configShopifyUrl = 'https://' + configShopifyApiKey + ':' + configShopifyPassword + '@muna-trading.myshopify.com/admin/';
2 - 34
var configShopifyProductsUrl = 'products.json';
32 - 35
var configShopifyProductCountUrl = 'products/count.json';
2 - 36
var configShopifyOrdersUrl = 'orders.json';
37
var configShopifyTransactionsUrl1 = 'orders/';
38
var configShopifyTransactionsUrl2 = '/transactions.json';
39
var configShopifyOrderLimit = 250;
40
var configeBayTradingVersion = '1085';
41
var configeBayMarketingVersion = 'v1.4.0';
42
var configeBayFinding = 'https://svcs.ebay.com/services/search/FindingService/v1';
43
var configeBayFindingVersion = '1.13.0';
17 - 44
var configeBayPostOrder = 'https://api.ebay.com/post-order/v2';
2 - 45
var configeBayShopping = 'http://open.api.ebay.com/shopping';
46
var configeBayShoppingVersion = '1063';
47
var configeBayAdCampaign = 'https://api.ebay.com/sell/marketing/v1/ad_campaign/';
48
var configUPSUrl = 'https://onlinetools.ups.com/ups.app/xml/Track';
49
var configUSPSUrl = 'https://secure.shippingapis.com/ShippingApi.dll';
50
var configGoogleMapsKey = 'AIzaSyBeSjH1CypAnYMYy_LIHqe8ngaAC6O-FWE';
51
 
52
var configTaxStateId = 'VA';
53
var configTaxRate = '6.000';
54
var configZip = '20120';
55
var configGetRecommendations = true;
56
var configDoesNotApply = 'Does not apply';
57
var configDefaultCountry = 'United States';
58
var configDefaultLanguage = 'English';
59
var configImage1Extension = ' Front.jpg';
60
var configImage2Extension = ' Rear.jpg';
61
var configdescriptionImageExtension = ' Front and Rear - small.jpg';
62
var configeBaySellerName = 'muna_trading';
63
var configAutoAcceptPrice = 0.85000;
64
var configMinBestOfferPrice = 0.65000;
65
 
66
var sessionId = '';
67
var eBayAuthToken = '';
68
var eBayAuthExpiration = '';
69
var eBayAuthTokenFlag = false;
70
 
71
//
72
// Prototypes
73
//
74
String.prototype.hashCode = function() {
75
	var hash = 0,
76
		i, chr;
77
	if (this.length === 0) return hash;
78
	for (i = 0; i < this.length; i++) {
79
		chr = this.charCodeAt(i);
80
		hash = ((hash << 5) - hash) + chr;
81
		hash |= 0; // Convert to 32bit integer
82
	}
83
 
84
	return (hash < 0 ? (hash * -1) : hash);
85
};
86
 
87
Number.prototype.pad = function(size) {
88
	var s = String(this);
89
	while (s.length < (size || 2)) {
90
		s = "0" + s;
91
	}
92
	return s;
93
};
94
 
95
String.prototype.toProperCase = function () {
96
    return this.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
97
};
98
 
99
Date.prototype.yyyymmdd = function() {
100
	var mm = this.getMonth() + 1; // getMonth() is zero-based
101
	var dd = this.getDate();
102
 
103
	return [this.getFullYear(), (mm > 9 ? '' : '0') + mm, (dd > 9 ? '' : '0') + dd].join('-');
104
};
105
 
106
String.prototype.contains = function(it) { return this.indexOf(it) != -1; };
107
 
19 - 108
String.prototype.b64encode = function() {
109
    return btoa(unescape(encodeURIComponent(this)));
17 - 110
};
19 - 111
String.prototype.b64decode = function() {
112
    return decodeURIComponent(escape(atob(this)));
17 - 113
};
114
 
2 - 115
//
116
// Functions
117
//
6 - 118
function getJsonArray(val) {
119
    if (val === undefined) {
120
        return ([]);
121
    }
122
 
123
    return(val instanceof Array ? val : [val]);
124
}
125
 
2 - 126
function round(value, decimals) {
127
  return Number(Math.round(value+'e'+decimals)+'e-'+decimals);
128
}
129
 
130
// Polyfill for Internet Explorer
131
Math.trunc = Math.trunc || function(x) {
132
	var n = x - x % 1;
133
	return n === 0 && (x < 0 || (x === 0 && (1 / x !== 1 / 0))) ? -0 : n;
134
};
135
 
136
function tableCell(str) {
137
	return ('<td>' + str + '</td>');
138
}
139
 
140
function tableCellHidden(str) {
141
	return ('<td class="w3-hide">' + str + '</td>');
142
}
143
 
144
function tableHeader(str) {
145
	return ('<th>' + str + '</th>');
146
}
147
 
148
function tableCellLabel(str) {
149
	return ('<td id="' + str + '"></td>');
150
}
151
 
152
function tableCellLabelHidden(str, val) {
153
	return ('<td id="' + str + '" class="w3-hide">' + val + '</td>');
154
}
155
 
156
function tableCellAndLabel(str, label) {
157
	return ('<td id="' + label + '">' + str + '</td>');
158
}
159
 
160
function tableHeaderHidden(str) {
161
	return ('<th class="w3-hide">' + str + '</th>');
162
}
163
 
6 - 164
function tableHeaderCheckbox() {
2 - 165
	return ('<th class="sorter-checkbox filter-false"><input type="checkbox"></th>');
166
}
167
 
168
function tableCellCheckbox() {
169
	return ('<td><input type="checkbox"></td>');
170
}
171
 
172
function escapeHtml(unsafe) {
173
	return unsafe
174
		.replace(/&/g, "&amp;")
175
		.replace(/</g, "&lt;")
176
		.replace(/>/g, "&gt;")
177
		.replace(/"/g, "&quot;")
178
		.replace(/'/g, "&#039;");
179
}
180
 
181
function pad(num, size) {
182
    var s = num+"";
183
    while (s.length < size) s = "0" + s;
184
    return s;
185
}
186
 
187
function isset () {
188
  var a = arguments;
189
  var l = a.length;
190
  var i = 0;
191
  var undef;
192
 
193
  if (l === 0) {
194
    return false;
195
  }
196
 
197
  while (i !== l) {
198
    if (a[i] === undef || a[i] === null) {
199
      return false;
200
    }
201
    i++;
202
  }
203
 
204
  return true;
205
}
206
 
207
function getJsonValue(obj){
208
  return (isset(obj) ? obj : "");
209
}
210
 
211
function writeCookie() {
212
	document.cookie = 'eBayAuthToken=' + encodeURIComponent(eBayAuthToken) + ';expires=' + eBayAuthExpiration + ';';
213
}
214
 
215
function readCookie() {
216
	var name = 'eBayAuthToken=';
217
	var decodedCookie = decodeURIComponent(document.cookie);
218
	var ca = decodedCookie.split(';');
219
	for (var i = 0; i < ca.length; i++) {
220
		var c = ca[i];
221
		while (c.charAt(0) == ' ') {
222
			c = c.substring(1);
223
		}
224
		if (c.indexOf(name) === 0) {
225
			return c.substring(name.length, c.length);
226
		}
227
	}
228
	return "";
229
}
230
 
231
function isNumeric(input) {
232
	return (input - 0) == input && ('' + input).trim().length > 0;
233
}
234
 
235
function getRadioValue(name) {
236
	var group = document.getElementsByName(name);
237
 
238
	for (var i = 0; i < group.length; i++) {
239
		if (group[i].checked) {
240
			return group[i].value;
241
		}
242
	}
243
 
244
	return '';
245
}
246
 
247
function removeDuplicateRows($table){
248
    function getVisibleRowText($row){
249
        return $row.find('td:visible').text().toLowerCase();
250
    }
251
 
252
    $table.find('tr').each(function(index, row){
253
        var $row = $(row);
254
 
255
        $row.nextAll('tr').each(function(index, next){
256
            var $next = $(next);
257
            if(getVisibleRowText($next) == getVisibleRowText($row)) {
258
                $next.remove();
259
            }
260
        });
261
    });
262
}
263
 
53 - 264
function calculateGtin12Res(upc) {
6 - 265
	var i;
266
 
267
	if (!isNumeric(upc) || upc.length !== 11) {
268
		return -1;
269
	}
270
 
2 - 271
	var sum = 0;
272
 
273
	for (i = 0; i < 11; i += 2) {
274
		sum += (parseInt(upc.substr(i, 1)) * 3);
275
	}
276
 
277
	for (i = 1; i < 11; i += 2) {
278
		sum += parseInt(upc.substr(i, 1));
279
	}
280
 
281
	var res = sum % 10;
282
 
283
	if (res > 0) {
284
		res = 10 - res;
285
	}
286
 
6 - 287
	return res;
2 - 288
}
289
 
6 - 290
 
53 - 291
function isValidISBN10Code(isbn) {
2 - 292
	var sum, weight, digit, check, i;
293
 
294
	if (isbn.length == 10) {
295
		weight = 10;
296
		sum = 0;
297
		for (i = 0; i < 9; i++) {
298
			digit = parseInt(isbn[i]);
299
			sum += weight * digit;
300
			weight--;
301
		}
302
		check = 11 - (sum % 11);
303
		if (check == 10) {
304
			check = 'X';
305
		}
306
		return (check == isbn[isbn.length - 1].toUpperCase());
307
	}
308
 
309
	return false;
310
}
311
 
312
function escapeXml(unsafe) {
313
	return unsafe.replace(/[<>&'"]/g, function(c) {
314
		switch (c) {
315
			case '<':
316
				return '&lt;';
317
			case '>':
318
				return '&gt;';
319
			case '&':
320
				return '&amp;';
321
			case '\'':
322
				return '&apos;';
323
			case '"':
324
				return '&quot;';
325
		}
326
	});
327
}
328
 
329
 
330
/*
331
/ eBay Login
332
*/
333
function eBayLogin() {
334
	if (eBayAuthTokenFlag === false) {
335
		getSessionID();
336
	}
337
}
338
 
339
function getSessionID() {
340
	// Expects function requireNewLogin
341
	// Expects <div id="results">
342
 
343
	var i;
344
	var xw = new XMLWriter('UTF-8', '1.0');
345
 
346
	xw.writeStartDocument();
347
	xw.writeStartElement('GetSessionIDRequest');
348
	xw.writeAttributeString('xmlns', 'urn:ebay:apis:eBLBaseComponents');
349
	xw.writeElementString('RuName', configRuName);
350
	xw.writeEndElement(); /* GetSessionIDRequest */
351
	xw.writeEndDocument();
352
 
353
	var my_xml = xw.flush();
354
	xw.close();
355
 
356
	var xhr = new XMLHttpRequest();
357
	xhr.open('POST', configProxyUrl, true);
358
	xhr.setRequestHeader('Content-Type', 'text/xml');
359
	xhr.setRequestHeader('X-EBAY-API-APP-NAME', configAppid);
360
	xhr.setRequestHeader('X-EBAY-API-DEV-NAME', configDevid);
361
	xhr.setRequestHeader('X-EBAY-API-CERT-NAME', configCertid);
3 - 362
	xhr.setRequestHeader('X-EBAY-API-COMPATIBILITY-LEVEL', configeBayTradingVersion);
2 - 363
	xhr.setRequestHeader('X-EBAY-API-CALL-NAME', 'GetSessionID');
364
	xhr.setRequestHeader('X-EBAY-API-SITEID', '0');
365
	xhr.setRequestHeader('X-Proxy-URL', configServiceEndpoint);
366
 
367
	xhr.onload = function() {
5 - 368
        var xmlDoc = xhr.responseXML;
369
		var returnCode = xmlDoc.getElementsByTagName("Ack")[0].childNodes[0].nodeValue;
2 - 370
 
371
		if (returnCode == 'Success') {
5 - 372
			sessionId = xmlDoc.getElementsByTagName("SessionID")[0].childNodes[0].nodeValue;
2 - 373
 
374
			var win = window.open(configSigninUrl + '?SignIn&RuName=' + configRuName + '&SessID=' + sessionId, "eBay Login", "");
375
			var pollTimer = window.setInterval(function() {
376
				if (win.closed !== false) {
377
					window.clearInterval(pollTimer);
378
					getToken();
3 - 379
        		}
2 - 380
			}, 200);
381
		} else {
382
			requireNewLogin();
6 - 383
 
2 - 384
			var x = document.getElementById("results");
385
			if (x.className.indexOf("w3-show") == -1) {
386
				x.className += " w3-show";
387
			}
388
 
389
			x.innerHTML = "<p><strong>" + returnCode + ":</strong></p>";
5 - 390
			var errors = xmlDoc.getElementsByTagName("Errors");
2 - 391
			x.innerHTML += "<p>";
5 - 392
			for (i = 0; i < errors.length; i++) {
393
				x.innerHTML += errors[0].getElementsByTagName("SeverityCode")[0].innerHTML + " (" + errors[0].getElementsByTagName("ErrorCode")[0].innerHTML + "): " + escapeHtml(errors[0].getElementsByTagName("LongMessage")[0].innerHTML) + "<br/>";
2 - 394
			}
395
			x.innerHTML += "</p>";
396
		}
397
	};
398
 
399
	xhr.send(my_xml);
400
}
401
 
402
function getToken() {
403
	var x;
404
	var i;
405
	var xw = new XMLWriter('UTF-8', '1.0');
406
 
407
	xw.writeStartDocument();
408
	xw.writeStartElement('FetchTokenRequest');
409
	xw.writeAttributeString('xmlns', 'urn:ebay:apis:eBLBaseComponents');
410
	xw.writeElementString('SessionID', sessionId);
411
	xw.writeEndElement(); /* FetchTokenRequest */
412
	xw.writeEndDocument();
413
 
414
	var my_xml = xw.flush();
415
	xw.close();
416
 
417
	var xhr = new XMLHttpRequest();
418
	xhr.open('POST', configProxyUrl, true);
419
	xhr.setRequestHeader('Content-Type', 'text/xml');
420
	xhr.setRequestHeader('X-EBAY-API-APP-NAME', configAppid);
421
	xhr.setRequestHeader('X-EBAY-API-DEV-NAME', configDevid);
422
	xhr.setRequestHeader('X-EBAY-API-CERT-NAME', configCertid);
3 - 423
	xhr.setRequestHeader('X-EBAY-API-COMPATIBILITY-LEVEL', configeBayTradingVersion);
2 - 424
	xhr.setRequestHeader('X-EBAY-API-CALL-NAME', 'FetchToken');
425
	xhr.setRequestHeader('X-EBAY-API-SITEID', '0');
426
	xhr.setRequestHeader('X-Proxy-URL', configServiceEndpoint);
427
 
428
	xhr.onload = function() {
5 - 429
        var xmlDoc = xhr.responseXML;
430
		var returnCode = xmlDoc.getElementsByTagName("Ack")[0].childNodes[0].nodeValue;
2 - 431
 
432
		if (returnCode == 'Success') {
5 - 433
			eBayAuthToken = xmlDoc.getElementsByTagName("eBayAuthToken")[0].childNodes[0].nodeValue;
434
			eBayAuthExpiration = new Date(xmlDoc.getElementsByTagName("HardExpirationTime")[0].childNodes[0].nodeValue).toUTCString();
2 - 435
			writeCookie();
436
			connected();
437
		} else {
438
			requireNewLogin();
439
 
440
			x = document.getElementById("results");
441
			if (x.className.indexOf("w3-show") == -1) {
442
				x.className += " w3-show";
443
			}
444
 
445
			x.innerHTML = "<p><strong>" + returnCode + ":</strong></p>";
446
 
5 - 447
			x.innerHTML = "<p><strong>" + returnCode + ":</strong></p>";
448
			var errors = xmlDoc.getElementsByTagName("Errors");
2 - 449
			x.innerHTML += "<p>";
5 - 450
			for (i = 0; i < errors.length; i++) {
451
				x.innerHTML += errors[0].getElementsByTagName("SeverityCode")[0].innerHTML + " (" + errors[0].getElementsByTagName("ErrorCode")[0].innerHTML + "): " + escapeHtml(errors[0].getElementsByTagName("LongMessage")[0].innerHTML) + "<br/>";
2 - 452
			}
453
			x.innerHTML += "</p>";
454
		}
455
	};
456
 
457
	xhr.send(my_xml);
458
}
459
 
3 - 460
function getUrlParameter(win, name) {
461
    name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
462
    var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
463
    var results = regex.exec(win.location.search);
464
    return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
6 - 465
}
3 - 466
 
2 - 467
function feebackStarImage(score) {
468
	if (score > 999999) {
469
		return '<img src="https://ir.ebaystatic.com/pictures/aw/pics/icon/iconShootSlvr_25x25.gif" alt="Silver shooting star">';
470
	} else if (score > 499999) {
471
		return '<img src="https://ir.ebaystatic.com/pictures/aw/pics/icon/iconShootGrn_25x25.gif" alt="Green shooting star">';
472
	} else if (score > 99999) {
473
		return '<img src="https://ir.ebaystatic.com/pictures/aw/pics/icon/iconShootRed_25x25.gif" alt="Red shooting star">';
474
	} else if (score > 49999) {
475
		return '<img src="https://ir.ebaystatic.com/pictures/aw/icon/iconShootPrpl_25x25.gif" alt="Purple shooting star">';
476
	} else if (score > 24999) {
477
		return '<img src="https://ir.ebaystatic.com/pictures/aw/pics/icon/iconShootTeal_25x25.gif" alt="Turquoise shooting star">';
478
	} else if (score > 9999) {
479
		return '<img src="https://ir.ebaystatic.com/pictures/aw/pics/icon/iconShootYllw_25x25.gif" alt="Yellow shooting star">';
480
	} else if (score > 4999) {
481
		return '<img src="https://ir.ebaystatic.com/pictures/aw/pics/icon/iconGreenStar_25x25.gif" alt="Green star">';
482
	} else if (score > 999) {
483
		return '<img src="https://ir.ebaystatic.com/pictures/aw/pics/icon/iconRedStar_25x25.gif" alt="Red star">';
484
	} else if (score > 499) {
485
		return '<img src="https://ir.ebaystatic.com/pictures/aw/pics/icon/iconPurpleStar_25x25.gif" alt="Purple star">';
486
	} else if (score > 99) {
487
		return '<img src="https://ir.ebaystatic.com/pictures/aw/pics/icon/iconTealStar_25x25.gif" alt="Turquoise star">';
488
	} else if (score > 49) {
489
		return '<img src="https://ir.ebaystatic.com/pictures/aw/pics/icon/iconBlueStar_25x25.gif" alt="Blue star">';
490
	} else if (score > 9) {
491
		return '<img src="https://ir.ebaystatic.com/pictures/aw/pics/icon/iconYellowStar_25x25.gif" alt="Yellow star">';
492
	}
493
	return '';
494
}
495
 
36 - 496
function exportTableToCSV(tablename, filename, utf8Flag = false) {
497
    var csv = [];
2 - 498
    var rows = document.getElementById(tablename).querySelectorAll("table tr");
6 - 499
    var dq = '"';
500
    var nq = "'";
75 - 501
 
36 - 502
    if (utf8Flag) {
503
        csv.push("\uFEFF");
504
    }
2 - 505
 
506
    for (var i = 0; i < rows.length; i++) {
507
        var row = [], cols = rows[i].querySelectorAll("td, th");
508
 
509
        for (var j = 0; j < cols.length; j++) {
6 - 510
            if (cols[j].className.indexOf("w3-hide") == -1) {
511
                if (isNaN(cols[j].innerText)) {
512
                    row.push(dq + cols[j].innerText.replace(/"/g, '""') + dq);
513
                } else {
10 - 514
                    if (cols[j].innerText.includes(".")) {
515
                        row.push(cols[j].innerText);
516
                    } else {
14 - 517
                        row.push((cols[j].innerText.length > 7 ? nq : "") + cols[j].innerText);
10 - 518
                    }
6 - 519
                }
520
            }
2 - 521
        }
522
 
523
        csv.push(row.join(","));
524
    }
525
 
526
    // Download CSV file
36 - 527
    downloadCSV(csv.join("\n"), filename, utf8Flag);
2 - 528
}
529
 
36 - 530
function downloadCSV(csv, filename, utf8Flag = false) {
2 - 531
    var csvFile;
532
    var downloadLink;
533
 
534
    // CSV file
36 - 535
    if (utf8Flag) {
536
        csvFile = new Blob([csv], {type: "text/csv;charset=utf-8"});
537
    } else {
538
        csvFile = new Blob([csv], {type: "text/csv"});
539
    }
2 - 540
 
541
    // Download link
542
    downloadLink = document.createElement("a");
543
 
544
    // File name
545
    downloadLink.download = filename;
546
 
547
    // Create a link to the file
548
    downloadLink.href = window.URL.createObjectURL(csvFile);
549
 
550
    // Hide download link
551
    downloadLink.style.display = "none";
552
 
553
    // Add the link to DOM
554
    document.body.appendChild(downloadLink);
555
 
556
    // Click download link
557
    downloadLink.click();
558
}
559
 
560
/* Progress Bar HTML
561
<div id="progressBarDiv" class="w3-container w3-padding w3-margin w3-card-4 w3-hide">
562
	<h2 id="progressBarHeader"></h2>
563
  <div class="w3-light-grey">
564
      <div id="progressBar" class="w3-container w3-green w3-center" style="width:0%">0%</div>
565
  </div>
566
</div>
567
*/
568
function initProgressBar(title) {
569
  	var elem = document.getElementById("progressBar");
570
	  elem.style.width = 0 + '%';
571
  	elem.innerHTML = 0 + '%';
572
 
573
  	elem = document.getElementById("progressBarDiv");
574
	  if (elem.className.indexOf("w3-show") == -1) {
575
		    elem.className += " w3-show";
576
  	}
577
 
578
	  elem = document.getElementById("progressBarHeader");
579
  	elem.innerHTML = title;
580
}
581
 
582
function updateProgressBar(maximum, current) {
10 - 583
	var elem = document.getElementById("progressBar");
584
	var width = (current / maximum) * 100;
585
	elem.style.width = width + '%';
586
	elem.innerHTML = width.toFixed(0) + '%';
2 - 587
}
588
 
589
function endProgressBar() {
590
    var elem = document.getElementById("progressBarDiv");
591
		elem.className = elem.className.replace(" w3-show", "");
592
}
593
 
10 - 594
// Progress Bar Modal
595
/*
596
<div class="modal" id="progressBarDiv">
597
  <div class="modal-dialog">
598
    <div class="modal-content">
599
      <div class="modal-header">
600
        <h4 id="progressBarHeader"></h4>
601
      </div>
602
      <div class="modal-body">
603
        <div class="progress">
604
          <div id="progressBar" class="progress-bar" style="width:0%">0%</div>
605
        </div>
606
      </div>
607
    </div>
608
  </div>
609
</div>
610
*/
611
function initProgressBarModal(title) {
612
  	var elem = document.getElementById("progressBar");
613
    elem.style.width = '0%';
614
  	elem.innerHTML = '0%';
615
 
616
    elem = document.getElementById("progressBarHeader");
617
  	elem.innerHTML = title;
19 - 618
 
10 - 619
  	$("#progressBarDiv").modal("show");
620
}
621
 
622
function endProgressBarModal() {
623
  	$("#progressBarDiv").modal("hide");
624
}
625
 
626
function extractTextContent(s) {
627
  var span = document.createElement('span');
628
  span.innerHTML = s;
629
  return span.textContent || span.innerText;
630
}
631
 
6 - 632
// xxxxx WIP
2 - 633
function sortHTMLTable(table, column = 0, type = 's', hasFooter = false) {
634
  var rows, switching, i, x, y, shouldSwitch;
635
  var nonData = (hasFooter ? 2 : 1);
636
  table = document.getElementById(table);
637
  switching = true;
638
  /* Make a loop that will continue until
639
  no switching has been done: */
640
  while (switching) {
641
    // Start by saying: no switching is done:
642
    switching = false;
643
    rows = table.rows;
644
    /* Loop through all table rows (except the
645
    first, which contains table headers): */
646
    for (i = 1; i < (rows.length - nonData); i++) {
647
      // Start by saying there should be no switching:
648
      shouldSwitch = false;
649
      /* Get the two elements you want to compare,
650
      one from current row and one from the next: */
651
      x = rows[i].getElementsByTagName("TD")[column];
652
      y = rows[i + 1].getElementsByTagName("TD")[column];
653
      // Check if the two rows should switch place:
654
      if (type == 'i') { // integer
655
        if (Number(x.innerHTML) > Number(y.innerHTML)) {
656
          // If so, mark as a switch and break the loop:
657
          shouldSwitch = true;
658
          break;
659
        }
660
      } else if (type == 'f') { // float
661
        if (Number(x.innerHTML).toFixed(2) > Number(y.innerHTML).toFixed(2)) {
662
          // If so, mark as a switch and break the loop:
663
          shouldSwitch = true;
664
          break;
665
        }
666
      } else if (type == 'c') { // currency
667
        if (Number(x.innerHTML.substr(1)).toFixed(2) > Number(y.innerHTML.substr(1)).toFixed(2)) {
668
          // If so, mark as a switch and break the loop:
669
          shouldSwitch = true;
670
          break;
671
        }
672
      } else if ('d') { // date
673
        if (Date(x.innerHTML) > Date(y.innerHTML)) {
674
          // If so, mark as a switch and break the loop:
675
          shouldSwitch = true;
676
          break;
677
        }
678
      } else { // string
679
        if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
680
          // If so, mark as a switch and break the loop:
681
          shouldSwitch = true;
682
          break;
683
        }
684
      }
685
    }
686
    if (shouldSwitch) {
687
      /* If a switch has been marked, make the switch
688
      and mark that a switch has been done: */
689
      rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
690
      switching = true;
691
    }
692
  }
7 - 693
}
694
 
695
// Update table sorter counters after processed deleting rows
696
// <p>Showing <span id="filtered-rows">0</span> of <span id="total-rows">0</span> / <span id="selected-rows">0</span> selected.</p>
697
function tableSorterUpdateCounters(tableName) {
698
    $("#" + tableName).trigger("update").trigger("appendCache").trigger("applyWidgets").trigger('search', false);
19 - 699
 
7 - 700
    var rowCount = $('#' + tableName + ' tbody tr').length;
701
    var filteredCount = rowCount - $('#' + tableName + ' tbody tr:hidden').length;
702
    var checkedCount = $('#' + tableName + ' tbody .checked').length;
19 - 703
 
7 - 704
    $('#total-rows').html(rowCount);
705
    $('#filtered-rows').html(filteredCount);
706
    $('#selected-rows').html(checkedCount);
707
    $("#" + tableName).find('thead input[type=checkbox]').prop('checked', false);
708
    $("#" + tableName).find('thead input[type=checkbox]').prop('indeterminate', false);
10 - 709
}
710
 
711
// flattens an object (recursively!), similarly to Array#flatten
712
// e.g. flatten({ a: { b: { c: "hello!" } } }); // => "hello!"
713
function flatten(object) {
714
  var check = _.isPlainObject(object) && _.size(object) === 1;
715
  return check ? flatten(_.values(object)[0]) : object;
716
}
717
 
718
function XMLparse(xml, flattenFlag = true) {
719
  var data = {};
720
 
17 - 721
  if (xml === null) {
722
    return data;
723
  }
19 - 724
 
10 - 725
  var isText = xml.nodeType === 3,
726
      isElement = xml.nodeType === 1,
727
      body = xml.textContent && xml.textContent.trim(),
728
      hasChildren = xml.children && xml.children.length,
729
      hasAttributes = xml.attributes && xml.attributes.length;
730
 
731
  // if it's text just return it
732
  if (isText) { return xml.nodeValue.trim(); }
733
 
734
  // if it doesn't have any children or attributes, just return the contents
735
  if (!hasChildren && !hasAttributes) { return body; }
736
 
737
  // if it doesn't have children but _does_ have body content, we'll use that
738
  if (!hasChildren && body.length) { data.text = body; }
739
 
740
  // if it's an element with attributes, add them to data.attributes
741
  if (isElement && hasAttributes) {
742
    data.attributes = _.reduce(xml.attributes, function(obj, name, id) {
743
      var attr = xml.attributes.item(id);
744
      obj[attr.name] = attr.value;
745
      return obj;
746
    }, {});
747
  }
748
 
749
  // recursively call #XMLparse over children, adding results to data
750
  _.each(xml.children, function(child) {
751
    var name = child.nodeName;
752
 
753
    // if we've not come across a child with this nodeType, add it as an object
754
    // and return here
755
    if (!_.has(data, name)) {
756
      data[name] = XMLparse(child, flattenFlag);
757
      return;
758
    }
759
 
760
    // if we've encountered a second instance of the same nodeType, make our
761
    // representation of it an array
762
    if (!_.isArray(data[name])) { data[name] = [data[name]]; }
763
 
764
    // and finally, append the new child
765
    data[name].push(XMLparse(child, flattenFlag));
766
  });
767
 
768
   // if we can, let's fold some attributes into the body
769
   _.each(data.attributes, function(value, key) {
770
   if (data[key] != null) { return; }
771
     data[key] = value;
772
     delete data.attributes[key];
773
   });
774
 
775
  // if data.attributes is now empty, get rid of it
776
  if (_.isEmpty(data.attributes)) { delete data.attributes; }
777
 
778
  // simplify to reduce number of final leaf nodes and return
779
  return (flattenFlag ? flatten(data) : data);
17 - 780
}
781
 
782
/* HTML include */
783
function includeHTML() {
784
    var z, i, elmnt, file, xhttp;
785
    /* Loop through a collection of all HTML elements: */
786
    z = document.getElementsByTagName("*");
787
    for (i = 0; i < z.length; i++) {
788
        elmnt = z[i];
789
        /* search for elements with a certain atrribute:*/
790
        file = elmnt.getAttribute("w3-include-html");
791
        if (file) {
792
            /* Make an HTTP request using the attribute value as the file name: */
793
            xhttp = new XMLHttpRequest();
794
            xhttp.onreadystatechange = function() {
795
                if (this.readyState == 4) {
796
                    if (this.status == 200) {
797
                        elmnt.innerHTML = this.responseText;
798
                    }
799
                    if (this.status == 404) {
800
                        elmnt.innerHTML = "<p>Page not found.</p>";
801
                    }
802
                    /* Remove the attribute, and call this function once more: */
803
                    elmnt.removeAttribute("w3-include-html");
804
                    includeHTML();
805
                }
806
            };
807
            xhttp.open("GET", file, true);
808
            xhttp.send();
809
            /* Exit the function: */
810
            return;
811
        }
812
    }
813
}
53 - 814
 
815
function cleanTitleForShopifySearch(title) {
816
    var cleanTitle = '';
817
    var len;
818
    var arr = [];
819
    var i, j;
820
 
821
    len = title.indexOf('(');;
822
    if (len > 0) {
823
        title = title.substr(0, len - 1);
824
    }
825
 
826
    len = title.indexOf('[');;
827
    if (len > 0) {
828
        title = title.substr(0, len - 1);
829
    }
75 - 830
 
53 - 831
    arr = title.split(' ');
832
    for (i = 0; i < arr.length; i++) {
833
        if (i > 0) {cleanTitle += '_';}
834
        for (j = 0; j < arr[i].length; j++) {
835
            cleanTitle += cleanCharForShopifySearch(arr[i][j]);
836
        }
837
    }
75 - 838
 
53 - 839
    return(cleanTitle);
840
}
841
 
842
function cleanCharForShopifySearch(c) {
843
    if (c == '?' ||
844
        c == '&' ||
845
        c == '=' ||
846
        c == '+' ||
847
        c == '$' ||
55 - 848
        c == '%' ||
54 - 849
        c.charCodeAt(0) > 127) {
53 - 850
            c = encodeURIComponent(c);
851
    }
75 - 852
 
53 - 853
    return c;
72 - 854
}