1 2// make sure all variables are defined 3if (typeof(functionCallAfterWindowLoad) == "undefined") var functionCallAfterWindowLoad = false; 4if (typeof(is_mobile_skin) == "undefined") var is_mobile_skin = false; 5if (typeof(app_ios_id) == "undefined") var app_ios_id = ''; 6if (typeof(app_android_id) == "undefined") var app_android_id = ''; 7if (typeof(app_kindle_url) == "undefined") var app_kindle_url = ''; 8if (typeof(app_board_url) == "undefined") var app_board_url = ''; 9if (typeof(app_forum_name) == "undefined" || !app_forum_name) var app_forum_name = "this forum"; 10if (typeof(app_banner_message) == "undefined" || !app_banner_message) var app_banner_message = "Follow {your_forum_name} <br /> with {app_name} for [os_platform]"; 11if (typeof(app_location_url) == "undefined" || !app_location_url) var app_location_url = "tapatalk://"; 12var app_location_url_byo = app_location_url.replace('tapatalk://', 'tapatalk-byo://'); 13 14// set default iOS app for native smart banner 15var app_ios_id_default = '307880732'; // Tapatalk Free, 585178888 for Tapatalk Pro 16var app_ios_hd_id_default = '307880732'; // Tapatalk Free, 481579541 for Tapatalk HD 17 18// Support native iOS Smartbanner 19var native_ios_banner = false; 20if (app_ios_id != '-1' && navigator.userAgent.match(/Safari/i) != null && 21 (navigator.userAgent.match(/CriOS/i) == null && window.Number(navigator.userAgent.
21substr(navigator.userAgent.indexOf('OS ') + 3, 3).replace('_', '.')) >= 6)) 22{ 23 banner_location_url = app_ios_id ? app_location_url_byo : app_location_url; 24 25 if (navigator.userAgent.match(/iPad/i) != null) 26 { 27 document.write('<meta name="apple-itunes-app" content="app-id='+(app_ios_id ? app_ios_id : app_ios_hd_id_default)+', app-argument='+banner_location_url+', affiliate-data=partnerId=30&siteID=w5J2vu1UnxA" />'); 28 native_ios_banner = true; 29 } 30 else if (navigator.userAgent.match(/iPod|iPhone/i) != null) 31 { 32 document.write('<meta name="apple-itunes-app" content="app-id='+(app_ios_id ? app_ios_id : app_ios_id_default)+', app-argument='+banner_location_url+', affiliate-data=partnerId=30&siteID=w5J2vu1UnxA" />'); 33 native_ios_banner = true; 34 } 35} 36 37// initialize app download url 38var app_install_url = 'http://tapatalk.com/m/?id=6'; 39if (app_ios_id) app_install_url = app_install_url+'&app_ios_id='+app_ios_id; 40if (app_android_id) app_install_url = app_install_url+'&app_android_id='+app_android_id; 41if (app_kindle_url) app_install_url = app_install_url+'&app_kindle_url='+app_kindle_url; 42if (app_board_url) app_install_url = app_install_url+'&referer='+app_board_url; 43 44 45// for those forum system which can not add js in html body 46if (functionCallAfterWindowLoad) addWindowOnload(tapatalkDetect) 47 48var bannerLoaded = false 49 50function tapatalkDetect() 51{ 52 var standalone = navigator.standalone // Check if it's already a standalone web app or running within a web ui view of an app (not mobile safari) 53 54 // work only when browser support cookie 55 if (!navigator.cookieEnabled 56 || bannerLoaded 57 || standalone 58 || document.cookie.indexOf("banner-closed=true") >= 0 59 || native_ios_banner) 60 return 61 62 bannerLoaded = true 63 64 app_banner_message = app_banner_message.replace(/\{your_forum_name\}/gi, app_forum_name); 65 app_banner_message = app_banner_message.replace(/\{app_name\}/gi, "Tapatalk"); 66 67 if (navigator.userAgent.match(/iPhone|iPod/i)) { 68 if (app_ios_id == '-1') return; 69 app_banner_message = app_banner_message.replace(/\[os_platform\]/gi, 'iPhone'); 70 banner_location_url = app_ios_id ? app_location_url_byo : app_location_url; 71 } 72 else if (navigator.userAgent.match(/iPad/i)) { 73 if (app_ios_id == '-1') return; 74 app_banner_message = app_banner_message.replace(/\[os_platform\]/gi, 'iPad'); 75 banner_location_url = app_ios_id ? app_location_url_byo : app_location_url; 76 } 77 else if (navigator.userAgent.match(/Silk|KFOT|KFTT|KFJWI|KFJWA/)) { 78 if (app_kindle_url == '-1') return; 79 app_banner_message = app_banner_message.replace(/\[os_platform\]/gi, 'Kindle'); 80 banner_location_url = app_kindle_url ? app_location_url_byo : app_location_url; 81 } 82 else if (navigator.userAgent.match(/Android/i)) { 83 if (app_android_id == '-1') return; 84 app_banner_message = app_banner_message.replace(/\[os_platform\]/gi, 'Android'); 85 banner_location_url = app_android_id ? app_location_url_byo : app_location_url; 86 } 87 else if (navigator.userAgent.match(/IEMobile|Windows Phone/i)) { 88 if (app_ios_id || app_android_id || app_kindle_url) return; 89 app_banner_message = app_banner_message.replace(/\[os_platform\]/gi, 'Windows Phone'); 90 banner_location_url = app_location_url; 91 } 92 /* 93 else if (navigator.userAgent.match(/BlackBerry/i)) { 94 app_banner_message = app_banner_message.replace(/\[os_platform\]/gi, 'BlackBerry'); 95 banner_location_url = app_location_url; 96 } 97 */ 98 else 99 return 100 101 102 htmlElement = document.getElementsByTagName("html")[0] 103 origHtmlMargin = parseFloat(htmlElement.style.marginTop) 104 if ( isNaN(origHtmlMargin)) origHtmlMargin = 0 105 106 var bannerScale = document.body.clientWidth / window.screen.width 107 108 if (bannerScale < 1 || (is_mobile_skin && navigator.userAgent.match(/mobile/i))) bannerScale = 1; 109
110 // mobile portrait mode may need bigger scale 111 if (window.innerWidth < window.innerHeight) 112 { 113 if (bannerScale < 2 && !is_mobile_skin && document.body.clientWidth > 600) { 114 bannerScale = 2 115 } else if (bannerScale > 2.8) { 116 bannerScale = 2.8 117 } 118 } 119 else 120 { 121 if (navigator.userAgent.match(/mobile/i) && bannerScale < 1.5 && !is_mobile_skin && document.body.clientWidth > 600) { 122 bannerScale = 1.5 123 } else if (bannerScale > 2) { 124 bannerScale = 2 125 } 126 } 127 128 129 bodyItem = document.body 130 appBanner = document.createElement("div") 131 appBanner.id = "mobile_banner" 132 appBanner.className = "mobile_banner banner_format_handset banner_device_android banner_theme_light mobile_banner_animate" 133 appBanner.innerHTML = 134 '<div class="mobile_banner_inner">'+ 135 '<span class="mobile_banner_icon"></span>'+ 136 '<div class="mobile_banner_body">'+ 137 '<h3 class="mobile_banner_heading">'+app_banner_message+'</h3>'+ 138 '</div>'+ 139 '<div class="mobile_banner_controls">'+ 140 '<a class="mobile_banner_button chrome white mobile_banner_open" href="'+banner_location_url+'" id="mobile_banner_open">'+'Open in app'+'</a>'+ 141 '<a class="mobile_banner_button chrome blue mobile_banner_install" href="'+app_install_url+'" id="mobile_banner_install">'+'Install'+'</a>'+ 142 '<a class="mobile_banner_close" href="#" onclick="closeBanner()" id="mobile_banner_close">x</a>'+ 143 '</div>'+ 144 '</div>' 145 bodyItem.insertBefore(appBanner, bodyItem.firstChild) 146 147 if (bannerScale > 1) { 148 appBanner.style.fontSize = (8*bannerScale)+"px" 149 } 150 151 bannerHeight = getWH(appBanner, 'height', true) 152 bannerTop = (origHtmlMargin+bannerHeight)+"px" 153 htmlElement.style.marginTop = bannerTop 154 155 if (getComputedStyle(bodyItem, null).position !== 'static') 156 appBanner.style.top = '-'+bannerTop 157 158 addWindowOnload(resetBannerTop) 159} 160 161function addWindowOnload(func) 162{ 163 if (typeof window.onload != 'function') { 164 window.onload = func; 165 } else { 166 var oldonload = window.onload; 167 window.onload = function() { 168 oldonload(); 169 func(); 170 } 171 } 172} 173 174function resetBannerTop() 175{ 176 if (getComputedStyle(bodyItem, null).position !== 'static' || document.getElementById('google_translate_element')) 177 appBanner.style.top = '-'+bannerTop 178} 179 180function closeBanner() 181{ 182 bodyItem.removeChild( appBanner ) 183 htmlElement.style.marginTop = origHtmlMargin+"px" 184 setBannerCookies('banner-closed', 'true', 90) 185} 186 187function setBannerCookies(name, value, exdays) 188{ 189 var exdate = new Date(); 190 exdate.setDate(exdate.getDate()+exdays); 191 value=escape(value)+((exdays==null)?'':'; expires='+exdate.toUTCString()); 192 document.cookie=name+'='+value+'; path=/;'; 193} 194 195 196/* to get element outer height */ 197 198var defView = document.defaultView; 199 200var getStyle = defView && defView.getComputedStyle ? 201 function( elem ) { 202 return defView.getComputedStyle( elem, null ); 203 } 204 : 205 function( elem ) { 206 return elem.currentStyle; 207 }; 208 209function hackPercentMargin( elem, computedStyle, marginValue ) { 210 if ( marginValue.indexOf('%') === -1 ) { 211 return marginValue; 212 } 213 214 var elemStyle = elem.style, 215 originalWidth = elemStyle.width, 216 ret; 217 218 // get measure by setting it on elem's width 219 elemStyle.width = marginValue; 220 ret = computedStyle.width; 221 elemStyle.width = originalWidth; 222 223 return ret; 224} 225 226function getWH( elem, measure, isOuter ) 227{ 228 // Start with offset property 229 var isWidth = measure !== 'height', 230 val = isWidth ? elem.offsetWidth : elem.offsetHeight, 231 dirA = isWidth ? 'Left' : 'Top', 232 dirB = isWidth ? 'Right' : 'Bottom', 233 computedStyle = getStyle( elem ), 234 paddingA = parseFloat( computedStyle[ 'padding' + dirA ] ) || 0, 235 paddingB = parseFloat( computedStyle[ 'padding' + dirB ] ) || 0, 236 borderA = parseFloat( computedStyle[ 'border' + dirA + 'Width' ] ) || 0, 237 borderB = parseFloat( computedStyle[ 'border' + dirB + 'Width' ] ) || 0, 238 computedMarginA = computedStyle[ 'margin' + dirA ], 239 computedMarginB = computedStyle[ 'margin' + dirB ], 240 marginA, marginB; 241 242 var tmpDiv = document.createElement('div'); 243 tmpDiv.style.marginTop = '1%'; 244 bodyItem.appendChild( tmpDiv ); 245 var supportsPercentMargin = getStyle( tmpDiv ).marginTop !== '1%'; 246 bodyItem.removeChild( tmpDiv ); 247 248 if ( !supportsPercentMargin ) { 249 computedMarginA = hackPercentMargin( elem, computedStyle, computedMarginA ); 250 computedMarginB = hackPercentMargin( elem, computedStyle, computedMarginB ); 251 } 252 253 marginA = parseFloat( computedMarginA ) || 0; 254 marginB = parseFloat( computedMarginB ) || 0; 255 256 if ( val > 0 ) { 257 258 if ( isOuter ) { 259 // outerWidth, outerHeight, add margin 260 val += marginA + marginB; 261 } else { 262 // like getting width() or height(), no padding or border 263 val -= paddingA + paddingB + borderA + borderB; 264 } 265 266 } else { 267 268 // Fall back to computed then uncomputed css if necessary 269 val = computedStyle[ measure ]; 270 if ( val < 0 || val === null ) { 271 val = elem.style[ measure ] || 0; 272 } 273 // Normalize "", auto, and prepare for extra 274 val = parseFloat( val ) || 0; 275 276 if ( isOuter ) { 277 // Add padding, border, margin 278 val += paddingA + paddingB + marginA + marginB + borderA + borderB; 279 } 280 } 281 282 return val; 283}
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.