1/** 2 * Eastman site meta â favicons, Open Graph, Twitter cards. 3 * Runs on every page. Static HTML may also include base tags for non-JS crawlers. 4 */ 5(function (global) { 6 "use strict"; 7 8 var ORIGIN = (global.location && /^https?:$/.test(global.location.protocol) && global.location.origin) 9 ? global.location.origin 10 : "https://eastmanbicycles.com"; 11 var DEFAULT_IMAGE = ORIGIN + "/assets/og-default.jpg?v=2"; 12 var DEFAULT_IMAGE_WIDTH = "1200"; 13 var DEFAULT_IMAGE_HEIGHT = "630"; 14 var SITE_NAME = "Eastman Bicycles"; 15 16 function upsertMeta(attr, key, content) { 17 if (!content) return; 18 var sel = 'meta[' + attr + '="' + key + '"]'; 19 var el = document.head.querySelector(sel); 20 if (!el) { 21 el = document.createElement("meta"); 22 el.setAttribute(attr, key); 23 document.head.appendChild(el); 24 } 25 el.setAttribute("content", content); 26 } 27 28 function desc() { 29 var m = document.querySelector('meta[name="description"]'); 30 return m ? m.getAttribute("content") || "" : ""; 31 } 32 33 function canonical() { 34 if (global.EastmanSEO && global.EastmanSEO.canonicalUrl) { 35 return global.EastmanSEO.canonicalUrl(); 36 } 37 var link = document.querySelector('link[rel="canonical"]'); 38 return link ? link.getAttribute("href") : ORIGIN + (location.pathname || "/"); 39 } 40 41 function pageImage() { 42 var body = document.body; 43 if (body && body.getAttribute("data-og-image")) { 44 var custom = body.getAttribute("data-og-image"); 45 if (custom.indexOf("http") === 0) return custom; 46 return ORIGIN + (custom.charAt(0) === "/" ? custom : "/" + custom); 47 } 48 var og = document.querySelector('meta[property="og:image"]'); 49 if (og && og.getAttribute("content")) { 50 var existing = og.getAttribute("content"); 51 // Old wide/low wordmark crops badly in social previews â upgrade to OG canvas 52 if (/eastman-logo-footer\.png/i.test(existing)) return DEFAULT_IMAGE; 53 return existing; 54 } 55 var hero = document.querySelector(".pdp-media img, .banner-tile--hero img, .about-media img"); 56 if (hero && hero.getAttribute("src")) { 57 var src = hero.getAttribute("src"); 58 if (src.indexOf("http") === 0) return src; 59 if (src.charAt(0) === "/") return ORIGIN + src; 60 return ORIGIN + "/" + src.replace(/^\.\.\//, ""); 61 } 62 return DEFAULT_IMAGE; 63 } 64 65 function ogType() { 66 var page = (document.body && document.body.getAttribute("data-page")) || ""; 67 if (page === "products" && /[?&](id|bike)=/.test(location.search || "")) return "product"; 68 if (page === "product") return "product"; 69 if (page === "country") return "website"; 70 return "website"; 71 } 72 73 function locale() { 74 var lang = (document.documentElement.getAttribute("lang") || "en").replace("-", "_"); 75 if (lang.indexOf("_") === -1) { 76 if (lang === "es") return "es_MX"; 77 if (lang === "pt") return "pt_BR"; 78 if (lang === "de") return "de_DE"; 79 if (lang === "nl") return "nl_NL"; 80 if (lang === "fr") return "fr_FR"; 81 if (lang === "it") return "it_IT"; 82 return "en_US"; 83 } 84 return lang; 85 } 86 87 function removeFaviconLinks() { 88 var nodes = document.head.querySelectorAll( 89 'link[rel="icon"], link[rel="shortcut icon"], link[rel="apple-touch-icon"], link[rel="mask-icon"]' 90 ); 91 Array.prototype.forEach.call(nodes, function (el) { 92 el.parentNode.removeChild(el); 93 }); 94 } 95 96 function addLink(rel, href, extras) { 97 var el = document.createElement("link"); 98 el.setAttribute("rel", rel); 99 el.setAttribute("href", href); 100 if (extras) { 101 Object.keys(extras).forEach(function (k) { 102 el.setAttribute(k, extras[k]); 103 }); 104 } 105 document.head.appendChild(el); 106 } 107 108 function applyFavicons() { 109 // Always replace every icon tag. Old cached site-meta / WP leftovers used the 110 // wide wordmark logo as a 32x32 favicon (invisible in the tab). 111 var v = "5"; 112 removeFaviconLinks(); 113 addLink("icon", ORIGIN + "/favicon.ico?v=" + v, { sizes: "any" }); 114 addLink("icon", ORIGIN + "/favicon-32.png?v=" + v, { type: "image/png", sizes: "32x32" }); 115 addLink("icon", ORIGIN + "/assets/eastman-mark.png?v=" + v, { type: "image/png", sizes: "192x192" }); 116 addLink("icon", ORIGIN + "/favicon.svg?v=" + v, { type: "image/svg+xml" }); 117 addLink("apple-touch-icon", ORIGIN + "/assets/apple-touch-icon.png?v=" + v, { sizes: "180x180" }); 118 addLink("mask-icon", ORIGIN + "/favicon.svg?v=" + v, { color: "#e
11811b22" }); 119 upsertMeta("name", "theme-color", "#e11b22"); 120 upsertMeta("name", "msapplication-TileColor", "#e11b22"); 121 } 122 123 function applySocial(opts) { 124 opts = opts || {}; 125 var title = opts.title || document.title || SITE_NAME; 126 var description = opts.description || desc(); 127 var url = opts.url || canonical(); 128 var image = opts.image || pageImage(); 129 var type = opts.type || ogType(); 130 131 upsertMeta("property", "og:type", type); 132 upsertMeta("property", "og:site_name", SITE_NAME); 133 upsertMeta("property", "og:locale", locale()); 134 upsertMeta("property", "og:title", title); 135 upsertMeta("property", "og:description", description); 136 upsertMeta("property", "og:url", url); 137 upsertMeta("property", "og:image", image); 138 upsertMeta("property", "og:image:width", DEFAULT_IMAGE_WIDTH); 139 upsertMeta("property", "og:image:height", DEFAULT_IMAGE_HEIGHT); 140 upsertMeta("property", "og:image:type", "image/jpeg"); 141 var imageAlt = opts.imageAlt || document.title || (SITE_NAME + " â complete bicycles and bicycle parts"); 142 upsertMeta("property", "og:image:alt", imageAlt); 143 144 upsertMeta("name", "twitter:card", "summary_large_image"); 145 upsertMeta("name", "twitter:site", "@eastmanbicycle"); 146 upsertMeta("name", "twitter:creator", "@eastmanbicycle"); 147 upsertMeta("name", "twitter:title", title); 148 upsertMeta("name", "twitter:description", description); 149 upsertMeta("name", "twitter:image", image); 150 upsertMeta("name", "twitter:image:alt", imageAlt); 151 152 upsertMeta("name", "author", "Eastman Industries Limited"); 153 upsertMeta("name", "application-name", SITE_NAME); 154 } 155 156 function apply() { 157 if (!document.head) return; 158 applyFavicons(); 159 applySocial(); 160 } 161 162 global.EastmanMeta = { 163 apply: apply, 164 applySocial: applySocial, 165 defaultImage: DEFAULT_IMAGE, 166 }; 167 168 if (document.readyState === "loading") { 169 document.addEventListener("DOMContentLoaded", apply); 170 } else { 171 apply(); 172 } 173})(typeof window !== "undefined" ? window : this);
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.