1(InnStyle = function (domain, opts) { 2 if (!domain && !opts) { 3 return; 4 } 5 var options = { 6 width: "100%", 7 height: 500, 8 domain: domain, 9 unique: `iframe-${Math.random().toString(36).substring(2, 5)}`, 10 color: "dark", // light, dark 11 policy: "show", // hide, show 12 target: null, 13 bookable: null, 14 date_in_view: null, 15 offset: 0, // useful if fixed position navbar 16 calendar: "show", // show, hide 17 packages: "show", // show, hide 18 protocol: "https", 19 env: "innstyle.co.uk", 20 datepicker: "all", 21 custom_enquiry_page: false, 22 calendar_for: null, 23 force_enquiry: null, 24 force_calendar: null, 25 staylist_search: false, 26 ignore_default_css: null, 27 no_bookable_name: null, 28 force_id: null, 29 ga: null, 30 start_date: null, 31 nights: null, 32 adults: 2, 33 infants: null, 34 children: null, 35 child_ages: null, 36 dogs: null, 37 console_debug: false, // this can be changed after load with window.innstyle_console_debug = true 38 secret_code: null, 39 listing: null, 40 enquiry: null, 41 locale: "en", 42 path: null, 43 destination: null, 44 host: null, 45 overflow: 500, 46 zIndex: 1, 47 }, 48 repainted = false, 49 log = function () { 50 if (innstyle_console_debug) { 51 console.log.apply(console.log, arguments); 52 } 53 }, 54 ext = function (object1, object2) { 55 for (var key in object2) { 56 if (key in object1) { 57 if (object1[key] && object1[key].constructor == Object) { 58 ext(object1[key], object2[key]); 59 } else { 60 object1[key] = object2[key]; 61 } 62 } 63 } 64 }, 65 render = function (tpl, data) { 66 var output = tpl, 67 dotData = function (d, dotKey) { 68 var invert = ""; 69 if (dotKey.indexOf("!") > -1) { 70 dotKey = dotKey.replace(/!/gi, ""); 71 invert = "!"; 72 } 73 try { 74 val = eval(invert + "d['" + dotKey.split(".").join("']['") + "']"); 75 } catch (e) { 76 val = ""; 77 } 78 return val; 79 }, 80 matches = tpl.match(/\{\{[^}}]*\}\}/gim); 81 for (var i = 0; i < matches.length; ++i) { 82 var m = matches[i], 83 val = dotData(data, matches[i].replace(/\{\{|\}\}/gi, "")) || ""; 84 output = output.replace(new RegExp(m, "igm"), val); 85 } 86 return output; 87 }, 88 build_path = function () { 89 if (options.host) { 90 base = "//{{host}}"; 91 } else { 92 base = "//{{domain}}.{{env}}"; 93 } 94 95 if (options.path) { 96 base = base + options.path; 97 } else if (options.calendar_for) { 98 base = base + "/calendar/" + String(options.calendar_for); 99 } else if (options.custom_enquiry_page) { 100 base = base + "/custom_enquiries/" + options.enquiry; 101 } else if (options.force_enquiry) { 102 base = base + "/enquiries/" + options.enquiry; 103 } else if (options.staylist_search) { 104 base = base + "/form"; 105 } else if (options.listing && options.enquiry) { 106 base = 107 base + 108 "/listings/" + 109 options.listing + 110 "/enquiries/" + 111 options.enquiry; 112 } else if (options.listing && options.force_calendar) { 113 base = base + "/listings/" + options.listing + "/calendars"; 114 } else if (options.listing) { 115 base = base + "/listings/" + options.listing; 116 } else if (options.enquiry) { 117 base = base + "/enquiries/" + options.enquiry; 118 } 119 120 function setCustomOrForcedEnquiryId() { 121 try { 122 const urlParams = new URLSearchParams(window.location.search); 123 const customEnquiryId = urlParams.get("custom_enquiry_id"); 124 return customEnquiryId || options.force_enquiry; 125 } catch (error) { 126 return options.force_enquiry; 127 } 128 } 129 130 let customURLParams = { 131 iframe: "1", 132 locale: options.locale, 133 color: options.color, 134 policy: options.policy, 135 bookable_id: options.bookable, 136 date_in_view: options.date_in_view, 137 calendar: options.calendar, 138 packages: options.packages, 139 datepicker: options.datepicker, 140 custom_enquiry_page: options.custom_enquiry_page, 141 force_enquiry: setCustomOrForcedEnquiryId(), 142 no_iframe_css: options.ignore_default_css, 143 no_bookable_name: options.no_bookable_name, 144 bo: options.force_id, 145 start_date: options.start_date, 146 secret_code: options.secret_code, 147 nights: options.nights, 148 adults: options.adults, 149 infants: options.infants, 150 children: options.children,
151 child_ages: options.child_ages, 152 dogs: options.dogs, 153 destination_id: options.destination, 154 }; 155 let compactCustomURLParams = Object.entries(customURLParams).reduce( 156 (a, [k, v]) => (v ? ((a[k] = v), a) : a), 157 {}, 158 ); 159 let customQueryString = new URLSearchParams( 160 compactCustomURLParams, 161 ).toString(); 162 163 return base + "?" + customQueryString; 164 }, 165 build_secure_path = function () { 166 if (options.host) { 167 return "https://{{host}}"; 168 } else if (options.env != "innstyle.co.uk") { 169 return "{{protocol}}://{{domain}}.{{env}}"; 170 } else { 171 return "https://{{domain}}.{{env}}"; 172 } 173 }, 174 google_track = function () { 175 if (typeof ga != "function") { 176 log( 177 "Cannot do GA tracking; GA has not been loaded in globally available ga variable", 178 ); 179 return; 180 } 181 ga("create", options.ga, "auto"); 182 ga(function (tracker) { 183 var clientId = tracker.get("clientId"); 184 var frameWindow = 185 document.getElementById("InnStyle_iFrame1").contentWindow; 186 var destination = render(build_secure_path(), options); 187 log("postMessage clientID: " + clientId); 188 log("postMessage destination: " + destination); 189 frameWindow.postMessage(clientId, destination); 190 }); 191 }, 192 build = function () { 193 var scripts = document.scripts[document.scripts.length - 1], 194 div = document.createElement("div"), 195 iframe = document.createElement("iframe"); 196 div.id = "InnStyle_Container1"; 197 div.style.position = "relative"; 198 div.style.zIndex = options.zIndex; 199 iframe.id = "InnStyle_iFrame1"; 200 iframe.title = "InnStyle Booking Engine"; 201 iframe.name = options.unique; 202 iframe.src = render(build_path(), options); 203 iframe.width = options.width; 204 iframe.height = "100%"; 205 iframe.frameBorder = 0; 206 iframe.scrolling = "yes"; 207 iframe.style.width = "1px"; 208 iframe.style.minWidth = "100%"; 209 iframe.style.display = "block"; 210 div.appendChild(iframe); 211 if (options.target === null) { 212 scripts.parentNode.insertBefore(div, scripts); 213 } else { 214 var target = document.getElementById(options.target); 215 if (target === null) { 216 alert( 217 "Target not found, have you put the div#target after the script?", 218 ); 219 return; 220 } 221 target.appendChild(div); 222 } 223 224 if (options.ga) { 225 setTimeout(function () { 226 google_track(); 227 }, 3000); 228 } 229 }, 230 done = function (event) { 231 if (event.data.iframe) { 232 var iframe = document.getElementsByName(event.data.iframe)[0], 233 div = iframe.parentElement, 234 intRegex = /^\d+$/; 235 if (intRegex.test(event.data.height)) { 236 log("Height received: " + event.data.height); 237 // remove scrolling as we know we can get height from embed 238 iframe.scrolling = "no"; 239 // datepickers and popovers can't overflow iFrame, 240 // BUT can overflow wrapping div 241 // so we make the iframe at 500px 242 // and set the height of wrapping div to that of the content 243 var new_height = Math.round(event.data.height); 244 div.style.height = new_height + "px"; 245 iframe.height = new_height; 246 247 log("Height changed to: " + new_height); 248 249 // Force repaint 250 // (Chrome can sometimes block overflow content being clicked) 251 // https://stackoverflow.com/a/3485654 252 if (!repainted) { 253 div.style.display = "none"; 254 div.offsetHeight; // no need to store this anywhere, the reference is enough 255 div.style.display = ""; 256 repainted = true; 257 log("Forced repaint"); 258 } 259 } 260 261 if (event.data.clicked_date || event.data.scrollIntoView) { 262 div.scrollIntoView({ behavior: "smooth" }); 263 } 264 265 // Dynamically add and remove iframe buffer to handle overflowing content 266 if (event.data.overflowIframe) { 267 log( 268 "overflowIframe: Setting iframe to a little taller than its containing div", 269 ); 270 iframe.height = div.clientHeight + options.overflow; 271 } 272 if (event.data.containIframe) { 273 log("containIframe: Setting iframe to exact containing div height"); 274 iframe.height = div.clientHeight; 275 } 276 } 277 }, 278 checkSubDomain = function (str, theoptions) {
279 if (theoptions && theoptions.host) { 280 return true; 281 } else { 282 var pattern = new RegExp( 283 /[-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi, 284 ); 285 if (!pattern.test(str)) { 286 if (str.match(/[^\-a-zA-Z0-9]/)) { 287 alert( 288 "Looks like you have invalid characters in your Inn Style subdomain.", 289 ); 290 return false; 291 } 292 return true; 293 } else { 294 alert( 295 "Looks like you entered a URL. Please try just your Inn Style subdomain.", 296 ); 297 return false; 298 } 299 } 300 }, 301 init = function (theoptions) { 302 checkSubDomain(domain, theoptions); 303 if (window.addEventListener) { 304 addEventListener("message", done, false); 305 } else { 306 attachEvent("onmessage", done); 307 } 308 if (theoptions && theoptions !== undefined) { 309 if (theoptions.constructor == String) { 310 var a = theoptions.split("/"), 311 b = {}; 312 ext(a, b); 313 } else if (theoptions.constructor == Object) { 314 ext(options, theoptions); 315 } 316 } 317 window.innstyle_console_debug = options.console_debug; 318 build(); 319 }; 320 this.create = function () { 321 init(opts); 322 }; 323 if (this.constructor != InnStyle) { 324 new InnStyle(domain, opts).create(); 325 } 326}).call(); 327 328Staylists = function (domain, opts) { 329 if (typeof domain === "object") { 330 // no domain provided, domain var is actually options 331 InnStyle(null, domain); 332 } else { 333 InnStyle(domain, opts); 334 } 335}; 336 337Bliss = function (domain, opts) { 338 Staylists(domain, opts); 339};
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.