1Packeta = window.Packeta || {} 2Packeta.Viewport = { 3 element: null, 4 originalValue: null, 5 set: function() { 6 if (!Packeta.Viewport.element) { 7 Packeta.Viewport.element = document.querySelector("meta[name=viewport]") 8 if (Packeta.Viewport.element) { 9 Packeta.Viewport.originalValue = Packeta.Viewport.element.getAttribute("content") 10 } else { 11 Packeta.Viewport.originalValue = 'user-scalable=yes' 12 Packeta.Viewport.element = document.createElement('meta') 13 Packeta.Viewport.element.setAttribute("name", "viewport"); 14 (document.head || document.getElementsByTagName('head')[0]).appendChild(Packeta.Viewport.element) 15 } 16 } 17 Packeta.Viewport.element.setAttribute('content', 'width=device-width, initial-scale=1.0, minimum-scale=1.0, user-scalable=yes') 18 }, 19 restore: function() { 20 if (Packeta.Viewport.originalValue !== null) { 21 Packeta.Viewport.element.setAttribute('content', Packeta.Viewport.originalValue) 22 } 23 } 24} 25 26Packeta.Util = { 27 28 makeRequest: function(method, url, data, callback) { 29 try { 30 var xhr = new XMLHttpRequest() 31 xhr.open(method, url) 32 xhr.timeout = 5000 33 34 xhr.onload = function() { 35 if (this.status >= 200 && this.status < 300) { 36 callback(xhr.response, false) 37 } else { 38 callback({ 39 status: this.status, 40 statusText: xhr.statusText 41 }, true) 42 } 43 } 44 45 xhr.onerror = function() { 46 callback({ 47 status: this.status, 48 statusText: xhr.statusText 49 }, true) 50 } 51 52 xhr.ontimeout = function() { 53 callback({ 54 status: this.status, 55 statusText: xhr.statusText 56 }, true) 57 } 58 59 if (method === "POST" && data) { 60 xhr.send(data) 61 } else { 62 xhr.send() 63 } 64 } catch (error) { 65 callback({ 66 error: "XMLHttpRequest error: " + error 67 }, true) 68 } 69 } 70} 71 72Packeta.Widget = { 73 baseUrl: 'https://widget.packeta.com/', 74 backupUrl: 'https://backup.widget.packeta.com/', 75 healthUrl: 'https://widget.packeta.com/v6/api/hcs/api/healthcheck', 76 versions: { 77 backup: 'backup', 78 base: 'base' 79 }, 80 close: function() {}, 81 initIframe: function(apiKey, callback, opts, inElement) { 82 Packeta.Widget.close() 83 84 if (!opts) { 85 opts = {} 86 } 87 if (!('version' in opts)) { 88 opts.version = 3 89 } 90 91 opts.apiKey = apiKey 92 93 var url = Packeta.Widget.baseUrl 94 95 if (opts.currentVersion === Packeta.Widget.versions.backup) { 96 url = Packeta.Widget.backupUrl 97 } 98 99 url = url + 'v6/#/?' 100 101 for (let param in opts) { 102 url += "&" + param + "=" + encodeURIComponent(opts[param]) 103 } 104 105 var inline = (typeof(inElement) != "undefined" && inElement !== null) 106 var wrapper 107 if (inline) { 108 wrapper = inElement 109 } else { 110 Packeta.Viewport.set() 111 wrapper = document.createElement("div") 112 wrapper.setAttribute("style", "z-index: 999999; position: fixed; -webkit-backface-visibility: hidden; left: 0; top: 0; width: 100%; height: 100%; background: " + (opts.overlayColor || "rgba(0, 0, 0, 0.3)") + "; ") 113 wrapper.addEventListener("click", function() { 114 Packeta.Widget.close() 115 }) 116 117 // fix for some older browsers which fail to do 100% width of position:absolute inside position:fixed element 118 setTimeout( 119 function() { 120 var rect = iframe.getBoundingClientRect() 121 var width = ('width' in rect ? rect.width : rect.right - rect.left) 122 if (Math.round(width) < window.innerWidth - 100) { // 10px = side padding sum, just as a safety measure 123 iframe.style.width = window.innerWidth + "px" 124 iframe.style.height = window.innerHeight + "px" 125 } 126 }, 127 0 128 ) 129 } 130
131 // always support Escape key immediatelly after the widget is displayed, even for inline 132 wrapper.addEventListener("keyup", function(e) { 133 if (e.keyCode == 27) { 134 Packeta.Widget.close() 135 } 136 }) 137 138 var iframe = document.createElement("iframe") 139 if (inline) { 140 iframe.setAttribute("style", "border: hidden; width: 100%; height: 100%; ") 141 } else { 142 iframe.setAttribute("style", "border: hidden; position: absolute; left: 0; top: 0; width: 100%; height: 100%; padding: 10px 5px; box-sizing: border-box; ") 143 } 144 iframe.setAttribute('id', "packeta-widget") 145 iframe.setAttribute('sandbox', "allow-scripts allow-same-origin allow-popups") 146 iframe.setAttribute('allow', "geolocation") 147 iframe.setAttribute('allowfullscreen', "true") 148 iframe.setAttribute('src', url) 149 150 wrapper.appendChild(iframe) 151 if (!inline) { 152 document.body.appendChild(wrapper) 153 } 154 155 if (wrapper.getAttribute("tabindex") === null) { 156 wrapper.setAttribute("tabindex", "-1") // make it focusable 157 } 158 wrapper.focus() 159 160 var receiver = function(e) { 161 // check if this is message from the Packeta Widget 162 try { 163 var message = typeof e.data === "object" ? e.data : JSON.parse(e.data) 164 if (!message.packetaWidgetMessage) return 165 } catch (err) { 166 return 167 } 168 if (opts.layout && ['hd', 'ac', 'rs'].includes(opts.layout.toLocaleLowerCase())) { 169 Packeta.Widget.close(message) 170 } else { 171 Packeta.Widget.close(message.packetaPoint) 172 } 173 174 175 } 176 window.addEventListener('message', receiver) 177 178 Packeta.Widget.close = function(point) { 179 window.removeEventListener('message', receiver) 180 if (inline) { 181 try { 182 iframe.parentNode.removeChild(iframe) 183 } catch (err) { 184 // ignore 185 } 186 } else { 187 document.body.removeChild(wrapper) 188 Packeta.Viewport.restore() 189 } 190 callback(point || null) 191 Packeta.Widget.close = function() {} 192 } 193 }, 194 pick: function(apiKey, callback, opts, inElement) { 195 196 if (!opts) { 197 opts = {} 198 } 199 200 opts.loader = 'library' 201 opts.referrer = window.location.origin 202 203 const vendorsKey = Object.keys(opts) 204 .find(key => (key.toLowerCase() === "vendors")) 205 206 if (vendorsKey && typeof opts[vendorsKey] === 'object') { 207 try { 208 opts[vendorsKey] = opts[vendorsKey] 209 .map(item => ( 210 `${item.country || ''},` 211 + `${item.group || ''},` 212 + `${item.carrierId || ''},` 213 + `${item.currency || ''},` 214 + `${(item.price || item.price === 0) ? item.price : ''},` 215 + `${item.selected || ''}`)) 216 .join('|') 217 } catch (error) { 218 opts[vendorsKey] = '' 219 } 220 } 221 222 if (opts.layout && ['hd', 'ac', 'rs'].includes(opts.layout.toLocaleLowerCase())) { 223 Packeta.Widget.baseUrl = 'https://hd.widget.packeta.com/' 224 Packeta.Widget.backupUrl = 'https://backup.widget.packeta.com/' 225 Packeta.Widget.healthUrl = 'https://hd.widget.packeta.com/api/hcs/api/healthcheck' 226 } else { 227 Packeta.Widget.baseUrl = 'https://widget.packeta.com/' 228 Packeta.Widget.backupUrl = 'https://backup.widget.packeta.com/' 229 Packeta.Widget.healthUrl = 'https://widget.packeta.com/v6/api/hcs/api/healthcheck' 230 } 231 232 function runBase() { 233 opts.currentVersion = Packeta.Widget.versions.base 234 Packeta.Widget.initIframe(apiKey, callback, opts, inElement) 235 }; 236 237 function runBA() { 238 opts.currentVersion = Packeta.Widget.versions.backup 239 Packeta.Widget.initIframe(apiKey, callback, opts, inElement) 240 } 241
242 Packeta.Util.makeRequest("GET", Packeta.Widget.healthUrl, null, function(data, error) { 243 244 if (!error) { 245 246 var result = data.toLocaleLowerCase() === "true" 247 248 // console.log("Widget health check result: " + result) 249 250 if (result === true) { 251 // console.log("starting Widget") 252 runBase() 253 } else { 254 // console.log("starting backup environment") 255 runBA() 256 } 257 258 } else { 259 // console.log("Widget health check result: " + JSON.stringify(data)) 260 // console.log("starting backup environment") 261 runBA() 262 } 263 }) 264 265 266 } 267}
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.