PageSourceSearch

https://electricliterature.com/wp-content/plugins/printful-shippin…/assets/js/product-customizer.js?ver=7.1.2

js electricliterature.com collected 2026-09-24 08:40:17 UTC 8,734 bytes, 207 lines download raw bytes

1/** Define class */
2var Printful_Product_Customizer;
3
4(function () {
5    'use strict';
6
7    /**
8     *
9     * @type {{modal: null, baseUrl: string, onCustomizeClick: onCustomizeClick, closeModal: closeModal, createModal: (function(string): HTMLDivElement), listenForResponse: listenForResponse, onCustomDesignSave: onCustomDesignSave}}
10     */
11    Printful_Product_Customizer = {
12        modal: null,
13        baseUrl: 'https://www.printful.com',
14
15        /**
16         * Handle click event
17         * @param {string} site_url
18         */
19        onCustomizeClick: function (site_url) {
20            var variation_id = jQuery('input[name="variation_id"]').val(); // get selected variation ID
21
22            if (!variation_id) {
23                // if variation does not exist, probably means single variant product
24                variation_id = jQuery('button[name="add-to-cart"]').val();
25            }
26
27            if (!variation_id) {
28                return;
29            }
30
31            var url = this.baseUrl + '/product-customizer/?website=' + site_url + '&variant=' + variation_id;
32
33            document.body.appendChild(this.createModal(url));
34            //start listening to post messaged
35            this.listenForResponse();
36        },
37
38        /**
39         * Close the modal element
40         */
41        closeModal: function () {
42            if (this.modal) {
43                this.modal.parentNode.removeChild(this.modal);
44                this.modal = null;
45            }
46        },
47
48        /**
49         * Create modal content
50         * @param {string} url
51         * @returns {HTMLDivElement}
52         */
53        createModal: function (url) {
54            // clear the old one just to be sure
55            this.closeModal();
56
57            // create iframe
58            var isMobileSafari = false;
59            var userAgent = (window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : false;
60
61            if (userAgent && userAgent.match(/iPhone|iPad|iPod/i)) {
62                isMobileSafari = true;
63            }
64
65            var modal = document.createElement('div');
66            modal.className = 'pf-customize-modal';
67            modal.setAttribute('style', 'position: fixed; z-index: 2147483648; padding: 20px; top: 0; width: 100%; height: 100%; left: 0; background: rgba(0, 0 , 0, 0.6); box-sizing: border-box;');
68
69
70            var modalHeader = document.createElement('div');
71            modalHeader.setAttribute('style', 'padding: 15px; border-bottom: 1px solid #e5e5e5; overflow:hidden; position:absolute; top:0; left:0; width:100%; box-sizing: border-box;');
72
73            var closeBtn = document.createElement('button');
74            closeBtn.onclick = this.closeModal.bind(this);
75            closeBtn.setAttribute('style', 'height:30px; width:30px; cursor:pointer; border:0px; background:0 0; padding:0; -webkit-appearance:none; color:#000; float:right; background:none;');
76            var closeImg = document.createElement('img');
77            closeImg.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAAAXNSR0IArs4c6QAAAgVJREFUaAXtmU2KwkAQhZ0hQbyDu7mIB3PhwoN5EXfeIYguJo9JQRMydurnNYxTDTH+dNWr71VD2mSzyZEOpAPpQDqQDqQD6UA6kA6kA80dOJ1O++Px+NVKGFrQ9Oh9WoMhPAzD5fF4XFpAQwNa0PRAf1iABXaMle7e+r4/nM/nqyVfLUZgx3nS3etutzuMddxqsfPf1cALsJKTAr0AK3omaPWSfj6f21ERx3zso5f3C1hob6da5nW8/KzuMLJVCgnpNEvDBMyGZsGibjMwC5oJ6waOhmbDhgBHQbeADQP2QreCDQW2QreEDQfWQreGpQCvhcY8bFTGk2wX8ZWMkGu5JCvPrstSmWj+vta9aX5TWGjSgJG8Ao0p80HrrAhRgSGigKbDoh468EroJrCoRf1vCUF/edA7/K+WtAJWFg19adM6XIGVWzPvcVmqweL+F1r6FhuPNbBys08zV9a89xy6pC0AlhgPdBiwp3BPrBY+BDii4Igca+DdwJGFRub6Dd4FzCiQkbOENwMzC2PmNgEzC5JusDTUwKxCBLQ8M7TU/5a6rruPReGYj/B9MDYo065MtqKl5n2qpfyu+l7dYWRceIIYDltWvtBp05ND5DQBI7CA3jKfDUMLo4C+W58N/2RyvAIahThSqEKhBU1VUE5OB9KBdCAdSAfSgXQgHUgH0oEQB74BG1sUIwNoL3cAAAAASUVORK5CYII=';
78            closeImg.setAttribute('style', 'height:30px; width:30px;');
79            closeBtn.appendChild(closeImg);
80            modalHeader.appendChild(closeBtn);
81
82            var modalHeaderTitle = document.createElement('h4');
83            modalHeaderTitle.className = 'product-customizer__header-title';
84            modalHeaderTitle.setAttribute('style', 'float: left;font-weight:bold;font-size:23px;color:#222;line-height:30px;margin:0px;clear:none;');
85            modalHeaderTitle.innerText = window.pfGlobalCustomizer && window.pfGlobalCustomizer.modal_title ? window.pfGlobalCustomizer.modal_title : 'Create a personalized design';
86            modalHeader.appendChild(modalHeaderTitle);
87
88            var modalContent = document.createElement('div');
89            modalContent.setAttribute('style', 'background-color: #fff; width: 100%; height: 100%;overflow:hidden;position:relative');
90            modalContent.appendChild(modalHeader);
91
92            var styles = document.createElement('style');
93            styles.innerHTML = '@media screen and (max-width: 768px) { .product-customizer__header-title {font-size: 16px !important;} }';
94            modalContent.appendChild(styles);
95
96            modal.appendChild(modalContent);
97
98            var iframe = document.createElement('iframe');
99            iframe.src = url;
100            iframe.width = '100%';
101            iframe.height = '100%';
102
103            if (isMobileSafari) {
104                var iframeWrapper = document.createElement('div');
105                iframeWrapper.setAttribute('style', '-webkit-overflow-scrolling: touch; overflow: scroll; height: 100%; top: 61px; box-sizing: border-box; position: absolute; width: 100%; padding-bottom: 60px;');
106                iframe.setAttribute('style', 'border: 0; box-sizing: border-box;');
107                iframeWrapper.appendChild(iframe);
108                modalContent.appendChild(iframeWrapper);
109            } else {
110                iframe.setAttribute('style', 'border: 0; padding-top: 60px; box-sizing: border-box;');
111                modalContent.appendChild(iframe);
112            }
113
114
115            this.modal = modal;
116
117            return modal;
118        },
119
120        /**
121         * Listen for response from PF
122         */
123        listenForResponse: function () {
124            var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
125            var eventer = window[eventMethod];
126            var messageEvent = eventMethod === "attachEvent" ? "onmessage" : "message";
127            eventer(messageEvent, function (e) {
128                if (e.origin !== this.baseUrl) {
129                    return;
130                }
131
132                if (typeof e.data['action'] === 'undefined' || e.data['action'] !== 'PFProductCustomized') {
133                    return;
134                }
135
136                this.onCustomDesignSave(e.data['hash']);
137            }.bind(this));
138        },
139
140        /**
141         * Manage response from PF
142         * @param {string} hash
143         */
144        onCustomDesignSave: function (hash) {
145            jQuery('#pfc_hash').val(hash);
146            this.closeModal();
147
148            jQuery('.single_add_to_cart_button').click();
149        }
150    };
151})();
152
153setInterval(function () {
154    /**
155     * @type {Array<HTMLImageElement>}
156     */
157    var toCheck = [];
158
159    jQuery('img.pf-image-pending').each(function () {
160        jQuery(this).removeClass('pf-image-pending');
161        jQuery(this).addClass('pf-image-checking');
162        toCheck.push(this);
163    });
164
165    var hashes = toCheck.reduce(function(carry, image){
166        carry[image.getAttribute('data-hash')] = image;
167
168        return carry;
169    }, {});
170
171    // Resolve admin base URL
172    var adminURL = window.pfGlobalCustomizer && window.pfGlobalCustomizer.admin_url && window.pfGlobalCustomizer.admin_url.length
173        ? window.pfGlobalCustomizer.admin_url
174        : '/wp-admin/';
175
176    // rtrim('/') + '/'
177    var hasSlash = adminURL.substring(adminURL.length - 1) === '/';
178    if (!hasSlash) {
179        adminURL += '/';
180    }
181
182    // if pending (loading) images exist, request image urls
183    if (Object.keys(hashes).length > 0) {
184        jQuery.ajax({
185            url: adminURL + 'admin-ajax.php',
186            type: 'GET',
187            data: {
188                action: 'printful_customized_thumb',
189                hashes: Object.keys(hashes)
190            },
191            success: function (response) {
192                var result = JSON.parse(response);
193                for (var hash in result){
194                    var image = hashes[hash];
195
196                    if (result[hash]) {
197                        image.src = result[hash];
198                        jQuery(image).removeClass('pf-image-checking');
199                    } else {
200                        jQuery(image).removeClass('pf-image-checking');
201                        jQuery(image).addClass('pf-image-pending');
202                    }
203                }
204            }
205        });
206    }
207}, 2000);

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.