PageSourceSearch

https://aartdevos.dk/js/varien/js.js

js aartdevos.dk collected 2026-09-26 19:32:24 UTC 24,724 bytes, 772 lines download raw bytes

1/**
2 * Magento
3 *
4 * NOTICE OF LICENSE
5 *
6 * This source file is subject to the Academic Free License (AFL 3.0)
7 * that is bundled with this package in the file LICENSE_AFL.txt.
8 * It is also available through the world-wide-web at this URL:
9 * http://opensource.org/licenses/afl-3.0.php
10 * If you did not receive a copy of the license and are unable to
11 * obtain it through the world-wide-web, please send an email
12 * to [email protected] so we can send you a copy immediately.
13 *
14 * DISCLAIMER
15 *
16 * Do not edit or add to this file if you wish to upgrade Magento to newer
17 * versions in the future. If you wish to customize Magento for your
18 * needs please refer to http://www.magento.com for more information.
19 *
20 * @category    Varien
21 * @package     js
22 * @copyright   Copyright (c) 2006-2019 Magento, Inc. (http://www.magento.com)
23 * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
24 */
25function popWin(url,win,para) {
26    var win = window.open(url,win,para);
27    win.focus();
28}
29
30function setLocation(url){
31    window.location.href = encodeURI(url);
32}
33
34function setPLocation(url, setFocus){
35    if( setFocus ) {
36        window.opener.focus();
37    }
38    window.opener.location.href = encodeURI(url);
39}
40
41/**
42 * @deprecated
43 */
44function setLanguageCode(code, fromCode){
45    //TODO: javascript cookies have different domain and path than php cookies
46    var href = window.location.href;
47    var after = '', dash;
48    if (dash = href.match(/\#(.*)$/)) {
49        href = href.replace(/\#(.*)$/, '');
50        after = dash[0];
51    }
52
53    if (href.match(/[?]/)) {
54        var re = /([?&]store=)[a-z0-9_]*/;
55        if (href.match(re)) {
56            href = href.replace(re, '$1'+code);
57        } else {
58            href += '&store='+code;
59        }
60
61        var re = /([?&]from_store=)[a-z0-9_]*/;
62        if (href.match(re)) {
63            href = href.replace(re, '');
64        }
65    } else {
66        href += '?store='+code;
67    }
68    if (typeof(fromCode) != 'undefined') {
69        href += '&from_store='+fromCode;
70    }
71    href += after;
72
73    setLocation(href);
74}
75
76/**
77 * Add classes to specified elements.
78 * Supported classes are: 'odd', 'even', 'first', 'last'
79 *
80 * @param elements - array of elements to be decorated
81 * [@param decorateParams] - array of classes to be set. If omitted, all available will be used
82 */
83function decorateGeneric(elements, decorateParams)
84{
85    var allSupportedParams = ['odd', 'even', 'first', 'last'];
86    var _decorateParams = {};
87    var total = elements.length;
88
89    if (total) {
90        // determine params called
91        if (typeof(decorateParams) == 'undefined') {
92            decorateParams = allSupportedParams;
93        }
94        if (!decorateParams.length) {
95            return;
96        }
97        for (var k in allSupportedParams) {
98            _decorateParams[allSupportedParams[k]] = false;
99        }
100        for (var k in decorateParams) {
101            _decorateParams[decorateParams[k]] = true;
102        }
103
104        // decorate elements
105        // elements[0].addClassName('first'); // will cause bug in IE (#5587)
106        if (_decorateParams.first) {
107            Element.addClassName(elements[0], 'first');
108        }
109        if (_decorateParams.last) {
110            Element.addClassName(elements[total-1], 'last');
111        }
112        for (var i = 0; i < total; i++) {
113            if ((i + 1) % 2 == 0) {
114                if (_decorateParams.even) {
115                    Element.addClassName(elements[i], 'even');
116                }
117            }
118            else {
119                if (_decorateParams.odd) {
120                    Element.addClassName(elements[i], 'odd');
121                }
122            }
123        }
124    }
125}
126
127/**
128 * Decorate table rows and cells, tbody etc
129 * @see decorateGeneric()
130 */
131function decorateTable(table, options) {
132    var table = $(table);
133    if (table) {
134        // set default options
135        var _options = {
136            'tbody'    : false,
137            'tbody tr' : ['odd', 'even', 'first', 'last'],
138            'thead tr' : ['first', 'last'],
139            'tfoot tr' : ['first', 'last'],
140            'tr td'    : ['last']
141        };
142        // overload options
143        if (typeof(options) != 'undefined') {
144            for (var k in options) {
145                _options[k] = options[k];
146            }
147        }
148        // decorate
149        if (_options['tbody']) {
150            decorateGeneric(table.select('tbody'), _options['tbody']);
151        }
152        if (_options['tbody tr']) {
153            decorateGeneric(table.select('tbody tr'), _options['tbody tr']);
154        }
155        if (_options['thead tr']) {
156            decorateGeneric(table.select('thead tr'), _options['thead tr']);
157        }
158        if (_options['tfoot tr']) {
159            decorateGeneric(table.select('tfoot tr'), _options['tfoot tr']);
160        }
161        if (_options['tr td']) {
162            var allRows = table.select('tr');
163            if (allRows.length) {
164                for (var i = 0; i < allRows.length; i++) {
165                    decorateGeneric(allRows[i].getElementsByTagName('TD'), _options['tr td']);
166                }
167            }
168        }
169    }
170}
171
172/**
173 * Set "odd", "even" and "last" CSS classes for list items
174 * @see decorateGeneric()
175 */
176function decorateList(list, nonRecursive) {
177    if ($(list)) {
178        if (typeof(nonRecursive) == 'undefined') {
179            var items = $(list).select('li');
180        }
181        else {
182            var items = $(list).childElements();
183        }
184        decorateGeneric(items, ['odd', 'even', 'last']);
185    }
186}
187
188/**
189 * Set "odd", "even" and "last" CSS classes for list items
190 * @see decorateGeneric()
191 */
192function decorateDataList(list) {
193    list = $(list);
194    if (list) {
195        decorateGeneric(list.select('dt'), ['odd', 'even', 'last']);
196        decorateGeneric(list.select('dd'), ['odd', 'even', 'last']);
197    }
198}
199
200/**
201 * Parse SID and produces the correct URL
202 */
203function parseSidUrl(baseUrl, urlExt) {
204    var sidPos = baseUrl.indexOf('/?SID=');
205    var sid = '';
206    urlExt = (urlExt != undefined) ? urlExt : '';
207
208    if(sidPos > -1) {
209        sid = '?' + baseUrl.substring(sidPos + 2);
210        baseUrl = baseUrl.substring(0, sidPos + 1);
211    }
212
213    return baseUrl+urlExt+sid;
214}
215
216/**
217 * Formats currency using patern
218 * format - JSON (pattern, decimal, decimalsDelimeter, groupsDelimeter)
219 * showPlus - true (always show '+'or '-'),
220 *      false (never show '-' even if number is negative)
221 *      null (show '-' if number is negative)
222 */
223
224function formatCurrency(price, format, showPlus){
225    var precision = isNaN(format.precision = Math.abs(format.precision)) ? 2 : format.precision;
226    var requiredPrecision = isNaN(format.requiredPrecision = Math.abs(format.requiredPrecision)) ? 2 : format.requiredPrecision;
227
228    //precision = (precision > requiredPrecision) ? precision : requiredPrecision;
229    //for now we don't need this difference so precision is requiredPrecision
230    precision = requiredPrecision;
231
232    var integerRequired = isNaN(format.integerRequired = Math.abs(format.integerRequired)) ? 1 : format.integerRequired;
233
234    var decimalSymbol = format.decimalSymbol == undefined ? "," : format.decimalSymbol;
235    var groupSymbol = format.groupSymbol == undefined ? "." : format.groupSymbol;
236    var groupLength = format.groupLength == undefined ? 3 : format.groupLength;
237
238    var s = '';
239
240    if (showPlus == undefined || showPlus == true) {
241        s = price < 0 ? "-" : ( showPlus ? "+" : "");
242    } else if (showPlus == false) {
243        s = '';
244    }
245
246    var i = parseInt(price = Math.abs(+price || 0).toFixed(precision)) + "";
247    var pad = (i.length < integerRequired) ? (integerRequired - i.length) : 0;
248    while (pad) { i = '0' + i; pad--; }
249    j = (j = i.length) > groupLength ? j % groupLength : 0;
250    re = new RegExp("(\\d{" + groupLength + "})(?=\\d)", "g");
251
252    /**
253     * replace(/-/, 0) is only for fixing Safari bug which appears
254     * when Math.abs(0).toFixed() executed on "0" number.
255     * Result is "0.-0" :(
256     */
257    var r = (j ? i.substr(0, j) + groupSymbol : "") + i.substr(j).replace(re, "$1" + groupSymbol) + (precision ? decimalSymbol + Math.abs(price - i).toFixed(precision).replace(/-/, 0).slice(2) : "");
258    var pattern = '';
259    if (format.pattern.indexOf('{sign}') == -1) {
260        pattern = s + format.pattern;
261    } else {
262        pattern = format.pattern.replace('{sign}', s);
263    }
264
265    return pattern.replace('%s', r).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
266};
267
268function expandDetails(el, childClass) {
269    if (Element.hasClassName(el,'show-details')) {
270        $$(childClass).each(function(item){
271            item.hide();
272        });
273        Element.removeClassName(el,'show-details');
274    }
275    else {
276        $$(childClass).each(function(item){
277            item.show();
278        });
279        Element.addClassName(el,'show-details');
280    }
281}
282
283// Version 1.0
284var isIE = navigator.appVersion.match(/MSIE/) == "MSIE";
285
286if (!window.Varien)
287    var Varien = new Object();
288
289Varien.showLoading = function(){
290    var loader = $('loading-process');
291    loader && loader.show();
292};
293Varien.hideLoading = function(){
294    var loader = $('loading-process');
295    loader && loader.hide();
296};
297Varien.GlobalHandlers = {
298    onCreate: function() {
299        Varien.showLoading();
300    },
301
302    onComplete: function() {
303        if(Ajax.activeRequestCount == 0) {
304            Varien.hideLoading();
305        }
306    }
307};
308
309Ajax.Responders.register(Varien.GlobalHandlers);
310
311/**
312 * Quick Search form client model
313 */
314Varien.searchForm = Class.create();
315Varien.searchForm.prototype = {
316    initialize : function(form, field, emptyText){
317        this.form   = $(form);
318        this.field  = $(field);
319        this.emptyText = emptyText;
320
321        Event.observe(this.form,  'submit', this.submit.bind(this));
322        Event.observe(this.field, 'focus', this.focus.bind(this));
323        Event.observe(this.field, 'blur', this.blur.bind(this));
324        this.blur();
325    },
326
327    submit : function(event){
328        if (this.field.value == this.emptyText || this.field.value == ''){
329            Event.stop(event);
330            return false;
331        }
332        return true;
333    },
334
335    focus : function(event){
336        if(this.field.value==this.emptyText){
337            this.field.value='';
338        }
339
340    },
341
342    blur : function(event){
343        if(this.field.value==''){
344            this.field.value=this.emptyText;
345        }
346    },
347
348    initAutocomplete : function(url, destinationElement){
349        new Ajax.Autocompleter(
350            this.field,
351            destinationElement,
352            url,
353            {
354                paramName: this.field.name,
355                method: 'get',
356                minChars: 2,
357                updateElement: this._selectAutocompleteItem.bind(this),
358                onShow : function(element, update) {
359                    if(!update.style.position || update.style.position=='absolute') {
360                        update.style.position = 'absolute';
361                        Position.clone(element, update, {
362                            setHeight: false,
363                            offsetTop: element.offsetHeight
364                        });
365                    }
366                    Effect.Appear(update,{duration:0});
367                }
368
369            }
370        );
371    },
372
373    _selectAutocompleteItem : function(element){
374        if(element.title){
375            this.field.value = element.title;
376        }
377        this.form.submit();
378    }
379};
380
381Varien.Tabs = Class.create();
382Varien.Tabs.prototype = {
383  initialize: function(selector) {
384    var self=this;
385    $$(selector+' a').each(this.initTab.bind(this));
386  },
387
388  initTab: function(el) {
389      el.href = 'javascript:void(0)';
390      if ($(el.parentNode).hasClassName('active')) {
391        this.showContent(el);
392      }
393      el.observe('click', this.showContent.bind(this, el));
394  },
395
396  showContent: function(a) {
397    var li = $(a.parentNode), ul = $(li.parentNode);
398    ul.getElementsBySelector('li', 'ol').each(function(el){
399      var contents = $(el.id+'_contents');
400      if (el==li) {
401        el.addClassName('active');
402        contents.show();
403      } else {
404        el.removeClassName('active');
405        contents.hide();
406      }
407    });
408  }
409};
410
411Varien.DateElement = Class.create();
412Varien.DateElement.prototype = {
413    initialize: function(type, content, required, format) {
414        if (type == 'id') {
415            // id prefix
416            this.day    = $(content + 'day');
417            this.month  = $(content + 'month');
418            this.year   = $(content + 'year');
419            this.full   = $(content + 'full');
420            this.advice = $(content + 'date-advice');
421        } else if (type == 'container') {
422            // content must be container with data
423            this.day    = content.day;
424            this.month  = content.month;
425            this.year   = content.year;
426            this.full   = content.full;
427            this.advice = content.advice;
428        } else {
429            return;
430        }
431
432        this.required = required;
433        this.format   = format;
434
435        this.day.addClassName('validate-custom');
436        this.day.validate = this.validate.bind(this);
437        this.month.addClassName('validate-custom');
438        this.month.validate = this.validate.bind(this);
439        this.year.addClassName('validate-custom');
440        this.year.validate = this.validate.bind(this);
441
442        this.setDateRange(false, false);
443        this.year.setAttribute('autocomplete','off');
444
445        this.advice.hide();
446
447        var date = new Date;
448        this.curyear = date.getFullYear();
449    },
450    validate: function() {
451        var error = false,
452            day   = parseInt(this.day.value, 10)   || 0,
453            month = parseInt(this.month.value, 10) || 0,
454            year  = parseInt(this.year.value, 10)  || 0;
455        if (this.day.value.strip().empty()
456            && this.month.value.strip().empty()
457            && this.year.value.strip().empty()
458        ) {
459            if (this.required) {
460                error = 'This date is a required value.';
461            } else {
462                this.full.value = '';
463            }
464        } else if (!day || !month || !year) {
465            error = 'Please enter a valid full date';
466        } else {
467            var date = new Date, countDaysInMonth = 0, errorType = null;
468            date.setYear(year);date.setMonth(month-1);date.setDate(32);
469            countDaysInMonth = 32 - date.getDate();
470            if(!countDaysInMonth || countDaysInMonth>31) countDaysInMonth = 31;
471            if(year < 1900) error = this.errorTextModifier(this.validateDataErrorText);
472
473            if (day<1 || day>countDaysInMonth) {
474                errorType = 'day';
475                error = 'Please enter a valid day (1-%d).';
476            } else if (month<1 || month>12) {
477                errorType = 'month';
478                error = 'Please enter a valid month (1-12).';
479            } else {
480                if(day % 10 == day) this.day.value = '0'+day;
481                if(month % 10 == month) this.month.value = '0'+month;
482                this.full.value = this.format.replace(/%[mb]/i, this.month.value).replace(/%[de]/i, this.day.value).replace(/%y/i, this.year.value);
483                var testFull = this.month.value + '/' + this.day.value + '/'+ this.year.value;
484                var test = new Date(testFull);
485                if (isNaN(test)) {
486                    error = 'Please enter a valid date.';
487                } else {
488                    this.setFullDate(test);
489                }
490            }
491            var valueError = false;
492            if (!error && !this.validateData()){//(year<1900 || year>curyear) {
493                errorType = this.validateDataErrorType;//'year';
494                valueError = this.validateDataErrorText;//'Please enter a valid year (1900-%d).';
495                error = valueError;
496            }
497        }
498
499        if (error !== false) {
500            try {
501                error = Translator.translate(error);
502            }
503            catch (e) {}
504            if (!valueError) {
505                this.advice.innerHTML = error.replace('%d', countDaysInMonth);
506            } else {
507                this.advice.innerHTML = this.errorTextModifier(error);
508            }
509            this.advice.show();
510            return false;
511        }
512
513        // fixing elements class
514        this.day.removeClassName('validation-failed');
515        this.month.removeClassName('validation-failed');
516        this.year.removeClassName('validation-failed');
517
518        this.advice.hide();
519        return true;
520    },
521    validateData: function() {
522        var year = this.fullDate.getFullYear();
523        return (year>=1900 && year<=this.curyear);
524    },
525    validateDataErrorType: 'year',
526    validateDataErrorText: 'Please enter a valid year (1900-%d).',
527    errorTextModifier: function(text) {
528        text = Translator.translate(text);
529        return text.replace('%d', this.curyear);
530    },
531    setDateRange: function(minDate, maxDate) {
532        this.minDate = minDate;
533        this.maxDate = maxDate;
534    },
535    setFullDate: function(date) {
536        this.fullDate = date;
537    }
538};
539
540Varien.DOB = Class.create();
541Varien.DOB.prototype = {
542    initialize: function(selector, required, format) {
543        var el = $$(selector)[0];
544        var container       = {};
545        container.day       = Element.select(el, '.dob-day input')[0];
546        container.month     = Element.select(el, '.dob-month input')[0];
547        container.year      = Element.select(el, '.dob-year input')[0];
548        container.full      = Element.select(el, '.dob-full input')[0];
549        container.advice    = Element.select(el, '.validation-advice')[0];
550
551        new Varien.DateElement('container', container, required, format);
552    }
553};
554
555Varien.dateRangeDate = Class.create();
556Varien.dateRangeDate.prototype = Object.extend(new Varien.DateElement(), {
557    validateData: function() {
558        var validate = true;
559        if (this.minDate || this.maxValue) {
560            if (this.minDate) {
561                this.minDate = new Date(this.minDate);
562                this.minDate.setHours(0);
563                if (isNaN(this.minDate)) {
564                    this.minDate = new Date('1/1/1900');
565                }
566                validate = validate && (this.fullDate >= this.minDate);
567            }
568            if (this.maxDate) {
569                this.maxDate = new Date(this.maxDate);
570                this.minDate.setHours(0);
571                if (isNaN(this.maxDate)) {
572                    this.maxDate = new Date();
573                }
574                validate = validate && (this.fullDate <= this.maxDate);
575            }
576            if (this.maxDate && this.minDate) {
577                this.validateDataErrorText = 'Please enter a valid date between %s and %s';
578            } else if (this.maxDate) {
579                this.validateDataErrorText = 'Please enter a valid date less than or equal to %s';
580            } else if (this.minDate) {
581                this.validateDataErrorText = 'Please enter a valid date equal to or greater than %s';
582            } else {
583                this.validateDataErrorText = '';
584            }
585        }
586        return validate;
587    },
588    validateDataErrorText: 'Date should be between %s and %s',
589    errorTextModifier: function(text) {
590        if (this.minDate) {
591            text = text.sub('%s', this.dateFormat(this.minDate));
592        }
593        if (this.maxDate) {
594            text = text.sub('%s', this.dateFormat(this.maxDate));
595        }
596        return text;
597    },
598    dateFormat: function(date) {
599        return (date.getMonth() + 1) + '/' + date.getDate() + '/' + date.getFullYear();
600    }
601});
602
603Varien.FileElement = Class.create();
604Varien.FileElement.prototype = {
605    initialize: function (id) {
606        this.fileElement = $(id);
607        this.hiddenElement = $(id + '_value');
608
609        this.fileElement.observe('change', this.selectFile.bind(this));
610    },
611    selectFile: function(event) {
612        this.hiddenElement.value = this.fileElement.getValue();
613    }
614};
615
616Validation.addAllThese([
617    ['validate-custom', ' ', function(v,elm) {
618        return elm.validate();
619    }]
620]);
621
622function truncateOptions() {
623    $$('.truncated').each(function(element){
624        Event.observe(element, 'mouseover', function(){
625            if (element.down('div.truncated_full_value')) {
626                element.down('div.truncated_full_value').addClassName('show');
627            }
628        });
629        Event.observe(element, 'mouseout', function(){
630            if (element.down('div.truncated_full_value')) {
631                element.down('div.truncated_full_value').removeClassName('show');
632            }
633        });
634
635    });
636}
637Event.observe(window, 'load', function(){
638   truncateOptions();
639});
640
641Element.addMethods({
642    getInnerText: function(element)
643    {
644        element = $(element);
645        if(element.innerText && !Prototype.Browser.Opera) {
646            return element.innerText;
647        }
648        return element.innerHTML.stripScripts().unescapeHTML().replace(/[\n\r\s]+/g, ' ').strip();
649    }
650});
651
652/*
653if (!("console" in window) || !("firebug" in console))
654{
655    var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
656    "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
657
658    window.console = {};
659    for (var i = 0; i < names.length; ++i)
660        window.console[names[i]] = function() {}
661}
662*/
663
664/**
665 * Executes event handler on the element. Works with event handlers attached by Prototype,
666 * in a browser-agnostic fashion.
667 * @param element The element object
668 * @param event Event name, like 'change'
669 *
670 * @example fireEvent($('my-input', 'click'));
671 */
672function fireEvent(element, event) {
673    if (document.createEvent) {
674        // dispatch for all browsers except IE before version 9
675        var evt = document.createEvent("HTMLEvents");
676        evt.initEvent(event, true, true ); // event type, bubbling, cancelable
677        return element.dispatchEvent(evt);
678    } else {
679        // dispatch for IE before version 9
680        var evt = document.createEventObject();
681        return element.fireEvent('on' + event, evt);
682    }
683}
684
685/**
686 * Returns more accurate results of floating-point modulo division
687 * E.g.:
688 * 0.6 % 0.2 = 0.19999999999999996
689 * modulo(0.6, 0.2) = 0
690 *
691 * @param dividend
692 * @param divisor
693 */
694function modulo(dividend, divisor)
695{
696    var epsilon = divisor / 10000;
697    var remainder = dividend % divisor;
698
699    if (Math.abs(remainder - divisor) < epsilon || Math.abs(remainder) < epsilon) {
700        remainder = 0;
701    }
702
703    return remainder;
704}
705
706/**
707 * createContextualFragment is not supported in IE9. Adding its support.
708 */
709if ((typeof Range != "undefined") && !Range.prototype.createContextualFragment)
710{
711    Range.prototype.createContextualFragment = function(html)
712    {
713        var frag = document.createDocumentFragment(),
714        div = document.createElement("div");
715        frag.appendChild(div);
716        div.outerHTML = html;
717        return frag;
718    };
719}
720
721/**
722 * Create form element. Set parameters into it and send
723 *
724 * @param url
725 * @param parametersArray
726 * @param method
727 */
728Varien.formCreator = Class.create();
729Varien.formCreator.prototype = {
730    initialize : function(url, parametersArray, method) {
731        this.url = url;
732        this.parametersArray = JSON.parse(parametersArray);
733        this.method = method;
734        this.form = '';
735
736        this.createForm();
737        this.setFormData();
738    },
739    createForm : function() {
740        this.form = new Element('form', { 'method': this.method, action: this.url });
741    },
742    setFormData : function () {
743        for (var key in this.parametersArray) {
744            Element.insert(
745                this.form,
746                new Element('input', { name: key, value: this.parametersArray[key], type: 'hidden' })
747            );
748        }
749    }
750};
751
752function customFormSubmit(url, parametersArray, method) {
753    var createdForm = new Varien.formCreator(url, parametersArray, method);
754    Element.insert($$('body')[0], createdForm.form);
755    createdForm.form.submit();
756}
757
758function customFormSubmitToParent(url, parametersArray, method) {
759    new Ajax.Request(url, {
760        method: method,
761        parameters: JSON.parse(parametersArray),
762        onSuccess: function (response) {
763            var node = document.createElement('div');
764            node.innerHTML = response.responseText;
765            var responseMessage = node.getElementsByClassName('messages')[0];
766            var pageTitle = window.document.body.getElementsByClassName('page-title')[0];
767            pageTitle.insertAdjacentHTML('afterend', responseMessage.outerHTML);
768            window.opener.focus();
769            window.opener.location.href = response.transport.responseURL;
770        }
771    });
772}

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.